@tea-agent/loop-agent 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/AGENTS.md +121 -0
- package/CHANGELOG.md +37 -0
- package/README.md +144 -0
- package/bin/loop-agent.js +21 -0
- package/dist/adapters/aimax.js +91 -0
- package/dist/adapters/context.js +32 -0
- package/dist/adapters/index.js +28 -0
- package/dist/adapters/loop-agent.js +98 -0
- package/dist/adapters/types.js +1 -0
- package/dist/cli/catalog.js +259 -0
- package/dist/cli/help.js +55 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/program.js +505 -0
- package/dist/cli.js +12 -0
- package/dist/commands/closeout.js +13 -0
- package/dist/commands/coverage-audit.js +14 -0
- package/dist/commands/cursor-prompt.js +222 -0
- package/dist/commands/cursor-worker.js +43 -0
- package/dist/commands/dag-approve.js +102 -0
- package/dist/commands/dag-final-verification.js +76 -0
- package/dist/commands/dag-init-hybrid.js +56 -0
- package/dist/commands/dag-reconcile-tasks.js +51 -0
- package/dist/commands/dag-reject.js +91 -0
- package/dist/commands/dag-report.js +177 -0
- package/dist/commands/dag-resume.js +34 -0
- package/dist/commands/dag-run-task.js +470 -0
- package/dist/commands/dag-validate.js +186 -0
- package/dist/commands/dag-workflow-compile.js +91 -0
- package/dist/commands/dag-workflow-plan.js +130 -0
- package/dist/commands/dag-workflow-validate.js +66 -0
- package/dist/commands/delegate.js +132 -0
- package/dist/commands/docs-archive.js +5 -0
- package/dist/commands/docs-audit.js +5 -0
- package/dist/commands/doctor.js +50 -0
- package/dist/commands/goal.js +92 -0
- package/dist/commands/handoff-check.js +5 -0
- package/dist/commands/harvest.js +44 -0
- package/dist/commands/inspect.js +11 -0
- package/dist/commands/instructions.js +195 -0
- package/dist/commands/knowledge.js +64 -0
- package/dist/commands/loop-benchmark.js +72 -0
- package/dist/commands/loop.js +241 -0
- package/dist/commands/new-task.js +5 -0
- package/dist/commands/pi-prompt.js +181 -0
- package/dist/commands/pi-reuse-benchmark.js +153 -0
- package/dist/commands/plan-list.js +5 -0
- package/dist/commands/promote-run.js +29 -0
- package/dist/commands/reference-index.js +16 -0
- package/dist/commands/run-dag.js +184 -0
- package/dist/commands/spine.js +38 -0
- package/dist/commands/stats.js +84 -0
- package/dist/commands/status.js +56 -0
- package/dist/commands/study-init.js +192 -0
- package/dist/commands/workflow.js +259 -0
- package/dist/commands/worktree-create.js +31 -0
- package/dist/commands/worktree-list.js +5 -0
- package/dist/commands/worktree-remove.js +26 -0
- package/dist/cursor-worker-entry.js +8 -0
- package/dist/executors/config-core.js +55 -0
- package/dist/executors/config.js +2 -0
- package/dist/executors/cursor-artifacts.js +33 -0
- package/dist/executors/cursor-execution-log.js +81 -0
- package/dist/executors/cursor-executor-artifacts.js +135 -0
- package/dist/executors/cursor-executor.js +468 -0
- package/dist/executors/cursor-run.js +115 -0
- package/dist/executors/cursor-tool.js +94 -0
- package/dist/executors/cursor-worker-client.js +213 -0
- package/dist/executors/cursor-worker-protocol.js +18 -0
- package/dist/executors/cursor-worker-server.js +54 -0
- package/dist/executors/cursor-worker.js +3 -0
- package/dist/executors/cursor.js +6 -0
- package/dist/executors/dag-cursor-executor.js +88 -0
- package/dist/executors/dag-pi-executor.js +322 -0
- package/dist/executors/dag-static-executor.js +45 -0
- package/dist/executors/dag.js +4 -0
- package/dist/executors/index.js +8 -0
- package/dist/executors/model-routing.js +60 -0
- package/dist/executors/pi-event-serializer.js +43 -0
- package/dist/executors/pi-executor.js +606 -0
- package/dist/executors/pi-reuse-benchmark.js +316 -0
- package/dist/executors/pi-runtime-reuse.js +29 -0
- package/dist/executors/pi-sdk-executor.js +255 -0
- package/dist/executors/pi-sdk.js +1 -0
- package/dist/executors/pi.js +3 -0
- package/dist/executors/shell-executor.js +300 -0
- package/dist/executors/shell-presets.js +47 -0
- package/dist/executors/shell-verification.js +251 -0
- package/dist/executors/shell-write-guard.js +126 -0
- package/dist/executors/shell.js +3 -0
- package/dist/executors/static.js +1 -0
- package/dist/governance/checks.js +434 -0
- package/dist/governance/harness.js +9 -0
- package/dist/governance/index.js +3 -0
- package/dist/governance/manifest-types.js +128 -0
- package/dist/governance/manifest.js +2 -0
- package/dist/governance/path-guard.js +69 -0
- package/dist/governance/path-guards.js +2 -0
- package/dist/governance/profiles.js +3 -0
- package/dist/governance/requirement-coverage.js +425 -0
- package/dist/governance/skill-safety.js +135 -0
- package/dist/governance/spine-audit.js +152 -0
- package/dist/records/closeout.js +2 -0
- package/dist/records/harvest.js +236 -0
- package/dist/records/index.js +3 -0
- package/dist/records/one-shot-runs.js +421 -0
- package/dist/records/promotion.js +199 -0
- package/dist/shared/artifacts-core.js +88 -0
- package/dist/shared/artifacts.js +2 -0
- package/dist/shared/context-files.js +32 -0
- package/dist/shared/context.js +2 -0
- package/dist/shared/copy-dir.js +17 -0
- package/dist/shared/git-progress.js +165 -0
- package/dist/shared/index.js +5 -0
- package/dist/shared/logger.js +23 -0
- package/dist/shared/one-shot-prompt-args.js +98 -0
- package/dist/shared/path-refs.js +31 -0
- package/dist/shared/prompts.js +26 -0
- package/dist/shared/reference-context.js +238 -0
- package/dist/shared/timeout-policy.js +19 -0
- package/dist/shared/timeout.js +1 -0
- package/dist/shared/types.js +5 -0
- package/dist/task/config-types.js +97 -0
- package/dist/task/config.js +2 -0
- package/dist/task/delegate.js +220 -0
- package/dist/task/goal-audit.js +51 -0
- package/dist/task/goal-policy.js +8 -0
- package/dist/task/goal.js +3 -0
- package/dist/task/ids.js +1 -0
- package/dist/task/index.js +9 -0
- package/dist/task/lifecycle.js +1 -0
- package/dist/task/paths.js +1 -0
- package/dist/task/read-model.js +149 -0
- package/dist/task/runtime.js +699 -0
- package/dist/task/source-state.js +1 -0
- package/dist/task/state.js +55 -0
- package/dist/task/subagent-guidance.js +1 -0
- package/dist/task/workflow-state-types.js +92 -0
- package/dist/task/worktree-cleanup.js +140 -0
- package/dist/task/worktree.js +171 -0
- package/dist/workflows/dag/authoring.js +8 -0
- package/dist/workflows/dag/authority-surface.js +138 -0
- package/dist/workflows/dag/canvas-observer.js +474 -0
- package/dist/workflows/dag/decision-envelope.js +502 -0
- package/dist/workflows/dag/decision-evidence.js +153 -0
- package/dist/workflows/dag/decision-gates.js +1 -0
- package/dist/workflows/dag/executor-registry.js +25 -0
- package/dist/workflows/dag/facts.js +4 -0
- package/dist/workflows/dag/failure-category.js +111 -0
- package/dist/workflows/dag/final-verification.js +180 -0
- package/dist/workflows/dag/governance-constants.js +5 -0
- package/dist/workflows/dag/governance-profile.js +405 -0
- package/dist/workflows/dag/index.js +6 -0
- package/dist/workflows/dag/init-hybrid.js +855 -0
- package/dist/workflows/dag/knowledge-curator.js +162 -0
- package/dist/workflows/dag/lifecycle.js +484 -0
- package/dist/workflows/dag/prompt-source.js +88 -0
- package/dist/workflows/dag/prompt.js +130 -0
- package/dist/workflows/dag/reconcile-tasks.js +404 -0
- package/dist/workflows/dag/recovery-recommendation.js +226 -0
- package/dist/workflows/dag/repair-artifact.js +136 -0
- package/dist/workflows/dag/report.js +1019 -0
- package/dist/workflows/dag/runner.js +1677 -0
- package/dist/workflows/dag/runtime.js +5 -0
- package/dist/workflows/dag/skill-instructions.js +471 -0
- package/dist/workflows/dag/skills.js +41 -0
- package/dist/workflows/dag/spec.js +3 -0
- package/dist/workflows/dag/topo.js +30 -0
- package/dist/workflows/dag/types.js +275 -0
- package/dist/workflows/dag/upstream-artifacts.js +95 -0
- package/dist/workflows/dag/validate.js +527 -0
- package/dist/workflows/dynamic/artifacts.js +65 -0
- package/dist/workflows/dynamic/compile.js +360 -0
- package/dist/workflows/dynamic/compileTypes.js +1 -0
- package/dist/workflows/dynamic/errors.js +5 -0
- package/dist/workflows/dynamic/index.js +7 -0
- package/dist/workflows/dynamic/profiles.js +156 -0
- package/dist/workflows/dynamic/spec.js +114 -0
- package/dist/workflows/dynamic/validate.js +275 -0
- package/dist/workflows/loop/actions.js +1334 -0
- package/dist/workflows/loop/benchmark.js +510 -0
- package/dist/workflows/loop/closeout.js +134 -0
- package/dist/workflows/loop/context.js +48 -0
- package/dist/workflows/loop/events.js +25 -0
- package/dist/workflows/loop/hash.js +32 -0
- package/dist/workflows/loop/index.js +8 -0
- package/dist/workflows/loop/paths.js +17 -0
- package/dist/workflows/loop/rounds.js +81 -0
- package/dist/workflows/loop/signals.js +55 -0
- package/dist/workflows/loop/state.js +116 -0
- package/dist/workflows/loop/templates.js +54 -0
- package/dist/workflows/loop/types.js +28 -0
- package/docs/README.md +62 -0
- package/docs/agent-dag-recovery-playbook.md +158 -0
- package/docs/agent-dag-runner.md +40 -0
- package/docs/cursor-executor-usage.md +25 -0
- package/docs/decisions/README.md +3 -0
- package/docs/design/README.md +36 -0
- package/docs/development-principles.md +71 -0
- package/docs/dynamic-workflow-dag-engine-roadmap.md +1749 -0
- package/docs/exec-plans/README.md +6 -0
- package/docs/exec-plans/active/README.md +5 -0
- package/docs/exec-plans/completed/README.md +5 -0
- package/docs/feature-workflow.md +184 -0
- package/docs/harness-methodology-debugging.md +153 -0
- package/docs/harness-methodology-tdd.md +130 -0
- package/docs/harness-methodology-verification.md +27 -0
- package/docs/loop-agent-harness.md +42 -0
- package/docs/progress/README.md +3 -0
- package/docs/reports/README.md +3 -0
- package/docs/templates/adr.md +60 -0
- package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -0
- package/docs/templates/agent-dag-decision-envelope.schema.json +213 -0
- package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -0
- package/docs/templates/agent-dag-decision-gate.prompt.md +246 -0
- package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -0
- package/docs/templates/agent-dag-report.schema.json +423 -0
- package/docs/templates/agent-dag-review-verdict.prompt.md +68 -0
- package/docs/templates/agent-dag.base.json +195 -0
- package/docs/templates/agent-dag.final-verification.json +190 -0
- package/docs/templates/agent-dag.schema.json +316 -0
- package/docs/templates/agent-dag.supervised-implementation.json +500 -0
- package/docs/templates/exec-plan.md +64 -0
- package/docs/templates/feature-spec.md +53 -0
- package/docs/templates/hybrid-dag.json +193 -0
- package/docs/templates/progress-log.md +17 -0
- package/docs/templates/project-start-checklist.md +9 -0
- package/docs/templates/qa-report.md +42 -0
- package/docs/templates/sprint-contract.md +29 -0
- package/docs/verification-matrix.md +30 -0
- package/examples/decision-gate-agent-dag.json +123 -0
- package/examples/example-dag.json +51 -0
- package/examples/hybrid-loop-agent-dag.json +194 -0
- package/harness.json +92 -0
- package/package.json +61 -0
- package/skills/ai-engineering-context/SKILL.md +48 -0
- package/skills/loop-agent/SKILL.md +260 -0
- package/skills/loop-agent/references/README.md +63 -0
- package/skills/loop-agent/references/command-reference.md +315 -0
- package/skills/loop-agent/references/harness-policy.md +258 -0
- package/skills/loop-agent/references/hybrid-dag.md +216 -0
- package/skills/loop-agent/references/learned/README.md +21 -0
- package/skills/loop-agent/references/model-routing.md +36 -0
- package/skills/loop-agent/references/multi-worktree.md +54 -0
- package/skills/loop-agent/references/one-shot-runs.md +85 -0
- package/skills/loop-agent/references/orchestrator-and-interventions.md +169 -0
- package/skills/loop-agent/references/pi-prompt.md +23 -0
- package/skills/loop-agent/references/pi-subagent-assisted-mode.md +83 -0
- package/skills/loop-agent/references/post-implementation-and-patterns.md +44 -0
- package/skills/loop-agent/references/task-workflow.md +84 -0
- package/skills/loop-agent/references/verification-and-failure-handling.md +74 -0
- package/skills/requesting-code-review/SKILL.md +101 -0
- package/skills/requesting-code-review/code-reviewer.md +168 -0
- package/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/skills/systematic-debugging/SKILL.md +296 -0
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/skills/systematic-debugging/find-polluter.sh +63 -0
- package/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/skills/systematic-debugging/test-academic.md +14 -0
- package/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/skills/verification-before-completion/SKILL.md +154 -0
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { resolveAdapter } from "../adapters/index.js";
|
|
4
|
+
import { runCloseout } from "../commands/closeout.js";
|
|
5
|
+
import { runCoverageAudit } from "../commands/coverage-audit.js";
|
|
6
|
+
import { runCursorWorker } from "../commands/cursor-worker.js";
|
|
7
|
+
import { parseCursorPromptArgs, printCursorPromptUsage, runCursorPrompt, } from "../commands/cursor-prompt.js";
|
|
8
|
+
import { runDagApprove } from "../commands/dag-approve.js";
|
|
9
|
+
import { runDagFinalVerification } from "../commands/dag-final-verification.js";
|
|
10
|
+
import { runDagInitHybrid } from "../commands/dag-init-hybrid.js";
|
|
11
|
+
import { runDagReconcileTasks } from "../commands/dag-reconcile-tasks.js";
|
|
12
|
+
import { runDagReject } from "../commands/dag-reject.js";
|
|
13
|
+
import { runDagCloseoutDraft, runDagReport } from "../commands/dag-report.js";
|
|
14
|
+
import { runDagResume } from "../commands/dag-resume.js";
|
|
15
|
+
import { runDagRunTask } from "../commands/dag-run-task.js";
|
|
16
|
+
import { runDagValidate } from "../commands/dag-validate.js";
|
|
17
|
+
import { runDagWorkflowCompile } from "../commands/dag-workflow-compile.js";
|
|
18
|
+
import { runDagWorkflowPlan } from "../commands/dag-workflow-plan.js";
|
|
19
|
+
import { runDagWorkflowValidate } from "../commands/dag-workflow-validate.js";
|
|
20
|
+
import { runDelegate } from "../commands/delegate.js";
|
|
21
|
+
import { runDocsArchive } from "../commands/docs-archive.js";
|
|
22
|
+
import { runDocsAudit } from "../commands/docs-audit.js";
|
|
23
|
+
import { runDoctor } from "../commands/doctor.js";
|
|
24
|
+
import { runGoal } from "../commands/goal.js";
|
|
25
|
+
import { runHandoffCheck } from "../commands/handoff-check.js";
|
|
26
|
+
import { runHarvest } from "../commands/harvest.js";
|
|
27
|
+
import { runInspect } from "../commands/inspect.js";
|
|
28
|
+
import { runInstructions } from "../commands/instructions.js";
|
|
29
|
+
import { runKnowledge } from "../commands/knowledge.js";
|
|
30
|
+
import { runLoop } from "../commands/loop.js";
|
|
31
|
+
import { runLoopBenchmark } from "../commands/loop-benchmark.js";
|
|
32
|
+
import { runNewTask } from "../commands/new-task.js";
|
|
33
|
+
import { runPiReuseBenchmark } from "../commands/pi-reuse-benchmark.js";
|
|
34
|
+
import { parsePiPromptArgs, printPiPromptUsage, runPiPrompt, } from "../commands/pi-prompt.js";
|
|
35
|
+
import { runPlanList } from "../commands/plan-list.js";
|
|
36
|
+
import { runPromoteRun } from "../commands/promote-run.js";
|
|
37
|
+
import { runReferenceIndex } from "../commands/reference-index.js";
|
|
38
|
+
import { runRunDag } from "../commands/run-dag.js";
|
|
39
|
+
import { runSpine } from "../commands/spine.js";
|
|
40
|
+
import { runStats } from "../commands/stats.js";
|
|
41
|
+
import { runStatus } from "../commands/status.js";
|
|
42
|
+
import { runStudyInit } from "../commands/study-init.js";
|
|
43
|
+
import { runWorkflowCommand } from "../commands/workflow.js";
|
|
44
|
+
import { runWorktreeCreate } from "../commands/worktree-create.js";
|
|
45
|
+
import { runWorktreeList } from "../commands/worktree-list.js";
|
|
46
|
+
import { runWorktreeRemove } from "../commands/worktree-remove.js";
|
|
47
|
+
import { handleStandaloneOneShotCommandError } from "../shared/one-shot-prompt-args.js";
|
|
48
|
+
import { runDagDecisionInspect, runDagDecisionValidate, } from "../workflows/dag/decision-envelope.js";
|
|
49
|
+
import { runDagDoctor, runDagStatus } from "../workflows/dag/lifecycle.js";
|
|
50
|
+
import { CODE_AGENT_COMMAND_MANIFEST } from "./catalog.js";
|
|
51
|
+
function collectGlobalOptions(command) {
|
|
52
|
+
let current = command;
|
|
53
|
+
const merged = {};
|
|
54
|
+
while (current) {
|
|
55
|
+
Object.assign(merged, current.opts());
|
|
56
|
+
current = current.parent;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
repoRoot: merged.repoRoot,
|
|
60
|
+
adapter: merged.adapter,
|
|
61
|
+
worktree: merged.worktree,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function commandChain(command) {
|
|
65
|
+
const names = [];
|
|
66
|
+
let current = command;
|
|
67
|
+
while (current?.parent) {
|
|
68
|
+
const name = current.name();
|
|
69
|
+
if (name)
|
|
70
|
+
names.unshift(name);
|
|
71
|
+
current = current.parent;
|
|
72
|
+
}
|
|
73
|
+
return names;
|
|
74
|
+
}
|
|
75
|
+
async function resolveDispatchContext(command, defaultRepoRoot) {
|
|
76
|
+
const options = collectGlobalOptions(command);
|
|
77
|
+
const repoRoot = path.resolve(options.repoRoot ?? defaultRepoRoot);
|
|
78
|
+
const adapter = await resolveAdapter(repoRoot, options.adapter);
|
|
79
|
+
if (options.adapter)
|
|
80
|
+
console.log(`[loop-agent] adapter: ${adapter.name}`);
|
|
81
|
+
if (options.repoRoot)
|
|
82
|
+
console.log(`[loop-agent] repo root: ${repoRoot}`);
|
|
83
|
+
return {
|
|
84
|
+
adapter,
|
|
85
|
+
repoRoot,
|
|
86
|
+
explicitWorktree: options.worktree,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async function dispatchRegisteredCommand(commandObject, defaultRepoRoot, rawArgs) {
|
|
90
|
+
const chain = commandChain(commandObject);
|
|
91
|
+
const command = chain[0] ?? "";
|
|
92
|
+
const [subcommand, ...rest] = chain.length <= 1 ? rawArgs : [chain[1], ...chain.slice(2), ...rawArgs];
|
|
93
|
+
const ctx = await resolveDispatchContext(commandObject, defaultRepoRoot);
|
|
94
|
+
await runCommanderAction(ctx, command, subcommand, rest);
|
|
95
|
+
}
|
|
96
|
+
async function runCommanderAction(ctx, command, subcommand, rest) {
|
|
97
|
+
switch (command) {
|
|
98
|
+
case "inspect":
|
|
99
|
+
await runInspect(ctx.adapter, ctx.repoRoot);
|
|
100
|
+
return;
|
|
101
|
+
case "doctor":
|
|
102
|
+
await runDoctor(ctx.adapter, ctx.repoRoot);
|
|
103
|
+
return;
|
|
104
|
+
case "docs":
|
|
105
|
+
if (subcommand === "audit") {
|
|
106
|
+
await runDocsAudit(ctx.repoRoot);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (subcommand === "archive") {
|
|
110
|
+
const [planPath] = rest;
|
|
111
|
+
if (!planPath)
|
|
112
|
+
throw new Error("usage: docs archive <active-plan-path>");
|
|
113
|
+
await runDocsArchive(ctx.repoRoot, planPath);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
throw new Error("usage: docs <audit|archive> ...");
|
|
117
|
+
case "new-task": {
|
|
118
|
+
const [taskId, ...titleParts] = [subcommand, ...rest];
|
|
119
|
+
if (!taskId)
|
|
120
|
+
throw new Error("taskId required");
|
|
121
|
+
await runNewTask(ctx.repoRoot, taskId, titleParts.join(" ") || undefined);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
case "status": {
|
|
125
|
+
if (!subcommand)
|
|
126
|
+
throw new Error("taskId required");
|
|
127
|
+
await runStatus(ctx.repoRoot, subcommand);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
case "instructions":
|
|
131
|
+
await runInstructions(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
132
|
+
return;
|
|
133
|
+
case "promote-run":
|
|
134
|
+
await runPromoteRun(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
135
|
+
return;
|
|
136
|
+
case "closeout":
|
|
137
|
+
await runCloseout(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
138
|
+
return;
|
|
139
|
+
case "stats":
|
|
140
|
+
await runStats(ctx.repoRoot);
|
|
141
|
+
return;
|
|
142
|
+
case "plan":
|
|
143
|
+
if (subcommand === "list") {
|
|
144
|
+
await runPlanList(ctx.repoRoot);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
throw new Error("usage: plan <list>");
|
|
148
|
+
case "spine":
|
|
149
|
+
await runSpine(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
150
|
+
return;
|
|
151
|
+
case "handoff":
|
|
152
|
+
if (subcommand === "check") {
|
|
153
|
+
await runHandoffCheck(ctx.repoRoot, rest[0]);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (subcommand === "coverage") {
|
|
157
|
+
const [taskId, ...flags] = rest;
|
|
158
|
+
if (!taskId) {
|
|
159
|
+
throw new Error("usage: handoff coverage <taskId> [--json|--markdown]");
|
|
160
|
+
}
|
|
161
|
+
const exitCode = await runCoverageAudit(ctx.repoRoot, taskId, {
|
|
162
|
+
json: flags.includes("--json"),
|
|
163
|
+
markdown: flags.includes("--markdown"),
|
|
164
|
+
});
|
|
165
|
+
process.exitCode = exitCode;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
throw new Error("usage: handoff <check|coverage> [taskId]");
|
|
169
|
+
case "goal":
|
|
170
|
+
await runGoal(ctx.repoRoot, subcommand, rest);
|
|
171
|
+
return;
|
|
172
|
+
case "reference":
|
|
173
|
+
if (subcommand === "index") {
|
|
174
|
+
const [taskId] = rest;
|
|
175
|
+
if (!taskId)
|
|
176
|
+
throw new Error("usage: reference index <task-id>");
|
|
177
|
+
await runReferenceIndex(ctx.repoRoot, taskId);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
throw new Error("usage: reference <index> <task-id>");
|
|
181
|
+
case "study":
|
|
182
|
+
if (subcommand === "init") {
|
|
183
|
+
await runStudyInit(ctx.repoRoot, rest);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
throw new Error("usage: study init <task-id> [title] ...");
|
|
187
|
+
case "worktree":
|
|
188
|
+
if (subcommand === "create") {
|
|
189
|
+
await runWorktreeCreate(ctx.repoRoot, rest);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (subcommand === "list") {
|
|
193
|
+
await runWorktreeList(ctx.repoRoot);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (subcommand === "remove") {
|
|
197
|
+
await runWorktreeRemove(ctx.repoRoot, rest);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
throw new Error("usage: worktree <create|list|remove> ...");
|
|
201
|
+
case "delegate":
|
|
202
|
+
await runDelegate(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
203
|
+
return;
|
|
204
|
+
case "harvest":
|
|
205
|
+
await runHarvest(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
206
|
+
return;
|
|
207
|
+
case "cursor-worker":
|
|
208
|
+
await runCursorWorker(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
209
|
+
return;
|
|
210
|
+
case "knowledge":
|
|
211
|
+
await runKnowledge(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
212
|
+
return;
|
|
213
|
+
case "dag":
|
|
214
|
+
await runDagAction(ctx.repoRoot, subcommand, rest);
|
|
215
|
+
return;
|
|
216
|
+
case "run-dag":
|
|
217
|
+
await runRunDag(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
218
|
+
return;
|
|
219
|
+
case "workflow":
|
|
220
|
+
await runWorkflowCommand(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
221
|
+
return;
|
|
222
|
+
case "loop":
|
|
223
|
+
await runLoop(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
224
|
+
return;
|
|
225
|
+
case "pi-reuse-benchmark":
|
|
226
|
+
await runPiReuseBenchmark(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
227
|
+
return;
|
|
228
|
+
case "loop-benchmark":
|
|
229
|
+
await runLoopBenchmark(ctx.repoRoot, compactArgs([subcommand, ...rest]));
|
|
230
|
+
return;
|
|
231
|
+
default:
|
|
232
|
+
throw new Error(`commander command is not wired to an action: ${command}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async function runDagAction(repoRoot, subcommand, rest) {
|
|
236
|
+
const args = compactArgs(rest);
|
|
237
|
+
switch (subcommand) {
|
|
238
|
+
case "init-hybrid":
|
|
239
|
+
await runDagInitHybrid(repoRoot, args);
|
|
240
|
+
return;
|
|
241
|
+
case "validate":
|
|
242
|
+
await runDagValidate(repoRoot, args);
|
|
243
|
+
return;
|
|
244
|
+
case "workflow-validate":
|
|
245
|
+
await runDagWorkflowValidate(repoRoot, args);
|
|
246
|
+
return;
|
|
247
|
+
case "workflow-plan":
|
|
248
|
+
await runDagWorkflowPlan(repoRoot, args);
|
|
249
|
+
return;
|
|
250
|
+
case "workflow-compile":
|
|
251
|
+
await runDagWorkflowCompile(repoRoot, args);
|
|
252
|
+
return;
|
|
253
|
+
case "approve":
|
|
254
|
+
await runDagApprove(repoRoot, args);
|
|
255
|
+
return;
|
|
256
|
+
case "reject":
|
|
257
|
+
await runDagReject(repoRoot, args);
|
|
258
|
+
return;
|
|
259
|
+
case "resume":
|
|
260
|
+
await runDagResume(repoRoot, args);
|
|
261
|
+
return;
|
|
262
|
+
case "status":
|
|
263
|
+
await runDagStatus(repoRoot, args);
|
|
264
|
+
return;
|
|
265
|
+
case "doctor":
|
|
266
|
+
await runDagDoctor(repoRoot, args);
|
|
267
|
+
return;
|
|
268
|
+
case "run-task":
|
|
269
|
+
await runDagRunTask(repoRoot, args);
|
|
270
|
+
return;
|
|
271
|
+
case "report":
|
|
272
|
+
await runDagReport(repoRoot, args);
|
|
273
|
+
return;
|
|
274
|
+
case "closeout-draft":
|
|
275
|
+
await runDagCloseoutDraft(repoRoot, args);
|
|
276
|
+
return;
|
|
277
|
+
case "reconcile-tasks":
|
|
278
|
+
await runDagReconcileTasks(repoRoot, args);
|
|
279
|
+
return;
|
|
280
|
+
case "final-verification":
|
|
281
|
+
await runDagFinalVerification(repoRoot, args);
|
|
282
|
+
return;
|
|
283
|
+
case "decision": {
|
|
284
|
+
const [decisionSubcommand, ...decisionArgs] = args;
|
|
285
|
+
if (decisionSubcommand === "inspect") {
|
|
286
|
+
await runDagDecisionInspect(repoRoot, decisionArgs);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (decisionSubcommand === "validate") {
|
|
290
|
+
await runDagDecisionValidate(repoRoot, decisionArgs);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
throw new Error("usage: dag decision <inspect|validate> --run-id <id> [--node-id <node-id>]");
|
|
294
|
+
}
|
|
295
|
+
default:
|
|
296
|
+
throw new Error("usage: dag <init-hybrid|run-task|validate|workflow-plan|workflow-validate|workflow-compile|approve|reject|resume|status|doctor|report|closeout-draft|reconcile-tasks|final-verification|decision> ...");
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function compactArgs(args) {
|
|
300
|
+
return args.filter((arg) => Boolean(arg));
|
|
301
|
+
}
|
|
302
|
+
function createRawArgsCommand(name, description, defaultRepoRoot) {
|
|
303
|
+
return new Command(name)
|
|
304
|
+
.description(description)
|
|
305
|
+
.allowUnknownOption(true)
|
|
306
|
+
.allowExcessArguments(true)
|
|
307
|
+
.argument("[args...]", "command-specific arguments")
|
|
308
|
+
.action(async (args, _options, command) => {
|
|
309
|
+
await dispatchRegisteredCommand(command, defaultRepoRoot, args);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function addRawSubcommands(parent, subcommands, defaultRepoRoot) {
|
|
313
|
+
for (const subcommand of subcommands) {
|
|
314
|
+
parent.addCommand(createRawArgsCommand(subcommand, `${parent.name()} ${subcommand}`, defaultRepoRoot));
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function configureDagValidate(command) {
|
|
318
|
+
command
|
|
319
|
+
.description("Validate an Agent DAG spec")
|
|
320
|
+
.option("--dag <path>", "DAG spec path")
|
|
321
|
+
.option("--strict-models", "fail on model routing warnings")
|
|
322
|
+
.option("--strict-governance", "fail on governance warnings")
|
|
323
|
+
.option("--forbid-executor <executor>", "forbid executor", (value, previous = []) => [
|
|
324
|
+
...previous,
|
|
325
|
+
value,
|
|
326
|
+
])
|
|
327
|
+
.option("--spine-task <task-id>", "run spine audit for task id");
|
|
328
|
+
}
|
|
329
|
+
function configureRunDag(command) {
|
|
330
|
+
command
|
|
331
|
+
.description("Execute a reviewed Agent DAG spec")
|
|
332
|
+
.option("--dag <path>", "DAG spec path")
|
|
333
|
+
.option("-C, --cwd <dir>", "working directory")
|
|
334
|
+
.option("--init-only", "initialize run artifacts without executing")
|
|
335
|
+
.option("--dry-run", "validate and plan without executing")
|
|
336
|
+
.option("--max-concurrent <n>", "maximum concurrent nodes")
|
|
337
|
+
.option("--run-id <id>", "run id")
|
|
338
|
+
.option("--no-cursor", "disable Cursor execution")
|
|
339
|
+
.option("--canvas-path <path>", "absolute canvas output path")
|
|
340
|
+
.option("--canvas <name>", "canvas name")
|
|
341
|
+
.option("--canvases-dir <dir>", "canvas output directory");
|
|
342
|
+
}
|
|
343
|
+
function configureDagRunTask(command) {
|
|
344
|
+
command
|
|
345
|
+
.description("Create and optionally execute a DAG for a task")
|
|
346
|
+
.option("-o, --output <path>", "output DAG path")
|
|
347
|
+
.option("--profile <profile>", "auto|minimal|standard|reviewed|supervised")
|
|
348
|
+
.option("--strict-models", "fail on model routing warnings")
|
|
349
|
+
.option("--no-cursor", "disable Cursor execution")
|
|
350
|
+
.option("--execute", "execute after creating the DAG")
|
|
351
|
+
.option("--init-only", "initialize run artifacts without executing")
|
|
352
|
+
.option("--dry-run", "validate and plan without executing")
|
|
353
|
+
.option("--cwd <dir>", "working directory")
|
|
354
|
+
.option("--max-concurrent <n>", "maximum concurrent nodes")
|
|
355
|
+
.option("--run-id <id>", "run id")
|
|
356
|
+
.option("--canvas-path <path>", "absolute canvas output path")
|
|
357
|
+
.option("--canvas <name>", "canvas name")
|
|
358
|
+
.option("--canvases-dir <dir>", "canvas output directory");
|
|
359
|
+
}
|
|
360
|
+
function optionTokens(command) {
|
|
361
|
+
const tokens = [];
|
|
362
|
+
const options = command.opts();
|
|
363
|
+
for (const option of command.options) {
|
|
364
|
+
const value = options[option.attributeName()];
|
|
365
|
+
if (value === undefined)
|
|
366
|
+
continue;
|
|
367
|
+
const flag = option.long ?? option.short;
|
|
368
|
+
if (!flag)
|
|
369
|
+
continue;
|
|
370
|
+
if (option.negate) {
|
|
371
|
+
if (value === false)
|
|
372
|
+
tokens.push(flag);
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
if (value === false)
|
|
376
|
+
continue;
|
|
377
|
+
if (value === true)
|
|
378
|
+
tokens.push(flag);
|
|
379
|
+
else if (Array.isArray(value)) {
|
|
380
|
+
for (const item of value)
|
|
381
|
+
tokens.push(flag, String(item));
|
|
382
|
+
}
|
|
383
|
+
else
|
|
384
|
+
tokens.push(flag, String(value));
|
|
385
|
+
}
|
|
386
|
+
return tokens;
|
|
387
|
+
}
|
|
388
|
+
function commandArgsWithOptions(args, command) {
|
|
389
|
+
return [...args, ...optionTokens(command)];
|
|
390
|
+
}
|
|
391
|
+
function replaceActionWithOptionAwareDispatch(command, defaultRepoRoot) {
|
|
392
|
+
command.action(async (args, _options, actionCommand) => {
|
|
393
|
+
await dispatchRegisteredCommand(actionCommand, defaultRepoRoot, commandArgsWithOptions(args, actionCommand));
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
function addDagCommand(program, defaultRepoRoot) {
|
|
397
|
+
const dag = new Command("dag").description("Agent DAG commands");
|
|
398
|
+
addRawSubcommands(dag, [
|
|
399
|
+
"init-hybrid",
|
|
400
|
+
"workflow-plan",
|
|
401
|
+
"workflow-validate",
|
|
402
|
+
"workflow-compile",
|
|
403
|
+
"approve",
|
|
404
|
+
"reject",
|
|
405
|
+
"resume",
|
|
406
|
+
"status",
|
|
407
|
+
"doctor",
|
|
408
|
+
"report",
|
|
409
|
+
"closeout-draft",
|
|
410
|
+
"reconcile-tasks",
|
|
411
|
+
"final-verification",
|
|
412
|
+
], defaultRepoRoot);
|
|
413
|
+
const validate = createRawArgsCommand("validate", "Validate an Agent DAG spec", defaultRepoRoot);
|
|
414
|
+
configureDagValidate(validate);
|
|
415
|
+
replaceActionWithOptionAwareDispatch(validate, defaultRepoRoot);
|
|
416
|
+
dag.addCommand(validate);
|
|
417
|
+
const runTask = createRawArgsCommand("run-task", "Create and optionally execute a DAG for a task", defaultRepoRoot);
|
|
418
|
+
configureDagRunTask(runTask);
|
|
419
|
+
replaceActionWithOptionAwareDispatch(runTask, defaultRepoRoot);
|
|
420
|
+
dag.addCommand(runTask);
|
|
421
|
+
const decision = new Command("decision").description("DAG decision envelope commands");
|
|
422
|
+
addRawSubcommands(decision, ["inspect", "validate"], defaultRepoRoot);
|
|
423
|
+
dag.addCommand(decision);
|
|
424
|
+
program.addCommand(dag);
|
|
425
|
+
}
|
|
426
|
+
async function runCursorPromptCommand(args) {
|
|
427
|
+
try {
|
|
428
|
+
const parsed = parseCursorPromptArgs(args);
|
|
429
|
+
if ("listModels" in parsed) {
|
|
430
|
+
const { listModels } = await import("../commands/cursor-prompt.js");
|
|
431
|
+
listModels();
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
await runCursorPrompt(parsed);
|
|
435
|
+
}
|
|
436
|
+
catch (err) {
|
|
437
|
+
handleStandaloneOneShotCommandError(err, printCursorPromptUsage);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
async function runPiPromptCommand(args) {
|
|
441
|
+
try {
|
|
442
|
+
const parsed = parsePiPromptArgs(args);
|
|
443
|
+
await runPiPrompt(parsed);
|
|
444
|
+
}
|
|
445
|
+
catch (err) {
|
|
446
|
+
handleStandaloneOneShotCommandError(err, printPiPromptUsage);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
export function buildLoopAgentProgram(options) {
|
|
450
|
+
const program = new Command();
|
|
451
|
+
program
|
|
452
|
+
.name("loop-agent")
|
|
453
|
+
.description("Loop Agent task and DAG automation CLI")
|
|
454
|
+
.showHelpAfterError()
|
|
455
|
+
.option("--repo-root <path>", "repository root")
|
|
456
|
+
.option("--adapter <name>", "harness adapter name")
|
|
457
|
+
.option("--worktree <path>", "explicit worktree path");
|
|
458
|
+
for (const entry of CODE_AGENT_COMMAND_MANIFEST) {
|
|
459
|
+
if (entry.name === "dag") {
|
|
460
|
+
addDagCommand(program, options.defaultRepoRoot);
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
if (entry.name === "cursor-prompt") {
|
|
464
|
+
program
|
|
465
|
+
.command("cursor-prompt")
|
|
466
|
+
.description(entry.intent)
|
|
467
|
+
.allowUnknownOption(true)
|
|
468
|
+
.allowExcessArguments(true)
|
|
469
|
+
.argument("[args...]", "prompt arguments")
|
|
470
|
+
.action(async (args) => runCursorPromptCommand(args));
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
if (entry.name === "pi-prompt") {
|
|
474
|
+
program
|
|
475
|
+
.command("pi-prompt")
|
|
476
|
+
.description(entry.intent)
|
|
477
|
+
.allowUnknownOption(true)
|
|
478
|
+
.allowExcessArguments(true)
|
|
479
|
+
.argument("[args...]", "prompt arguments")
|
|
480
|
+
.action(async (args) => runPiPromptCommand(args));
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
const command = createRawArgsCommand(entry.name, entry.intent, options.defaultRepoRoot);
|
|
484
|
+
if (entry.name === "run-dag") {
|
|
485
|
+
configureRunDag(command);
|
|
486
|
+
replaceActionWithOptionAwareDispatch(command, options.defaultRepoRoot);
|
|
487
|
+
}
|
|
488
|
+
if (entry.subcommands)
|
|
489
|
+
addRawSubcommands(command, entry.subcommands, options.defaultRepoRoot);
|
|
490
|
+
program.addCommand(command);
|
|
491
|
+
}
|
|
492
|
+
return program;
|
|
493
|
+
}
|
|
494
|
+
export function getRegisteredCommandNames(program) {
|
|
495
|
+
return program.commands.map((command) => command.name());
|
|
496
|
+
}
|
|
497
|
+
export function findRegisteredCommand(program, pathSegments) {
|
|
498
|
+
let current = program;
|
|
499
|
+
for (const segment of pathSegments) {
|
|
500
|
+
current = current.commands.find((command) => command.name() === segment);
|
|
501
|
+
if (!current)
|
|
502
|
+
return undefined;
|
|
503
|
+
}
|
|
504
|
+
return current;
|
|
505
|
+
}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { buildLoopAgentProgram } from "./cli/program.js";
|
|
3
|
+
async function main() {
|
|
4
|
+
const program = buildLoopAgentProgram({
|
|
5
|
+
defaultRepoRoot: process.cwd(),
|
|
6
|
+
});
|
|
7
|
+
await program.parseAsync(process.argv);
|
|
8
|
+
}
|
|
9
|
+
main().catch((error) => {
|
|
10
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
11
|
+
process.exit(1);
|
|
12
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { closeoutTask } from '../records/promotion.js';
|
|
2
|
+
export function parseCloseoutArgs(args) {
|
|
3
|
+
const [subcommand, taskId, ...rest] = args;
|
|
4
|
+
if (subcommand !== 'task' || !taskId || rest.length > 0) {
|
|
5
|
+
throw new Error('usage: closeout task <task-id>');
|
|
6
|
+
}
|
|
7
|
+
return { taskId };
|
|
8
|
+
}
|
|
9
|
+
export async function runCloseout(repoRoot, args) {
|
|
10
|
+
const parsed = parseCloseoutArgs(args);
|
|
11
|
+
const result = await closeoutTask(repoRoot, parsed.taskId);
|
|
12
|
+
console.log(JSON.stringify(result, null, 2));
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { formatRequirementCoverageJson, formatRequirementCoverageMarkdown, runRequirementCoverageAudit, } from '../governance/requirement-coverage.js';
|
|
2
|
+
export async function runCoverageAudit(repoRoot, taskId, options = {}) {
|
|
3
|
+
const audit = await runRequirementCoverageAudit(repoRoot, taskId);
|
|
4
|
+
if (options.json) {
|
|
5
|
+
process.stdout.write(formatRequirementCoverageJson(audit));
|
|
6
|
+
}
|
|
7
|
+
else if (options.markdown) {
|
|
8
|
+
process.stdout.write(formatRequirementCoverageMarkdown(audit));
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
process.stdout.write(`${formatRequirementCoverageJson(audit)}`);
|
|
12
|
+
}
|
|
13
|
+
return audit.ok ? 0 : 1;
|
|
14
|
+
}
|