import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { runCli, resolveProject } from "./cli.ts"; /** * Slash commands, all prefixed `cbm:`. pi accepts `:` in command names (it's * also its own suffix delimiter, but registration + invocation work). */ export function registerCommands(pi: ExtensionAPI) { pi.registerCommand("cbm:index-status", { description: "Show codebase-memory index status for the current workspace", handler: async (args, ctx) => { const explicit = args?.trim(); const project = explicit || (await resolveProject(ctx.cwd)); if (!project) { ctx.ui.notify( `No indexed codebase-memory project found for ${ctx.cwd}. Pass a name: /cbm:index-status `, "warn", ); return; } let status: { status?: string; nodes?: number; edges?: number; root_path?: string; parse_partial?: { count?: number }; not_indexed?: { files_count?: number; dirs_count?: number }; }; try { status = JSON.parse(await runCli("index_status", { project })); } catch (e) { ctx.ui.notify(`index_status failed for ${project}: ${(e as Error).message}`, "error"); return; } const extras: string[] = []; if (status.parse_partial?.count) extras.push(`partial: ${status.parse_partial.count}`); if (status.not_indexed?.files_count) extras.push(`unindexed: ${status.not_indexed.files_count}`); ctx.ui.notify( `codebase-memory · ${project}\n` + `status: ${status.status ?? "?"} · nodes: ${status.nodes ?? "?"} · edges: ${status.edges ?? "?"}` + (extras.length ? ` · ${extras.join(" · ")}` : "") + `\nroot: ${status.root_path ?? "?"}`, "info", ); }, }); pi.registerCommand("cbm:index-repository", { description: "(Re)index the current workspace into the codebase-memory graph", handler: async (args, ctx) => { const explicit = args?.trim(); // Resolve to an existing project root when possible; otherwise index cwd. const project = explicit || (await resolveProject(ctx.cwd)); const repoPath = ctx.cwd; ctx.ui.notify(`Indexing ${project ?? repoPath}\u2026 this may take a while.`, "info"); let result: { nodes?: number; edges?: number; status?: string }; try { // index_repository takes repo_path; pass an explicit name only if given. const cliArgs: Record = { repo_path: repoPath }; if (explicit) cliArgs.name = explicit; result = JSON.parse(await runCli("index_repository", cliArgs)); } catch (e) { ctx.ui.notify(`index_repository failed: ${(e as Error).message}`, "error"); return; } ctx.ui.notify( `Indexed ${project ?? repoPath}\n` + `status: ${result.status ?? "done"} · nodes: ${result.nodes ?? "?"} · edges: ${result.edges ?? "?"}`, "info", ); }, }); }