@kal-elsam/kairo-runtime 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +937 -0
- package/bin/harness.js +11 -0
- package/bin/kairo-runtime.js +11 -0
- package/bin/kairo.js +11 -0
- package/global-template/components/catalog.json +25 -0
- package/global-template/components/orchestrator/orchestrator.md +55 -0
- package/global-template/components/sdd-core/handoff.md +38 -0
- package/global-template/components/sdd-core/spec-sizing.md +38 -0
- package/global-template/components/sdd-core/workflow.md +31 -0
- package/global-template/core/orchestrator.md +55 -0
- package/package.json +64 -0
- package/prompts/HARNESS_ENFORCEMENT_UPGRADE.md +11 -0
- package/prompts/HARNESS_ENTERPRISE.md +33 -0
- package/prompts/HARNESS_INSTALLER_MASTER.md +853 -0
- package/prompts/HARNESS_MINIMAL.md +30 -0
- package/prompts/HARNESS_SPEC_SIZING_UPGRADE.md +41 -0
- package/prompts/HARNESS_STANDARD.md +35 -0
- package/prompts/HARNESS_UNIVERSAL_PARITY.md +56 -0
- package/repo-template/.claude/agents/adapter-parity-reviewer.md +17 -0
- package/repo-template/.claude/agents/architect.md +17 -0
- package/repo-template/.claude/agents/eval-engineer.md +17 -0
- package/repo-template/.claude/agents/reviewer.md +17 -0
- package/repo-template/.claude/agents/sdd-reviewer.md +17 -0
- package/repo-template/.claude/agents/sdd-spec-writer.md +17 -0
- package/repo-template/.claude/skills/checkpoint/SKILL.md +13 -0
- package/repo-template/.claude/skills/eval-design/SKILL.md +3 -0
- package/repo-template/.claude/skills/evals/SKILL.md +13 -0
- package/repo-template/.claude/skills/loop-engineering/SKILL.md +16 -0
- package/repo-template/.claude/skills/maintainability-review/SKILL.md +3 -0
- package/repo-template/.claude/skills/quality-gate-review/SKILL.md +3 -0
- package/repo-template/.claude/skills/sdd/SKILL.md +13 -0
- package/repo-template/.claude/skills/spec-complexity-classifier/SKILL.md +10 -0
- package/repo-template/.claude/skills/spec-escalation-review/SKILL.md +10 -0
- package/repo-template/.claude/skills/spec-intake/SKILL.md +10 -0
- package/repo-template/.claude/skills/tdd/SKILL.md +13 -0
- package/repo-template/.claude/skills/trust-review/SKILL.md +3 -0
- package/repo-template/.codex/skills/adapter-parity/SKILL.md +29 -0
- package/repo-template/.codex/skills/checkpoint/SKILL.md +36 -0
- package/repo-template/.codex/skills/eval-design/SKILL.md +3 -0
- package/repo-template/.codex/skills/evals/SKILL.md +28 -0
- package/repo-template/.codex/skills/loop-engineering/SKILL.md +24 -0
- package/repo-template/.codex/skills/maintainability-review/SKILL.md +3 -0
- package/repo-template/.codex/skills/quality-gate-review/SKILL.md +3 -0
- package/repo-template/.codex/skills/sdd/SKILL.md +30 -0
- package/repo-template/.codex/skills/spec-complexity-classifier/SKILL.md +10 -0
- package/repo-template/.codex/skills/spec-escalation-review/SKILL.md +10 -0
- package/repo-template/.codex/skills/spec-intake/SKILL.md +10 -0
- package/repo-template/.codex/skills/tdd/SKILL.md +27 -0
- package/repo-template/.codex/skills/trust-review/SKILL.md +3 -0
- package/repo-template/.cursor/agents/adapter-parity-reviewer.md +29 -0
- package/repo-template/.cursor/agents/architect.md +27 -0
- package/repo-template/.cursor/agents/context-engineer.md +27 -0
- package/repo-template/.cursor/agents/debugger.md +27 -0
- package/repo-template/.cursor/agents/eval-engineer.md +27 -0
- package/repo-template/.cursor/agents/harness-orchestrator.md +27 -0
- package/repo-template/.cursor/agents/loop-controller.md +17 -0
- package/repo-template/.cursor/agents/loop-debugger.md +16 -0
- package/repo-template/.cursor/agents/reviewer.md +27 -0
- package/repo-template/.cursor/agents/sdd/sdd-acceptance-reviewer.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-implementation-guardian.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-intake-analyst.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-orchestrator.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-spec-reviewer.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-spec-writer.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-task-breakdown.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-technical-planner.md +31 -0
- package/repo-template/.cursor/agents/sdd/sdd-test-planner.md +31 -0
- package/repo-template/.cursor/agents/spec-intake-analyst.md +14 -0
- package/repo-template/.cursor/agents/test-engineer.md +27 -0
- package/repo-template/.cursor/commands/adapter-parity.md +34 -0
- package/repo-template/.cursor/commands/checkpoint.md +30 -0
- package/repo-template/.cursor/commands/debug.md +13 -0
- package/repo-template/.cursor/commands/init-eval.md +12 -0
- package/repo-template/.cursor/commands/init-feature.md +12 -0
- package/repo-template/.cursor/commands/init-harness.md +13 -0
- package/repo-template/.cursor/commands/loop-debug.md +3 -0
- package/repo-template/.cursor/commands/loop-review.md +3 -0
- package/repo-template/.cursor/commands/loop-run.md +5 -0
- package/repo-template/.cursor/commands/review.md +21 -0
- package/repo-template/.cursor/commands/sdd-intake.md +18 -0
- package/repo-template/.cursor/commands/sdd-plan.md +18 -0
- package/repo-template/.cursor/commands/sdd-spec.md +18 -0
- package/repo-template/.cursor/commands/sdd-tasks.md +18 -0
- package/repo-template/.cursor/commands/sdd-validate.md +18 -0
- package/repo-template/.cursor/commands/spec-escalate.md +9 -0
- package/repo-template/.cursor/commands/spec-intake.md +10 -0
- package/repo-template/.cursor/commands/spec-size.md +21 -0
- package/repo-template/.cursor/rules/adapter-parity.mdc +20 -0
- package/repo-template/.cursor/rules/api.mdc +12 -0
- package/repo-template/.cursor/rules/core.mdc +21 -0
- package/repo-template/.cursor/rules/enforcement.mdc +16 -0
- package/repo-template/.cursor/rules/evals.mdc +10 -0
- package/repo-template/.cursor/rules/git.mdc +19 -0
- package/repo-template/.cursor/rules/harness.mdc +14 -0
- package/repo-template/.cursor/rules/loops.mdc +17 -0
- package/repo-template/.cursor/rules/testing.mdc +13 -0
- package/repo-template/.cursor/rules/ui.mdc +13 -0
- package/repo-template/.cursor/skills/api-design/SKILL.md +23 -0
- package/repo-template/.cursor/skills/architecture/SKILL.md +23 -0
- package/repo-template/.cursor/skills/code-review/SKILL.md +23 -0
- package/repo-template/.cursor/skills/context-graph/SKILL.md +23 -0
- package/repo-template/.cursor/skills/debugging/SKILL.md +23 -0
- package/repo-template/.cursor/skills/evals/SKILL.md +23 -0
- package/repo-template/.cursor/skills/git-workflow/SKILL.md +23 -0
- package/repo-template/.cursor/skills/testing/SKILL.md +23 -0
- package/repo-template/.cursor/skills/ui-design/SKILL.md +23 -0
- package/repo-template/.gentle-ai/README.md +37 -0
- package/repo-template/.gentle-ai/loops/README.md +27 -0
- package/repo-template/.gentle-ai/loops/sdd-tdd-repair.loop.md +27 -0
- package/repo-template/.gentle-ai/model-routing.md +25 -0
- package/repo-template/.github/copilot-instructions.md +37 -0
- package/repo-template/.github/dependabot.yml +11 -0
- package/repo-template/.github/instructions/harness.instructions.md +11 -0
- package/repo-template/.github/workflows/harness-quality-gate.yml +67 -0
- package/repo-template/.github/workflows/harness-security-gate.yml +32 -0
- package/repo-template/.harness/spec-sizing.json +33 -0
- package/repo-template/.opencode/README.md +71 -0
- package/repo-template/.opencode/agents/adapter-parity-reviewer.md +23 -0
- package/repo-template/.opencode/agents/architect.md +38 -0
- package/repo-template/.opencode/agents/checkpoint-reviewer.md +38 -0
- package/repo-template/.opencode/agents/eval-engineer.md +38 -0
- package/repo-template/.opencode/agents/loop-controller.md +38 -0
- package/repo-template/.opencode/agents/loop-debugger.md +38 -0
- package/repo-template/.opencode/agents/model-router.md +38 -0
- package/repo-template/.opencode/agents/sdd-orchestrator.md +38 -0
- package/repo-template/.opencode/agents/sdd-spec-reviewer.md +38 -0
- package/repo-template/.opencode/agents/spec-intake-analyst.md +19 -0
- package/repo-template/.opencode/agents/tdd-engineer.md +38 -0
- package/repo-template/.opencode/commands/checkpoint.md +3 -0
- package/repo-template/.opencode/commands/eval-design.md +3 -0
- package/repo-template/.opencode/commands/maintainability-review.md +3 -0
- package/repo-template/.opencode/commands/quality-gate.md +3 -0
- package/repo-template/.opencode/commands/spec-escalate.md +9 -0
- package/repo-template/.opencode/commands/spec-intake.md +10 -0
- package/repo-template/.opencode/commands/spec-size.md +21 -0
- package/repo-template/.opencode/commands/trust-review.md +3 -0
- package/repo-template/.opencode/loops/ai-behavior-improvement.loop.md +15 -0
- package/repo-template/.opencode/loops/bug-repair.loop.md +16 -0
- package/repo-template/.opencode/loops/documentation-sync.loop.md +13 -0
- package/repo-template/.opencode/loops/feature-development.loop.md +25 -0
- package/repo-template/.opencode/skills/spec-complexity-classifier/SKILL.md +10 -0
- package/repo-template/.opencode/skills/spec-escalation-review/SKILL.md +10 -0
- package/repo-template/.opencode/skills/spec-intake/SKILL.md +10 -0
- package/repo-template/.pi/README.md +21 -0
- package/repo-template/.pi/prompts/checkpoint.md +11 -0
- package/repo-template/.pi/prompts/loop-run.md +10 -0
- package/repo-template/.pi/prompts/sdd-plan.md +11 -0
- package/repo-template/.pi/prompts/sdd-spec.md +13 -0
- package/repo-template/.pi/prompts/spec-escalate.md +9 -0
- package/repo-template/.pi/prompts/spec-intake.md +10 -0
- package/repo-template/.pi/prompts/spec-size.md +21 -0
- package/repo-template/.pi/skills/adapter-parity/SKILL.md +7 -0
- package/repo-template/.pi/skills/checkpoint/SKILL.md +7 -0
- package/repo-template/.pi/skills/eval-design/SKILL.md +3 -0
- package/repo-template/.pi/skills/evals/SKILL.md +7 -0
- package/repo-template/.pi/skills/loop-engineering/SKILL.md +7 -0
- package/repo-template/.pi/skills/maintainability-review/SKILL.md +3 -0
- package/repo-template/.pi/skills/quality-gate-review/SKILL.md +3 -0
- package/repo-template/.pi/skills/sdd/SKILL.md +7 -0
- package/repo-template/.pi/skills/spec-complexity-classifier/SKILL.md +10 -0
- package/repo-template/.pi/skills/spec-escalation-review/SKILL.md +10 -0
- package/repo-template/.pi/skills/spec-intake/SKILL.md +10 -0
- package/repo-template/.pi/skills/tdd/SKILL.md +7 -0
- package/repo-template/.pi/skills/trust-review/SKILL.md +3 -0
- package/repo-template/AGENT.md +8 -0
- package/repo-template/AGENTS.md +165 -0
- package/repo-template/CLAUDE.md +9 -0
- package/repo-template/GEMINI.md +9 -0
- package/repo-template/docs/ai/adapter-parity.md +135 -0
- package/repo-template/docs/ai/agent-workflow.md +45 -0
- package/repo-template/docs/ai/api.md +28 -0
- package/repo-template/docs/ai/architecture.md +53 -0
- package/repo-template/docs/ai/context-budget.md +54 -0
- package/repo-template/docs/ai/context-graph.md +39 -0
- package/repo-template/docs/ai/conventions.md +34 -0
- package/repo-template/docs/ai/decision-log.md +5 -0
- package/repo-template/docs/ai/enforcement.md +63 -0
- package/repo-template/docs/ai/eval-strategy.md +42 -0
- package/repo-template/docs/ai/evals.md +44 -0
- package/repo-template/docs/ai/git-workflow.md +35 -0
- package/repo-template/docs/ai/governance.md +61 -0
- package/repo-template/docs/ai/harness.md +49 -0
- package/repo-template/docs/ai/installer-cli.md +34 -0
- package/repo-template/docs/ai/loop-log.md +5 -0
- package/repo-template/docs/ai/loop-observability.md +57 -0
- package/repo-template/docs/ai/loop-policy.md +86 -0
- package/repo-template/docs/ai/loops.md +95 -0
- package/repo-template/docs/ai/maintainability-gates.md +26 -0
- package/repo-template/docs/ai/memory.md +71 -0
- package/repo-template/docs/ai/model-policy.md +105 -0
- package/repo-template/docs/ai/observability-runtime.md +48 -0
- package/repo-template/docs/ai/provider-routing.md +138 -0
- package/repo-template/docs/ai/quality-gates.md +48 -0
- package/repo-template/docs/ai/rollback-runtime.md +25 -0
- package/repo-template/docs/ai/security.md +12 -0
- package/repo-template/docs/ai/spec-driven-development.md +124 -0
- package/repo-template/docs/ai/spec-escalation.md +44 -0
- package/repo-template/docs/ai/spec-intake.md +46 -0
- package/repo-template/docs/ai/spec-sizing.md +207 -0
- package/repo-template/docs/ai/test-driven-development.md +35 -0
- package/repo-template/docs/ai/testing.md +28 -0
- package/repo-template/docs/ai/tool-adapters.md +186 -0
- package/repo-template/docs/ai/trust-allowlist.md +5 -0
- package/repo-template/docs/ai/trust-policy.md +41 -0
- package/repo-template/docs/ai/ui.md +17 -0
- package/repo-template/docs/skills/adapter-parity-review.md +46 -0
- package/repo-template/docs/skills/api-design.md +37 -0
- package/repo-template/docs/skills/architecture.md +37 -0
- package/repo-template/docs/skills/code-review.md +37 -0
- package/repo-template/docs/skills/context-graph.md +38 -0
- package/repo-template/docs/skills/debugging.md +37 -0
- package/repo-template/docs/skills/eval-design.md +12 -0
- package/repo-template/docs/skills/evals.md +37 -0
- package/repo-template/docs/skills/git-workflow.md +37 -0
- package/repo-template/docs/skills/look-trust-review.md +12 -0
- package/repo-template/docs/skills/loop-debugging.md +16 -0
- package/repo-template/docs/skills/loop-design.md +39 -0
- package/repo-template/docs/skills/loop-retrospective.md +15 -0
- package/repo-template/docs/skills/loop-review.md +16 -0
- package/repo-template/docs/skills/maintainability-review.md +12 -0
- package/repo-template/docs/skills/model-selection.md +36 -0
- package/repo-template/docs/skills/quality-gate-review.md +12 -0
- package/repo-template/docs/skills/spec-complexity-classifier.md +41 -0
- package/repo-template/docs/skills/spec-escalation-review.md +34 -0
- package/repo-template/docs/skills/spec-intake.md +25 -0
- package/repo-template/docs/skills/testing.md +37 -0
- package/repo-template/docs/skills/tool-adapter-sync.md +36 -0
- package/repo-template/docs/skills/ui-design.md +37 -0
- package/repo-template/docs/specs/README.md +9 -0
- package/repo-template/docs/specs/templates/basic-spec.md +41 -0
- package/repo-template/docs/specs/templates/complex-spec.md +145 -0
- package/repo-template/docs/specs/templates/standard-spec.md +58 -0
- package/repo-template/evals/README.md +11 -0
- package/repo-template/evals/golden/sample-golden.json +12 -0
- package/repo-template/evals/loop-regression/README.md +11 -0
- package/repo-template/evals/regression/sample-regression.json +12 -0
- package/repo-template/evals/schema/sample-schema.json +12 -0
- package/repo-template/evals/tool-calls/sample-tool-calls.json +12 -0
- package/repo-template/opencode.json.sample +29 -0
- package/repo-template/scripts/harness/backup.mjs +7 -0
- package/repo-template/scripts/harness/doctor.mjs +20 -0
- package/repo-template/scripts/harness/run-evals.mjs +27 -0
- package/repo-template/setup-agent-links.sh +54 -0
- package/scripts/check-published-release.mjs +127 -0
- package/scripts/check-release-commit.mjs +32 -0
- package/scripts/install.sh +225 -0
- package/scripts/installer-smoke-test.sh +155 -0
- package/scripts/lib/attribution-guard.mjs +59 -0
- package/scripts/registry-smoke-test.sh +149 -0
- package/scripts/smoke-test.sh +197 -0
- package/scripts/ux-smoke-test.sh +140 -0
- package/src/cli.js +625 -0
- package/src/doctor.js +68 -0
- package/src/global/adapter-context.js +27 -0
- package/src/global/adapter-matrix.js +38 -0
- package/src/global/adapters/claude.js +8 -0
- package/src/global/adapters/codex.js +8 -0
- package/src/global/adapters/cursor.js +8 -0
- package/src/global/adapters/opencode.js +8 -0
- package/src/global/agents.js +7 -0
- package/src/global/apply-confirmation.js +62 -0
- package/src/global/backups.js +54 -0
- package/src/global/brand/cli.js +52 -0
- package/src/global/brand/index.js +85 -0
- package/src/global/clack/setup-preview.js +48 -0
- package/src/global/clack/setup-wizard-constants.js +6 -0
- package/src/global/clack/setup-wizard.js +207 -0
- package/src/global/clack/theme.js +145 -0
- package/src/global/component-authoring.js +121 -0
- package/src/global/component-builders.js +43 -0
- package/src/global/component-distribution.js +270 -0
- package/src/global/component-installer.js +106 -0
- package/src/global/component-paths.js +22 -0
- package/src/global/component-registry.js +89 -0
- package/src/global/components/orchestrator.js +14 -0
- package/src/global/components/sdd-core.js +17 -0
- package/src/global/diff.js +233 -0
- package/src/global/drift.js +264 -0
- package/src/global/explain.js +144 -0
- package/src/global/global-cli.js +1145 -0
- package/src/global/global-doctor.js +67 -0
- package/src/global/global-installer.js +284 -0
- package/src/global/history.js +313 -0
- package/src/global/ink/run-setup-ink.js +77 -0
- package/src/global/ink/setup-app.js +278 -0
- package/src/global/ink/setup-routing.js +51 -0
- package/src/global/ink/setup-state.js +180 -0
- package/src/global/ink/terminal.js +13 -0
- package/src/global/json-output.js +22 -0
- package/src/global/load-component-catalog.js +41 -0
- package/src/global/load-workspace-component-catalog.js +123 -0
- package/src/global/managed-body.js +28 -0
- package/src/global/managed-config-adapter.js +134 -0
- package/src/global/managed-section.js +73 -0
- package/src/global/npm-registry.js +25 -0
- package/src/global/paths.js +22 -0
- package/src/global/policy.js +344 -0
- package/src/global/preflight.js +65 -0
- package/src/global/registry.js +79 -0
- package/src/global/report.js +110 -0
- package/src/global/rollback.js +126 -0
- package/src/global/setup.js +284 -0
- package/src/global/state-migration.js +65 -0
- package/src/global/state.js +50 -0
- package/src/global/status.js +94 -0
- package/src/global/sync.js +129 -0
- package/src/global/upgrade.js +145 -0
- package/src/harness-files.js +145 -0
- package/src/harness-updater.js +120 -0
- package/src/hash.js +5 -0
- package/src/manifest.js +36 -0
- package/src/project-detection.js +105 -0
- package/src/template-installer.js +72 -0
- package/src/text-template.js +24 -0
- package/src/workspace-cli.js +115 -0
package/src/cli.js
ADDED
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, resolve } from "node:path";
|
|
4
|
+
import { ADAPTERS } from "./harness-files.js";
|
|
5
|
+
import { GLOBAL_AGENT_IDS } from "./global/registry.js";
|
|
6
|
+
import { COMPONENT_IDS, DEFAULT_COMPONENT_IDS } from "./global/component-registry.js";
|
|
7
|
+
import {
|
|
8
|
+
printGlobalComponents,
|
|
9
|
+
printGlobalDetect,
|
|
10
|
+
runComponentsImport,
|
|
11
|
+
runComponentsInit,
|
|
12
|
+
runComponentsPack,
|
|
13
|
+
runComponentsValidate,
|
|
14
|
+
runGlobalAdapters,
|
|
15
|
+
runGlobalBackups,
|
|
16
|
+
runGlobalDoctor,
|
|
17
|
+
runGlobalInstall,
|
|
18
|
+
runGlobalRollback,
|
|
19
|
+
runGlobalSetup,
|
|
20
|
+
runGlobalStatus,
|
|
21
|
+
runGlobalSync,
|
|
22
|
+
runGlobalUninstall,
|
|
23
|
+
runGlobalUpgrade,
|
|
24
|
+
runGlobalExplain,
|
|
25
|
+
runGlobalDiff,
|
|
26
|
+
runGlobalPolicy,
|
|
27
|
+
runGlobalHistory,
|
|
28
|
+
runGlobalReport
|
|
29
|
+
} from "./global/global-cli.js";
|
|
30
|
+
import { applyPolicyToOptions, loadPolicyFile } from "./global/policy.js";
|
|
31
|
+
import { resolveHomeDir } from "./global/paths.js";
|
|
32
|
+
import { runWorkspaceDetect, runWorkspaceDoctor, runWorkspaceInit, runWorkspaceUpdate } from "./workspace-cli.js";
|
|
33
|
+
import {
|
|
34
|
+
ALL_CLI_NAMES,
|
|
35
|
+
LEGACY_PACKAGE_NAME,
|
|
36
|
+
PACKAGE_NAME,
|
|
37
|
+
PREFERRED_CLI,
|
|
38
|
+
formatCliCommand,
|
|
39
|
+
maybeWarnLegacyCli
|
|
40
|
+
} from "./global/brand/cli.js";
|
|
41
|
+
import { BRAND } from "./global/brand/index.js";
|
|
42
|
+
|
|
43
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
44
|
+
const packageRoot = resolve(__dirname, "..");
|
|
45
|
+
const SCOPES = new Set(["agent-global", "workspace"]);
|
|
46
|
+
|
|
47
|
+
export function resolveSuggestedInvocation(packageName, argv = process.argv) {
|
|
48
|
+
const invokedPath = argv[1] ?? PREFERRED_CLI;
|
|
49
|
+
const invokedBase = basename(invokedPath);
|
|
50
|
+
|
|
51
|
+
if (!invokedBase.endsWith(".js") && ALL_CLI_NAMES.has(invokedBase)) {
|
|
52
|
+
return invokedBase;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const packageManager = detectInvocationPackageManager();
|
|
56
|
+
|
|
57
|
+
switch (packageManager) {
|
|
58
|
+
case "pnpm":
|
|
59
|
+
return `pnpm dlx ${packageName}`;
|
|
60
|
+
case "yarn":
|
|
61
|
+
return `yarn dlx ${packageName}`;
|
|
62
|
+
case "bun":
|
|
63
|
+
return `bunx ${packageName}`;
|
|
64
|
+
default:
|
|
65
|
+
return `npx ${packageName}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function detectInvocationPackageManager() {
|
|
70
|
+
const execPath = process.env.npm_execpath ?? "";
|
|
71
|
+
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
72
|
+
|
|
73
|
+
if (execPath.includes("pnpm") || userAgent.startsWith("pnpm/")) return "pnpm";
|
|
74
|
+
if (execPath.includes("yarn") || userAgent.startsWith("yarn/")) return "yarn";
|
|
75
|
+
if (execPath.includes("bun") || userAgent.startsWith("bun/")) return "bun";
|
|
76
|
+
return "npm";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function runCli(argv) {
|
|
80
|
+
const { command, options } = parseArgs(argv);
|
|
81
|
+
maybeWarnLegacyCli(process.argv, { json: options.json });
|
|
82
|
+
|
|
83
|
+
if (options.help || command === "help") {
|
|
84
|
+
printHelp();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const packageManifest = await readPackageManifest();
|
|
89
|
+
|
|
90
|
+
if (options.version || command === "version") {
|
|
91
|
+
console.log(packageManifest.version);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const optionsWithPolicy = await applyCommandPolicy(command, options);
|
|
96
|
+
const invoke = resolveSuggestedInvocation(packageManifest.name);
|
|
97
|
+
|
|
98
|
+
switch (command) {
|
|
99
|
+
case "setup":
|
|
100
|
+
await runGlobalSetup(optionsWithPolicy, packageManifest, packageRoot);
|
|
101
|
+
return;
|
|
102
|
+
case "status":
|
|
103
|
+
await runGlobalStatus(packageRoot, {
|
|
104
|
+
workspaceRoot: optionsWithPolicy.cwd,
|
|
105
|
+
json: optionsWithPolicy.json,
|
|
106
|
+
cliVersion: packageManifest.version
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
case "sync":
|
|
110
|
+
await runGlobalSync(optionsWithPolicy, packageManifest, packageRoot);
|
|
111
|
+
return;
|
|
112
|
+
case "upgrade":
|
|
113
|
+
await runGlobalUpgrade(optionsWithPolicy, packageManifest, packageRoot);
|
|
114
|
+
return;
|
|
115
|
+
case "install":
|
|
116
|
+
await dispatchByScope(options, "agent-global", {
|
|
117
|
+
"agent-global": () => runGlobalInstall(options, packageManifest, packageRoot),
|
|
118
|
+
workspace: () => runWorkspaceInit(options, packageManifest, packageRoot, invoke)
|
|
119
|
+
});
|
|
120
|
+
return;
|
|
121
|
+
case "init":
|
|
122
|
+
await dispatchByScope(options, "workspace", {
|
|
123
|
+
"agent-global": () => runGlobalInstall(options, packageManifest, packageRoot),
|
|
124
|
+
workspace: () => runWorkspaceInit(options, packageManifest, packageRoot, invoke)
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
case "update":
|
|
128
|
+
await dispatchByScope(options, "agent-global", {
|
|
129
|
+
"agent-global": () => runGlobalInstall(options, packageManifest, packageRoot, { update: true }),
|
|
130
|
+
workspace: () => runWorkspaceUpdate(options, packageManifest, packageRoot)
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
case "doctor":
|
|
134
|
+
await dispatchByScope(options, "agent-global", {
|
|
135
|
+
"agent-global": () => runGlobalDoctor(packageRoot, {
|
|
136
|
+
workspaceRoot: options.cwd,
|
|
137
|
+
json: options.json,
|
|
138
|
+
cliVersion: packageManifest.version
|
|
139
|
+
}),
|
|
140
|
+
workspace: () => runWorkspaceDoctor(options)
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
case "uninstall":
|
|
144
|
+
if (options.scope === "workspace") {
|
|
145
|
+
throw new Error('Workspace uninstall is not supported yet. Remove workspace files manually or via git.');
|
|
146
|
+
}
|
|
147
|
+
await runGlobalUninstall(options, packageManifest);
|
|
148
|
+
return;
|
|
149
|
+
case "detect":
|
|
150
|
+
printGlobalDetect();
|
|
151
|
+
console.log("");
|
|
152
|
+
await runWorkspaceDetect(options, invoke);
|
|
153
|
+
return;
|
|
154
|
+
case "adapters":
|
|
155
|
+
await runGlobalAdapters({
|
|
156
|
+
json: options.json,
|
|
157
|
+
cliVersion: packageManifest.version
|
|
158
|
+
});
|
|
159
|
+
return;
|
|
160
|
+
case "explain":
|
|
161
|
+
await runGlobalExplain({
|
|
162
|
+
json: options.json,
|
|
163
|
+
cliVersion: packageManifest.version
|
|
164
|
+
});
|
|
165
|
+
return;
|
|
166
|
+
case "diff":
|
|
167
|
+
await runGlobalDiff({
|
|
168
|
+
packageManifest,
|
|
169
|
+
packageRoot,
|
|
170
|
+
json: options.json,
|
|
171
|
+
workspaceRoot: options.cwd
|
|
172
|
+
});
|
|
173
|
+
return;
|
|
174
|
+
case "backups":
|
|
175
|
+
await runGlobalBackups();
|
|
176
|
+
return;
|
|
177
|
+
case "history":
|
|
178
|
+
await runGlobalHistory(options, packageManifest);
|
|
179
|
+
return;
|
|
180
|
+
case "rollback":
|
|
181
|
+
await runGlobalRollback(options, packageManifest);
|
|
182
|
+
return;
|
|
183
|
+
case "components":
|
|
184
|
+
await dispatchComponentsCommand(options, invoke);
|
|
185
|
+
return;
|
|
186
|
+
case "policy":
|
|
187
|
+
await runGlobalPolicy(options, packageManifest);
|
|
188
|
+
return;
|
|
189
|
+
case "report":
|
|
190
|
+
await runGlobalReport({
|
|
191
|
+
packageManifest,
|
|
192
|
+
packageRoot,
|
|
193
|
+
json: options.json,
|
|
194
|
+
workspaceRoot: options.cwd,
|
|
195
|
+
historyLimit: options.limit,
|
|
196
|
+
outPath: options.outPath
|
|
197
|
+
});
|
|
198
|
+
return;
|
|
199
|
+
default:
|
|
200
|
+
throw new Error(`Unknown command "${command}". Run "${invoke} help".`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function dispatchByScope(options, defaultScope, handlers) {
|
|
205
|
+
const scope = options.scope ?? defaultScope;
|
|
206
|
+
const handler = handlers[scope];
|
|
207
|
+
await handler();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function dispatchComponentsCommand(options, invoke) {
|
|
211
|
+
switch (options.componentsAction) {
|
|
212
|
+
case null:
|
|
213
|
+
printGlobalComponents({ workspaceRoot: options.cwd });
|
|
214
|
+
return;
|
|
215
|
+
case "validate":
|
|
216
|
+
runComponentsValidate({ workspaceRoot: options.cwd });
|
|
217
|
+
return;
|
|
218
|
+
case "init":
|
|
219
|
+
await runComponentsInit(options);
|
|
220
|
+
return;
|
|
221
|
+
case "pack":
|
|
222
|
+
await runComponentsPack(options);
|
|
223
|
+
return;
|
|
224
|
+
case "import":
|
|
225
|
+
await runComponentsImport(options);
|
|
226
|
+
return;
|
|
227
|
+
default:
|
|
228
|
+
throw new Error(
|
|
229
|
+
`Unknown components action "${options.componentsAction}". Run "${invoke} help".`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function applyCommandPolicy(command, options) {
|
|
235
|
+
if (!new Set(["setup", "sync", "upgrade"]).has(command)) {
|
|
236
|
+
return options;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const homeDir = resolveHomeDir();
|
|
240
|
+
const rawPolicy = await loadPolicyFile(homeDir);
|
|
241
|
+
return applyPolicyToOptions(options, rawPolicy);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function readPackageManifest() {
|
|
245
|
+
return JSON.parse(await readFile(resolve(packageRoot, "package.json"), "utf8"));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function resolveImplicitCommand(args) {
|
|
249
|
+
if (argsWantsWorkspaceScope(args)) {
|
|
250
|
+
return "init";
|
|
251
|
+
}
|
|
252
|
+
return "setup";
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function argsWantsWorkspaceScope(args) {
|
|
256
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
257
|
+
const arg = args[index];
|
|
258
|
+
if (arg === "--scope=workspace") return true;
|
|
259
|
+
if (arg === "--scope" && args[index + 1] === "workspace") return true;
|
|
260
|
+
}
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function parseArgs(argv) {
|
|
265
|
+
const args = [...argv];
|
|
266
|
+
const firstArg = args[0];
|
|
267
|
+
const implicitCommand = !firstArg || firstArg.startsWith("-");
|
|
268
|
+
const rawCommand = implicitCommand ? resolveImplicitCommand(args) : args.shift();
|
|
269
|
+
const command = normalizeCommand(rawCommand);
|
|
270
|
+
const options = {
|
|
271
|
+
cwd: process.cwd(),
|
|
272
|
+
scope: null,
|
|
273
|
+
mode: "standard",
|
|
274
|
+
modeExplicit: false,
|
|
275
|
+
detect: implicitCommand,
|
|
276
|
+
adapters: null,
|
|
277
|
+
allAdapters: false,
|
|
278
|
+
components: null,
|
|
279
|
+
componentsAction: null,
|
|
280
|
+
componentId: null,
|
|
281
|
+
label: null,
|
|
282
|
+
outPath: null,
|
|
283
|
+
bundlePath: null,
|
|
284
|
+
noDefaultComponents: false,
|
|
285
|
+
force: false,
|
|
286
|
+
dryRun: false,
|
|
287
|
+
yes: false,
|
|
288
|
+
confirm: false,
|
|
289
|
+
preflight: true,
|
|
290
|
+
preflightExplicit: false,
|
|
291
|
+
yesExplicit: false,
|
|
292
|
+
confirmExplicit: false,
|
|
293
|
+
adaptersExplicit: false,
|
|
294
|
+
componentsExplicit: false,
|
|
295
|
+
json: false,
|
|
296
|
+
apply: false,
|
|
297
|
+
snapshot: null,
|
|
298
|
+
policyAction: null,
|
|
299
|
+
policyKey: null,
|
|
300
|
+
policyValue: null,
|
|
301
|
+
historyAction: null,
|
|
302
|
+
historyCommand: null,
|
|
303
|
+
historyEventAction: null,
|
|
304
|
+
limit: null,
|
|
305
|
+
simple: false,
|
|
306
|
+
help: false,
|
|
307
|
+
version: false,
|
|
308
|
+
interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY)
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
if (command === "components") {
|
|
312
|
+
parseComponentsAction(args, options);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (command === "policy") {
|
|
316
|
+
parsePolicyAction(args, options);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (command === "history") {
|
|
320
|
+
parseHistoryAction(args, options);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
324
|
+
const arg = args[index];
|
|
325
|
+
|
|
326
|
+
if (arg === "--cwd") options.cwd = resolve(args[++index]);
|
|
327
|
+
else if (arg === "--scope") options.scope = parseScope(args[++index]);
|
|
328
|
+
else if (arg.startsWith("--scope=")) options.scope = parseScope(arg.slice("--scope=".length));
|
|
329
|
+
else if (arg === "--mode") {
|
|
330
|
+
options.mode = args[++index];
|
|
331
|
+
options.modeExplicit = true;
|
|
332
|
+
} else if (arg.startsWith("--mode=")) {
|
|
333
|
+
options.mode = arg.slice("--mode=".length);
|
|
334
|
+
options.modeExplicit = true;
|
|
335
|
+
} else if (arg === "--detect") options.detect = true;
|
|
336
|
+
else if (arg === "--all-adapters") {
|
|
337
|
+
options.allAdapters = true;
|
|
338
|
+
options.adapters = null;
|
|
339
|
+
options.adaptersExplicit = true;
|
|
340
|
+
} else if (arg === "--adapters" || arg === "--agents") {
|
|
341
|
+
options.adapters = parseAdapters(args[++index]);
|
|
342
|
+
options.adaptersExplicit = true;
|
|
343
|
+
} else if (arg.startsWith("--adapters=")) {
|
|
344
|
+
options.adapters = parseAdapters(arg.slice("--adapters=".length));
|
|
345
|
+
options.adaptersExplicit = true;
|
|
346
|
+
} else if (arg.startsWith("--agents=")) {
|
|
347
|
+
options.adapters = parseAdapters(arg.slice("--agents=".length));
|
|
348
|
+
options.adaptersExplicit = true;
|
|
349
|
+
} else if (arg === "--components") {
|
|
350
|
+
options.components = parseAdapters(args[++index]);
|
|
351
|
+
options.componentsExplicit = true;
|
|
352
|
+
} else if (arg.startsWith("--components=")) {
|
|
353
|
+
options.components = parseAdapters(arg.slice("--components=".length));
|
|
354
|
+
options.componentsExplicit = true;
|
|
355
|
+
} else if (arg === "--no-default-components") {
|
|
356
|
+
options.noDefaultComponents = true;
|
|
357
|
+
options.componentsExplicit = true;
|
|
358
|
+
} else if (arg === "--force") options.force = true;
|
|
359
|
+
else if (arg === "--dry-run") options.dryRun = true;
|
|
360
|
+
else if (arg === "--json") options.json = true;
|
|
361
|
+
else if (arg === "--yes" || arg === "-y") {
|
|
362
|
+
options.yes = true;
|
|
363
|
+
options.yesExplicit = true;
|
|
364
|
+
} else if (arg === "--confirm") {
|
|
365
|
+
options.confirm = true;
|
|
366
|
+
options.confirmExplicit = true;
|
|
367
|
+
} else if (arg === "--no-preflight") {
|
|
368
|
+
options.preflight = false;
|
|
369
|
+
options.preflightExplicit = true;
|
|
370
|
+
} else if (arg === "--apply") options.apply = true;
|
|
371
|
+
else if (arg === "--to") options.snapshot = args[++index];
|
|
372
|
+
else if (arg.startsWith("--to=")) options.snapshot = arg.slice("--to=".length);
|
|
373
|
+
else if (arg === "--limit") options.limit = parsePositiveInt(args[++index], "limit");
|
|
374
|
+
else if (arg.startsWith("--limit=")) options.limit = parsePositiveInt(arg.slice("--limit=".length), "limit");
|
|
375
|
+
else if (arg === "--command") options.historyCommand = args[++index];
|
|
376
|
+
else if (arg.startsWith("--command=")) options.historyCommand = arg.slice("--command=".length);
|
|
377
|
+
else if (arg === "--action") options.historyEventAction = args[++index];
|
|
378
|
+
else if (arg.startsWith("--action=")) options.historyEventAction = arg.slice("--action=".length);
|
|
379
|
+
else if (arg === "--label") options.label = args[++index];
|
|
380
|
+
else if (arg.startsWith("--label=")) options.label = arg.slice("--label=".length);
|
|
381
|
+
else if (arg === "--out") options.outPath = resolve(args[++index]);
|
|
382
|
+
else if (arg.startsWith("--out=")) options.outPath = resolve(arg.slice("--out=".length));
|
|
383
|
+
else if (arg === "--simple") options.simple = true;
|
|
384
|
+
else if (arg === "--help" || arg === "-h") options.help = true;
|
|
385
|
+
else if (arg === "--version" || arg === "-v") options.version = true;
|
|
386
|
+
else throw new Error(`Unknown option "${arg}".`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return { command, options };
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function parseComponentsAction(args, options) {
|
|
393
|
+
const action = args[0];
|
|
394
|
+
if (!action || action.startsWith("-")) return;
|
|
395
|
+
|
|
396
|
+
args.shift();
|
|
397
|
+
options.componentsAction = action;
|
|
398
|
+
|
|
399
|
+
if (action === "init" || action === "pack") {
|
|
400
|
+
const componentId = args[0];
|
|
401
|
+
if (!componentId || componentId.startsWith("-")) {
|
|
402
|
+
const usage = action === "init"
|
|
403
|
+
? `${formatCliCommand("components init <id> --label \"My Label\"")}`
|
|
404
|
+
: formatCliCommand("components pack <id> --out <file>");
|
|
405
|
+
throw new Error(`Missing component id. Use: ${usage}`);
|
|
406
|
+
}
|
|
407
|
+
options.componentId = args.shift();
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (action === "import") {
|
|
412
|
+
const bundlePath = args[0];
|
|
413
|
+
if (!bundlePath || bundlePath.startsWith("-")) {
|
|
414
|
+
throw new Error(`Missing bundle path. Use: ${formatCliCommand("components import <file>")}`);
|
|
415
|
+
}
|
|
416
|
+
options.bundlePath = resolve(args.shift());
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (action === "validate") return;
|
|
421
|
+
|
|
422
|
+
throw new Error(`Unknown components action "${action}". Use validate, init, pack, or import.`);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function parsePolicyAction(args, options) {
|
|
426
|
+
const action = args[0];
|
|
427
|
+
|
|
428
|
+
if (!action || action.startsWith("-")) {
|
|
429
|
+
options.policyAction = "show";
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
args.shift();
|
|
434
|
+
|
|
435
|
+
if (action === "set") {
|
|
436
|
+
options.policyAction = "set";
|
|
437
|
+
const key = args[0];
|
|
438
|
+
const value = args[1];
|
|
439
|
+
|
|
440
|
+
if (!key || key.startsWith("-") || !value || value.startsWith("-")) {
|
|
441
|
+
throw new Error(`Missing policy key or value. Use: ${formatCliCommand("policy set <key> <value>")}`);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
options.policyKey = args.shift();
|
|
445
|
+
options.policyValue = args.shift();
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (action === "reset") {
|
|
450
|
+
options.policyAction = "reset";
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
throw new Error(`Unknown policy action "${action}". Use set or reset.`);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function parseHistoryAction(args, options) {
|
|
458
|
+
const action = args[0];
|
|
459
|
+
|
|
460
|
+
if (!action || action.startsWith("-")) {
|
|
461
|
+
options.historyAction = "list";
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (action === "last") {
|
|
466
|
+
args.shift();
|
|
467
|
+
options.historyAction = "last";
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
throw new Error(`Unknown history action "${action}". Use last or omit for the full log.`);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function parsePositiveInt(value, label) {
|
|
475
|
+
const parsed = Number.parseInt(value, 10);
|
|
476
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
477
|
+
throw new Error(`Invalid --${label} value "${value}". Use a positive integer.`);
|
|
478
|
+
}
|
|
479
|
+
return parsed;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function parseScope(value) {
|
|
483
|
+
if (!SCOPES.has(value)) {
|
|
484
|
+
throw new Error(`Invalid scope "${value}". Use agent-global or workspace.`);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return value;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function normalizeCommand(command) {
|
|
491
|
+
if (!command) return "install";
|
|
492
|
+
|
|
493
|
+
if (command === "install" || command === "i") return "install";
|
|
494
|
+
if (command === "setup") return "setup";
|
|
495
|
+
if (command === "status") return "status";
|
|
496
|
+
if (command === "sync") return "sync";
|
|
497
|
+
if (command === "upgrade") return "upgrade";
|
|
498
|
+
if (command === "init") return "init";
|
|
499
|
+
if (command === "update" || command === "u") return "update";
|
|
500
|
+
if (command === "doctor") return "doctor";
|
|
501
|
+
if (command === "uninstall") return "uninstall";
|
|
502
|
+
if (command === "detect" || command === "d") return "detect";
|
|
503
|
+
if (command === "adapters") return "adapters";
|
|
504
|
+
if (command === "explain") return "explain";
|
|
505
|
+
if (command === "diff") return "diff";
|
|
506
|
+
if (command === "backups") return "backups";
|
|
507
|
+
if (command === "history") return "history";
|
|
508
|
+
if (command === "rollback") return "rollback";
|
|
509
|
+
if (command === "components") return "components";
|
|
510
|
+
if (command === "policy") return "policy";
|
|
511
|
+
if (command === "report") return "report";
|
|
512
|
+
if (command === "help") return "help";
|
|
513
|
+
if (command === "version") return "version";
|
|
514
|
+
|
|
515
|
+
return command;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function parseAdapters(value) {
|
|
519
|
+
if (!value) return [];
|
|
520
|
+
|
|
521
|
+
const items = [...new Set(
|
|
522
|
+
value
|
|
523
|
+
.split(",")
|
|
524
|
+
.map((item) => item.trim().toLowerCase())
|
|
525
|
+
.filter(Boolean)
|
|
526
|
+
)];
|
|
527
|
+
|
|
528
|
+
if (items.length === 1 && items[0] === "all") {
|
|
529
|
+
return ["all"];
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (items.includes("all")) {
|
|
533
|
+
throw new Error('Use --agents all alone to target all supported agents, not mixed with other ids.');
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return items;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function printHelp() {
|
|
540
|
+
const cli = PREFERRED_CLI;
|
|
541
|
+
console.log(`${BRAND.displayName} (${PACKAGE_NAME})
|
|
542
|
+
|
|
543
|
+
${BRAND.tagline}. ${BRAND.displayName} does not install AI apps — it powers and
|
|
544
|
+
coordinates agents you already have (Cursor, Codex, OpenCode, Claude) with managed
|
|
545
|
+
sections, components, backups, and drift repair under ~/.harness.
|
|
546
|
+
|
|
547
|
+
Bootstrap: see README.md (curl install.sh or npx ${PACKAGE_NAME}).
|
|
548
|
+
|
|
549
|
+
Usage:
|
|
550
|
+
${cli} [--dry-run] [--yes] [--confirm] [--agents <list|all>] [--components <list>]
|
|
551
|
+
${cli} --version
|
|
552
|
+
${cli} setup [--dry-run] [--yes] [--confirm] [--simple] [--no-preflight] [--agents <list|all>] [--components <list>]
|
|
553
|
+
${cli} status [--json]
|
|
554
|
+
${cli} sync [--dry-run] [--yes] [--confirm] [--json] [--no-preflight]
|
|
555
|
+
${cli} upgrade [--dry-run] [--yes] [--confirm] [--no-preflight]
|
|
556
|
+
${cli} install [--agents <list|all>] [--components <list>] [--dry-run]
|
|
557
|
+
${cli} install --no-default-components
|
|
558
|
+
${cli} doctor [--json]
|
|
559
|
+
${cli} adapters [--json]
|
|
560
|
+
${cli} explain [--json]
|
|
561
|
+
${cli} diff [--json]
|
|
562
|
+
${cli} update [--dry-run]
|
|
563
|
+
${cli} install --scope=workspace [--mode minimal|standard|enterprise] (opt-in/legacy)
|
|
564
|
+
${cli} init [--mode minimal|standard|enterprise] (workspace alias)
|
|
565
|
+
${cli} detect
|
|
566
|
+
${cli} backups
|
|
567
|
+
${cli} history [--json] [--limit <n>] [--command <name>] [--action <name>]
|
|
568
|
+
${cli} history last [--json] [--command <name>] [--action <name>]
|
|
569
|
+
${cli} rollback --to <snapshot> [--apply]
|
|
570
|
+
${cli} policy [--json]
|
|
571
|
+
${cli} policy set <key> <value>
|
|
572
|
+
${cli} policy reset
|
|
573
|
+
${cli} report [--json] [--out <file>] [--limit <n>]
|
|
574
|
+
${cli} components
|
|
575
|
+
${cli} components validate|init|pack|import ...
|
|
576
|
+
${cli} uninstall [--dry-run]
|
|
577
|
+
|
|
578
|
+
Scopes:
|
|
579
|
+
agent-global (default) Configure local agent roots and managed sections.
|
|
580
|
+
Primary product path. Writes ~/.harness state.
|
|
581
|
+
workspace (opt-in) Legacy repo scaffolding into the current project.
|
|
582
|
+
Explicit --scope=workspace only.
|
|
583
|
+
|
|
584
|
+
Commands:
|
|
585
|
+
setup Interactive Ink UI (TTY). Use --simple for Clack prompts.
|
|
586
|
+
status Control panel: agents, components, drift, backups, next action.
|
|
587
|
+
sync Converge managed content (repair drift), then show status.
|
|
588
|
+
upgrade Preview or apply ecosystem updates (apply requires --yes).
|
|
589
|
+
install Non-interactive configure (agent-global) or legacy workspace scaffold.
|
|
590
|
+
doctor Detailed health checks for managed state and configs.
|
|
591
|
+
update Technical repair alias (prefer sync for day-to-day use).
|
|
592
|
+
detect Inspect global agents and the current project. Read-only.
|
|
593
|
+
adapters Official adapter matrix: roots, config files, detected/managed.
|
|
594
|
+
explain Read-only audit of managed adapters, configs, markers, and backups.
|
|
595
|
+
diff Read-only preview of managed content changes (sync/setup plan).
|
|
596
|
+
backups List config snapshots under ~/.harness/backups.
|
|
597
|
+
history Local audit log of managed operations under ~/.harness/history.jsonl.
|
|
598
|
+
Use "history last" for the most recent event. Read-only.
|
|
599
|
+
rollback Preview or restore a prior config snapshot (--apply to write).
|
|
600
|
+
policy View or edit local operation preferences under ~/.harness/policy.json.
|
|
601
|
+
report Read-only diagnostics bundle: status, policy, adapters, diff, history.
|
|
602
|
+
components List, validate, scaffold, pack, or import workspace components.
|
|
603
|
+
uninstall Remove managed sections and global state. Backups are preserved.
|
|
604
|
+
init Alias for install --scope=workspace (legacy).
|
|
605
|
+
|
|
606
|
+
JSON output (--json on supported commands):
|
|
607
|
+
status, sync, doctor, adapters, explain, diff, history, history last,
|
|
608
|
+
policy (show/set/reset), report
|
|
609
|
+
Human text remains the default. See README.md for examples and field notes.
|
|
610
|
+
|
|
611
|
+
Version:
|
|
612
|
+
${cli} --version Installed CLI version
|
|
613
|
+
npm view ${PACKAGE_NAME} version Latest published version
|
|
614
|
+
npx ${PACKAGE_NAME}@latest sync Converge with latest package
|
|
615
|
+
|
|
616
|
+
More examples: README.md
|
|
617
|
+
|
|
618
|
+
Preferred CLI: kairo, kairo-runtime
|
|
619
|
+
Legacy aliases: harness, agentic-harness, sgs-harness, harness-sgs (prefer kairo)
|
|
620
|
+
Legacy package: ${LEGACY_PACKAGE_NAME}
|
|
621
|
+
Global agents: ${GLOBAL_AGENT_IDS.join(", ")}
|
|
622
|
+
Global components: ${COMPONENT_IDS.join(", ")} (default: ${DEFAULT_COMPONENT_IDS.join(", ")})
|
|
623
|
+
Workspace adapters: ${[...ADAPTERS].join(", ")}
|
|
624
|
+
`);
|
|
625
|
+
}
|
package/src/doctor.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { readManifest } from "./manifest.js";
|
|
4
|
+
import { formatCliCommand } from "./global/brand/cli.js";
|
|
5
|
+
|
|
6
|
+
const REQUIRED_FILES = ["AGENTS.md", "docs/ai/harness.md", "docs/ai/memory.md"];
|
|
7
|
+
|
|
8
|
+
const RECOMMENDED_FILES = [
|
|
9
|
+
"docs/ai/context-graph.md",
|
|
10
|
+
"docs/ai/architecture.md",
|
|
11
|
+
".github/copilot-instructions.md",
|
|
12
|
+
".cursor/rules/core.mdc"
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const DRIFT_PREVIEW_LIMIT = 5;
|
|
16
|
+
|
|
17
|
+
export async function runDoctorChecks(project) {
|
|
18
|
+
const checks = [
|
|
19
|
+
...REQUIRED_FILES.map((relativePath) => fileCheck(project.root, relativePath, "required")),
|
|
20
|
+
...RECOMMENDED_FILES.map((relativePath) => fileCheck(project.root, relativePath, "recommended"))
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
checks.push(...await manifestChecks(project.root));
|
|
24
|
+
|
|
25
|
+
const hasMissingRequired = checks.some((check) => check.status === "missing");
|
|
26
|
+
return { checks, ok: !hasMissingRequired };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function fileCheck(root, relativePath, severity) {
|
|
30
|
+
const exists = existsSync(resolve(root, relativePath));
|
|
31
|
+
if (exists) return { name: relativePath, status: "ok" };
|
|
32
|
+
return { name: relativePath, status: severity === "required" ? "missing" : "warning" };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function manifestChecks(root) {
|
|
36
|
+
const manifest = await readManifest(root);
|
|
37
|
+
|
|
38
|
+
if (!manifest) {
|
|
39
|
+
return [{
|
|
40
|
+
name: ".harness/manifest.json",
|
|
41
|
+
status: "warning",
|
|
42
|
+
detail: `Not found. Run "${formatCliCommand("init")}" to enable "${formatCliCommand("update")}".`
|
|
43
|
+
}];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const checks = [{
|
|
47
|
+
name: ".harness/manifest.json",
|
|
48
|
+
status: "ok",
|
|
49
|
+
detail: `mode=${manifest.mode}, cliVersion=${manifest.cliVersion ?? "unknown"}`
|
|
50
|
+
}];
|
|
51
|
+
|
|
52
|
+
const drifted = Object.keys(manifest.files ?? {}).filter(
|
|
53
|
+
(relativePath) => !existsSync(resolve(root, relativePath))
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (drifted.length > 0) {
|
|
57
|
+
const preview = drifted.slice(0, DRIFT_PREVIEW_LIMIT).join(", ");
|
|
58
|
+
const suffix = drifted.length > DRIFT_PREVIEW_LIMIT ? ", ..." : "";
|
|
59
|
+
|
|
60
|
+
checks.push({
|
|
61
|
+
name: "manifest drift",
|
|
62
|
+
status: "warning",
|
|
63
|
+
detail: `${drifted.length} tracked file(s) missing on disk: ${preview}${suffix}`
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return checks;
|
|
68
|
+
}
|