@tea-agent/loop-agent 0.41.1-beta.0 → 0.42.0-next.2

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 (277) hide show
  1. package/CHANGELOG.md +78 -206
  2. package/dist/adapters/context-transfer/optional-pi-handoff.js +31 -0
  3. package/dist/adapters/context-transfer/pi-session.js +61 -0
  4. package/dist/application/dag/generate-task-dag.js +19 -75
  5. package/dist/application/task-lifecycle/advance.js +5 -24
  6. package/dist/application/task-lifecycle/observe.js +17 -171
  7. package/dist/application/task-lifecycle/plan-transitions.js +7 -42
  8. package/dist/application/task-lifecycle/recommendations.js +2 -13
  9. package/dist/build-stamp.json +3 -3
  10. package/dist/cli/command-definitions.js +12 -7
  11. package/dist/cli/program.js +23 -6
  12. package/dist/commands/client-recovery.js +0 -3
  13. package/dist/commands/dag-artifact.js +284 -0
  14. package/dist/commands/dag-context.js +184 -0
  15. package/dist/commands/dag-rerun.js +206 -1
  16. package/dist/commands/init.js +1 -27
  17. package/dist/commands/task-advance.js +0 -19
  18. package/dist/executors/dag-pi-executor.js +266 -3792
  19. package/dist/executors/pi-executor.js +4 -15
  20. package/dist/executors/pi-sdk-executor.js +3 -0
  21. package/dist/executors/shell-executor.js +217 -945
  22. package/dist/executors/shell-write-guard.js +0 -7
  23. package/dist/{worker → infrastructure}/console/app-data.js +4 -0
  24. package/dist/infrastructure/console/artifact-revision-store.js +430 -0
  25. package/dist/infrastructure/console/context-export-store.js +160 -0
  26. package/dist/infrastructure/console/dir-lock.js +132 -0
  27. package/dist/infrastructure/console/operation-store.js +197 -0
  28. package/dist/infrastructure/harness/artifact-store.js +10 -1
  29. package/dist/infrastructure/harness/atomic-write.js +12 -2
  30. package/dist/shared/context-transfer/artifact-revision.js +172 -0
  31. package/dist/shared/context-transfer.js +418 -0
  32. package/dist/shared/dag-failure-category.js +0 -12
  33. package/dist/shared/openspec-spec.js +4 -70
  34. package/dist/shared/operator/capabilities.js +14 -7
  35. package/dist/shared/operator/safe-run-summary.js +1 -0
  36. package/dist/shared/path-safety.js +93 -0
  37. package/dist/shared/preview.js +28 -4
  38. package/dist/task/config-types.js +80 -35
  39. package/dist/task/contract/adopt.js +0 -4
  40. package/dist/task/contract/import-revision.js +0 -4
  41. package/dist/task/contract/project.js +0 -3
  42. package/dist/task/contract/schema.js +1 -2
  43. package/dist/task/frontend-project-capability.js +20 -203
  44. package/dist/task/runtime.js +2 -5
  45. package/dist/task/source-prepare/build-draft.js +3 -3
  46. package/dist/task/source-prepare/fragment-inventory.js +9 -15
  47. package/dist/task/source-prepare/prepare.js +1 -89
  48. package/dist/task/source-prepare/semantic-intake.js +2 -6
  49. package/dist/task/source-references.js +1 -22
  50. package/dist/task/task-demand-routing.js +3 -0
  51. package/dist/worker/console/chat/chat-event-store.js +2 -2
  52. package/dist/worker/console/chat/pi-runtime.js +3 -2
  53. package/dist/worker/console/chat/resource-preferences-store.js +1 -1
  54. package/dist/worker/console/chat/routes.js +13 -4
  55. package/dist/worker/console/chat/semantic-activity.js +12 -11
  56. package/dist/worker/console/chat/session-stats.js +96 -0
  57. package/dist/worker/console/chat/session-store.js +1 -1
  58. package/dist/worker/console/chat/turn-process.js +28 -4
  59. package/dist/worker/console/chat/user-questions.js +1 -1
  60. package/dist/worker/console/console-update-runtime.js +1 -1
  61. package/dist/worker/console/context-transfer-diagnostics.js +198 -0
  62. package/dist/worker/console/dag-confirmation.js +1 -1
  63. package/dist/worker/console/dag-execution-receipt.js +1 -1
  64. package/dist/worker/console/doctor.js +1 -1
  65. package/dist/worker/console/draft-store.js +1 -1
  66. package/dist/worker/console/human-gate-token.js +1 -1
  67. package/dist/worker/console/index.js +3 -6
  68. package/dist/worker/console/interview/assessment.js +1 -1
  69. package/dist/worker/console/interview/session.js +1 -1
  70. package/dist/worker/console/operation-runner.js +45 -4
  71. package/dist/worker/console/operation-sse.js +1 -1
  72. package/dist/worker/console/operation-wait.js +1 -1
  73. package/dist/worker/console/operator-actions.js +107 -168
  74. package/dist/worker/console/operator-surface-health.js +1 -1
  75. package/dist/worker/console/operator-user-error.js +169 -0
  76. package/dist/worker/console/pi-plugins.js +60 -1
  77. package/dist/worker/console/routes.js +637 -8
  78. package/dist/worker/console/security.js +35 -0
  79. package/dist/worker/console/server.js +6 -6
  80. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-Bho4we4c.js → abnfDiagram-N423BO3Z-DZZ8m3PO.js} +1 -1
  81. package/dist/worker/console/static/assets/{arc-TBDkTeK0.js → arc-D6PvaVd-.js} +1 -1
  82. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-BF_fZrn2.js → architectureDiagram-T3A2C74G-B_OTOiI8.js} +1 -1
  83. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CCnPgUe2.js → blockDiagram-VBNYF7ZC-Bv6rqHBg.js} +1 -1
  84. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BCYZJLAT.js → c4Diagram-5PPSVZJV-B8eHr0oz.js} +1 -1
  85. package/dist/worker/console/static/assets/channel-BU5gOilw.js +1 -0
  86. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-D8K6adhU.js → chunk-2GRJ4B5K-DYwR0im2.js} +1 -1
  87. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DkT1Q78b.js → chunk-2Q5K7J3B-D2WPGqXt.js} +1 -1
  88. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DuhvpIr7.js → chunk-5RXB4S5H-CQISJ_I7.js} +1 -1
  89. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BnK6dC49.js → chunk-5VM5RSS4-C0o2Du1e.js} +1 -1
  90. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DPz__z7r.js → chunk-6Q2QTUOP-4f8kr-U7.js} +1 -1
  91. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-0kkppM2j.js → chunk-GF5L2VYU-D_OWvXzX.js} +1 -1
  92. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BB41iK5t.js → chunk-JWPE2WC7-CasdPz5X.js} +1 -1
  93. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CiVrxKHU.js → chunk-KBJHAD2P-Cj8lRrla.js} +1 -1
  94. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-C2h9Xje1.js → chunk-RYQCIY6F-CUvD1FSd.js} +1 -1
  95. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-3iOSHdbM.js → chunk-XXDRQBXY-CqLw_eqB.js} +1 -1
  96. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DIzKJGHr.js +1 -0
  97. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DIzKJGHr.js +1 -0
  98. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BN3A7tkk.js → cose-bilkent-JH36ORCC-ku-WqJPx.js} +1 -1
  99. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-CTuBy0Or.js → cynefin-VYW2F7L2-Bq_PYDhl.js} +1 -1
  100. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-wb6tUlMN.js → cynefinDiagram-MW4NZA55-BiGZV641.js} +1 -1
  101. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-GP1Ivx8B.js → dagre-VZM6K2ZE-C4JRlglF.js} +1 -1
  102. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-ejrcK6L0.js → diagram-7IWD3JNH-B0dNeWYG.js} +1 -1
  103. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-YFkCCvUU.js → diagram-B4RE2ZJO-Cj35YvYM.js} +1 -1
  104. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-B4rrvIaL.js → diagram-LBJQPF4R-uzQoJ2-8.js} +1 -1
  105. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-C-YIZcUf.js → diagram-Q27KOJAE-D1a-Buoz.js} +1 -1
  106. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BPF5wcL1.js → diagram-UB23O5K3-XjRrLRSs.js} +1 -1
  107. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-CU5SzXjO.js → ebnfDiagram-BXEA7PRR-Da_O24cW.js} +1 -1
  108. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-CpL414DE.js → erDiagram-JOGREHBK-BLJ8jrYU.js} +1 -1
  109. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-MrhLzNau.js → flowDiagram-UKHOOZJN-B9GrLjM0.js} +1 -1
  110. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Bg4qFuUo.js → ganttDiagram-PKOTCBZU-CeJ0TqiK.js} +1 -1
  111. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-ColxSXLR.js → gitGraphDiagram-DS77QQ5N-Bm2eNNFX.js} +1 -1
  112. package/dist/worker/console/static/assets/index-H9rFJiGL.css +1 -0
  113. package/dist/worker/console/static/assets/index-xwu9GxEc.js +451 -0
  114. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-Czvtm6gc.js → infoDiagram-6WML65LV-DB26i3d8.js} +1 -1
  115. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-B7Xp8HyJ.js → ishikawaDiagram-WSZJBQD7-BOGRyeZT.js} +1 -1
  116. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DWYZcvph.js → journeyDiagram-NVQOT4AX-CZRoBO_6.js} +1 -1
  117. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-KTLZRUjx.js → kanban-definition-27J2QSJJ-qlWhJyoB.js} +1 -1
  118. package/dist/worker/console/static/assets/{linear-_Exn7bfl.js → linear-CfUiDDB3.js} +1 -1
  119. package/dist/worker/console/static/assets/{mermaid.core-Cxg8kX8V.js → mermaid.core-BQe6fpqj.js} +5 -5
  120. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-oKrlo2Bt.js → mindmap-definition-FAOFIHXS-zFzWHw64.js} +1 -1
  121. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-XAeteiNd.js → pegDiagram-VL7TDLO6-DFGUqjZO.js} +1 -1
  122. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-BTf1K-lp.js → pieDiagram-7S7Q4E2Y-BB5i0l8Z.js} +1 -1
  123. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-C0IlY0Jf.js → quadrantDiagram-CIZ2JOQS-obbVZ_X5.js} +1 -1
  124. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BVbKtZhW.js → railroadDiagram-AXF67PYL-BwdaNzc1.js} +1 -1
  125. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-C5e4JFcr.js → requirementDiagram-LRYGKXZP-CkTJaugh.js} +1 -1
  126. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cz30hc29.js → sankeyDiagram-W5VNT64P-BwJ-hIgq.js} +1 -1
  127. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DS33n6d0.js → sequenceDiagram-SI44F4Z6-BzSgmm7w.js} +1 -1
  128. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-46w7v-9T.js → sizeCapture-X5ZJPWSS-Bn3oj5Q1.js} +1 -1
  129. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-pbcD5SsZ.js → stateDiagram-OKZ733FA-dxhGtL8K.js} +1 -1
  130. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Cld2qK9v.js +1 -0
  131. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DuivYBSj.js → swimlanes-SLNWSIFB-BLpEInya.js} +2 -2
  132. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-TIHpiT7w.js +8 -0
  133. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-Cb9VZVIl.js → timeline-definition-Z64GVDOM-ChJGYcXy.js} +1 -1
  134. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-D2-mfOgR.js → vennDiagram-T6HMQDX7-DK-qjRer.js} +1 -1
  135. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-DeS2aC76.js → wardleyDiagram-T6FBY63Y-3qeaWAg-.js} +1 -1
  136. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-WGsrFjxH.js → xychartDiagram-ELKLHX3M-CootlyP9.js} +1 -1
  137. package/dist/worker/console/static/index.html +7 -2
  138. package/dist/worker/console/static-src/app/useOperatorActions.js +3 -2
  139. package/dist/worker/console/static-src/app/useRunProgress.js +9 -2
  140. package/dist/worker/console/static-src/operator-chat/dag-progress-link.js +22 -0
  141. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +2 -0
  142. package/dist/worker/console/static-src/operator-chat/useChatThread.js +6 -0
  143. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +28 -3
  144. package/dist/worker/console/static-src/pages/tasks/run-panel-progress.js +106 -0
  145. package/dist/worker/console/static-src/shell/console-update-reload.js +25 -0
  146. package/dist/worker/console/workspace-context.js +28 -112
  147. package/dist/worker/console/workspace-registry.js +2 -2
  148. package/dist/worker/continuation/worker-continuation.js +278 -0
  149. package/dist/worker/observability/read-model.js +4 -0
  150. package/dist/worker/observe/health.js +1 -1
  151. package/dist/worker/observe/node-transparency.js +572 -0
  152. package/dist/worker/observe/routes.js +51 -1
  153. package/dist/worker/observe/static/api.js +69 -5
  154. package/dist/worker/observe/static/dag-context-reason-labels.d.ts +9 -0
  155. package/dist/worker/observe/static/dag-context-reason-labels.js +120 -0
  156. package/dist/worker/observe/static/dag-node-purpose.js +0 -5
  157. package/dist/worker/observe/static/state.js +3 -1
  158. package/dist/worker/observe/static/styles.css +1037 -126
  159. package/dist/worker/observe/static/views/dag-inspector.js +1217 -65
  160. package/dist/worker/observe/static/views/session-timeline.js +121 -25
  161. package/dist/worker/outcomes/adapters.js +19 -0
  162. package/dist/worker/outcomes/types.js +1 -0
  163. package/dist/worker/pool/attempt-lease.js +97 -66
  164. package/dist/worker/pool/begin-attempt-with-lease.js +1 -0
  165. package/dist/worker/pool/reconcile.js +46 -1
  166. package/dist/worker/pool/run-store.js +2 -0
  167. package/dist/worker/pool/state-projection.js +2 -0
  168. package/dist/worker/task-spec/workflow-routing.js +8 -3
  169. package/dist/workflows/dag/artifact-bindings.js +149 -0
  170. package/dist/workflows/dag/artifact-revision-schema-registry.js +31 -0
  171. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +99 -4
  172. package/dist/workflows/dag/backend-test-markdown-workflow.js +13 -1
  173. package/dist/workflows/dag/backend-test-result-contract.js +1 -1
  174. package/dist/workflows/dag/backend-test-writer-completeness.js +45 -3
  175. package/dist/workflows/dag/budget-enforcement.js +10 -0
  176. package/dist/workflows/dag/context-receipt.js +305 -0
  177. package/dist/workflows/dag/context-transfer/context-bundle.js +423 -0
  178. package/dist/workflows/dag/context-transfer/operator-actions.js +61 -0
  179. package/dist/workflows/dag/context-transfer/renderers.js +93 -0
  180. package/dist/workflows/dag/contract-validator-registrations.js +2 -1
  181. package/dist/workflows/dag/frontend-implementation-contract.js +162 -932
  182. package/dist/workflows/dag/frontend-plan-render.js +1 -2
  183. package/dist/workflows/dag/frontend-prewrite-gate.js +349 -255
  184. package/dist/workflows/dag/frontend-recovery-plan.js +10 -17
  185. package/dist/workflows/dag/frontend-recovery-run.js +20 -33
  186. package/dist/workflows/dag/frontend-repair.js +432 -1
  187. package/dist/workflows/dag/frontend-review-context.js +15 -261
  188. package/dist/workflows/dag/frontend-verification-trace.js +24 -249
  189. package/dist/workflows/dag/frontend-worktree-diff.js +17 -250
  190. package/dist/workflows/dag/frontend-writer-rollback.js +32 -0
  191. package/dist/workflows/dag/init-hybrid.js +740 -718
  192. package/dist/workflows/dag/interrupt-request.js +0 -7
  193. package/dist/workflows/dag/node-execution.js +136 -759
  194. package/dist/workflows/dag/path-safety.js +1 -0
  195. package/dist/workflows/dag/prompt.js +30 -38
  196. package/dist/workflows/dag/report.js +1 -37
  197. package/dist/workflows/dag/rerun-feedback.js +1 -256
  198. package/dist/workflows/dag/rerun-plan.js +557 -11
  199. package/dist/workflows/dag/rerun-run.js +601 -38
  200. package/dist/workflows/dag/rerun-task.js +0 -29
  201. package/dist/workflows/dag/retry-policy.js +109 -214
  202. package/dist/workflows/dag/runner.js +142 -430
  203. package/dist/workflows/dag/scheduler.js +16 -114
  204. package/dist/workflows/dag/skill-snapshot.js +17 -0
  205. package/dist/workflows/dag/types.js +195 -246
  206. package/dist/workflows/dag/validate.js +12 -28
  207. package/docs/architecture/runtime-boundaries.md +6 -6
  208. package/docs/architecture/worker-and-feature.md +1 -1
  209. package/docs/init-surface.manifest.json +12 -30
  210. package/docs/skills/vetted-skill-registry.md +2 -4
  211. package/docs/templates/README.md +0 -2
  212. package/docs/templates/agent-dag-report.schema.json +2 -8
  213. package/docs/templates/agent-dag.schema.json +33 -1
  214. package/docs/templates/backend-test-dag.json +18 -18
  215. package/docs/templates/frontend-implementation-contract.schema.json +1 -4
  216. package/docs/templates/product-line/task.yaml +1 -1
  217. package/harness.json +3 -3
  218. package/package.json +3 -1
  219. package/skills/frontend-bounded-implement/SKILL.md +14 -15
  220. package/skills/frontend-design-review/SKILL.md +41 -22
  221. package/skills/frontend-implementation/SKILL.md +52 -0
  222. package/skills/frontend-implementation/references/code-standards.md +33 -0
  223. package/skills/frontend-implementation/references/design-spec.md +56 -0
  224. package/skills/frontend-implementation/references/node-contracts.md +31 -0
  225. package/skills/frontend-review/SKILL.md +15 -20
  226. package/skills/frontend-review/references/review-findings.md +7 -6
  227. package/skills/frontend-verification/SKILL.md +1 -1
  228. package/skills/loop-agent/references/command-reference.md +6 -1
  229. package/skills/loop-agent/references/hybrid-dag.md +2 -2
  230. package/dist/commands/dag-follow-up.js +0 -138
  231. package/dist/executors/pi-read-budget-policy.js +0 -239
  232. package/dist/worker/console/frontend-human-decision-adapter.js +0 -19
  233. package/dist/worker/console/frontend-split-operation-adapter.js +0 -20
  234. package/dist/worker/console/operation-store.js +0 -389
  235. package/dist/worker/console/static/assets/channel-bnXW0U3C.js +0 -1
  236. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-rZpq_twR.js +0 -1
  237. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-rZpq_twR.js +0 -1
  238. package/dist/worker/console/static/assets/index-D3CC4eUz.css +0 -1
  239. package/dist/worker/console/static/assets/index-DLt4ZFvD.js +0 -437
  240. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-zBMYiUyi.js +0 -1
  241. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-d_rms-5i.js +0 -8
  242. package/dist/worker/console/static-src/active-run-badge.js +0 -17
  243. package/dist/worker/materialize/frontend-split-task-materializer.js +0 -72
  244. package/dist/workflows/dag/dag-retry-schema.js +0 -138
  245. package/dist/workflows/dag/frontend-closeout.js +0 -221
  246. package/dist/workflows/dag/frontend-design-policy.js +0 -400
  247. package/dist/workflows/dag/frontend-human-decision.js +0 -182
  248. package/dist/workflows/dag/frontend-provider-capability-matrix.js +0 -159
  249. package/dist/workflows/dag/frontend-read-budgets.js +0 -12
  250. package/dist/workflows/dag/frontend-recovery-capsule.js +0 -455
  251. package/dist/workflows/dag/frontend-recovery-controller.js +0 -202
  252. package/dist/workflows/dag/frontend-recovery-lineage.js +0 -178
  253. package/dist/workflows/dag/frontend-review-findings.js +0 -270
  254. package/dist/workflows/dag/frontend-shadow-dual-write.js +0 -914
  255. package/dist/workflows/dag/frontend-shape-capsule-store.js +0 -191
  256. package/dist/workflows/dag/frontend-shape-facts.js +0 -409
  257. package/dist/workflows/dag/frontend-shape.js +0 -427
  258. package/dist/workflows/dag/frontend-source-fidelity-ledger.js +0 -108
  259. package/dist/workflows/dag/frontend-split-application-service.js +0 -203
  260. package/dist/workflows/dag/frontend-split-orchestrator.js +0 -899
  261. package/dist/workflows/dag/frontend-typed-event-store.js +0 -452
  262. package/dist/workflows/dag/frontend-typed-event-transaction.js +0 -180
  263. package/dist/workflows/dag/frontend-writer-admission.js +0 -285
  264. package/dist/workflows/dag/frontend-writer-status.js +0 -256
  265. package/dist/workflows/dag/recovery-lease.js +0 -80
  266. package/docs/templates/frontend-implementation-dag.json +0 -89
  267. package/docs/templates/spec-registry.schema.json +0 -45
  268. package/skills/frontend-bounded-implement/references/code-standards.md +0 -19
  269. package/skills/frontend-contract/SKILL.md +0 -23
  270. package/skills/frontend-contract/references/contract-protocol.md +0 -34
  271. package/skills/frontend-plan/SKILL.md +0 -26
  272. package/skills/frontend-plan/references/decision-contract.md +0 -37
  273. package/skills/frontend-plan/references/design-decisions.md +0 -17
  274. package/skills/frontend-scout/SKILL.md +0 -25
  275. package/skills/frontend-scout/references/design-evidence.md +0 -16
  276. package/skills/frontend-scout/references/scout-evidence.md +0 -23
  277. /package/dist/{worker → infrastructure}/console/repo-fingerprint.js +0 -0
