UNPKG

@blundergoat/goat-flow

Version:

AI coding agent harness and local dashboard for Claude Code, OpenAI Codex, Google Antigravity, and GitHub Copilot - setup audits, guardrails, structured skills, deny hooks, and persistent learning loops.

162 lines (158 loc) 8.35 kB
#!/usr/bin/env node /** * Command-line entry point for goat-flow. * Handles argv parsing, command dispatch, exit codes, and on-disk output for audit, quality, setup, dashboard, events, and info workflows. */ import { realpathSync } from "node:fs"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { QUALITY_MODES } from "./quality/schema.js"; import { getPackageVersion } from "./paths.js"; import { validAgentList } from "./cli-agent-options.js"; import { CLIError } from "./cli-error.js"; import { dispatchCommand } from "./cli-handlers.js"; import { parseCLIArgs } from "./cli-parser.js"; export { dispatchCommand } from "./cli-handlers.js"; export { parseCLIArgs } from "./cli-parser.js"; /** Current package version used in --version output. */ const PACKAGE_VERSION = getPackageVersion(); /** Print usage instructions and available commands to stdout */ function printHelp() { console.log(` goat-flow - GOAT Flow CLI Auditor Usage: goat-flow [command] [project-path] [flags] Commands: menu Interactive command picker (default when run with no args) audit Deterministic pass/fail: GOAT Flow Setup + Agent Setup (add --harness for AI Harness Completeness) quality Agent-driven quality prompt plus history/diff surfaces setup Generate setup prompt (adapts to project state) install Deterministically copy/update goat-flow system files status Show project state (bare/partial/v0.9/outdated/current) dashboard Launch browser dashboard with audit, setup, and terminal manifest Print the resolved single-source-of-truth manifest (--check validates consistency) stats Learning-loop health report (live entry counts, stale refs, freshness). Use --check for CI. index Regenerate the generated learning-loop INDEX.md files (footguns, lessons, patterns, decisions) events tail Read local gitignored evidence-envelope events skill new Author a new skill or playbook from a description, draft, or interactive prompt. hooks list List registered hook state for this project hooks enable Enable one registered hook and sync agent configs hooks disable Disable one registered hook and sync agent configs hooks sync Re-apply config.yaml hook truth to agent configs Arguments: project-path Target project directory (default: .) Flags: --format <type> Output format: json, text, markdown, sarif (omit for auto-detect: text in terminal, json otherwise) --agent <id> Filter to one agent: ${validAgentList()} --mode <mode> Quality prompt/history/diff mode: ${QUALITY_MODES.join(", ")} --all Quality history: lift the default 20-run limit --limit <n> Events tail: number of newest envelopes to read (default: 20, max: 500) --harness Audit: add AI Harness Completeness scope (pass/fail checks across 5 concerns) --check-drift Audit: detect skill template-vs-installed drift and orphan directories --check-content Audit: cold-path content lint (vague terms, generic instructions, factual drift) --untrusted-target Audit: skip executing the target's deny-hook code (static checks only; use for a checkout you don't trust) --no-audit-details Audit JSON: omit structured harness detail payloads --check Manifest: validate static-vs-observed consistency (exits non-zero on drift) --json Hooks: emit machine-readable JSON (alias for --format json) --apply Setup: copy/update deterministic system files instead of generating a prompt --force Install/setup --apply: overwrite settings, config, and remove deprecated skills --update-config-version Install: update only the version field in existing config.yaml --clean-deprecated Install: remove deprecated skill directories --verbose Show per-check details --output <file> Write output to file instead of stdout --dev Dashboard: live reload on file changes --help, -h Show this help --version, -v Show version Examples: goat-flow Open the interactive menu goat-flow . Audit current directory goat-flow audit . --harness Audit with AI harness completeness checks goat-flow audit . --agent claude Audit scoped to Claude goat-flow audit . --format json JSON output for CI goat-flow audit . --format sarif SARIF output for CI/code scanning upload goat-flow install . --agent claude Copy/update goat-flow system files goat-flow setup . --agent claude --apply goat-flow setup --agent claude Setup prompt for Claude goat-flow quality . --agent claude Quality assessment prompt for Claude goat-flow quality . --agent claude --mode skills goat-flow quality history --agent claude goat-flow quality history --agent codex --mode skills goat-flow quality diff --agent claude --mode agent-setup goat-flow quality validate <path> Schema-check a freshly written report (exit 2 on any error) goat-flow manifest Print the resolved manifest goat-flow manifest --check Verify the manifest is consistent with code goat-flow hooks list --json Print hook state as JSON goat-flow hooks enable gruff-code-quality goat-flow hooks sync Re-apply hook toggles from config.yaml goat-flow stats Learning-loop health report goat-flow stats --check Fail if any bucket is missing last_reviewed or has stale refs goat-flow index Regenerate learning-loop INDEX.md files after editing entries goat-flow events tail . --limit 20 Print local evidence-envelope events as JSONL goat-flow skill new "<description>" Scaffold a skill from a natural-language description goat-flow skill ./repo new "<description>" goat-flow skill new --draft <path> Validate an existing draft against the candidacy check goat-flow skill new --interactive Prompt for description and name, then scaffold goat-flow --format markdown PR-comment friendly output goat-flow --output report.json Write results to file `); } /** Print the current package version to stdout */ function printVersion() { console.log(`goat-flow v${PACKAGE_VERSION}`); } /** * Entry point that dispatches to the appropriate command handler. * Installs an EPIPE guard that exits 0 when stdout is closed early (e.g. piped to `head`); any * other stdout error is rethrown. Parse and dispatch errors are not handled here - they throw and * are caught by the top-level runner below, which maps CLIError to its exit code. */ async function main() { // Gracefully handle EPIPE (e.g., output piped to `head`) process.stdout.on("error", (err) => { if (err.code === "EPIPE") process.exit(0); throw err; }); const rawArgs = process.argv.slice(2); // Empty argv opens the menu; path-only argv still uses the audit shorthand. const options = parseCLIArgs(rawArgs); if (options.showHelp) { printHelp(); return; } if (options.showVersion) { printVersion(); return; } await dispatchCommand(options); } /** * True when this module is the CLI entry point, including when launched through a symlink like * `node_modules/.bin/goat-flow`. Resolves both the invoked path and this module's URL through * realpath so the symlink and its target compare equal. A resolution error (missing or * unreadable path) is swallowed and treated as a fallback `false`, so importing this module as a * library never accidentally triggers the CLI runner. */ function isMainModule() { const entry = process.argv[1]; if (!entry) return false; try { return (realpathSync(resolve(entry)) === realpathSync(fileURLToPath(import.meta.url))); } catch { return false; } } if (isMainModule()) { main().catch((err) => { if (err instanceof CLIError) { console.error(err.message); process.exit(err.exitCode); } console.error(`Fatal error: ${err instanceof Error ? err.message : String(err)}`); process.exit(1); }); } //# sourceMappingURL=cli.js.map