@tea-agent/loop-agent 0.42.0-next.1 → 0.42.0-next.10
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 +1 -1
- package/CHANGELOG.md +319 -1
- package/dist/application/dag/generate-task-dag.js +75 -19
- package/dist/application/dag/run-dag.js +41 -0
- package/dist/application/task-lifecycle/advance.js +24 -5
- package/dist/application/task-lifecycle/observe.js +171 -17
- package/dist/application/task-lifecycle/plan-transitions.js +42 -7
- package/dist/application/task-lifecycle/recommendations.js +13 -2
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +7 -0
- package/dist/cli/program.js +6 -1
- package/dist/commands/client-recovery.js +3 -0
- package/dist/commands/dag-follow-up.js +138 -0
- package/dist/commands/dag-rerun-task.js +2 -0
- package/dist/commands/init.js +27 -1
- package/dist/commands/task-advance.js +19 -0
- package/dist/executors/dag-pi-executor.js +3976 -76
- package/dist/executors/pi-executor.js +15 -4
- package/dist/executors/pi-read-budget-policy.js +239 -0
- package/dist/executors/shell-executor.js +978 -188
- package/dist/executors/shell-write-guard.js +7 -0
- package/dist/infrastructure/console/operation-store.js +226 -6
- package/dist/shared/dag-failure-category.js +12 -0
- package/dist/shared/openspec-spec.js +70 -4
- package/dist/shared/operator/capabilities.js +7 -0
- package/dist/task/config-types.js +105 -5
- package/dist/task/contract/adopt.js +4 -0
- package/dist/task/contract/import-revision.js +4 -0
- package/dist/task/contract/project.js +3 -0
- package/dist/task/contract/schema.js +2 -1
- package/dist/task/frontend-project-capability.js +203 -20
- package/dist/task/runtime.js +5 -2
- package/dist/task/source-prepare/build-draft.js +3 -3
- package/dist/task/source-prepare/fragment-inventory.js +64 -25
- package/dist/task/source-prepare/prepare.js +126 -21
- package/dist/task/source-prepare/semantic-intake.js +6 -2
- package/dist/task/source-references.js +22 -1
- package/dist/worker/console/chat/chat-ui-policy.js +4 -2
- package/dist/worker/console/chat/model-resolver.js +7 -4
- package/dist/worker/console/chat/pi-runtime.js +258 -11
- package/dist/worker/console/chat/repo-browser.js +10 -3
- package/dist/worker/console/chat/routes.js +165 -71
- package/dist/worker/console/chat/sdd-data-alignment.js +222 -0
- package/dist/worker/console/chat/session-catalog.js +2 -0
- package/dist/worker/console/chat/session-store.js +159 -70
- package/dist/worker/console/chat/shortcuts.js +19 -3
- package/dist/worker/console/chat/turn-process.js +111 -56
- package/dist/worker/console/frontend-human-decision-adapter.js +19 -0
- package/dist/worker/console/frontend-split-operation-adapter.js +20 -0
- package/dist/worker/console/index.js +3 -0
- package/dist/worker/console/operator-actions.js +169 -7
- package/dist/worker/console/pi-readiness.js +3 -2
- package/dist/worker/console/server.js +23 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-DZZ8m3PO.js → abnfDiagram-N423BO3Z-CcS17TBr.js} +1 -1
- package/dist/worker/console/static/assets/{arc-D6PvaVd-.js → arc-COptKq2S.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-B_OTOiI8.js → architectureDiagram-T3A2C74G-h4LKMHjP.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Bv6rqHBg.js → blockDiagram-VBNYF7ZC-COA1MOH0.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-B8eHr0oz.js → c4Diagram-5PPSVZJV-DJUf0QPm.js} +1 -1
- package/dist/worker/console/static/assets/channel-DdBCaOJ6.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DYwR0im2.js → chunk-2GRJ4B5K-mtWfKrUX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-D2WPGqXt.js → chunk-2Q5K7J3B-B8pXsxDQ.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-CQISJ_I7.js → chunk-5RXB4S5H-ipKzByl1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-C0o2Du1e.js → chunk-5VM5RSS4-DYi3Ald_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-4f8kr-U7.js → chunk-6Q2QTUOP-DQtGYoty.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D_OWvXzX.js → chunk-GF5L2VYU-BU0qS2YV.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CasdPz5X.js → chunk-JWPE2WC7-DVH9dIGE.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-Cj8lRrla.js → chunk-KBJHAD2P-Dt60SmgM.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CUvD1FSd.js → chunk-RYQCIY6F-BoaUGuEY.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CqLw_eqB.js → chunk-XXDRQBXY-_WHFDTp2.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DZFra1GO.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DZFra1GO.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-ku-WqJPx.js → cose-bilkent-JH36ORCC-BxkbTIRd.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-Bq_PYDhl.js → cynefin-VYW2F7L2-Bf2UVnoG.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BiGZV641.js → cynefinDiagram-MW4NZA55-Bo23q1J_.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-C4JRlglF.js → dagre-VZM6K2ZE-Dd_UU49i.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-B0dNeWYG.js → diagram-7IWD3JNH-ebUa1a9y.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-Cj35YvYM.js → diagram-B4RE2ZJO-BucthU8r.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-uzQoJ2-8.js → diagram-LBJQPF4R-BgqNpAkm.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-D1a-Buoz.js → diagram-Q27KOJAE-DC4q5NGa.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-XjRrLRSs.js → diagram-UB23O5K3-CBqCaMeb.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Da_O24cW.js → ebnfDiagram-BXEA7PRR-CGtnbQ3-.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-BLJ8jrYU.js → erDiagram-JOGREHBK-CG3LUao5.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-B9GrLjM0.js → flowDiagram-UKHOOZJN-D2ZVgoFS.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CeJ0TqiK.js → ganttDiagram-PKOTCBZU-DoYFZiKt.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bm2eNNFX.js → gitGraphDiagram-DS77QQ5N-CKoP1s6j.js} +1 -1
- package/dist/worker/console/static/assets/index-CAZ2fC_X.css +1 -0
- package/dist/worker/console/static/assets/index-vbTcFnFs.js +449 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DB26i3d8.js → infoDiagram-6WML65LV-Duofv8p2.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BOGRyeZT.js → ishikawaDiagram-WSZJBQD7-D2nlCkA1.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-CZRoBO_6.js → journeyDiagram-NVQOT4AX-Dd4IHdus.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-qlWhJyoB.js → kanban-definition-27J2QSJJ-Bi20AOdt.js} +1 -1
- package/dist/worker/console/static/assets/{linear-CfUiDDB3.js → linear-D59YJ9kB.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BQe6fpqj.js → mermaid.core-Bl13LpNa.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-zFzWHw64.js → mindmap-definition-FAOFIHXS-C6DLP5eY.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DFGUqjZO.js → pegDiagram-VL7TDLO6-BjO4cy64.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-BB5i0l8Z.js → pieDiagram-7S7Q4E2Y-D7i2qZTG.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-obbVZ_X5.js → quadrantDiagram-CIZ2JOQS-Dx8o_h0y.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BwdaNzc1.js → railroadDiagram-AXF67PYL-B55orI_t.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-CkTJaugh.js → requirementDiagram-LRYGKXZP-zWaehp6f.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-BwJ-hIgq.js → sankeyDiagram-W5VNT64P-CcA-pjvD.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BzSgmm7w.js → sequenceDiagram-SI44F4Z6-BOFbzNHI.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-Bn3oj5Q1.js → sizeCapture-X5ZJPWSS-BjAejah1.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-dxhGtL8K.js → stateDiagram-OKZ733FA-DXYwxJwZ.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Clg3V9t1.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BLpEInya.js → swimlanes-SLNWSIFB-OYiOch8n.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DX1dxAAW.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-ChJGYcXy.js → timeline-definition-Z64GVDOM-cZfH3nmU.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DK-qjRer.js → vennDiagram-T6HMQDX7-BDE7b3E1.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-3qeaWAg-.js → wardleyDiagram-T6FBY63Y-kyyGy9WJ.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CootlyP9.js → xychartDiagram-ELKLHX3M-CJj6VTog.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/active-run-badge.js +17 -0
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +5 -5
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +19 -8
- package/dist/worker/console/static-src/operator-chat/input-history.js +8 -6
- package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +15 -7
- package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +10 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +258 -23
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +112 -4
- package/dist/worker/console/static-src/operator-chat/useComposer.js +13 -4
- package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +29 -6
- package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +8 -2
- package/dist/worker/console/static-src/shell/console-update-reload.js +36 -9
- package/dist/worker/console/static-src/shell/workspace-route.js +11 -0
- package/dist/worker/console/workspace-context.js +115 -1
- package/dist/worker/materialize/frontend-split-task-materializer.js +72 -0
- package/dist/worker/observe/routes.js +4 -0
- package/dist/worker/observe/static/dag-helpers.js +4 -2
- package/dist/worker/observe/static/dag-node-purpose.js +5 -0
- package/dist/worker/observe/static/inspect-workspace.js +23 -0
- package/dist/worker/observe/static/kpi.js +2 -2
- package/dist/worker/observe/static/operator-chrome.d.ts +10 -2
- package/dist/worker/observe/static/operator-chrome.js +37 -23
- package/dist/worker/observe/static/relations.js +2 -2
- package/dist/worker/observe/static/router.d.ts +12 -1
- package/dist/worker/observe/static/router.js +48 -6
- package/dist/worker/observe/static/run-processing.js +4 -2
- package/dist/worker/observe/static/shell-chrome.js +2 -2
- package/dist/worker/observe/static/state.js +5 -0
- package/dist/worker/observe/static/styles.css +95 -0
- package/dist/worker/observe/static/views/dag-inspector.js +14 -7
- package/dist/worker/observe/static/views/dag.js +10 -2
- package/dist/worker/observe/static/views/dags.js +3 -1
- package/dist/worker/observe/static/views/dashboard.js +14 -6
- package/dist/worker/observe/static/views/pool.js +7 -2
- package/dist/worker/observe/static/views/run.js +12 -3
- package/dist/worker/observe/static/views/session-timeline.js +69 -10
- package/dist/worker/observe/static/views/task.js +7 -2
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +215 -28
- package/dist/workflows/dag/backend-test-markdown-workflow.js +13 -1
- package/dist/workflows/dag/backend-test-plan-protocol.js +106 -0
- package/dist/workflows/dag/backend-test-scenario-param.js +172 -25
- package/dist/workflows/dag/backend-test-scenario-partitions.js +62 -1
- package/dist/workflows/dag/backend-test-writer-completeness.js +104 -12
- package/dist/workflows/dag/contract-validator-registrations.js +1 -2
- package/dist/workflows/dag/dag-retry-schema.js +138 -0
- package/dist/workflows/dag/frontend-closeout.js +221 -0
- package/dist/workflows/dag/frontend-design-policy.js +400 -0
- package/dist/workflows/dag/frontend-human-decision.js +182 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +1237 -192
- package/dist/workflows/dag/frontend-plan-render.js +2 -1
- package/dist/workflows/dag/frontend-prewrite-gate.js +256 -350
- package/dist/workflows/dag/frontend-provider-capability-matrix.js +159 -0
- package/dist/workflows/dag/frontend-recovery-capsule.js +455 -0
- package/dist/workflows/dag/frontend-recovery-controller.js +226 -0
- package/dist/workflows/dag/frontend-recovery-lineage.js +178 -0
- package/dist/workflows/dag/frontend-recovery-plan.js +21 -10
- package/dist/workflows/dag/frontend-recovery-run.js +166 -34
- package/dist/workflows/dag/frontend-repair.js +1 -432
- package/dist/workflows/dag/frontend-review-context.js +261 -15
- package/dist/workflows/dag/frontend-review-findings.js +270 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +941 -0
- package/dist/workflows/dag/frontend-shape-capsule-store.js +191 -0
- package/dist/workflows/dag/frontend-shape-facts.js +419 -0
- package/dist/workflows/dag/frontend-shape.js +435 -0
- package/dist/workflows/dag/frontend-source-fidelity-ledger.js +108 -0
- package/dist/workflows/dag/frontend-split-application-service.js +203 -0
- package/dist/workflows/dag/frontend-split-orchestrator.js +899 -0
- package/dist/workflows/dag/frontend-typed-event-store.js +452 -0
- package/dist/workflows/dag/frontend-typed-event-transaction.js +180 -0
- package/dist/workflows/dag/frontend-verification-trace.js +252 -25
- package/dist/workflows/dag/frontend-worktree-diff.js +250 -17
- package/dist/workflows/dag/frontend-writer-admission.js +319 -0
- package/dist/workflows/dag/frontend-writer-status.js +256 -0
- package/dist/workflows/dag/init-hybrid.js +1028 -562
- package/dist/workflows/dag/interrupt-request.js +7 -0
- package/dist/workflows/dag/node-execution.js +828 -4
- package/dist/workflows/dag/prompt.js +70 -3
- package/dist/workflows/dag/recovery-lease.js +170 -0
- package/dist/workflows/dag/report.js +37 -1
- package/dist/workflows/dag/rerun-feedback.js +315 -1
- package/dist/workflows/dag/rerun-plan.js +17 -6
- package/dist/workflows/dag/rerun-run.js +44 -6
- package/dist/workflows/dag/rerun-task.js +251 -13
- package/dist/workflows/dag/retry-policy.js +219 -104
- package/dist/workflows/dag/runner.js +580 -124
- package/dist/workflows/dag/scheduler.js +133 -20
- package/dist/workflows/dag/types.js +244 -16
- package/dist/workflows/dag/validate.js +28 -12
- package/docs/examples/README.md +5 -0
- package/docs/init-surface.manifest.json +30 -12
- package/docs/skills/vetted-skill-registry.md +4 -2
- package/docs/templates/README.md +2 -0
- package/docs/templates/agent-dag-report.schema.json +8 -2
- package/docs/templates/agent-dag.schema.json +1 -1
- package/docs/templates/backend-test-dag.json +23 -20
- package/docs/templates/frontend-implementation-contract.schema.json +4 -1
- package/docs/templates/frontend-implementation-dag.json +89 -0
- package/docs/templates/spec-registry.schema.json +45 -0
- package/harness.json +1 -1
- package/package.json +4 -3
- package/skills/frontend-bounded-implement/SKILL.md +15 -14
- package/skills/frontend-bounded-implement/references/code-standards.md +19 -0
- package/skills/frontend-contract/SKILL.md +23 -0
- package/skills/frontend-contract/references/contract-protocol.md +34 -0
- package/skills/frontend-design-review/SKILL.md +22 -41
- package/skills/frontend-plan/SKILL.md +26 -0
- package/skills/frontend-plan/references/decision-contract.md +37 -0
- package/skills/frontend-plan/references/design-decisions.md +17 -0
- package/skills/frontend-review/SKILL.md +20 -15
- package/skills/frontend-review/references/review-findings.md +6 -7
- package/skills/frontend-scout/SKILL.md +25 -0
- package/skills/frontend-scout/references/design-evidence.md +16 -0
- package/skills/frontend-scout/references/scout-evidence.md +23 -0
- package/skills/frontend-verification/SKILL.md +1 -1
- package/skills/loop-agent/references/command-reference.md +1 -0
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
- package/dist/worker/console/static/assets/channel-BU5gOilw.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DIzKJGHr.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DIzKJGHr.js +0 -1
- package/dist/worker/console/static/assets/index-H9rFJiGL.css +0 -1
- package/dist/worker/console/static/assets/index-xwu9GxEc.js +0 -451
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Cld2qK9v.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-TIHpiT7w.js +0 -8
- package/skills/frontend-implementation/SKILL.md +0 -52
- package/skills/frontend-implementation/references/code-standards.md +0 -33
- package/skills/frontend-implementation/references/design-spec.md +0 -56
- package/skills/frontend-implementation/references/node-contracts.md +0 -31
|
@@ -37,6 +37,7 @@ import { runDagReconcileTasks } from "../commands/dag-reconcile-tasks.js";
|
|
|
37
37
|
import { runDagReconcileRun } from "../commands/dag-reconcile-run.js";
|
|
38
38
|
import { runDagRequestInterrupt } from "../commands/dag-request-interrupt.js";
|
|
39
39
|
import { runDagRerunTask } from "../commands/dag-rerun-task.js";
|
|
40
|
+
import { runDagFollowUp } from "../commands/dag-follow-up.js";
|
|
40
41
|
import { runDagRerun } from "../commands/dag-rerun.js";
|
|
41
42
|
import { runDagResume } from "../commands/dag-resume.js";
|
|
42
43
|
import { runDagDecisionInspect, runDagDecisionValidate, } from "../workflows/dag/decision-envelope.js";
|
|
@@ -137,6 +138,7 @@ const DAG_SUBCOMMANDS = [
|
|
|
137
138
|
"request-interrupt",
|
|
138
139
|
"rerun",
|
|
139
140
|
"rerun-task",
|
|
141
|
+
"follow-up",
|
|
140
142
|
"reconcile-tasks",
|
|
141
143
|
"final-verification",
|
|
142
144
|
"context",
|
|
@@ -585,6 +587,11 @@ export const COMMAND_DEFINITIONS = [
|
|
|
585
587
|
await runDagRerunTask(repoRoot, rerunTaskArgs);
|
|
586
588
|
return;
|
|
587
589
|
}
|
|
590
|
+
if (subcommand === "follow-up") {
|
|
591
|
+
const followUpArgs = rest.filter((arg) => Boolean(arg));
|
|
592
|
+
await runDagFollowUp(repoRoot, followUpArgs);
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
588
595
|
if (subcommand === "reconcile-tasks") {
|
|
589
596
|
const reconcileArgs = rest.filter((arg) => Boolean(arg));
|
|
590
597
|
await runDagReconcileTasks(repoRoot, reconcileArgs);
|
package/dist/cli/program.js
CHANGED
|
@@ -15,6 +15,7 @@ import { runDagReconcileTasks } from "../commands/dag-reconcile-tasks.js";
|
|
|
15
15
|
import { runDagReconcileRun } from "../commands/dag-reconcile-run.js";
|
|
16
16
|
import { runDagRequestInterrupt } from "../commands/dag-request-interrupt.js";
|
|
17
17
|
import { runDagRerunTask } from "../commands/dag-rerun-task.js";
|
|
18
|
+
import { runDagFollowUp } from "../commands/dag-follow-up.js";
|
|
18
19
|
import { runDagRerun } from "../commands/dag-rerun.js";
|
|
19
20
|
import { runDagReject } from "../commands/dag-reject.js";
|
|
20
21
|
import { runDagCloseoutDraft, runDagReport } from "../commands/dag-report.js";
|
|
@@ -359,6 +360,9 @@ async function runDagAction(repoRoot, subcommand, rest) {
|
|
|
359
360
|
case "rerun-task":
|
|
360
361
|
await runDagRerunTask(repoRoot, args);
|
|
361
362
|
return;
|
|
363
|
+
case "follow-up":
|
|
364
|
+
await runDagFollowUp(repoRoot, args);
|
|
365
|
+
return;
|
|
362
366
|
case "reconcile-tasks":
|
|
363
367
|
await runDagReconcileTasks(repoRoot, args);
|
|
364
368
|
return;
|
|
@@ -436,7 +440,7 @@ const RAW_SUBCOMMAND_USAGE = {
|
|
|
436
440
|
"dag approve": 'usage: dag approve --run-id <id> --option <A|B|...> [--notes "..."]',
|
|
437
441
|
"dag reject": 'usage: dag reject --run-id <id> --reason "..."',
|
|
438
442
|
"dag rerun": "usage: dag rerun --run-id <id> --from-node <node-id> --plan [--json] | dag rerun --run-id <id> --from-node <node-id> --plan-hash <hash> --request-id <key> --reason <text> [--json]",
|
|
439
|
-
"dag rerun-task": "usage: dag rerun-task --run-id <id> --reason <text> --request-id <key> [--profile auto|minimal|standard|reviewed|supervised] [--task-id <id>] [--json]",
|
|
443
|
+
"dag rerun-task": "usage: dag rerun-task --run-id <id> --reason <text> --request-id <key> [--profile auto|minimal|standard|reviewed|supervised] [--task-id <id>] [--frontend-recovery --recovery-operation-id <id>] [--json]",
|
|
440
444
|
"dag reconcile-run": "usage: dag reconcile-run --run-id <id> [--action supersede|abandon] [--reason <text>]",
|
|
441
445
|
"dag doctor": "usage: dag doctor [--run-id <id>]\nInspect health issues before approve/reject/resume; no --json (output is already structured JSON).",
|
|
442
446
|
"dag report": "usage: dag report [--run-id <id>] [--lifecycle active|paused|completed|all] [--json|--markdown] [--failed-only] [--latest] [--paused-latest]\nRead-only run report; --json gives structured facts (canonical: `dag report --run-id <id> --lifecycle completed --json`).",
|
|
@@ -553,6 +557,7 @@ function addDagCommand(program, defaultRepoRoot) {
|
|
|
553
557
|
"request-interrupt",
|
|
554
558
|
"rerun",
|
|
555
559
|
"rerun-task",
|
|
560
|
+
"follow-up",
|
|
556
561
|
"reconcile-tasks",
|
|
557
562
|
"final-verification",
|
|
558
563
|
"context",
|
|
@@ -1328,12 +1328,15 @@ export async function runClientRecovery(input) {
|
|
|
1328
1328
|
}
|
|
1329
1329
|
const plugin = await installProjectOpenCodePlugin({
|
|
1330
1330
|
repoRoot: input.repoRoot,
|
|
1331
|
+
onlyIfMissing: true,
|
|
1331
1332
|
});
|
|
1332
1333
|
const overflowPlugin = await installProjectOpenCodeOverflowCompactPlugin({
|
|
1333
1334
|
repoRoot: input.repoRoot,
|
|
1335
|
+
onlyIfMissing: true,
|
|
1334
1336
|
});
|
|
1335
1337
|
const piExtension = await installProjectPiContextOverflowExtension({
|
|
1336
1338
|
repoRoot: input.repoRoot,
|
|
1339
|
+
onlyIfMissing: true,
|
|
1337
1340
|
});
|
|
1338
1341
|
const pi = await applyProjectPiSettingsMerge({ repoRoot: input.repoRoot });
|
|
1339
1342
|
if (mode !== "user") {
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { mkdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { FRONTEND_REVIEW_FINDINGS_PRD_REL, readFrontendReviewFindingsPrd, } from "../workflows/dag/frontend-review-findings.js";
|
|
4
|
+
import { locateDagRun } from "../workflows/dag/lifecycle.js";
|
|
5
|
+
import { createTask, getTaskPaths } from "../task/runtime.js";
|
|
6
|
+
import { importPrdDocument } from "../task/source-references.js";
|
|
7
|
+
function parseFlagValue(rawArgs, flag) {
|
|
8
|
+
const index = rawArgs.indexOf(flag);
|
|
9
|
+
if (index < 0 || index + 1 >= rawArgs.length)
|
|
10
|
+
return undefined;
|
|
11
|
+
return rawArgs[index + 1];
|
|
12
|
+
}
|
|
13
|
+
export function parseDagFollowUpArgs(rawArgs) {
|
|
14
|
+
const positional = rawArgs.filter((arg) => !arg.startsWith("-"));
|
|
15
|
+
const parentRunId = positional[0];
|
|
16
|
+
if (!parentRunId) {
|
|
17
|
+
throw new Error("usage: dag follow-up <parent-run-id> [--task-id <id>] [--execute] [--profile <profile>]");
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
parentRunId,
|
|
21
|
+
taskId: parseFlagValue(rawArgs, "--task-id"),
|
|
22
|
+
execute: rawArgs.includes("--execute"),
|
|
23
|
+
profile: parseFlagValue(rawArgs, "--profile"),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function deriveFollowUpTaskId(parentRunId) {
|
|
27
|
+
// Deterministic, valid task id derived from the parent run id.
|
|
28
|
+
return `${parentRunId}-followup`;
|
|
29
|
+
}
|
|
30
|
+
/** CLI entry: parse raw args and run the follow-up flow. */
|
|
31
|
+
export async function runDagFollowUp(repoRoot, rawArgs) {
|
|
32
|
+
const parsed = parseDagFollowUpArgs(rawArgs);
|
|
33
|
+
const result = await runDagFollowUpInternal(repoRoot, parsed.parentRunId, {
|
|
34
|
+
taskId: parsed.taskId,
|
|
35
|
+
execute: parsed.execute,
|
|
36
|
+
profile: parsed.profile,
|
|
37
|
+
});
|
|
38
|
+
console.log(JSON.stringify(result, null, 2));
|
|
39
|
+
if (!result.ok) {
|
|
40
|
+
process.exitCode = result.mode === "blocked" ? 2 : 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export async function runDagFollowUpInternal(repoRoot, parentRunId, options = {}) {
|
|
44
|
+
const located = await locateDagRun(repoRoot, parentRunId);
|
|
45
|
+
if (!located) {
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
mode: "invalid",
|
|
49
|
+
reason: `dag run not found: ${parentRunId}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const prd = await readFrontendReviewFindingsPrd(located.runDir);
|
|
53
|
+
if (!prd) {
|
|
54
|
+
return {
|
|
55
|
+
ok: false,
|
|
56
|
+
mode: "invalid",
|
|
57
|
+
reason: `no frontend review findings PRD found in run ${parentRunId} (${FRONTEND_REVIEW_FINDINGS_PRD_REL}); the review must have committed request_review_changes`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const taskId = options.taskId ?? deriveFollowUpTaskId(parentRunId);
|
|
61
|
+
try {
|
|
62
|
+
await createTask(repoRoot, taskId, `修复 review 发现(parent ${parentRunId})`);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
mode: "blocked",
|
|
68
|
+
reason: `failed to create task ${taskId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Materialize the PRD draft into the task's source directory so the task
|
|
72
|
+
// lifecycle can import it as its requirement.
|
|
73
|
+
const prdMaterialized = path.join(getTaskPaths(repoRoot, taskId).sourceDir, "review-findings-prd.md");
|
|
74
|
+
try {
|
|
75
|
+
await mkdir(path.dirname(prdMaterialized), { recursive: true });
|
|
76
|
+
await importPrdDocument({
|
|
77
|
+
repoRoot,
|
|
78
|
+
taskId,
|
|
79
|
+
filePath: path.join(located.runDir, FRONTEND_REVIEW_FINDINGS_PRD_REL),
|
|
80
|
+
name: "review-findings-prd",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
mode: "blocked",
|
|
87
|
+
reason: `failed to import PRD into task ${taskId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (!options.execute) {
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
mode: "created",
|
|
94
|
+
taskId,
|
|
95
|
+
prdPath: prdMaterialized,
|
|
96
|
+
next: {
|
|
97
|
+
kind: "advance",
|
|
98
|
+
command: `loop-agent task advance ${taskId} --task-kind frontend-implementation --json`,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Execute: advance through the frontend DAG.
|
|
103
|
+
const { advanceTaskLifecycle } = await import("../application/task-lifecycle/advance.js");
|
|
104
|
+
const profile = options.profile === "auto" ||
|
|
105
|
+
options.profile === "minimal" ||
|
|
106
|
+
options.profile === "standard" ||
|
|
107
|
+
options.profile === "reviewed" ||
|
|
108
|
+
options.profile === "supervised"
|
|
109
|
+
? options.profile
|
|
110
|
+
: undefined;
|
|
111
|
+
const result = await advanceTaskLifecycle({
|
|
112
|
+
repoRoot,
|
|
113
|
+
taskId,
|
|
114
|
+
taskKind: "frontend-implementation",
|
|
115
|
+
taskKindExplicit: true,
|
|
116
|
+
...(profile ? { profile, profileExplicit: true } : {}),
|
|
117
|
+
observer: undefined,
|
|
118
|
+
});
|
|
119
|
+
const ok = result.lifecycleState === "run-succeeded" ||
|
|
120
|
+
result.lifecycleState === "awaiting-write-set-approval";
|
|
121
|
+
return {
|
|
122
|
+
ok,
|
|
123
|
+
mode: ok ? "created" : "blocked",
|
|
124
|
+
taskId,
|
|
125
|
+
prdPath: prdMaterialized,
|
|
126
|
+
reason: ok
|
|
127
|
+
? undefined
|
|
128
|
+
: `advance lifecycleState: ${result.lifecycleState}${result.blockers.length > 0
|
|
129
|
+
? `; blockers: ${result.blockers.map((b) => b.code).join(", ")}`
|
|
130
|
+
: ""}`,
|
|
131
|
+
next: ok
|
|
132
|
+
? undefined
|
|
133
|
+
: {
|
|
134
|
+
kind: "advance",
|
|
135
|
+
command: `loop-agent task advance ${taskId} --task-kind frontend-implementation --json`,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -11,6 +11,8 @@ export async function runDagRerunTask(repoRoot, rawArgs) {
|
|
|
11
11
|
profileExplicit: parsed.profileExplicit,
|
|
12
12
|
taskIdOverride: parsed.taskIdOverride,
|
|
13
13
|
execute: parsed.execute,
|
|
14
|
+
frontendRecovery: parsed.frontendRecovery,
|
|
15
|
+
recoveryOperationId: parsed.recoveryOperationId,
|
|
14
16
|
});
|
|
15
17
|
console.log(JSON.stringify(result, null, 2));
|
|
16
18
|
if (!result.ok) {
|
package/dist/commands/init.js
CHANGED
|
@@ -14,6 +14,19 @@ const GITIGNORE_BLOCK_START = "# LOOP_AGENT_INIT_START";
|
|
|
14
14
|
const GITIGNORE_BLOCK_END = "# LOOP_AGENT_INIT_END";
|
|
15
15
|
const INIT_SURFACE_STATE_PATH = ".harness/init-surface.json";
|
|
16
16
|
const DEFAULT_GOVERNANCE_ROOT = "ai_workspace/loop-agent";
|
|
17
|
+
function buildSpecRegistry() {
|
|
18
|
+
return `${JSON.stringify({
|
|
19
|
+
version: 1,
|
|
20
|
+
roots: [],
|
|
21
|
+
discovery: {
|
|
22
|
+
enabled: true,
|
|
23
|
+
maxDepth: 3,
|
|
24
|
+
maxFiles: 100,
|
|
25
|
+
maxBytes: 1048576,
|
|
26
|
+
timeoutMs: 2000,
|
|
27
|
+
},
|
|
28
|
+
}, null, 2)}\n`;
|
|
29
|
+
}
|
|
17
30
|
const CORE_DOC_FILES = [
|
|
18
31
|
{ source: "README.md", target: "README.md" },
|
|
19
32
|
{
|
|
@@ -610,7 +623,7 @@ if (
|
|
|
610
623
|
(assessment.status === "passed" && assessment.currentExitCode !== 0) ||
|
|
611
624
|
(assessment.status === "baseline-debt" && assessment.currentExitCode === 0)
|
|
612
625
|
) fail();
|
|
613
|
-
if (!assessment.baselineRef || assessment.baselineRef.nodeId !== "frontend-
|
|
626
|
+
if (!assessment.baselineRef || assessment.baselineRef.nodeId !== "frontend-writer-admission-shell") fail();
|
|
614
627
|
const baselineRaw = readContained(assessment.baselineRef.path);
|
|
615
628
|
if (sha256(baselineRaw) !== assessment.baselineRef.sha256) fail();
|
|
616
629
|
let baseline;
|
|
@@ -1312,6 +1325,9 @@ async function buildDesiredSurfaceContent(input) {
|
|
|
1312
1325
|
}), null, 2)}\n`,
|
|
1313
1326
|
};
|
|
1314
1327
|
}
|
|
1328
|
+
if (manifestPath === "docs/spec-registry.json") {
|
|
1329
|
+
return { content: buildSpecRegistry() };
|
|
1330
|
+
}
|
|
1315
1331
|
if (manifestPath === OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH) {
|
|
1316
1332
|
return { content: buildOpenCodeTransientRetryPluginSource() };
|
|
1317
1333
|
}
|
|
@@ -1709,6 +1725,8 @@ async function listRelativeFiles(rootPath) {
|
|
|
1709
1725
|
async function expectedLegacyInitFileSha(input) {
|
|
1710
1726
|
if (input.legacyPath.startsWith("docs/")) {
|
|
1711
1727
|
const doc = input.legacyPath.slice("docs/".length);
|
|
1728
|
+
if (doc === "spec-registry.json")
|
|
1729
|
+
return sha256Text(buildSpecRegistry());
|
|
1712
1730
|
const generated = buildGeneratedCoreDoc({
|
|
1713
1731
|
doc,
|
|
1714
1732
|
projectName: input.projectName,
|
|
@@ -2707,6 +2725,14 @@ export async function initializeLoopAgentProject(options) {
|
|
|
2707
2725
|
targetRelativePath: path.join(governanceRoot, "templates"),
|
|
2708
2726
|
written,
|
|
2709
2727
|
});
|
|
2728
|
+
await writeTextIfMissing({
|
|
2729
|
+
repoRoot,
|
|
2730
|
+
relativePath: path.join(governanceRoot, "spec-registry.json"),
|
|
2731
|
+
content: buildSpecRegistry(),
|
|
2732
|
+
merge,
|
|
2733
|
+
written,
|
|
2734
|
+
skipped,
|
|
2735
|
+
});
|
|
2710
2736
|
if (profile === "full") {
|
|
2711
2737
|
// Project repo-local skills live only under `.agents/skills/`.
|
|
2712
2738
|
// The package still ships `skills/` as the built-in fallback source.
|
|
@@ -377,6 +377,25 @@ export async function runTaskAdvance(repoRoot, args) {
|
|
|
377
377
|
intervalMs: options.progressIntervalMs,
|
|
378
378
|
});
|
|
379
379
|
}
|
|
380
|
+
// Idempotent client-recovery surface install before any DAG run: the Pi
|
|
381
|
+
// context-overflow extension / OpenCode plugins / project .pi settings
|
|
382
|
+
// are normally installed by `loop-agent init`, but an upgraded or
|
|
383
|
+
// non-init-created project may lack them. Installing here (missing-only)
|
|
384
|
+
// ensures the overflow compact+retry recovery path is always present,
|
|
385
|
+
// independent of how the project was created. Best-effort: a failure to
|
|
386
|
+
// install never blocks the run.
|
|
387
|
+
if (options.approveGate && !options.dryRun) {
|
|
388
|
+
try {
|
|
389
|
+
const { runClientRecovery } = await import("./client-recovery.js");
|
|
390
|
+
// mode "project" installs only project-owned surfaces
|
|
391
|
+
// (.pi/extensions + .opencode/plugins + .pi/settings.json),
|
|
392
|
+
// never the user home; installs are missing-only.
|
|
393
|
+
await runClientRecovery({ repoRoot, mode: "project" });
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
// best-effort; do not fail the run over a recovery-surface install
|
|
397
|
+
}
|
|
398
|
+
}
|
|
380
399
|
const result = await advanceTaskLifecycle(toUseCaseInput(repoRoot, taskId, options, progress?.observer));
|
|
381
400
|
const outcome = mapOutcome(result);
|
|
382
401
|
const gateStop = result.lifecycleState === "awaiting-write-set-approval" &&
|