import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; import * as fs from "node:fs"; import * as path from "node:path"; import { parseFeaturesMd, getStats, progressBar } from "../lib/features-parser.js"; export function registerStatusCommand(pi: ExtensionAPI) { pi.registerCommand("hive:status", { description: "Show feature progress from features.md", handler: async (_args, ctx) => { const featuresPath = path.join(ctx.cwd, "features.md"); if (!fs.existsSync(featuresPath)) { ctx.ui.notify("features.md not found. Run /hive:spec first.", "warning"); return; } const content = fs.readFileSync(featuresPath, "utf-8"); const features = parseFeaturesMd(content); const stats = getStats(features); // Detect project name let projectName = path.basename(ctx.cwd); try { const pkg = JSON.parse(fs.readFileSync(path.join(ctx.cwd, "package.json"), "utf-8")); if (pkg.name) projectName = pkg.name; } catch { /* ignore */ } let output = `\nHive Status: ${projectName}\n${"=".repeat(30)}\n\n`; output += `Progress: ${progressBar(stats.done.length, stats.total)}\n`; output += ` Done: ${stats.done.length}\n`; output += ` In Progress: ${stats.inProgress.length}\n`; output += ` Ready: ${stats.pending.length}\n`; output += ` Blocked: ${stats.blocked.length}\n`; if (stats.pending.length > 0) { output += `\nReady (next up):\n`; for (const f of stats.pending) { output += ` Feature ${f.number}: ${f.title}\n`; } } if (stats.inProgress.length > 0) { output += `\nIn Progress:\n`; for (const f of stats.inProgress) { output += ` Feature ${f.number}: ${f.title}\n`; } } if (stats.blocked.length > 0) { output += `\nBlocked:\n`; for (const f of stats.blocked) { output += ` Feature ${f.number}: ${f.title} (needs: ${f.dependencies})\n`; } } if (stats.done.length === stats.total && stats.total > 0) { output += `\nAll features complete! 🎉\n`; } ctx.ui.notify(output); }, }); }