@tea-agent/loop-agent 0.41.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 +397 -5
- package/dist/adapters/context-transfer/optional-pi-handoff.js +31 -0
- package/dist/adapters/context-transfer/pi-session.js +61 -0
- 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 +19 -0
- package/dist/cli/program.js +29 -2
- package/dist/commands/client-recovery.js +3 -0
- package/dist/commands/dag-artifact.js +284 -0
- package/dist/commands/dag-context.js +184 -0
- package/dist/commands/dag-follow-up.js +138 -0
- package/dist/commands/dag-rerun-task.js +2 -0
- package/dist/commands/dag-rerun.js +206 -1
- package/dist/commands/init.js +27 -1
- package/dist/commands/task-advance.js +19 -0
- package/dist/executors/dag-pi-executor.js +4013 -86
- package/dist/executors/pi-executor.js +15 -4
- package/dist/executors/pi-read-budget-policy.js +239 -0
- package/dist/executors/pi-sdk-executor.js +3 -0
- package/dist/executors/shell-executor.js +978 -188
- package/dist/executors/shell-write-guard.js +7 -0
- package/dist/{worker → infrastructure}/console/app-data.js +4 -0
- package/dist/infrastructure/console/artifact-revision-store.js +430 -0
- package/dist/infrastructure/console/context-export-store.js +160 -0
- package/dist/infrastructure/console/dir-lock.js +132 -0
- package/dist/infrastructure/console/operation-store.js +417 -0
- package/dist/infrastructure/harness/artifact-store.js +10 -1
- package/dist/infrastructure/harness/atomic-write.js +12 -2
- package/dist/shared/context-transfer/artifact-revision.js +172 -0
- package/dist/shared/context-transfer.js +418 -0
- package/dist/shared/dag-failure-category.js +12 -0
- package/dist/shared/openspec-spec.js +70 -4
- package/dist/shared/operator/capabilities.js +21 -0
- package/dist/shared/operator/safe-run-summary.js +1 -0
- package/dist/shared/path-safety.js +93 -0
- package/dist/shared/preview.js +28 -4
- package/dist/task/config-types.js +107 -6
- 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/task/task-demand-routing.js +3 -0
- package/dist/worker/console/chat/chat-event-store.js +2 -2
- package/dist/worker/console/chat/model-resolver.js +7 -4
- package/dist/worker/console/chat/pi-runtime.js +86 -5
- package/dist/worker/console/chat/resource-preferences-store.js +1 -1
- package/dist/worker/console/chat/routes.js +136 -53
- 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 +43 -1
- package/dist/worker/console/chat/shortcuts.js +18 -2
- package/dist/worker/console/chat/user-questions.js +1 -1
- package/dist/worker/console/console-update-runtime.js +1 -1
- package/dist/worker/console/context-transfer-diagnostics.js +198 -0
- package/dist/worker/console/dag-confirmation.js +1 -1
- package/dist/worker/console/dag-execution-receipt.js +1 -1
- package/dist/worker/console/doctor.js +1 -1
- package/dist/worker/console/draft-store.js +1 -1
- 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/human-gate-token.js +1 -1
- package/dist/worker/console/index.js +6 -3
- package/dist/worker/console/interview/assessment.js +1 -1
- package/dist/worker/console/interview/session.js +1 -1
- package/dist/worker/console/operation-runner.js +45 -4
- package/dist/worker/console/operation-sse.js +1 -1
- package/dist/worker/console/operation-wait.js +1 -1
- package/dist/worker/console/operator-actions.js +273 -10
- package/dist/worker/console/operator-surface-health.js +1 -1
- package/dist/worker/console/operator-user-error.js +169 -0
- package/dist/worker/console/pi-plugins.js +57 -0
- package/dist/worker/console/pi-readiness.js +3 -2
- package/dist/worker/console/routes.js +637 -8
- package/dist/worker/console/security.js +35 -0
- package/dist/worker/console/server.js +29 -4
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-D7oU983t.js → abnfDiagram-N423BO3Z-CcS17TBr.js} +1 -1
- package/dist/worker/console/static/assets/{arc-BrKSRdFS.js → arc-COptKq2S.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CiXV7L56.js → architectureDiagram-T3A2C74G-h4LKMHjP.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-D_Hs_gIG.js → blockDiagram-VBNYF7ZC-COA1MOH0.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DbM-Lqqh.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-D1M8uqJw.js → chunk-2GRJ4B5K-mtWfKrUX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-4D3RFHT6.js → chunk-2Q5K7J3B-B8pXsxDQ.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-CdwpY_n9.js → chunk-5RXB4S5H-ipKzByl1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BLeLZ9PG.js → chunk-5VM5RSS4-DYi3Ald_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-CeRNEMvc.js → chunk-6Q2QTUOP-DQtGYoty.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CjkHP8Vy.js → chunk-GF5L2VYU-BU0qS2YV.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-B54ZUQY-.js → chunk-JWPE2WC7-DVH9dIGE.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-4bKaMVmx.js → chunk-KBJHAD2P-Dt60SmgM.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-Cyjfznu_.js → chunk-RYQCIY6F-BoaUGuEY.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CDN-zGFV.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-HxJmz411.js → cose-bilkent-JH36ORCC-BxkbTIRd.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-DtSt5K2w.js → cynefin-VYW2F7L2-Bf2UVnoG.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-VtkSpRmG.js → cynefinDiagram-MW4NZA55-Bo23q1J_.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-Bj4DT4du.js → dagre-VZM6K2ZE-Dd_UU49i.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-Bpuk6BmP.js → diagram-7IWD3JNH-ebUa1a9y.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BHYGv_yO.js → diagram-B4RE2ZJO-BucthU8r.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DEx3WwnT.js → diagram-LBJQPF4R-BgqNpAkm.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Cj0dS5e8.js → diagram-Q27KOJAE-DC4q5NGa.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-B97h8l21.js → diagram-UB23O5K3-CBqCaMeb.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-DMSFAhBd.js → ebnfDiagram-BXEA7PRR-CGtnbQ3-.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DhVOCbt6.js → erDiagram-JOGREHBK-CG3LUao5.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-GlakITWL.js → flowDiagram-UKHOOZJN-D2ZVgoFS.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-VxPpu9eQ.js → ganttDiagram-PKOTCBZU-DoYFZiKt.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bs_e5DRT.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-BXYuU4Uw.js → infoDiagram-6WML65LV-Duofv8p2.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-C34erCbU.js → ishikawaDiagram-WSZJBQD7-D2nlCkA1.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DZCAiOU3.js → journeyDiagram-NVQOT4AX-Dd4IHdus.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-C9gaTdUm.js → kanban-definition-27J2QSJJ-Bi20AOdt.js} +1 -1
- package/dist/worker/console/static/assets/{linear-CvI0Z17U.js → linear-D59YJ9kB.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-DMMSIx7j.js → mermaid.core-Bl13LpNa.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BKKP0EO6.js → mindmap-definition-FAOFIHXS-C6DLP5eY.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-C3LiFbl5.js → pegDiagram-VL7TDLO6-BjO4cy64.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-Bb3Om2Dz.js → pieDiagram-7S7Q4E2Y-D7i2qZTG.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-DNthMjzc.js → quadrantDiagram-CIZ2JOQS-Dx8o_h0y.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-miFsr4Tv.js → railroadDiagram-AXF67PYL-B55orI_t.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-yXUncmn6.js → requirementDiagram-LRYGKXZP-zWaehp6f.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-DLeWKLak.js → sankeyDiagram-W5VNT64P-CcA-pjvD.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CI3he1R3.js → sequenceDiagram-SI44F4Z6-BOFbzNHI.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-B7jfDkS5.js → sizeCapture-X5ZJPWSS-BjAejah1.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BmrZod7J.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-CDOlHVSY.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-Cz-XX1gy.js → timeline-definition-Z64GVDOM-cZfH3nmU.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-caV4cI8C.js → vennDiagram-T6HMQDX7-BDE7b3E1.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-dImPlnIO.js → wardleyDiagram-T6FBY63Y-kyyGy9WJ.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CtRYVJcn.js → xychartDiagram-ELKLHX3M-CJj6VTog.js} +1 -1
- package/dist/worker/console/static/index.html +7 -2
- package/dist/worker/console/static-src/active-run-badge.js +17 -0
- package/dist/worker/console/static-src/app/useOperatorActions.js +3 -2
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +5 -5
- package/dist/worker/console/static-src/operator-chat/input-history.js +8 -6
- 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 +52 -0
- package/dist/worker/console/static-src/shell/workspace-route.js +11 -0
- package/dist/worker/console/workspace-context.js +142 -2
- package/dist/worker/console/workspace-registry.js +2 -2
- package/dist/worker/continuation/worker-continuation.js +278 -0
- package/dist/worker/materialize/frontend-split-task-materializer.js +72 -0
- package/dist/worker/observe/health.js +1 -1
- package/dist/worker/observe/node-transparency.js +572 -0
- package/dist/worker/observe/routes.js +55 -1
- package/dist/worker/observe/static/api.js +69 -5
- package/dist/worker/observe/static/dag-context-reason-labels.d.ts +9 -0
- package/dist/worker/observe/static/dag-context-reason-labels.js +120 -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 +8 -1
- package/dist/worker/observe/static/styles.css +1092 -86
- package/dist/worker/observe/static/views/dag-inspector.js +1228 -64
- 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 +142 -18
- package/dist/worker/observe/static/views/task.js +7 -2
- package/dist/worker/outcomes/adapters.js +19 -0
- package/dist/worker/outcomes/types.js +1 -0
- package/dist/worker/pool/attempt-lease.js +97 -66
- package/dist/worker/pool/begin-attempt-with-lease.js +1 -0
- package/dist/worker/pool/reconcile.js +46 -1
- package/dist/worker/pool/run-store.js +2 -0
- package/dist/worker/pool/state-projection.js +2 -0
- package/dist/worker/task-spec/workflow-routing.js +8 -3
- package/dist/workflows/dag/artifact-bindings.js +149 -0
- package/dist/workflows/dag/artifact-revision-schema-registry.js +31 -0
- 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/budget-enforcement.js +10 -0
- package/dist/workflows/dag/context-receipt.js +305 -0
- package/dist/workflows/dag/context-transfer/context-bundle.js +423 -0
- package/dist/workflows/dag/context-transfer/operator-actions.js +61 -0
- package/dist/workflows/dag/context-transfer/renderers.js +93 -0
- 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-rollback.js +32 -0
- package/dist/workflows/dag/frontend-writer-status.js +256 -0
- package/dist/workflows/dag/init-hybrid.js +1174 -562
- package/dist/workflows/dag/interrupt-request.js +7 -0
- package/dist/workflows/dag/node-execution.js +940 -31
- package/dist/workflows/dag/path-safety.js +1 -0
- package/dist/workflows/dag/prompt.js +99 -7
- 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 +568 -3
- package/dist/workflows/dag/rerun-run.js +642 -18
- package/dist/workflows/dag/rerun-task.js +251 -13
- package/dist/workflows/dag/retry-policy.js +219 -104
- package/dist/workflows/dag/runner.js +596 -121
- package/dist/workflows/dag/scheduler.js +133 -20
- package/dist/workflows/dag/skill-snapshot.js +17 -0
- package/dist/workflows/dag/types.js +426 -22
- package/dist/workflows/dag/validate.js +28 -12
- package/docs/architecture/runtime-boundaries.md +6 -6
- package/docs/architecture/worker-and-feature.md +1 -1
- 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 +33 -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/product-line/task.yaml +1 -1
- package/docs/templates/spec-registry.schema.json +45 -0
- package/harness.json +1 -1
- package/package.json +6 -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 +7 -0
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
- package/dist/worker/console/operation-store.js +0 -169
- package/dist/worker/console/static/assets/channel-D1xajGpe.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BmuGTfRr.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BmuGTfRr.js +0 -1
- package/dist/worker/console/static/assets/index-BLzcAykx.js +0 -451
- package/dist/worker/console/static/assets/index-Cs9JUSPs.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-D9ykKEWP.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BvPOXALT.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
- /package/dist/{worker → infrastructure}/console/repo-fingerprint.js +0 -0
|
@@ -7,7 +7,7 @@ import { attachRuntimeSnapshotController } from "./useRuntimeSnapshot.js";
|
|
|
7
7
|
/** Composer state: input text, @file palette, image attachments, /shortcuts,
|
|
8
8
|
* IME composition guards, auto-grow and server-side draft sync. */
|
|
9
9
|
export function useComposer(params) {
|
|
10
|
-
const { origin, sessionId, refs, setError } = params;
|
|
10
|
+
const { origin, sessionId, refs, setError, onUnrecoverableSession } = params;
|
|
11
11
|
const [input, setInputState] = useState("");
|
|
12
12
|
const [fileOptions, setFileOptions] = useState([]);
|
|
13
13
|
const [pendingImages, setPendingImages] = useState([]);
|
|
@@ -28,6 +28,7 @@ export function useComposer(params) {
|
|
|
28
28
|
}, []);
|
|
29
29
|
const [shortcutIndex, setShortcutIndex] = useState(0);
|
|
30
30
|
const [dynamicCommands, setDynamicCommands] = useState([]);
|
|
31
|
+
const [commandCapabilities, setCommandCapabilities] = useState({ sddBingo: false });
|
|
31
32
|
const [dynamicCommandsLoading, setDynamicCommandsLoading] = useState(false);
|
|
32
33
|
const [dynamicCommandsError, setDynamicCommandsError] = useState(null);
|
|
33
34
|
const [commandsEpoch, setCommandsEpoch] = useState(0);
|
|
@@ -74,6 +75,7 @@ export function useComposer(params) {
|
|
|
74
75
|
commandsSessionRef.current = sessionId;
|
|
75
76
|
commandsGenerationRef.current += 1;
|
|
76
77
|
setDynamicCommands([]);
|
|
78
|
+
setCommandCapabilities({ sddBingo: false });
|
|
77
79
|
setDynamicCommandsError(null);
|
|
78
80
|
setDynamicCommandsLoading(false);
|
|
79
81
|
}, [sessionId]);
|
|
@@ -122,6 +124,7 @@ export function useComposer(params) {
|
|
|
122
124
|
if (!isCurrent())
|
|
123
125
|
return;
|
|
124
126
|
setDynamicCommands(items);
|
|
127
|
+
setCommandCapabilities({ sddBingo: body?.capabilities?.sddBingo === true });
|
|
125
128
|
// Compact server fail-soft / partial-source warning; local Operator/Web still merge.
|
|
126
129
|
const warning = typeof body?.warning === "string" ? body.warning.trim() : "";
|
|
127
130
|
setDynamicCommandsError(warning ? warning.slice(0, 160) : null);
|
|
@@ -131,6 +134,7 @@ export function useComposer(params) {
|
|
|
131
134
|
return;
|
|
132
135
|
setDynamicCommandsError("动态命令加载失败");
|
|
133
136
|
setDynamicCommands([]);
|
|
137
|
+
setCommandCapabilities({ sddBingo: false });
|
|
134
138
|
}
|
|
135
139
|
finally {
|
|
136
140
|
if (isCurrent()) {
|
|
@@ -227,7 +231,7 @@ export function useComposer(params) {
|
|
|
227
231
|
}, 400);
|
|
228
232
|
return () => window.clearTimeout(timer);
|
|
229
233
|
}, [origin, sessionId, input]);
|
|
230
|
-
const mergedCommands = useMemo(() => mergeSlashCommands(dynamicCommands), [dynamicCommands]);
|
|
234
|
+
const mergedCommands = useMemo(() => mergeSlashCommands(dynamicCommands, commandCapabilities), [dynamicCommands, commandCapabilities]);
|
|
231
235
|
const filteredShortcuts = useMemo(() => input.startsWith("/")
|
|
232
236
|
? filterSlashCommands(mergedCommands, input)
|
|
233
237
|
: [], [input, mergedCommands]);
|
|
@@ -258,8 +262,13 @@ export function useComposer(params) {
|
|
|
258
262
|
// origin + sessionId + refs in a writable file; the snapshot store is
|
|
259
263
|
// consumed by ChatComposer / panels / runtime-context popover).
|
|
260
264
|
useEffect(() => {
|
|
261
|
-
attachRuntimeSnapshotController({
|
|
262
|
-
|
|
265
|
+
attachRuntimeSnapshotController({
|
|
266
|
+
origin,
|
|
267
|
+
sessionId,
|
|
268
|
+
refs,
|
|
269
|
+
onUnrecoverableSession,
|
|
270
|
+
});
|
|
271
|
+
}, [origin, sessionId, refs, onUnrecoverableSession]);
|
|
263
272
|
return {
|
|
264
273
|
input,
|
|
265
274
|
setInput,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { formatModelRef, mergeSessionRuntime, sessionRuntimeMatches, } from "../../chat/runtime-selection.js";
|
|
3
3
|
import { confirmationToken } from "./format.js";
|
|
4
|
-
import { mergeRuntimeContextWithSnapshot, runtimeSelectionFromSnapshot, } from "./runtime-snapshot-store.js";
|
|
4
|
+
import { isLostChatSessionError, mergeRuntimeContextWithSnapshot, runtimeSelectionFromSnapshot, } from "./runtime-snapshot-store.js";
|
|
5
5
|
import { buildToolCatalog } from "./tools-catalog.js";
|
|
6
6
|
import { adoptMutationSnapshot, dispatchRuntimeSnapshot, getRuntimeSnapshotState, refreshRuntimeSnapshot, settleMutationLifecycle, useRuntimeSnapshot, } from "./useRuntimeSnapshot.js";
|
|
7
7
|
/**
|
|
@@ -14,7 +14,7 @@ let mutationSeq = 0;
|
|
|
14
14
|
/** Capabilities catalog, model / thinking-level switcher, runtime-context
|
|
15
15
|
* popover and the outside-click dismissal for both transient menus. */
|
|
16
16
|
export function useRuntimeControls(params) {
|
|
17
|
-
const { origin, session, setSession, refs, setError } = params;
|
|
17
|
+
const { origin, session, setSession, refs, setError, onUnrecoverableSession } = params;
|
|
18
18
|
const [capabilities, setCapabilities] = useState(null);
|
|
19
19
|
const [models, setModels] = useState([]);
|
|
20
20
|
const [modelsStatus, setModelsStatus] = useState("idle");
|
|
@@ -84,9 +84,20 @@ export function useRuntimeControls(params) {
|
|
|
84
84
|
if (refs.sessionRef.current?.sessionId !== sessionId)
|
|
85
85
|
return;
|
|
86
86
|
if (!res.ok || !body) {
|
|
87
|
+
const error = body
|
|
88
|
+
?.error;
|
|
89
|
+
if (isLostChatSessionError({
|
|
90
|
+
status: res.status,
|
|
91
|
+
code: error?.code,
|
|
92
|
+
message: error?.message,
|
|
93
|
+
})) {
|
|
94
|
+
setModelsStatus("idle");
|
|
95
|
+
setModelsError(null);
|
|
96
|
+
onUnrecoverableSession?.(sessionId);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
87
99
|
setModelsStatus("error");
|
|
88
|
-
setModelsError(
|
|
89
|
-
?.error?.message ?? `模型列表读取失败(HTTP ${res.status})`);
|
|
100
|
+
setModelsError(error?.message ?? `模型列表读取失败(HTTP ${res.status})`);
|
|
90
101
|
return;
|
|
91
102
|
}
|
|
92
103
|
setModels(body.models ?? []);
|
|
@@ -99,7 +110,7 @@ export function useRuntimeControls(params) {
|
|
|
99
110
|
setModelsStatus("error");
|
|
100
111
|
setModelsError(reason instanceof Error ? reason.message : String(reason));
|
|
101
112
|
}
|
|
102
|
-
}, [origin, session, refs]);
|
|
113
|
+
}, [origin, session, refs, onUnrecoverableSession]);
|
|
103
114
|
useEffect(() => {
|
|
104
115
|
void loadModels();
|
|
105
116
|
}, [loadModels]);
|
|
@@ -126,6 +137,18 @@ export function useRuntimeControls(params) {
|
|
|
126
137
|
if (refs.sessionRef.current?.sessionId !== sessionId)
|
|
127
138
|
return;
|
|
128
139
|
if (!body?.context) {
|
|
140
|
+
if (!r.ok &&
|
|
141
|
+
isLostChatSessionError({
|
|
142
|
+
status: r.status,
|
|
143
|
+
code: body
|
|
144
|
+
?.error?.code,
|
|
145
|
+
message: body
|
|
146
|
+
?.error?.message,
|
|
147
|
+
})) {
|
|
148
|
+
setRuntimeContextLoading(false);
|
|
149
|
+
onUnrecoverableSession?.(sessionId);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
129
152
|
if (!r.ok)
|
|
130
153
|
setRuntimeContextError("注入上下文读取失败,请重试");
|
|
131
154
|
return;
|
|
@@ -158,7 +181,7 @@ export function useRuntimeControls(params) {
|
|
|
158
181
|
return;
|
|
159
182
|
setRuntimeContextError("注入上下文读取失败,请重试");
|
|
160
183
|
});
|
|
161
|
-
}, [origin, session?.sessionId, refs]);
|
|
184
|
+
}, [origin, session?.sessionId, refs, onUnrecoverableSession]);
|
|
162
185
|
// AC-01/RF3-01: hydrate the Composer from the unified snapshot — real
|
|
163
186
|
// model and thinking selection; `auto` displays the Pi actual effective
|
|
164
187
|
// level. Derived session/runtimeContext state ONLY comes from a snapshot
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { useSyncExternalStore } from "react";
|
|
13
13
|
import { confirmationToken } from "./format.js";
|
|
14
|
-
import { createRuntimeSnapshotStore, parseRuntimeSnapshotError, } from "./runtime-snapshot-store.js";
|
|
14
|
+
import { createRuntimeSnapshotStore, isLostChatSessionError, parseRuntimeSnapshotError, } from "./runtime-snapshot-store.js";
|
|
15
15
|
const store = createRuntimeSnapshotStore();
|
|
16
16
|
let controller;
|
|
17
17
|
function snapshotUrl(sessionId) {
|
|
@@ -49,10 +49,16 @@ async function fetchSnapshot(sessionId, origin) {
|
|
|
49
49
|
if (controller?.sessionId !== sessionId)
|
|
50
50
|
return; // stale session reply
|
|
51
51
|
if (!res.ok) {
|
|
52
|
+
const error = { ...parseRuntimeSnapshotError(body), status: res.status };
|
|
53
|
+
if (isLostChatSessionError(error)) {
|
|
54
|
+
store.dispatch({ type: "reset" });
|
|
55
|
+
controller.onUnrecoverableSession?.(sessionId);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
52
58
|
store.dispatch({
|
|
53
59
|
type: "load-failure",
|
|
54
60
|
sessionId,
|
|
55
|
-
error
|
|
61
|
+
error,
|
|
56
62
|
});
|
|
57
63
|
return;
|
|
58
64
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export function isReplacementConsoleHealth(health, expectedConsoleInstanceId, previousConsoleInstanceId) {
|
|
2
|
+
if (!health || typeof health !== "object")
|
|
3
|
+
return false;
|
|
4
|
+
const instanceId = typeof health.consoleInstanceId ===
|
|
5
|
+
"string"
|
|
6
|
+
? health.consoleInstanceId.trim()
|
|
7
|
+
: "";
|
|
8
|
+
if (!instanceId)
|
|
9
|
+
return false;
|
|
10
|
+
const expected = expectedConsoleInstanceId?.trim();
|
|
11
|
+
if (expected)
|
|
12
|
+
return instanceId === expected;
|
|
13
|
+
return previousConsoleInstanceId !== null && instanceId !== previousConsoleInstanceId;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Poll /api/health until the replacement Console answers, then reload. A
|
|
17
|
+
* handoff deliberately leaves the old process alive briefly, so HTTP 200 alone
|
|
18
|
+
* is insufficient: the response must carry the new instance identity.
|
|
19
|
+
*/
|
|
20
|
+
export async function reloadWhenConsoleReady(options = {}) {
|
|
21
|
+
const timeoutMs = options.timeoutMs ?? 30_000;
|
|
22
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
23
|
+
const reload = options.reload ?? (() => window.location.reload());
|
|
24
|
+
const started = Date.now();
|
|
25
|
+
let previousConsoleInstanceId = null;
|
|
26
|
+
while (Date.now() - started < timeoutMs) {
|
|
27
|
+
try {
|
|
28
|
+
const res = await fetchImpl(`/api/health?ts=${Date.now()}`, {
|
|
29
|
+
cache: "no-store",
|
|
30
|
+
});
|
|
31
|
+
if (res.ok) {
|
|
32
|
+
const health = await res.json().catch(() => null);
|
|
33
|
+
if (isReplacementConsoleHealth(health, options.expectedConsoleInstanceId, previousConsoleInstanceId)) {
|
|
34
|
+
reload();
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
const healthRecord = health;
|
|
38
|
+
const instanceId = typeof healthRecord?.consoleInstanceId === "string"
|
|
39
|
+
? healthRecord.consoleInstanceId.trim()
|
|
40
|
+
: "";
|
|
41
|
+
if (instanceId && previousConsoleInstanceId === null) {
|
|
42
|
+
previousConsoleInstanceId = instanceId;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// old process gone, new one not listening yet — keep polling
|
|
48
|
+
}
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
@@ -170,6 +170,17 @@ export function withWorkspaceId(href, workspaceId) {
|
|
|
170
170
|
const qs = query.toString();
|
|
171
171
|
return `/#${path}${qs ? `?${qs}` : ""}`;
|
|
172
172
|
}
|
|
173
|
+
/** Preserve the selected scope for a deep link emitted inside an Operate page.
|
|
174
|
+
* Components should prefer this to hand-writing `/#/inspect/...`: it reads the
|
|
175
|
+
* canonical hash at click/render time and intentionally leaves bare Chat URLs
|
|
176
|
+
* unchanged because Chat selection is client state. */
|
|
177
|
+
export function withCurrentWorkspaceId(href, locationLike = typeof globalThis.location === "undefined" ? undefined : globalThis.location) {
|
|
178
|
+
const { query } = splitHash(locationLike?.hash ?? "");
|
|
179
|
+
const workspaceId = query.get("workspaceId")?.trim() ||
|
|
180
|
+
new URLSearchParams(locationLike?.search ?? "").get("workspaceId")?.trim() ||
|
|
181
|
+
undefined;
|
|
182
|
+
return withWorkspaceId(href, workspaceId);
|
|
183
|
+
}
|
|
173
184
|
export function buildCanonicalHref(input) {
|
|
174
185
|
if (input.workspace === "chat")
|
|
175
186
|
return buildChatHref(input);
|
|
@@ -19,9 +19,10 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import { randomBytes } from "node:crypto";
|
|
21
21
|
import { existsSync } from "node:fs";
|
|
22
|
+
import { rm } from "node:fs/promises";
|
|
22
23
|
import path from "node:path";
|
|
23
24
|
import { LoopAgentClient } from "../loop-agent/loop-agent-client.js";
|
|
24
|
-
import { openConsoleAppData } from "
|
|
25
|
+
import { openConsoleAppData, sha256Json, writeSecureJson, } from "../../infrastructure/console/app-data.js";
|
|
25
26
|
import { DagConfirmationStore } from "./dag-confirmation.js";
|
|
26
27
|
import { DagExecutionReceiptStore } from "./dag-execution-receipt.js";
|
|
27
28
|
import { DraftStore } from "./draft-store.js";
|
|
@@ -31,13 +32,20 @@ import { ChatSessionStore } from "./chat/session-store.js";
|
|
|
31
32
|
import { createChatEventStore, createChatOperationLinker, } from "./chat/chat-event-store.js";
|
|
32
33
|
import { createChatTurnExecutionRegistry } from "./chat/turn-execution-registry.js";
|
|
33
34
|
import { ConsolePiRuntime } from "./chat/pi-runtime.js";
|
|
35
|
+
import { AimaxAuthReader, SddDataAlignmentService } from "./chat/sdd-data-alignment.js";
|
|
34
36
|
import { UserQuestionRegistry } from "./chat/user-questions.js";
|
|
35
37
|
import { TodoListRegistry } from "./chat/todos.js";
|
|
36
38
|
import { GoalRegistry } from "./chat/goals.js";
|
|
37
39
|
import { GoalRoundDriver } from "./chat/goal-round-driver.js";
|
|
38
40
|
import { driveGoalRound, recoverDeferredTurns } from "./chat/routes.js";
|
|
39
41
|
import { createOperationEventStore, } from "./operation-sse.js";
|
|
40
|
-
import { OperationStore } from "
|
|
42
|
+
import { OperationStore } from "../../infrastructure/console/operation-store.js";
|
|
43
|
+
import { createFrontendSplitOperationAdapter, } from "./frontend-split-operation-adapter.js";
|
|
44
|
+
import { createFrontendHumanDecisionAdapter } from "./frontend-human-decision-adapter.js";
|
|
45
|
+
import { FrontendSplitTaskMaterializer, } from "../materialize/frontend-split-task-materializer.js";
|
|
46
|
+
import { reconcileContextExports } from "../../infrastructure/console/context-export-store.js";
|
|
47
|
+
import { reconcileArtifactRevisions } from "../../infrastructure/console/artifact-revision-store.js";
|
|
48
|
+
import { recordContextTransferEvent } from "./context-transfer-diagnostics.js";
|
|
41
49
|
import { probePiReadiness, } from "./pi-readiness.js";
|
|
42
50
|
import { resolveSiblingLoopAgentBin } from "./sibling-controller.js";
|
|
43
51
|
import { NightAuxTicker } from "./night-aux-ticker.js";
|
|
@@ -73,6 +81,106 @@ export async function createWorkspaceContext(record, deps) {
|
|
|
73
81
|
const events = createOperationEventStore({
|
|
74
82
|
persistenceDir: path.join(appData.operations, "events"),
|
|
75
83
|
});
|
|
84
|
+
// Frontend split runtime is repo-scoped: materialization, durable schedule
|
|
85
|
+
// intents, and aggregate closeout must use this workspace's app-data and
|
|
86
|
+
// OperationStore rather than the process startup workspace.
|
|
87
|
+
const splitScheduleDir = path.join(appData.root, "frontend-split-schedule");
|
|
88
|
+
const splitAuditDir = path.join(appData.root, "frontend-split-audit");
|
|
89
|
+
const splitAggregateDir = path.join(appData.root, "frontend-split-aggregate");
|
|
90
|
+
const splitMaterializationBackend = {
|
|
91
|
+
async ensureTask({ taskId }) {
|
|
92
|
+
return { taskId, complete: true };
|
|
93
|
+
},
|
|
94
|
+
async ensureOperation({ taskId, operationId, payloadDigest, request }) {
|
|
95
|
+
const action = request.kind === "child"
|
|
96
|
+
? "frontendSplitChild"
|
|
97
|
+
: "frontendSplitIntegration";
|
|
98
|
+
const { operation } = await operations.ensureSplitMaterializedOperation({
|
|
99
|
+
operationId,
|
|
100
|
+
taskId,
|
|
101
|
+
action,
|
|
102
|
+
actionParams: request,
|
|
103
|
+
payloadHash: payloadDigest,
|
|
104
|
+
});
|
|
105
|
+
return {
|
|
106
|
+
taskId: operation.taskId ?? taskId,
|
|
107
|
+
operationId: operation.operationId,
|
|
108
|
+
complete: true,
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const materializer = new FrontendSplitTaskMaterializer(splitMaterializationBackend);
|
|
113
|
+
const schedule = async (input) => {
|
|
114
|
+
const fact = {
|
|
115
|
+
schemaVersion: 1,
|
|
116
|
+
kind: "frontend-split-schedule-intent",
|
|
117
|
+
operationId: input.operationId,
|
|
118
|
+
generation: input.generation,
|
|
119
|
+
bindingDigest: input.bindingDigest,
|
|
120
|
+
recordedAt: new Date().toISOString(),
|
|
121
|
+
};
|
|
122
|
+
const name = `${sha256Json({
|
|
123
|
+
operationId: input.operationId,
|
|
124
|
+
generation: input.generation,
|
|
125
|
+
bindingDigest: input.bindingDigest,
|
|
126
|
+
})}.json`;
|
|
127
|
+
await writeSecureJson(path.join(splitScheduleDir, name), fact);
|
|
128
|
+
};
|
|
129
|
+
const auditStale = async (input) => {
|
|
130
|
+
const fact = {
|
|
131
|
+
schemaVersion: 1,
|
|
132
|
+
kind: "frontend-split-stale-audit",
|
|
133
|
+
operationId: input.operationId,
|
|
134
|
+
reason: input.reason,
|
|
135
|
+
fact: input.fact,
|
|
136
|
+
recordedAt: new Date().toISOString(),
|
|
137
|
+
};
|
|
138
|
+
await writeSecureJson(path.join(splitAuditDir, `${sha256Json(fact)}.json`), fact);
|
|
139
|
+
};
|
|
140
|
+
const prepareAggregate = async ({ operationId, aggregate, }) => {
|
|
141
|
+
const before = await operations.get(operationId);
|
|
142
|
+
if (!before) {
|
|
143
|
+
throw new Error(`cannot prepare aggregate: parent operation not found: ${operationId}`);
|
|
144
|
+
}
|
|
145
|
+
const aggregateFile = path.join(splitAggregateDir, `${aggregate.digest}.json`);
|
|
146
|
+
let parentRecordPath = "";
|
|
147
|
+
let wroteAggregate = false;
|
|
148
|
+
let wroteParent = false;
|
|
149
|
+
return {
|
|
150
|
+
committedRef: {
|
|
151
|
+
ref: aggregateFile,
|
|
152
|
+
digest: aggregate.digest,
|
|
153
|
+
commitState: "committed",
|
|
154
|
+
},
|
|
155
|
+
async commit(input) {
|
|
156
|
+
parentRecordPath = input.parentRecordPath;
|
|
157
|
+
await writeSecureJson(aggregateFile, {
|
|
158
|
+
schemaVersion: 1,
|
|
159
|
+
kind: "frontend-split-aggregate-closeout",
|
|
160
|
+
operationId,
|
|
161
|
+
aggregate,
|
|
162
|
+
});
|
|
163
|
+
wroteAggregate = true;
|
|
164
|
+
await writeSecureJson(input.parentRecordPath, input.parentRecord);
|
|
165
|
+
wroteParent = true;
|
|
166
|
+
},
|
|
167
|
+
async rollback() {
|
|
168
|
+
if (wroteAggregate)
|
|
169
|
+
await rm(aggregateFile, { force: true });
|
|
170
|
+
if (wroteParent && parentRecordPath) {
|
|
171
|
+
await writeSecureJson(parentRecordPath, before);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
const splitOrchestrator = createFrontendSplitOperationAdapter({
|
|
177
|
+
store: operations,
|
|
178
|
+
materializer,
|
|
179
|
+
schedule,
|
|
180
|
+
auditStale,
|
|
181
|
+
prepareAggregate,
|
|
182
|
+
});
|
|
183
|
+
const humanDecisionAdapter = createFrontendHumanDecisionAdapter(operations);
|
|
76
184
|
const drafts = new DraftStore(appData);
|
|
77
185
|
const confirmations = new DagConfirmationStore(appData, deps.bootToken.confirmationToken);
|
|
78
186
|
const dagExecutionReceipts = new DagExecutionReceiptStore(appData);
|
|
@@ -80,6 +188,29 @@ export async function createWorkspaceContext(record, deps) {
|
|
|
80
188
|
const assessments = new AssessmentStore(appData);
|
|
81
189
|
if (!deps.skipReconcile) {
|
|
82
190
|
await operations.reconcileOnBoot();
|
|
191
|
+
const [expiredExports, expiredRevisions] = await Promise.all([
|
|
192
|
+
reconcileContextExports({ appData }),
|
|
193
|
+
reconcileArtifactRevisions({ appData }),
|
|
194
|
+
]);
|
|
195
|
+
// Boot-time lifecycle evidence for what reconcile reclaimed. Only
|
|
196
|
+
// 32-hex ids are real export/revision identities; uploads/ and lock/
|
|
197
|
+
// entries are blob housekeeping and get no event.
|
|
198
|
+
await Promise.all([
|
|
199
|
+
...expiredExports.removed
|
|
200
|
+
.filter((exportId) => /^[a-f0-9]{32}$/.test(exportId))
|
|
201
|
+
.map((exportId) => recordContextTransferEvent({
|
|
202
|
+
appData,
|
|
203
|
+
event: "context_export.expired",
|
|
204
|
+
fields: { exportId },
|
|
205
|
+
}).catch(() => undefined)),
|
|
206
|
+
...expiredRevisions
|
|
207
|
+
.filter((revisionId) => /^[a-f0-9]{32}$/.test(revisionId))
|
|
208
|
+
.map((revisionId) => recordContextTransferEvent({
|
|
209
|
+
appData,
|
|
210
|
+
event: "artifact_revision.expired",
|
|
211
|
+
fields: { revisionId },
|
|
212
|
+
}).catch(() => undefined)),
|
|
213
|
+
]);
|
|
83
214
|
}
|
|
84
215
|
const getReadiness = () => readinessCache;
|
|
85
216
|
const refreshReadiness = async () => {
|
|
@@ -97,6 +228,9 @@ export async function createWorkspaceContext(record, deps) {
|
|
|
97
228
|
client,
|
|
98
229
|
operations,
|
|
99
230
|
events,
|
|
231
|
+
splitOrchestrator,
|
|
232
|
+
humanDecisionAdapter,
|
|
233
|
+
materializer,
|
|
100
234
|
drafts,
|
|
101
235
|
confirmations,
|
|
102
236
|
dagExecutionReceipts,
|
|
@@ -120,6 +254,7 @@ export async function createWorkspaceContext(record, deps) {
|
|
|
120
254
|
}
|
|
121
255
|
},
|
|
122
256
|
});
|
|
257
|
+
const sddDataAlignment = new SddDataAlignmentService(chatStore, new AimaxAuthReader(), deps.fetchImpl);
|
|
123
258
|
const chatEventEpoch = randomBytes(12).toString("hex");
|
|
124
259
|
const chatEvents = createChatEventStore({
|
|
125
260
|
appData,
|
|
@@ -158,6 +293,7 @@ export async function createWorkspaceContext(record, deps) {
|
|
|
158
293
|
questionRegistry,
|
|
159
294
|
todoRegistry,
|
|
160
295
|
goalRegistry,
|
|
296
|
+
sddDataAlignment,
|
|
161
297
|
});
|
|
162
298
|
let chatRouteDeps;
|
|
163
299
|
const goalRoundDriver = new GoalRoundDriver((sessionId) => driveGoalRound(chatRouteDeps, sessionId));
|
|
@@ -169,6 +305,7 @@ export async function createWorkspaceContext(record, deps) {
|
|
|
169
305
|
questionRegistry,
|
|
170
306
|
todoRegistry,
|
|
171
307
|
goalRegistry,
|
|
308
|
+
sddDataAlignment,
|
|
172
309
|
goalRoundDriver,
|
|
173
310
|
operationLinker: chatOperationLinker,
|
|
174
311
|
appData,
|
|
@@ -192,6 +329,9 @@ export async function createWorkspaceContext(record, deps) {
|
|
|
192
329
|
client,
|
|
193
330
|
operations,
|
|
194
331
|
events,
|
|
332
|
+
splitOrchestrator,
|
|
333
|
+
humanDecisionAdapter,
|
|
334
|
+
materializer,
|
|
195
335
|
drafts,
|
|
196
336
|
confirmations,
|
|
197
337
|
dagExecutionReceipts,
|
|
@@ -19,8 +19,8 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
19
19
|
import { realpathSync, statSync, unwatchFile, watchFile } from "node:fs";
|
|
20
20
|
import { mkdir, open, readFile, rm, stat } from "node:fs/promises";
|
|
21
21
|
import path from "node:path";
|
|
22
|
-
import { readJsonIfExists, writeSecureJson, } from "
|
|
23
|
-
import { normalizeWorktreeRealpath, repoFingerprintV1, } from "
|
|
22
|
+
import { readJsonIfExists, writeSecureJson, } from "../../infrastructure/console/app-data.js";
|
|
23
|
+
import { normalizeWorktreeRealpath, repoFingerprintV1, } from "../../infrastructure/console/repo-fingerprint.js";
|
|
24
24
|
export const WORKSPACE_REGISTRY_SCHEMA_VERSION = 3;
|
|
25
25
|
/** Stable workspaceId: sha256("loop-console-workspace-v1\0" + normalizedRealpath). */
|
|
26
26
|
export function workspaceIdForRealpath(normalizedRealpath) {
|