UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

126 lines (125 loc) • 5.05 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. /** * Setup wizard steps for agent platforms and agent-CLI selection: detect * agent platform config dirs as stash sources, and pick a default agent CLI. */ import * as p from "../../cli/clack.js"; import { detectAgentCliProfiles, pickDefaultAgentProfile } from "../../integrations/agent/index.js"; import { detectAgentPlatforms } from "../detect.js"; import { readAgentEngineSelection } from "../engine-config.js"; import { prompt } from "../prompt.js"; // The just-computed source list is threaded through the private setup draft. export async function stepAgentPlatforms(current) { const platforms = detectAgentPlatforms(); if (platforms.length === 0) { p.log.info("No agent platform configurations detected."); return []; } const existingPaths = new Set((current.additionalSources ?? []).map((s) => s.path)); // Filter out platforms already configured const newPlatforms = platforms.filter((pl) => !existingPaths.has(pl.path)); if (newPlatforms.length === 0) { p.log.info(`Detected ${platforms.length} agent platform(s), all already configured as bundle sources.`); return []; } const selected = await prompt(() => p.multiselect({ message: "Found agent platform configurations. Add as bundle sources?", options: newPlatforms.map((pl) => ({ value: pl.path, label: pl.name, hint: pl.path, })), required: false, })); const entries = []; for (const selectedPath of selected) { const platform = newPlatforms.find((pl) => pl.path === selectedPath); if (platform) { entries.push({ type: "filesystem", path: platform.path, name: platform.name.toLowerCase().replace(/\s+/g, "-"), }); } } return entries; } /** * Print a feature capability summary after both connection steps are complete. */ export function printCapabilitySummary(smallModelSkipped, agentConfigured) { const lines = ["Setup complete. Here's what's enabled:", ""]; lines.push(" ✓ akm search, akm curate, akm show, akm index, akm remember — always available"); if (!smallModelSkipped) { lines.push(" ✓ akm improve, akm remember --enrich — small model configured"); } else { lines.push(" ✗ akm improve, akm remember --enrich — run `akm setup` to enable"); } if (agentConfigured) { lines.push(" ✓ akm proposal new, akm improve, akm task — agent configured"); } else { lines.push(" ✗ akm proposal new, akm improve, akm task — run `akm setup` to enable"); } p.note(lines.join("\n"), "Feature Summary"); } export async function stepAgentSelection(current, detections) { const currentAgentBlock = readAgentEngineSelection(current); const available = detections.filter((d) => d.available); if (available.length === 0) { return currentAgentBlock; } const initialValue = pickDefaultAgentProfile(detections, currentAgentBlock?.default) ?? available[0]?.name; const selectedDefault = await prompt(() => p.select({ message: "Which detected agent CLI should be the default?", options: [ ...available.map((d) => ({ value: d.name, label: d.name, hint: d.resolvedPath ?? d.bin, })), { value: "disabled", label: "Disabled", hint: "do not configure a default agent CLI" }, ], initialValue, })); if (selectedDefault === "disabled") { if (!currentAgentBlock?.engines) { return undefined; } return { ...(currentAgentBlock ?? {}), default: undefined, }; } return { ...(currentAgentBlock ?? {}), default: selectedDefault, }; } /** * Detect installed agent CLIs and produce an updated `agent` config block * with a sensible `default` (the first detected profile that the user has * not already overridden). * * Pure-ish: file system / PATH probes are routed through `detectFn` so * tests can drive the branches without touching the real PATH. * * @internal Exported for testing only. */ export function stepAgentCliDetection(current, detectFn = detectAgentCliProfiles) { const detections = detectFn(current); const currentAgentBlock = readAgentEngineSelection(current); const defaultName = pickDefaultAgentProfile(detections, currentAgentBlock?.default); // No installed agents found and no existing config → leave block absent. if (!defaultName && !currentAgentBlock) { return { detections }; } const agent = { ...(currentAgentBlock ?? {}), ...(defaultName ? { default: defaultName } : {}), }; return { agent, detections }; }