@@ -0,0 +1,198 @@
1
+ import path from "node:path";
2
+ import { appendFile, chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
+ import { randomBytes } from "node:crypto";
4
+ import { assertSafeAppDataPath, readJsonIfExists, writeSecureJson, } from "../../infrastructure/console/app-data.js";
5
+ const diagnosticWriteChains = new Map();
6
+ function serializeDiagnostic(filePath, operation) {
7
+ const previous = diagnosticWriteChains.get(filePath) ?? Promise.resolve();
8
+ const next = previous.then(operation, operation);
9
+ diagnosticWriteChains.set(filePath, next.then(() => undefined, () => undefined));
10
+ return next;
11
+ }
12
+ function diagnosticsPath(appData) {
13
+ const repoNamespace = path.dirname(appData.operations);
14
+ return assertSafeAppDataPath(repoNamespace, path.join(repoNamespace, "context-transfer-diagnostics.json"));
15
+ }
16
+ function safeNonNegative(value) {
17
+ return Number.isFinite(value) && (value ?? 0) >= 0 ? Math.round(value ?? 0) : 0;
18
+ }
19
+ function safeReasonCode(value) {
20
+ if (!value)
21
+ return undefined;
22
+ const normalized = value.trim().slice(0, 96);
23
+ return /^[A-Za-z0-9_.-]+$/.test(normalized) ? normalized : "UNCLASSIFIED";
24
+ }
25
+ export async function recordContextTransferDiagnostic(input) {
26
+ const filePath = diagnosticsPath(input.appData);
27
+ return serializeDiagnostic(filePath, async () => {
28
+ const current = (await readJsonIfExists(filePath)) ?? {
29
+ schemaVersion: 1,
30
+ updatedAt: (input.now ?? new Date()).toISOString(),
31
+ counters: [],
32
+ };
33
+ const dimensions = {
34
+ outcome: input.dimensions.outcome,
35
+ ...(input.dimensions.target ? { target: input.dimensions.target } : {}),
36
+ ...(input.dimensions.profile ? { profile: input.dimensions.profile } : {}),
37
+ ...(input.dimensions.diffKind ? { diffKind: input.dimensions.diffKind } : {}),
38
+ ...(safeReasonCode(input.dimensions.reasonCode)
39
+ ? { reasonCode: safeReasonCode(input.dimensions.reasonCode) }
40
+ : {}),
41
+ };
42
+ const key = JSON.stringify({ event: input.event, ...dimensions });
43
+ const existing = current.counters.find((counter) => JSON.stringify({ event: counter.event, ...dimensionsFromCounter(counter) }) === key);
44
+ if (existing) {
45
+ existing.count += 1;
46
+ existing.bytes += safeNonNegative(input.dimensions.bytes);
47
+ existing.durationMs += safeNonNegative(input.dimensions.durationMs);
48
+ existing.affectedNodeCount += safeNonNegative(input.dimensions.affectedNodeCount);
49
+ existing.importedNodeCount += safeNonNegative(input.dimensions.importedNodeCount);
50
+ }
51
+ else {
52
+ current.counters.push({
53
+ event: input.event,
54
+ ...dimensions,
55
+ count: 1,
56
+ bytes: safeNonNegative(input.dimensions.bytes),
57
+ durationMs: safeNonNegative(input.dimensions.durationMs),
58
+ affectedNodeCount: safeNonNegative(input.dimensions.affectedNodeCount),
59
+ importedNodeCount: safeNonNegative(input.dimensions.importedNodeCount),
60
+ });
61
+ }
62
+ current.updatedAt = (input.now ?? new Date()).toISOString();
63
+ await writeSecureJson(filePath, current);
64
+ return current;
65
+ });
66
+ }
67
+ function dimensionsFromCounter(counter) {
68
+ return {
69
+ outcome: counter.outcome,
70
+ ...(counter.target ? { target: counter.target } : {}),
71
+ ...(counter.profile ? { profile: counter.profile } : {}),
72
+ ...(counter.diffKind ? { diffKind: counter.diffKind } : {}),
73
+ ...(counter.reasonCode ? { reasonCode: counter.reasonCode } : {}),
74
+ };
75
+ }
76
+ export async function readContextTransferDiagnostics(appData) {
77
+ return readJsonIfExists(diagnosticsPath(appData));
78
+ }
79
+ /**
80
+ * Append-only lifecycle event log for context-transfer mutations
81
+ * (exec-plan observability: context_export.* / artifact_revision.* /
82
+ * artifact_rerun.*). Events carry ids, counts, bytes, duration and reason
83
+ * codes only — never prompt text, artifact content, secret finding values or
84
+ * host absolute paths. The Console emits only stages it truly observes;
85
+ * CLI-kernel-internal stages (capture, secret scan, adapters) stay in the
86
+ * kernel's own evidence.
87
+ */
88
+ export const CONTEXT_TRANSFER_EVENT_LOG_LIMIT = 512;
89
+ const CONTEXT_TRANSFER_EVENT_NAME_PATTERN = /^(?:context_export|artifact_revision|artifact_rerun)\.[a-z][a-z_]{0,47}$/;
90
+ const CONTEXT_TRANSFER_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
91
+ export async function recordContextTransferEvent(input) {
92
+ const at = (input.now ?? new Date()).toISOString();
93
+ if (!CONTEXT_TRANSFER_EVENT_NAME_PATTERN.test(input.event)) {
94
+ return { recorded: false, total: 0 };
95
+ }
96
+ const fields = input.fields ?? {};
97
+ const entry = {
98
+ schemaVersion: 1,
99
+ at,
100
+ event: input.event,
101
+ ...sanitizeLifecycleFields(fields),
102
+ };
103
+ const filePath = lifecycleEventsPath(input.appData);
104
+ return serializeDiagnostic(filePath, async () => {
105
+ await appendLifecycleEvent(filePath, entry);
106
+ const total = await countLifecycleEvents(filePath);
107
+ if (total > CONTEXT_TRANSFER_EVENT_LOG_LIMIT) {
108
+ await trimLifecycleEvents(filePath, CONTEXT_TRANSFER_EVENT_LOG_LIMIT);
109
+ return { recorded: true, total: CONTEXT_TRANSFER_EVENT_LOG_LIMIT };
110
+ }
111
+ return { recorded: true, total };
112
+ });
113
+ }
114
+ export async function readContextTransferEvents(appData) {
115
+ const filePath = lifecycleEventsPath(appData);
116
+ const raw = await readFile(filePath, "utf8").catch(() => "");
117
+ const events = [];
118
+ for (const line of raw.split("\n")) {
119
+ if (!line.trim())
120
+ continue;
121
+ try {
122
+ const parsed = JSON.parse(line);
123
+ if (parsed &&
124
+ typeof parsed === "object" &&
125
+ parsed.schemaVersion === 1 &&
126
+ typeof parsed.event === "string") {
127
+ events.push(parsed);
128
+ }
129
+ }
130
+ catch {
131
+ // A torn final line after a crash must not break readers.
132
+ }
133
+ }
134
+ return events;
135
+ }
136
+ function lifecycleEventsPath(appData) {
137
+ const repoNamespace = path.dirname(appData.operations);
138
+ return assertSafeAppDataPath(repoNamespace, path.join(repoNamespace, "context-transfer-events.jsonl"));
139
+ }
140
+ function safeLifecycleId(value) {
141
+ if (!value)
142
+ return undefined;
143
+ return CONTEXT_TRANSFER_ID_PATTERN.test(value) ? value : undefined;
144
+ }
145
+ function sanitizeLifecycleFields(fields) {
146
+ return {
147
+ ...(safeLifecycleId(fields.runId) ? { runId: fields.runId } : {}),
148
+ ...(safeLifecycleId(fields.nodeId) ? { nodeId: fields.nodeId } : {}),
149
+ ...(safeLifecycleId(fields.exportId) ? { exportId: fields.exportId } : {}),
150
+ ...(safeLifecycleId(fields.revisionId)
151
+ ? { revisionId: fields.revisionId }
152
+ : {}),
153
+ ...(safeLifecycleId(fields.operationId)
154
+ ? { operationId: fields.operationId }
155
+ : {}),
156
+ ...(fields.profile === "redacted" || fields.profile === "raw"
157
+ ? { profile: fields.profile }
158
+ : {}),
159
+ ...(fields.target === "generic" ||
160
+ fields.target === "pi-session" ||
161
+ fields.target === "pi-handoff" ||
162
+ fields.target === "readable"
163
+ ? { target: fields.target }
164
+ : {}),
165
+ ...(fields.bytes !== undefined
166
+ ? { bytes: safeNonNegative(fields.bytes) }
167
+ : {}),
168
+ ...(fields.durationMs !== undefined
169
+ ? { durationMs: safeNonNegative(fields.durationMs) }
170
+ : {}),
171
+ ...(safeReasonCode(fields.reasonCode)
172
+ ? { reasonCode: safeReasonCode(fields.reasonCode) }
173
+ : {}),
174
+ };
175
+ }
176
+ async function appendLifecycleEvent(filePath, entry) {
177
+ await mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 });
178
+ await appendFile(filePath, `${JSON.stringify(entry)}\n`, { mode: 0o600 });
179
+ await chmod(filePath, 0o600).catch(() => undefined);
180
+ }
181
+ async function countLifecycleEvents(filePath) {
182
+ const raw = await readFile(filePath, "utf8").catch(() => "");
183
+ let total = 0;
184
+ for (const line of raw.split("\n")) {
185
+ if (line.trim())
186
+ total += 1;
187
+ }
188
+ return total;
189
+ }
190
+ async function trimLifecycleEvents(filePath, limit) {
191
+ const raw = await readFile(filePath, "utf8").catch(() => "");
192
+ const lines = raw.split("\n").filter((line) => line.trim());
193
+ const kept = lines.slice(-limit);
194
+ const tmp = `${filePath}.${randomBytes(8).toString("hex")}.tmp`;
195
+ await writeFile(tmp, `${kept.join("\n")}\n`, { mode: 0o600, flag: "wx" });
196
+ await rename(tmp, filePath);
197
+ await chmod(filePath, 0o600).catch(() => undefined);
198
+ }
@@ -1,6 +1,6 @@
1
1
  import { createHash, randomBytes } from "node:crypto";
