import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent"; import type { AutocompleteItem } from "@earendil-works/pi-tui"; import type { CorridorRuntime } from "../application/corridor-runtime.ts"; import { ensureHub, readHubMeta, sessionViewerUrl, shouldAutoOpenBrowser, } from "../application/hub-client.ts"; const SUBCOMMANDS = ["status", "doctor", "viewer"] as const; function emit( ctx: ExtensionCommandContext, message: string, type: "info" | "warning" | "error" = "info", ): void { if (ctx.mode === "print") { console.log(message); return; } if (ctx.mode === "json") { process.stderr.write(`${message}\n`); return; } ctx.ui.notify(message, type); } function statusText(runtime: CorridorRuntime): string { const view = runtime.getView(); return [ `North Star: ${view.rootIntent}`, `Revision: ${view.revision}`, `Stack depth: ${view.stack.length}`, `Current action: ${view.now}`, `Position: ${view.position.mode}`, `Snapshot: ${view.snapshotHash}`, ].join("\n"); } function viewerGuidance(runtime: CorridorRuntime, hub?: ReturnType): string { const sessionId = runtime.getSessionId(); const meta = readHubMeta(); const baseUrl = hub?.baseUrl ?? meta?.baseUrl; const url = baseUrl ? sessionViewerUrl(baseUrl, sessionId) : undefined; return [ "Intent Petri visualization lives in the local web hub (multi-session).", url ? `Open: ${url}` : "Start hub: intent-petri-hub ensure --open", "List all sessions: open the hub root URL (default http://127.0.0.1:7731/)", `Projection: ${runtime.getProjectionPath() ?? "not initialized"}`, "Herdr terminal graph plugin is deprecated and no longer the primary UI.", ].join("\n"); } function hubOptions(runtime: CorridorRuntime, extra: { open?: boolean } = {}) { const sessionId = runtime.getSessionId(); return { ...(sessionId ? { sessionId } : {}), ...(extra.open ? { open: true as const } : extra.open === false ? { open: false as const } : {}), }; } export function registerCommands(pi: ExtensionAPI, runtime: CorridorRuntime): void { pi.registerCommand("intent-petri", { description: "Inspect Intent Petri state or open the local web hub viewer", getArgumentCompletions(prefix): AutocompleteItem[] | null { const options = SUBCOMMANDS.filter((item) => item.startsWith(prefix)).map((item) => ({ value: item, label: item })); return options.length > 0 ? options : null; }, handler: async (args, ctx) => { const command = args.trim().toLowerCase(); if (command === "status") { emit(ctx, statusText(runtime)); return; } if (command === "doctor") { const report = runtime.doctor(ctx); const hub = ensureHub(hubOptions(runtime)); emit( ctx, [ `Extension: intent-petri v${report.version}`, `Source: ${report.sourceKind} · ${report.sourcePath}`, ...(report.installedUserVersion ? [`Installed user npm version: ${report.installedUserVersion}`] : []), `Revision: ${report.revision}`, `Snapshot: ${report.snapshotHash}`, `Branch checkpoints: ${report.branchCheckpoints}`, `Migrated schema-1 checkpoints: ${report.migratedBranchCheckpoints}`, `Invalid checkpoints skipped: ${report.invalidBranchCheckpoints}`, `Stale rollback checkpoints ignored: ${report.ignoredDivergentCheckpoints}`, ...report.branchIssues.slice(0, 3).map( (issue) => `Checkpoint ${issue.entryId}${issue.revision !== undefined ? ` r${issue.revision}` : ""}: ${issue.reason}`, ), `Branch hashes: ${report.branchHashVerified ? "verified" : "mismatch"}`, `Projection: ${report.projectionPath ?? "not initialized"}`, `Projection renderer: ${report.projectionError ? `fallback · ${report.projectionError}` : "healthy"}`, `Activity projection: ${report.activityProjectionError ?? "healthy"}`, `Web hub: ${hub.ok ? hub.baseUrl ?? "ok" : hub.error ?? "unavailable"}`, `SQLite audit: ${report.sqlite ? `${report.sqlite.checkpoints} checkpoint(s) · ${report.sqlite.path}` : "closed"}`, ].join("\n"), report.branchHashVerified ? "info" : "warning", ); return; } if (command === "viewer") { const hub = ensureHub(hubOptions(runtime, { open: true })); emit( ctx, viewerGuidance(runtime, hub), hub.ok ? "info" : "warning", ); return; } if (command) { emit(ctx, "Usage: /intent-petri [status|doctor|viewer]", "error"); return; } const hub = ensureHub(hubOptions(runtime, { open: shouldAutoOpenBrowser() })); emit(ctx, viewerGuidance(runtime, hub), hub.ok ? "info" : "warning"); }, }); }