@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.
Files changed (302) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +397 -5
  3. package/dist/adapters/context-transfer/optional-pi-handoff.js +31 -0
  4. package/dist/adapters/context-transfer/pi-session.js +61 -0
  5. package/dist/application/dag/generate-task-dag.js +75 -19
  6. package/dist/application/dag/run-dag.js +41 -0
  7. package/dist/application/task-lifecycle/advance.js +24 -5
  8. package/dist/application/task-lifecycle/observe.js +171 -17
  9. package/dist/application/task-lifecycle/plan-transitions.js +42 -7
  10. package/dist/application/task-lifecycle/recommendations.js +13 -2
  11. package/dist/build-stamp.json +3 -3
  12. package/dist/cli/command-definitions.js +19 -0
  13. package/dist/cli/program.js +29 -2
  14. package/dist/commands/client-recovery.js +3 -0
  15. package/dist/commands/dag-artifact.js +284 -0
  16. package/dist/commands/dag-context.js +184 -0
  17. package/dist/commands/dag-follow-up.js +138 -0
  18. package/dist/commands/dag-rerun-task.js +2 -0
  19. package/dist/commands/dag-rerun.js +206 -1
  20. package/dist/commands/init.js +27 -1
  21. package/dist/commands/task-advance.js +19 -0
  22. package/dist/executors/dag-pi-executor.js +4013 -86
  23. package/dist/executors/pi-executor.js +15 -4
  24. package/dist/executors/pi-read-budget-policy.js +239 -0
  25. package/dist/executors/pi-sdk-executor.js +3 -0
  26. package/dist/executors/shell-executor.js +978 -188
  27. package/dist/executors/shell-write-guard.js +7 -0
  28. package/dist/{worker → infrastructure}/console/app-data.js +4 -0
  29. package/dist/infrastructure/console/artifact-revision-store.js +430 -0
  30. package/dist/infrastructure/console/context-export-store.js +160 -0
  31. package/dist/infrastructure/console/dir-lock.js +132 -0
  32. package/dist/infrastructure/console/operation-store.js +417 -0
  33. package/dist/infrastructure/harness/artifact-store.js +10 -1
  34. package/dist/infrastructure/harness/atomic-write.js +12 -2
  35. package/dist/shared/context-transfer/artifact-revision.js +172 -0
  36. package/dist/shared/context-transfer.js +418 -0
  37. package/dist/shared/dag-failure-category.js +12 -0
  38. package/dist/shared/openspec-spec.js +70 -4
  39. package/dist/shared/operator/capabilities.js +21 -0
  40. package/dist/shared/operator/safe-run-summary.js +1 -0
  41. package/dist/shared/path-safety.js +93 -0
  42. package/dist/shared/preview.js +28 -4
  43. package/dist/task/config-types.js +107 -6
  44. package/dist/task/contract/adopt.js +4 -0
  45. package/dist/task/contract/import-revision.js +4 -0
  46. package/dist/task/contract/project.js +3 -0
  47. package/dist/task/contract/schema.js +2 -1
  48. package/dist/task/frontend-project-capability.js +203 -20
  49. package/dist/task/runtime.js +5 -2
  50. package/dist/task/source-prepare/build-draft.js +3 -3
  51. package/dist/task/source-prepare/fragment-inventory.js +64 -25
  52. package/dist/task/source-prepare/prepare.js +126 -21
  53. package/dist/task/source-prepare/semantic-intake.js +6 -2
  54. package/dist/task/source-references.js +22 -1
  55. package/dist/task/task-demand-routing.js +3 -0
  56. package/dist/worker/console/chat/chat-event-store.js +2 -2
  57. package/dist/worker/console/chat/model-resolver.js +7 -4
  58. package/dist/worker/console/chat/pi-runtime.js +86 -5
  59. package/dist/worker/console/chat/resource-preferences-store.js +1 -1
  60. package/dist/worker/console/chat/routes.js +136 -53
  61. package/dist/worker/console/chat/sdd-data-alignment.js +222 -0
  62. package/dist/worker/console/chat/session-catalog.js +2 -0
  63. package/dist/worker/console/chat/session-store.js +43 -1
  64. package/dist/worker/console/chat/shortcuts.js +18 -2
  65. package/dist/worker/console/chat/user-questions.js +1 -1
  66. package/dist/worker/console/console-update-runtime.js +1 -1
  67. package/dist/worker/console/context-transfer-diagnostics.js +198 -0
  68. package/dist/worker/console/dag-confirmation.js +1 -1
  69. package/dist/worker/console/dag-execution-receipt.js +1 -1
  70. package/dist/worker/console/doctor.js +1 -1
  71. package/dist/worker/console/draft-store.js +1 -1
  72. package/dist/worker/console/frontend-human-decision-adapter.js +19 -0
  73. package/dist/worker/console/frontend-split-operation-adapter.js +20 -0
  74. package/dist/worker/console/human-gate-token.js +1 -1
  75. package/dist/worker/console/index.js +6 -3
  76. package/dist/worker/console/interview/assessment.js +1 -1
  77. package/dist/worker/console/interview/session.js +1 -1
  78. package/dist/worker/console/operation-runner.js +45 -4
  79. package/dist/worker/console/operation-sse.js +1 -1
  80. package/dist/worker/console/operation-wait.js +1 -1
  81. package/dist/worker/console/operator-actions.js +273 -10
  82. package/dist/worker/console/operator-surface-health.js +1 -1
  83. package/dist/worker/console/operator-user-error.js +169 -0
  84. package/dist/worker/console/pi-plugins.js +57 -0
  85. package/dist/worker/console/pi-readiness.js +3 -2
  86. package/dist/worker/console/routes.js +637 -8
  87. package/dist/worker/console/security.js +35 -0
  88. package/dist/worker/console/server.js +29 -4
  89. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-D7oU983t.js → abnfDiagram-N423BO3Z-CcS17TBr.js} +1 -1
  90. package/dist/worker/console/static/assets/{arc-BrKSRdFS.js → arc-COptKq2S.js} +1 -1
  91. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CiXV7L56.js → architectureDiagram-T3A2C74G-h4LKMHjP.js} +1 -1
  92. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-D_Hs_gIG.js → blockDiagram-VBNYF7ZC-COA1MOH0.js} +1 -1
  93. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DbM-Lqqh.js → c4Diagram-5PPSVZJV-DJUf0QPm.js} +1 -1
  94. package/dist/worker/console/static/assets/channel-DdBCaOJ6.js +1 -0
  95. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-D1M8uqJw.js → chunk-2GRJ4B5K-mtWfKrUX.js} +1 -1
  96. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-4D3RFHT6.js → chunk-2Q5K7J3B-B8pXsxDQ.js} +1 -1
  97. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-CdwpY_n9.js → chunk-5RXB4S5H-ipKzByl1.js} +1 -1
  98. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BLeLZ9PG.js → chunk-5VM5RSS4-DYi3Ald_.js} +1 -1
  99. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-CeRNEMvc.js → chunk-6Q2QTUOP-DQtGYoty.js} +1 -1
  100. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CjkHP8Vy.js → chunk-GF5L2VYU-BU0qS2YV.js} +1 -1
  101. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-B54ZUQY-.js → chunk-JWPE2WC7-DVH9dIGE.js} +1 -1
  102. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-4bKaMVmx.js → chunk-KBJHAD2P-Dt60SmgM.js} +1 -1
  103. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-Cyjfznu_.js → chunk-RYQCIY6F-BoaUGuEY.js} +1 -1
  104. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CDN-zGFV.js → chunk-XXDRQBXY-_WHFDTp2.js} +1 -1
  105. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DZFra1GO.js +1 -0
  106. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DZFra1GO.js +1 -0
  107. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-HxJmz411.js → cose-bilkent-JH36ORCC-BxkbTIRd.js} +1 -1
  108. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-DtSt5K2w.js → cynefin-VYW2F7L2-Bf2UVnoG.js} +1 -1
  109. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-VtkSpRmG.js → cynefinDiagram-MW4NZA55-Bo23q1J_.js} +1 -1
  110. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-Bj4DT4du.js → dagre-VZM6K2ZE-Dd_UU49i.js} +1 -1
  111. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-Bpuk6BmP.js → diagram-7IWD3JNH-ebUa1a9y.js} +1 -1
  112. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BHYGv_yO.js → diagram-B4RE2ZJO-BucthU8r.js} +1 -1
  113. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DEx3WwnT.js → diagram-LBJQPF4R-BgqNpAkm.js} +1 -1
  114. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Cj0dS5e8.js → diagram-Q27KOJAE-DC4q5NGa.js} +1 -1
  115. package/dist/worker/console/static/assets/{diagram-UB23O5K3-B97h8l21.js → diagram-UB23O5K3-CBqCaMeb.js} +1 -1
  116. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-DMSFAhBd.js → ebnfDiagram-BXEA7PRR-CGtnbQ3-.js} +1 -1
  117. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DhVOCbt6.js → erDiagram-JOGREHBK-CG3LUao5.js} +1 -1
  118. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-GlakITWL.js → flowDiagram-UKHOOZJN-D2ZVgoFS.js} +1 -1
  119. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-VxPpu9eQ.js → ganttDiagram-PKOTCBZU-DoYFZiKt.js} +1 -1
  120. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bs_e5DRT.js → gitGraphDiagram-DS77QQ5N-CKoP1s6j.js} +1 -1
  121. package/dist/worker/console/static/assets/index-CAZ2fC_X.css +1 -0
  122. package/dist/worker/console/static/assets/index-vbTcFnFs.js +449 -0
  123. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BXYuU4Uw.js → infoDiagram-6WML65LV-Duofv8p2.js} +1 -1
  124. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-C34erCbU.js → ishikawaDiagram-WSZJBQD7-D2nlCkA1.js} +1 -1
  125. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DZCAiOU3.js → journeyDiagram-NVQOT4AX-Dd4IHdus.js} +1 -1
  126. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-C9gaTdUm.js → kanban-definition-27J2QSJJ-Bi20AOdt.js} +1 -1
  127. package/dist/worker/console/static/assets/{linear-CvI0Z17U.js → linear-D59YJ9kB.js} +1 -1
  128. package/dist/worker/console/static/assets/{mermaid.core-DMMSIx7j.js → mermaid.core-Bl13LpNa.js} +5 -5
  129. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BKKP0EO6.js → mindmap-definition-FAOFIHXS-C6DLP5eY.js} +1 -1
  130. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-C3LiFbl5.js → pegDiagram-VL7TDLO6-BjO4cy64.js} +1 -1
  131. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-Bb3Om2Dz.js → pieDiagram-7S7Q4E2Y-D7i2qZTG.js} +1 -1
  132. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-DNthMjzc.js → quadrantDiagram-CIZ2JOQS-Dx8o_h0y.js} +1 -1
  133. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-miFsr4Tv.js → railroadDiagram-AXF67PYL-B55orI_t.js} +1 -1
  134. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-yXUncmn6.js → requirementDiagram-LRYGKXZP-zWaehp6f.js} +1 -1
  135. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-DLeWKLak.js → sankeyDiagram-W5VNT64P-CcA-pjvD.js} +1 -1
  136. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CI3he1R3.js → sequenceDiagram-SI44F4Z6-BOFbzNHI.js} +1 -1
  137. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-B7jfDkS5.js → sizeCapture-X5ZJPWSS-BjAejah1.js} +1 -1
  138. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BmrZod7J.js → stateDiagram-OKZ733FA-DXYwxJwZ.js} +1 -1
  139. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Clg3V9t1.js +1 -0
  140. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CDOlHVSY.js → swimlanes-SLNWSIFB-OYiOch8n.js} +2 -2
  141. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DX1dxAAW.js +8 -0
  142. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-Cz-XX1gy.js → timeline-definition-Z64GVDOM-cZfH3nmU.js} +1 -1
  143. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-caV4cI8C.js → vennDiagram-T6HMQDX7-BDE7b3E1.js} +1 -1
  144. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-dImPlnIO.js → wardleyDiagram-T6FBY63Y-kyyGy9WJ.js} +1 -1
  145. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CtRYVJcn.js → xychartDiagram-ELKLHX3M-CJj6VTog.js} +1 -1
  146. package/dist/worker/console/static/index.html +7 -2
  147. package/dist/worker/console/static-src/active-run-badge.js +17 -0
  148. package/dist/worker/console/static-src/app/useOperatorActions.js +3 -2
  149. package/dist/worker/console/static-src/app/useRecoveryConsole.js +5 -5
  150. package/dist/worker/console/static-src/operator-chat/input-history.js +8 -6
  151. package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +10 -0
  152. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +258 -23
  153. package/dist/worker/console/static-src/operator-chat/useChatThread.js +112 -4
  154. package/dist/worker/console/static-src/operator-chat/useComposer.js +13 -4
  155. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +29 -6
  156. package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +8 -2
  157. package/dist/worker/console/static-src/shell/console-update-reload.js +52 -0
  158. package/dist/worker/console/static-src/shell/workspace-route.js +11 -0
  159. package/dist/worker/console/workspace-context.js +142 -2
  160. package/dist/worker/console/workspace-registry.js +2 -2
  161. package/dist/worker/continuation/worker-continuation.js +278 -0
  162. package/dist/worker/materialize/frontend-split-task-materializer.js +72 -0
  163. package/dist/worker/observe/health.js +1 -1
  164. package/dist/worker/observe/node-transparency.js +572 -0
  165. package/dist/worker/observe/routes.js +55 -1
  166. package/dist/worker/observe/static/api.js +69 -5
  167. package/dist/worker/observe/static/dag-context-reason-labels.d.ts +9 -0
  168. package/dist/worker/observe/static/dag-context-reason-labels.js +120 -0
  169. package/dist/worker/observe/static/dag-helpers.js +4 -2
  170. package/dist/worker/observe/static/dag-node-purpose.js +5 -0
  171. package/dist/worker/observe/static/inspect-workspace.js +23 -0
  172. package/dist/worker/observe/static/kpi.js +2 -2
  173. package/dist/worker/observe/static/operator-chrome.d.ts +10 -2
  174. package/dist/worker/observe/static/operator-chrome.js +37 -23
  175. package/dist/worker/observe/static/relations.js +2 -2
  176. package/dist/worker/observe/static/router.d.ts +12 -1
  177. package/dist/worker/observe/static/router.js +48 -6
  178. package/dist/worker/observe/static/run-processing.js +4 -2
  179. package/dist/worker/observe/static/shell-chrome.js +2 -2
  180. package/dist/worker/observe/static/state.js +8 -1
  181. package/dist/worker/observe/static/styles.css +1092 -86
  182. package/dist/worker/observe/static/views/dag-inspector.js +1228 -64
  183. package/dist/worker/observe/static/views/dag.js +10 -2
  184. package/dist/worker/observe/static/views/dags.js +3 -1
  185. package/dist/worker/observe/static/views/dashboard.js +14 -6
  186. package/dist/worker/observe/static/views/pool.js +7 -2
  187. package/dist/worker/observe/static/views/run.js +12 -3
  188. package/dist/worker/observe/static/views/session-timeline.js +142 -18
  189. package/dist/worker/observe/static/views/task.js +7 -2
  190. package/dist/worker/outcomes/adapters.js +19 -0
  191. package/dist/worker/outcomes/types.js +1 -0
  192. package/dist/worker/pool/attempt-lease.js +97 -66
  193. package/dist/worker/pool/begin-attempt-with-lease.js +1 -0
  194. package/dist/worker/pool/reconcile.js +46 -1
  195. package/dist/worker/pool/run-store.js +2 -0
  196. package/dist/worker/pool/state-projection.js +2 -0
  197. package/dist/worker/task-spec/workflow-routing.js +8 -3
  198. package/dist/workflows/dag/artifact-bindings.js +149 -0
  199. package/dist/workflows/dag/artifact-revision-schema-registry.js +31 -0
  200. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +215 -28
  201. package/dist/workflows/dag/backend-test-markdown-workflow.js +13 -1
  202. package/dist/workflows/dag/backend-test-plan-protocol.js +106 -0
  203. package/dist/workflows/dag/backend-test-scenario-param.js +172 -25
  204. package/dist/workflows/dag/backend-test-scenario-partitions.js +62 -1
  205. package/dist/workflows/dag/backend-test-writer-completeness.js +104 -12
  206. package/dist/workflows/dag/budget-enforcement.js +10 -0
  207. package/dist/workflows/dag/context-receipt.js +305 -0
  208. package/dist/workflows/dag/context-transfer/context-bundle.js +423 -0
  209. package/dist/workflows/dag/context-transfer/operator-actions.js +61 -0
  210. package/dist/workflows/dag/context-transfer/renderers.js +93 -0
  211. package/dist/workflows/dag/contract-validator-registrations.js +1 -2
  212. package/dist/workflows/dag/dag-retry-schema.js +138 -0
  213. package/dist/workflows/dag/frontend-closeout.js +221 -0
  214. package/dist/workflows/dag/frontend-design-policy.js +400 -0
  215. package/dist/workflows/dag/frontend-human-decision.js +182 -0
  216. package/dist/workflows/dag/frontend-implementation-contract.js +1237 -192
  217. package/dist/workflows/dag/frontend-plan-render.js +2 -1
  218. package/dist/workflows/dag/frontend-prewrite-gate.js +256 -350
  219. package/dist/workflows/dag/frontend-provider-capability-matrix.js +159 -0
  220. package/dist/workflows/dag/frontend-recovery-capsule.js +455 -0
  221. package/dist/workflows/dag/frontend-recovery-controller.js +226 -0
  222. package/dist/workflows/dag/frontend-recovery-lineage.js +178 -0
  223. package/dist/workflows/dag/frontend-recovery-plan.js +21 -10
  224. package/dist/workflows/dag/frontend-recovery-run.js +166 -34
  225. package/dist/workflows/dag/frontend-repair.js +1 -432
  226. package/dist/workflows/dag/frontend-review-context.js +261 -15
  227. package/dist/workflows/dag/frontend-review-findings.js +270 -0
  228. package/dist/workflows/dag/frontend-shadow-dual-write.js +941 -0
  229. package/dist/workflows/dag/frontend-shape-capsule-store.js +191 -0
  230. package/dist/workflows/dag/frontend-shape-facts.js +419 -0
  231. package/dist/workflows/dag/frontend-shape.js +435 -0
  232. package/dist/workflows/dag/frontend-source-fidelity-ledger.js +108 -0
  233. package/dist/workflows/dag/frontend-split-application-service.js +203 -0
  234. package/dist/workflows/dag/frontend-split-orchestrator.js +899 -0
  235. package/dist/workflows/dag/frontend-typed-event-store.js +452 -0
  236. package/dist/workflows/dag/frontend-typed-event-transaction.js +180 -0
  237. package/dist/workflows/dag/frontend-verification-trace.js +252 -25
  238. package/dist/workflows/dag/frontend-worktree-diff.js +250 -17
  239. package/dist/workflows/dag/frontend-writer-admission.js +319 -0
  240. package/dist/workflows/dag/frontend-writer-rollback.js +32 -0
  241. package/dist/workflows/dag/frontend-writer-status.js +256 -0
  242. package/dist/workflows/dag/init-hybrid.js +1174 -562
  243. package/dist/workflows/dag/interrupt-request.js +7 -0
  244. package/dist/workflows/dag/node-execution.js +940 -31
  245. package/dist/workflows/dag/path-safety.js +1 -0
  246. package/dist/workflows/dag/prompt.js +99 -7
  247. package/dist/workflows/dag/recovery-lease.js +170 -0
  248. package/dist/workflows/dag/report.js +37 -1
  249. package/dist/workflows/dag/rerun-feedback.js +315 -1
  250. package/dist/workflows/dag/rerun-plan.js +568 -3
  251. package/dist/workflows/dag/rerun-run.js +642 -18
  252. package/dist/workflows/dag/rerun-task.js +251 -13
  253. package/dist/workflows/dag/retry-policy.js +219 -104
  254. package/dist/workflows/dag/runner.js +596 -121
  255. package/dist/workflows/dag/scheduler.js +133 -20
  256. package/dist/workflows/dag/skill-snapshot.js +17 -0
  257. package/dist/workflows/dag/types.js +426 -22
  258. package/dist/workflows/dag/validate.js +28 -12
  259. package/docs/architecture/runtime-boundaries.md +6 -6
  260. package/docs/architecture/worker-and-feature.md +1 -1
  261. package/docs/examples/README.md +5 -0
  262. package/docs/init-surface.manifest.json +30 -12
  263. package/docs/skills/vetted-skill-registry.md +4 -2
  264. package/docs/templates/README.md +2 -0
  265. package/docs/templates/agent-dag-report.schema.json +8 -2
  266. package/docs/templates/agent-dag.schema.json +33 -1
  267. package/docs/templates/backend-test-dag.json +23 -20
  268. package/docs/templates/frontend-implementation-contract.schema.json +4 -1
  269. package/docs/templates/frontend-implementation-dag.json +89 -0
  270. package/docs/templates/product-line/task.yaml +1 -1
  271. package/docs/templates/spec-registry.schema.json +45 -0
  272. package/harness.json +1 -1
  273. package/package.json +6 -3
  274. package/skills/frontend-bounded-implement/SKILL.md +15 -14
  275. package/skills/frontend-bounded-implement/references/code-standards.md +19 -0
  276. package/skills/frontend-contract/SKILL.md +23 -0
  277. package/skills/frontend-contract/references/contract-protocol.md +34 -0
  278. package/skills/frontend-design-review/SKILL.md +22 -41
  279. package/skills/frontend-plan/SKILL.md +26 -0
  280. package/skills/frontend-plan/references/decision-contract.md +37 -0
  281. package/skills/frontend-plan/references/design-decisions.md +17 -0
  282. package/skills/frontend-review/SKILL.md +20 -15
  283. package/skills/frontend-review/references/review-findings.md +6 -7
  284. package/skills/frontend-scout/SKILL.md +25 -0
  285. package/skills/frontend-scout/references/design-evidence.md +16 -0
  286. package/skills/frontend-scout/references/scout-evidence.md +23 -0
  287. package/skills/frontend-verification/SKILL.md +1 -1
  288. package/skills/loop-agent/references/command-reference.md +7 -0
  289. package/skills/loop-agent/references/hybrid-dag.md +2 -2
  290. package/dist/worker/console/operation-store.js +0 -169
  291. package/dist/worker/console/static/assets/channel-D1xajGpe.js +0 -1
  292. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BmuGTfRr.js +0 -1
  293. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BmuGTfRr.js +0 -1
  294. package/dist/worker/console/static/assets/index-BLzcAykx.js +0 -451
  295. package/dist/worker/console/static/assets/index-Cs9JUSPs.css +0 -1
  296. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-D9ykKEWP.js +0 -1
  297. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BvPOXALT.js +0 -8
  298. package/skills/frontend-implementation/SKILL.md +0 -52
  299. package/skills/frontend-implementation/references/code-standards.md +0 -33
  300. package/skills/frontend-implementation/references/design-spec.md +0 -56
  301. package/skills/frontend-implementation/references/node-contracts.md +0 -31
  302. /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({ origin, sessionId, refs });
262
- }, [origin, sessionId, refs]);
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(body
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: { ...parseRuntimeSnapshotError(body), status: res.status },
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 "./app-data.js";
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 "./operation-store.js";
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 "./app-data.js";
23
- import { normalizeWorktreeRealpath, repoFingerprintV1, } from "./repo-fingerprint.js";
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) {