2
2
  import path from "node:path";
3
- import { readJsonIfExists, sha256Utf8, writeSecureJson, } from "./app-data.js";
3
+ import { readJsonIfExists, sha256Utf8, writeSecureJson, } from "../../infrastructure/console/app-data.js";
4
4
  import { confirmationPayloadHash, issueHumanGateToken, verifyHumanGateToken, } from "./human-gate-token.js";
5
5
  export const ALL_CONFIRMATION_CHALLENGES = [
6
6
  "source",
@@ -20,7 +20,7 @@ import { randomBytes } from "node:crypto";
20
20
  import { readFile } from "node:fs/promises";
21
21
  import path from "node:path";
22
22
  import { pathMatchesPattern } from "../../shared/git-progress.js";
23
- import { readJsonIfExists, sha256Utf8, writeSecureJson, } from "./app-data.js";
23
+ import { readJsonIfExists, sha256Utf8, writeSecureJson, } from "../../infrastructure/console/app-data.js";
24
24
  import { hashDagBytes, } from "./dag-confirmation.js";
25
25
  /**
26
26
  * Structured verification command patterns for the G2 autonomous-execution
@@ -6,7 +6,7 @@ import { LoopAgentClient } from "../loop-agent/loop-agent-client.js";
6
6
  import { preflightTargetRepo } from "../preflight.js";
7
7
  import { probePiReadiness, } from "./pi-readiness.js";
8
8
  import { DEFAULT_OBSERVE_BASE_URL, OBSERVE_START_COMMAND, probeAndClassifyObserve, } from "./observe-health-match.js";
9
- import { repoFingerprintV1 } from "./repo-fingerprint.js";
9
+ import { repoFingerprintV1 } from "../../infrastructure/console/repo-fingerprint.js";
10
10
  import { resolveSiblingLoopAgentBin } from "./sibling-controller.js";
11
11
  import { defaultObserveStaticDir, ROUTES } from "../observe/routes.js";
12
12
  import { deriveObserveRouteCapabilities } from "../observe/health.js";
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { readJsonIfExists, sha256Json, writeSecureJson, } from "./app-data.js";
2
+ import { readJsonIfExists, sha256Json, writeSecureJson, } from "../../infrastructure/console/app-data.js";
3
3
  /**
4
4
  * 从任意上游载荷安全投影 ledger 摘要(未知形状丢弃,绝不抛错、绝不信任字段外的数据)。
5
5
  * 供 DraftStore / prd-intake-bridge 把 prepare/advance 结果中的 ledger 摘要带入草稿。
@@ -85,7 +85,7 @@ export function verifyHumanGateToken(presented, expected, secret, now = new Date
85
85
  * invalidates the token (defense against drift-then-confirm).
86
86
  */
87
87
  import { createHash } from "node:crypto";
88
- import { sha256Utf8 } from "./app-data.js";
88
+ import { sha256Utf8 } from "../../infrastructure/console/app-data.js";
89
89
  export function confirmationPayloadHash(b) {
90
90
  const canonical = [
91
91
  `dag=${b.dagSha256}`,
@@ -3,17 +3,14 @@ export { buildOperatorSurfaceHealthV1 } from "./operator-surface-health.js";
3
3
  export { runConsoleDoctor, formatConsoleDoctorHuman } from "./doctor.js";
4
4
  export { isLoopbackHost } from "./loopback.js";
5
5
  export { shouldOpenConsoleBrowser, normalizeConsoleBrowserUrl, openSystemBrowser, maybeOpenConsoleBrowser, } from "./open-browser.js";
6
- export { repoFingerprintV1, normalizeWorktreeRealpath, } from "./repo-fingerprint.js";
6
+ export { repoFingerprintV1, normalizeWorktreeRealpath, } from "../../infrastructure/console/repo-fingerprint.js";
7
7
  export { buildObserveDeepLink } from "./observe-link.js";
8
8
  export { classifyObserveHealth, probeAndClassifyObserve, capabilityForObserveTarget, OBSERVE_START_COMMAND, DEFAULT_OBSERVE_BASE_URL, } from "./observe-health-match.js";
9
9
  export { allowedRecoveryCtas, classifyRecoveryFact, partitionRecoveryCtas, recoveryMatrixInvariants, } from "./recovery-cta.js";
10
10
  export { createClosedResourceLoader, createInterviewResourceLoader, tryActivateTool, assertOfficialToolAllowed, listOfficialTools, OFFICIAL_DENIED_TOOL_IDS, INTERVIEW_ALLOWED_TOOLS, INTERVIEW_DENIED_TOOLS, authorizeInterviewTool, } from "./resource-loader.js";
11
11
  export { resolveSiblingLoopAgentBin } from "./sibling-controller.js";
12
- export { openConsoleAppData, defaultConsoleAppDataRoot } from "./app-data.js";
13
- export { OperationStore } from "./operation-store.js";
14
- export { createFrontendSplitOperationAdapter } from "./frontend-split-operation-adapter.js";
15
- export { createFrontendHumanDecisionAdapter } from "./frontend-human-decision-adapter.js";
16
- export { FrontendSplitTaskMaterializer } from "../materialize/frontend-split-task-materializer.js";
12
+ export { openConsoleAppData, defaultConsoleAppDataRoot } from "../../infrastructure/console/app-data.js";
13
+ export { OperationStore } from "../../infrastructure/console/operation-store.js";
17
14
  export { createOperationEventStore } from "./operation-sse.js";
18
15
  export { DagConfirmationStore } from "./dag-confirmation.js";
19
16
  export { DraftStore } from "./draft-store.js";
@@ -1,6 +1,6 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import path from "node:path";
3
- import { readJsonIfExists, writeSecureJson, } from "../app-data.js";
3
+ import { readJsonIfExists, writeSecureJson, } from "../../../infrastructure/console/app-data.js";
4
4
  import { computeDraftSha256, } from "../draft-store.js";
5
5
  function assessmentPath(appData, assessmentId) {
6
6
  return path.join(appData.assessments, `${assessmentId}.json`);
@@ -1,6 +1,6 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import path from "node:path";
3
- import { readJsonIfExists, writeSecureJson, } from "../app-data.js";
3
+ import { readJsonIfExists, writeSecureJson, } from "../../../infrastructure/console/app-data.js";
4
4
  import { createInterviewResourceLoader, } from "./tools.js";
5
5
  function sessionPath(appData, sessionId) {
6
6
  return path.join(appData.interviews, `${sessionId}.json`);
@@ -1,6 +1,14 @@
1
- import { clipPreview, } from "./operation-store.js";
1
+ import { clipPreview, } from "../../infrastructure/console/operation-store.js";
2
2
  import { stateEvent } from "./operation-sse.js";
3
3
  import { extractTrustedRunFacts } from "./operation-run-facts.js";
4
+ /** Swallow-all invoker so observers can never break the state path. */
5
+ function notifySettled(deps, operation, state, info) {
6
+ if (!deps.onSettled)
7
+ return;
8
+ void Promise.resolve()
9
+ .then(() => deps.onSettled?.(operation, state, info))
10
+ .catch(() => undefined);
11
+ }
4
12
  /**
5
13
  * Execute a queued operation via LoopAgentClient (or inject).
6
14
  * Timeout without proven exit → needs-reconcile (never Cancel).
@@ -42,6 +50,7 @@ export async function runOperation(operationId, deps) {
42
50
  artifactName: `operation-${operationId}`,
43
51
  expectJson: true,
44
52
  timeoutMs: deps.defaultTimeoutMs,
53
+ env: deps.env,
45
54
  onSpawn: (info) => {
46
55
  // Chain onto the per-operation write lock; never fire-and-forget a
47
56
  // rejected update (unhandled rejection can crash Console on Windows).
@@ -119,6 +128,10 @@ export async function runOperation(operationId, deps) {
119
128
  message: finished.errorMessage,
120
129
  state: "needs-reconcile",
121
130
  });
131
+ notifySettled(deps, finished, "needs-reconcile", {
132
+ ok: false,
133
+ errorCode: finished.errorCode,
134
+ });
122
135
  }
123
136
  return finished;
124
137
  }
@@ -169,9 +182,10 @@ async function finalizeFromWorkerResult(operationId, result, deps) {
169
182
  // Supervisory timeout without classified CLI timeout → needs-reconcile
170
183
  // Only mark timed-out when we have a machine timeout result after exit.
171
184
  const state = result.exitCode !== null ? "timed-out" : "needs-reconcile";
172
- const updated = await deps.store.update(operationId, {
185
+ const finishedAt = new Date().toISOString();
186
+ const patch = {
173
187
  state,
174
- finishedAt: new Date().toISOString(),
188
+ finishedAt,
175
189
  artifactRefs,
176
190
  stdoutPreview: previewStdout,
177
191
  stderrPreview: previewStderr,
@@ -186,7 +200,15 @@ async function finalizeFromWorkerResult(operationId, result, deps) {
186
200
  ...(runFacts.runSummary ? { runSummary: runFacts.runSummary } : {}),
187
201
  }
188
202
  : {}),
203
+ };
204
+ const current = await deps.store.get(operationId);
205
+ if (!current)
206
+ throw new Error(`operation not found: ${operationId}`);
207
+ await deps.beforeTerminal?.({ ...current, ...patch }, state, {
208
+ ok: false,
209
+ errorCode: patch.errorCode,
189
210
  });
211
+ const updated = await deps.store.update(operationId, patch);
190
212
  stateEvent(deps.events, updated, state, updated.errorMessage);
191
213
  if (runFacts) {
192
214
  appendSafeResultEvent(deps, operationId, state, {
@@ -202,6 +224,10 @@ async function finalizeFromWorkerResult(operationId, result, deps) {
202
224
  data: { ok: false, exitCode: result.exitCode },
203
225
  });
204
226
  }
227
+ notifySettled(deps, updated, state, {
228
+ ok: false,
229
+ errorCode: updated.errorCode,
230
+ });
205
231
  return updated;
206
232
  }
207
233
  const envelope = coerceEnvelope(result);
@@ -210,7 +236,7 @@ async function finalizeFromWorkerResult(operationId, result, deps) {
210
236
  const processOk = envelope?.ok === true || (result.ok && result.exitCode === 0);
211
237
  const ok = processOk && !businessBlock;
212
238
  const state = ok ? "succeeded" : "failed";
213
- const updated = await deps.store.update(operationId, {
239
+ const patch = {
214
240
  state,
215
241
  finishedAt: new Date().toISOString(),
216
242
  artifactRefs,
@@ -238,9 +264,20 @@ async function finalizeFromWorkerResult(operationId, result, deps) {
238
264
  ...(runFacts.runSummary ? { runSummary: runFacts.runSummary } : {}),
239
265
  }
240
266
  : {}),
267
+ };
268
+ if (!operation)
269
+ throw new Error(`operation not found: ${operationId}`);
270
+ await deps.beforeTerminal?.({ ...operation, ...patch }, state, {
271
+ ok,
272
+ errorCode: patch.errorCode,
241
273
  });
274
+ const updated = await deps.store.update(operationId, patch);
242
275
  stateEvent(deps.events, updated, state, updated.errorMessage);
243
276
  appendSafeResultEvent(deps, operationId, state, { ok, exitCode: result.exitCode }, runFacts);
277
+ notifySettled(deps, updated, state, {
278
+ ok,
279
+ errorCode: updated.errorCode,
280
+ });
244
281
  if (ok && operation?.action === "dagRequestInterrupt") {
245
282
  await projectInterruptRequestOntoTarget(operation, result.json, deps);
246
283
  }
@@ -300,6 +337,10 @@ export function scheduleOperation(operationId, deps) {
300
337
  })
301
338
  .then((updated) => {
302
339
  stateEvent(deps.events, updated, "needs-reconcile", message);
340
+ notifySettled(deps, updated, "needs-reconcile", {
341
+ ok: false,
342
+ errorCode: updated.errorCode,
343
+ });
303
344
  })
304
345
  .catch(() => {
305
346
  // A failed canonical store update cannot be represented safely.
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readFileSync, rmSync } from "node:fs";
2
2
  import path from "node:path";
3
- import { ensureSecureDir, writeSecureJsonSync } from "./app-data.js";
3
+ import { ensureSecureDir, writeSecureJsonSync } from "../../infrastructure/console/app-data.js";
4
4
  const DEFAULT_MAX_EVENTS = 1000;
5
5
  function safeOperationId(operationId) {
6
6
  return operationId.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 180);
@@ -1,5 +1,5 @@
1
1
  import { projectOperationEventSummary, projectOperationForChat, } from "./chat/chat-event-store.js";
2
- import { isTerminalOperationState, } from "./operation-store.js";
2
+ import { isTerminalOperationState, } from "../../infrastructure/console/operation-store.js";
3
3
  /**
4
4
  * P2: read-only event-driven long poll on the canonical operation event ring
5
5
  * (2026-08-13 Operator Chat long-run supervision). Server contract bounds: