@tea-agent/loop-agent 0.43.0-next.17 → 0.43.0-next.19

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 (236) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +68 -2309
  3. package/README.md +7 -0
  4. package/dist/application/dag/args.js +8 -0
  5. package/dist/application/task-lifecycle/advance.js +38 -7
  6. package/dist/build-stamp.json +3 -3
  7. package/dist/cli/command-definitions.js +2 -0
  8. package/dist/cli/program.js +3 -1
  9. package/dist/cli/update/init-surface-notifier.js +2 -0
  10. package/dist/cli/update/policy.js +2 -0
  11. package/dist/commands/cursor-prompt.js +2 -0
  12. package/dist/commands/dag-approve.js +2 -0
  13. package/dist/commands/dag-final-verification.js +2 -0
  14. package/dist/commands/dag-init-hybrid.js +2 -0
  15. package/dist/commands/dag-reconcile-tasks.js +2 -0
  16. package/dist/commands/dag-reject.js +2 -0
  17. package/dist/commands/dag-report.js +2 -0
  18. package/dist/commands/dag-rerun.js +2 -0
  19. package/dist/commands/dag-resume.js +2 -0
  20. package/dist/commands/dag-workflow-compile.js +2 -0
  21. package/dist/commands/dag-workflow-plan.js +2 -0
  22. package/dist/commands/dag-workflow-validate.js +2 -0
  23. package/dist/commands/delegate.js +2 -0
  24. package/dist/commands/examples.js +2 -0
  25. package/dist/commands/import-prd.js +2 -0
  26. package/dist/commands/init-model-catalog.js +2 -0
  27. package/dist/commands/init.js +19 -13
  28. package/dist/commands/instructions.js +2 -0
  29. package/dist/commands/knowledge.js +2 -0
  30. package/dist/commands/loop-benchmark.js +2 -0
  31. package/dist/commands/pi-prompt.js +2 -0
  32. package/dist/commands/pi-reuse-benchmark.js +2 -0
  33. package/dist/commands/promote-run.js +2 -0
  34. package/dist/commands/stats.js +1 -1
  35. package/dist/commands/study-init.js +2 -0
  36. package/dist/commands/task-advance.js +34 -0
  37. package/dist/commands/task-source-prepare.js +2 -0
  38. package/dist/commands/worktree-create.js +2 -0
  39. package/dist/commands/worktree-remove.js +2 -0
  40. package/dist/executors/dag-pi-executor.js +1640 -194
  41. package/dist/executors/pi-executor.js +85 -3
  42. package/dist/executors/pi-sdk-executor.js +18 -0
  43. package/dist/executors/shell-executor.js +92 -7
  44. package/dist/executors/shell-verification.js +3 -0
  45. package/dist/governance/exec-plans.js +6 -3
  46. package/dist/infrastructure/console/app-data.js +6 -0
  47. package/dist/shared/artifacts-core.js +2 -0
  48. package/dist/shared/backend-dogfood-preflight.js +47 -0
  49. package/dist/shared/dag-failure-category.js +3 -0
  50. package/dist/shared/git-progress.js +2 -0
  51. package/dist/shared/one-shot-prompt-args.js +2 -0
  52. package/dist/shared/operator/capabilities.js +180 -0
  53. package/dist/shared/package-metadata.js +6 -4
  54. package/dist/shared/pi-context-pressure/sift-bridge.js +1 -1
  55. package/dist/shared/reference-context.js +2 -0
  56. package/dist/task/config-types.js +29 -0
  57. package/dist/task/contract/project.js +9 -0
  58. package/dist/task/contract/recover.js +6 -0
  59. package/dist/task/contract/schema.js +17 -0
  60. package/dist/task/source-prepare/artifact-meta.js +9 -2
  61. package/dist/task/source-prepare/build-draft.js +60 -0
  62. package/dist/task/source-prepare/fragment-inventory.js +4 -1
  63. package/dist/task/source-prepare/parse-intent.js +36 -11
  64. package/dist/task/task-demand-routing.js +5 -2
  65. package/dist/worker/console/chat/browser-automation.js +468 -308
  66. package/dist/worker/console/chat/browser-routes.js +175 -57
  67. package/dist/worker/console/chat/explore-tools.js +5 -2
  68. package/dist/worker/console/chat/pi-mode-loop-isolation.js +155 -0
  69. package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +115 -20
  70. package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +24 -16
  71. package/dist/worker/console/chat/pi-runtime/custom-tools/scheduled-goal-tools.js +22 -0
  72. package/dist/worker/console/chat/pi-runtime/progressive-tools.js +195 -0
  73. package/dist/worker/console/chat/pi-runtime.js +95 -28
  74. package/dist/worker/console/chat/routes.js +20 -1
  75. package/dist/worker/console/chat/scheduled-goal-booking.js +59 -0
  76. package/dist/worker/console/chat/scheduled-goal-delivery.js +27 -0
  77. package/dist/worker/console/chat/scheduled-goal-request.js +190 -0
  78. package/dist/worker/console/chat/sdd-data-alignment.js +1 -1
  79. package/dist/worker/console/chat/session-mode.js +8 -4
  80. package/dist/worker/console/chat/session-store.js +42 -9
  81. package/dist/worker/console/chat/tool-preview.js +115 -0
  82. package/dist/worker/console/chat/tools.js +7 -1
  83. package/dist/worker/console/chat/turn-order.js +13 -0
  84. package/dist/worker/console/chat/turn-process.js +32 -30
  85. package/dist/worker/console/operator-actions.js +50 -0
  86. package/dist/worker/console/prd-intake-bridge.js +54 -1
  87. package/dist/worker/console/scheduled-goal-host.js +98 -0
  88. package/dist/worker/console/scheduled-goal-operation-adapter.js +127 -0
  89. package/dist/worker/console/server.js +15 -0
  90. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C4NXyedy.js → abnfDiagram-N423BO3Z-8-j6y-sd.js} +1 -1
  91. package/dist/worker/console/static/assets/{arc-NZ3qXvBI.js → arc-eoQiMvuk.js} +1 -1
  92. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-COZSRvml.js → architectureDiagram-T3A2C74G-C4A3uMcI.js} +1 -1
  93. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Ck0Gxi9C.js → blockDiagram-VBNYF7ZC-D4zD2F-Q.js} +1 -1
  94. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BX5HQ4Ox.js → c4Diagram-5PPSVZJV-j1RkJziL.js} +1 -1
  95. package/dist/worker/console/static/assets/channel-ChE7y-cx.js +1 -0
  96. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CoviemSL.js → chunk-2GRJ4B5K-YBHmhik1.js} +1 -1
  97. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DbOdOkbZ.js → chunk-2Q5K7J3B-COfWyo9P.js} +1 -1
  98. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BsG2pmdQ.js → chunk-5RXB4S5H-I99OUkHY.js} +1 -1
  99. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DGdvrNm8.js → chunk-5VM5RSS4-XKxoJNJ4.js} +1 -1
  100. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BAy7Yd6y.js → chunk-6Q2QTUOP-DLT_cYx1.js} +1 -1
  101. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D9UA7hUb.js → chunk-GF5L2VYU-CxcKZ9mV.js} +1 -1
  102. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-DPz7SZ8V.js → chunk-JWPE2WC7-V1EqXdjY.js} +1 -1
  103. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BmuEOIh7.js → chunk-KBJHAD2P-DebTtdFp.js} +1 -1
  104. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CIhBWnd8.js → chunk-RYQCIY6F-B-ivNRDf.js} +1 -1
  105. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CScR6mDD.js → chunk-XXDRQBXY-DC_Ds11b.js} +1 -1
  106. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C01TCf2X.js +1 -0
  107. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C01TCf2X.js +1 -0
  108. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BjpfWaUr.js → cose-bilkent-JH36ORCC-sWEqKwIb.js} +1 -1
  109. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BFQohJgT.js → cynefin-VYW2F7L2-BXa_dcu4.js} +1 -1
  110. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-D3gzRJnS.js → cynefinDiagram-MW4NZA55-C-Mle84F.js} +1 -1
  111. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-5eojkhoA.js → dagre-VZM6K2ZE-CXPDBITe.js} +1 -1
  112. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CpD8LWu_.js → diagram-7IWD3JNH-CC-WJQfa.js} +1 -1
  113. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B8_4qJ2a.js → diagram-B4RE2ZJO-CDAV5Vs4.js} +1 -1
  114. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-HOsXf0eu.js → diagram-LBJQPF4R-CmFiAcNz.js} +1 -1
  115. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BqwRwiWP.js → diagram-Q27KOJAE-DPBZHuyn.js} +1 -1
  116. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BRVCNZe1.js → diagram-UB23O5K3-jUlm_Ds3.js} +1 -1
  117. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Cvb1TgGh.js → ebnfDiagram-BXEA7PRR-DWhQ3mfY.js} +1 -1
  118. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DS0O0qG9.js → erDiagram-JOGREHBK-Tr2gMqet.js} +1 -1
  119. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BHIRvRr3.js → flowDiagram-UKHOOZJN-DJjVQHPA.js} +1 -1
  120. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DcCJ1JWx.js → ganttDiagram-PKOTCBZU-D74dQ4u0.js} +1 -1
  121. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-B9ia5ony.js → gitGraphDiagram-DS77QQ5N-DwW0tZ0X.js} +1 -1
  122. package/dist/worker/console/static/assets/index-BWkIfcrK.css +1 -0
  123. package/dist/worker/console/static/assets/{index-wXlQohNs.js → index-Cdkvw_H6.js} +97 -97
  124. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-3ogpgegn.js → infoDiagram-6WML65LV-ILCbxJyb.js} +1 -1
  125. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-4tgpQ5SL.js → ishikawaDiagram-WSZJBQD7-DeuWBQ89.js} +1 -1
  126. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DNfgHqFx.js → journeyDiagram-NVQOT4AX-CF5ih8Fk.js} +1 -1
  127. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Dz7ngC8z.js → kanban-definition-27J2QSJJ-C7yOSuRO.js} +1 -1
  128. package/dist/worker/console/static/assets/{linear-DI7Jv62E.js → linear-BDZ9riWi.js} +1 -1
  129. package/dist/worker/console/static/assets/{mermaid.core-CQA4Nzmo.js → mermaid.core-7pKqYtpZ.js} +5 -5
  130. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CtsMc8Mf.js → mindmap-definition-FAOFIHXS-LeJDybSU.js} +1 -1
  131. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-ByppE9yH.js → pegDiagram-VL7TDLO6-BJvT3pMD.js} +1 -1
  132. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-B5PtgFgt.js → pieDiagram-7S7Q4E2Y-_rGqpMan.js} +1 -1
  133. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Cq4p0k2K.js → quadrantDiagram-CIZ2JOQS-DPcSv5aA.js} +1 -1
  134. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-DjfkyljN.js → railroadDiagram-AXF67PYL-Drxx4hkJ.js} +1 -1
  135. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DzynNRSl.js → requirementDiagram-LRYGKXZP-BCTUdU4z.js} +1 -1
  136. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cj7TCpTJ.js → sankeyDiagram-W5VNT64P-B6wzbZmB.js} +1 -1
  137. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-C73C6ykA.js → sequenceDiagram-SI44F4Z6-BGt8d3QQ.js} +1 -1
  138. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-BiNLgN2x.js → sizeCapture-X5ZJPWSS-7nlhJKo7.js} +1 -1
  139. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-UwvjS64-.js → stateDiagram-OKZ733FA-Cv2stqMA.js} +1 -1
  140. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DC7V5vcq.js +1 -0
  141. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CC7DH98r.js → swimlanes-SLNWSIFB-qDAo4Yc1.js} +2 -2
  142. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bwy4QUTO.js +8 -0
  143. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-LSBXTR70.js → timeline-definition-Z64GVDOM-CKbDNKTr.js} +1 -1
  144. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BAuxWwGP.js → vennDiagram-T6HMQDX7-DI-9EHic.js} +1 -1
  145. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y--E5_gjZx.js → wardleyDiagram-T6FBY63Y-BrzzRDpX.js} +1 -1
  146. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-dJWNmyzF.js → xychartDiagram-ELKLHX3M-BclH5hGh.js} +1 -1
  147. package/dist/worker/console/static/index.html +2 -2
  148. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +41 -11
  149. package/dist/worker/console/static-src/operator-chat/compaction-message.js +3 -17
  150. package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +15 -5
  151. package/dist/worker/console/static-src/operator-chat/timeline-merge.js +29 -0
  152. package/dist/worker/console/static-src/operator-chat/useChatThread.js +2 -5
  153. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +2 -0
  154. package/dist/worker/console/static-src/prd-file-import.js +3 -1
  155. package/dist/worker/console/workspace-context.js +17 -1
  156. package/dist/worker/delivery/git-transaction.js +2 -0
  157. package/dist/worker/feature/fullstack-validate.js +2 -0
  158. package/dist/worker/loop-agent/loop-agent-client.js +8 -2
  159. package/dist/worker/materialize/harness-task-materializer.js +4 -1
  160. package/dist/worker/metrics/projector.js +1 -1
  161. package/dist/worker/observability/event-store.js +4 -1
  162. package/dist/worker/observability/read-model.js +4 -1
  163. package/dist/worker/observe/node-transparency.js +23 -1
  164. package/dist/worker/observe/routes.js +4 -0
  165. package/dist/worker/observe/static/operator-chrome.js +3 -1
  166. package/dist/worker/outcomes/declared-artifacts.js +2 -0
  167. package/dist/worker/preflight.js +3 -0
  168. package/dist/worker/scheduler/scheduled-goal-dispatch.js +117 -0
  169. package/dist/worker/scheduler/scheduled-goal-evidence.js +167 -0
  170. package/dist/worker/scheduler/scheduled-goal-recovery.js +62 -0
  171. package/dist/worker/scheduler/scheduled-goal-store.js +699 -0
  172. package/dist/worker/scheduler/scheduled-goal-supervisor.js +132 -0
  173. package/dist/worker/scheduler/scheduled-goal-time.js +102 -0
  174. package/dist/worker/scheduler/scheduled-goal-types.js +95 -0
  175. package/dist/worker/task-spec/validate.js +4 -1
  176. package/dist/workflows/dag/backend-test-markdown-workflow.js +6 -24
  177. package/dist/workflows/dag/backend-test-plan-protocol.js +82 -5
  178. package/dist/workflows/dag/dag-retry-schema.js +11 -0
  179. package/dist/workflows/dag/decision-envelope.js +2 -0
  180. package/dist/workflows/dag/dynamic-runtime/shared.js +2 -2
  181. package/dist/workflows/dag/frontend-closeout.js +4 -2
  182. package/dist/workflows/dag/frontend-committed-facts.js +461 -0
  183. package/dist/workflows/dag/frontend-durable-tools.js +15 -3
  184. package/dist/workflows/dag/frontend-implementation-contract.js +365 -8
  185. package/dist/workflows/dag/frontend-plan-canary.js +53 -0
  186. package/dist/workflows/dag/frontend-plan-decision-contract.js +803 -0
  187. package/dist/workflows/dag/frontend-plan-render.js +0 -2
  188. package/dist/workflows/dag/frontend-prewrite-gate.js +3 -3
  189. package/dist/workflows/dag/frontend-provider-capability-matrix.js +8 -61
  190. package/dist/workflows/dag/frontend-recovery-run.js +57 -0
  191. package/dist/workflows/dag/frontend-review-context.js +43 -70
  192. package/dist/workflows/dag/frontend-risk.js +92 -10
  193. package/dist/workflows/dag/frontend-session-budget.js +117 -3
  194. package/dist/workflows/dag/frontend-shape.js +11 -55
  195. package/dist/workflows/dag/frontend-test-execution-evidence.js +35 -10
  196. package/dist/workflows/dag/frontend-typed-event-store.js +32 -25
  197. package/dist/workflows/dag/frontend-verification-trace.js +25 -12
  198. package/dist/workflows/dag/frontend-writer-admission.js +3 -47
  199. package/dist/workflows/dag/frontend-writer-status.js +0 -23
  200. package/dist/workflows/dag/init-hybrid.js +202 -111
  201. package/dist/workflows/dag/interrupt-request.js +2 -0
  202. package/dist/workflows/dag/lifecycle.js +11 -2
  203. package/dist/workflows/dag/node-execution.js +50 -13
  204. package/dist/workflows/dag/reconcile-run.js +2 -0
  205. package/dist/workflows/dag/repair-artifact.js +3 -1
  206. package/dist/workflows/dag/report.js +2 -0
  207. package/dist/workflows/dag/rerun-plan.js +10 -0
  208. package/dist/workflows/dag/rerun-task.js +79 -1
  209. package/dist/workflows/dag/retry-policy.js +18 -0
  210. package/dist/workflows/dag/scheduler.js +2 -4
  211. package/dist/workflows/dag/types.js +44 -6
  212. package/dist/workflows/dag/validate.js +4 -0
  213. package/docs/README.md +1 -0
  214. package/docs/governance/README.md +1 -0
  215. package/docs/init-surface.manifest.json +1 -0
  216. package/docs/operations/README.md +2 -0
  217. package/docs/templates/README.md +1 -1
  218. package/docs/templates/agent-dag.schema.json +2 -2
  219. package/docs/templates/backend-test-dag.json +14 -10
  220. package/docs/templates/frontend-implementation-contract.schema.json +0 -7
  221. package/docs/templates/frontend-implementation-dag.json +8 -9
  222. package/package.json +8 -3
  223. package/skills/frontend-bounded-implement/SKILL.md +3 -4
  224. package/skills/frontend-design-review/SKILL.md +7 -12
  225. package/skills/frontend-design-review/references/review-checklist.md +7 -7
  226. package/skills/frontend-plan/SKILL.md +8 -18
  227. package/skills/frontend-plan/references/decision-contract.md +19 -26
  228. package/skills/frontend-review/SKILL.md +21 -25
  229. package/skills/frontend-review/references/review-findings.md +48 -24
  230. package/dist/worker/console/static/assets/channel-BxdTlb_5.js +0 -1
  231. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-_ByA1Nf8.js +0 -1
  232. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-_ByA1Nf8.js +0 -1
  233. package/dist/worker/console/static/assets/index-B9goN3S5.css +0 -1
  234. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-nLgMZ0D3.js +0 -1
  235. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BcYqTady.js +0 -8
  236. package/dist/workflows/dag/frontend-shadow-dual-write.js +0 -975
package/README.md CHANGED
@@ -126,6 +126,13 @@ agent-worker console doctor --repo .
126
126
 
127
127
  ```
128
128
 
129
+ Console Chat 支持直接用自然语言预约工作流,例如:“请预约3分钟后检查当前项目的Git状态,汇总修改文件,不修改业务文件,结果发回当前对话。”服务在当前项目目录准备任务,生成真实预约卡;核对时间、范围和验收后点击“确认预约”,后台执行并把结果关联回原对话。相对延时从准备完成起算,以卡片显示的准确时间为准。预约要求当前目录与已提交 HEAD 一致,确认后若基线或文件变化则停止启动;执行产生的改动留在当前目录,无需另行合并。测试类报告交付可以包含业务失败,不等同于全部用例通过。取消停止后续启动,已执行事实与报告保留。
130
+
131
+ 预约任务的完整列表与验收详情位于 **Console → 观测 → 定时任务**;Chat保留简洁确认卡和「查看执行」入口。
132
+
133
+ 预约由 Console 进程持有,关闭浏览器不停止后台工作;退出 Console、系统休眠或断电不能保证准点执行。需要夜间运行时,由当前用户的 OS 服务管理器保持 Console 可用,使用固定版本和明确的工作目录/环境,避免运行期间升级。恢复后按冻结的最晚启动、授权到期和错过时间策略处理;未知运行不会自动重发。目标项目 `init` 不安装服务,也不复制凭据。
134
+
135
+
129
136
  裸 `agent-worker console` 不在终端询问升级。操作 → 设置提供非阻塞的「更新并初始化」入口,默认选择 npm `latest` 稳定版,也可由操作者显式选择 `next` 预发布版;更新前会先检查活跃运行和全局安装来源。`console doctor`、帮助和版本命令均不触发更新检查。
130
137
 
131
138
  访问 Console <http://127.0.0.1:8790/>;**Operator Chat Official** 是 Console 内的主引导交互,默认打开「对话」工作区。构建时设置 `VITE_OPERATOR_CHAT_DEFAULT_LANDING=tasks` 可改回 Tasks;URL hash(`#/tasks`)与 localStorage 仍优先于默认值。顶部「检视」以及 `/inspect/` 提供只读 Dashboard、DAG、时间线与 artifacts;`loop-agent …` / `agent-worker …` CLI direct path 仍是受治理 fallback。当前状态为 **code ready, dogfood pending/unmet**,不宣称已替代 openCode 或其他外部主会话。
@@ -34,6 +34,8 @@ export function parseDagRunTaskArgs(args, defaultCwd) {
34
34
  let profileExplicit = false;
35
35
  for (let i = 0; i < args.length; i += 1) {
36
36
  const arg = args[i];
37
+ if (arg === undefined)
38
+ break;
37
39
  if (arg === "--output" || arg === "-o") {
38
40
  outputPath = args[++i];
39
41
  if (!outputPath) {
@@ -165,6 +167,8 @@ export function parseDagValidateArgs(args) {
165
167
  let spineTaskId;
166
168
  for (let i = 0; i < args.length; i += 1) {
167
169
  const arg = args[i];
170
+ if (arg === undefined)
171
+ break;
168
172
  if (arg === "--dag") {
169
173
  dagPath = args[++i];
170
174
  if (!dagPath) {
@@ -264,6 +268,8 @@ export function parseRunDagArgs(args, defaultCwd) {
264
268
  let workerAssociation;
265
269
  for (let i = 0; i < args.length; i += 1) {
266
270
  const arg = args[i];
271
+ if (arg === undefined)
272
+ break;
267
273
  if (arg === "--dag") {
268
274
  dagPath = args[++i];
269
275
  }
@@ -398,6 +404,8 @@ export function parseDagReportArgs(args) {
398
404
  let action;
399
405
  for (let i = 0; i < args.length; i += 1) {
400
406
  const arg = args[i];
407
+ if (arg === undefined)
408
+ break;
401
409
  if (arg === "--run-id") {
402
410
  runId = args[++i];
403
411
  continue;
@@ -271,6 +271,17 @@ function nextMutationAction(actions) {
271
271
  }
272
272
  return actions[0] ?? null;
273
273
  }
274
+ /**
275
+ * True when a create-task step lost a create race: `createTask` refuses an id
276
+ * that another writer created between our lifecycle snapshot and the create
277
+ * call. That is not a failure of intent (the id exists), so the advance
278
+ * re-observes instead of aborting — Console issues `newTask` and `importPrd`
279
+ * back to back and used to lose the whole intake when newTask landed first.
280
+ */
281
+ export function isConcurrentTaskCreateError(taskId, error) {
282
+ const message = error instanceof Error ? error.message : String(error);
283
+ return message.startsWith(`task already exists: ${taskId}`);
284
+ }
274
285
  export async function advanceTaskLifecycle(input) {
275
286
  const completed = [];
276
287
  const blockers = [];
@@ -507,13 +518,24 @@ export async function advanceTaskLifecycle(input) {
507
518
  }
508
519
  if (action.type === "create-task") {
509
520
  if (!snapshot.exists) {
510
- await createTask(input.repoRoot, input.taskId, input.title, {
511
- taskKind: input.taskKind,
512
- taskKindExplicit: input.taskKindExplicit,
513
- });
514
- record = appendTransition(record, "task-created");
515
- completed.push("task-created");
516
- await saveLifecycleRecord(input.repoRoot, record);
521
+ try {
522
+ await createTask(input.repoRoot, input.taskId, input.title, {
523
+ taskKind: input.taskKind,
524
+ taskKindExplicit: input.taskKindExplicit,
525
+ });
526
+ record = appendTransition(record, "task-created");
527
+ completed.push("task-created");
528
+ await saveLifecycleRecord(input.repoRoot, record);
529
+ }
530
+ catch (error) {
531
+ // Lost create race: a concurrent writer (Console `newTask`
532
+ // issued alongside `importPrd`) created the same id between
533
+ // our snapshot and this call. The intent — this id exists and
534
+ // carries this PRD — is already satisfied, so fall through to
535
+ // the re-observe below instead of failing the advance.
536
+ if (!isConcurrentTaskCreateError(input.taskId, error))
537
+ throw error;
538
+ }
517
539
  }
518
540
  snapshot = await observeTaskLifecycle(input.repoRoot, input.taskId);
519
541
  continue;
@@ -663,6 +685,9 @@ export async function advanceTaskLifecycle(input) {
663
685
  allowedPaths: effectiveInput.allowedPaths,
664
686
  forbiddenPaths: input.forbiddenPaths,
665
687
  verifyCommands: effectiveInput.verifyCommands,
688
+ requirementOwnership: effectiveInput.requirementOwnership,
689
+ capabilityBoundary: effectiveInput.capabilityBoundary,
690
+ interactionIds: effectiveInput.interactionIds,
666
691
  backendTest: input.backendTest,
667
692
  },
668
693
  ...(sourceFidelity ? { sourceFidelity } : {}),
@@ -720,6 +745,9 @@ export async function advanceTaskLifecycle(input) {
720
745
  allowedPaths: effectiveInput.allowedPaths,
721
746
  forbiddenPaths: input.forbiddenPaths,
722
747
  verifyCommands: effectiveInput.verifyCommands,
748
+ requirementOwnership: effectiveInput.requirementOwnership,
749
+ capabilityBoundary: effectiveInput.capabilityBoundary,
750
+ interactionIds: effectiveInput.interactionIds,
723
751
  backendTest: input.backendTest,
724
752
  },
725
753
  });
@@ -741,6 +769,9 @@ export async function advanceTaskLifecycle(input) {
741
769
  allowedPaths: effectiveInput.allowedPaths,
742
770
  forbiddenPaths: input.forbiddenPaths,
743
771
  verifyCommands: effectiveInput.verifyCommands,
772
+ requirementOwnership: effectiveInput.requirementOwnership,
773
+ capabilityBoundary: effectiveInput.capabilityBoundary,
774
+ interactionIds: effectiveInput.interactionIds,
744
775
  backendTest: input.backendTest,
745
776
  },
746
777
  ...(sourceFidelity ? { sourceFidelity } : {}),
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.43.0-next.17",
4
- "gitSha": "a823bd9b58b0a599309bb3f0b8436fc16b2ff309",
5
- "builtAt": "2026-09-11T14:32:03.700Z"
3
+ "version": "0.43.0-next.19",
4
+ "gitSha": "7caee615c6037ecebb14ceddd8e253135844dbbb",
5
+ "builtAt": "2026-09-14T00:48:12.692Z"
6
6
  }
@@ -67,6 +67,8 @@ export function formatSubcommandUsageError(name, subcommands) {
67
67
  export function parseSummaryFlag(tokens) {
68
68
  for (let i = 0; i < tokens.length; i += 1) {
69
69
  const token = tokens[i];
70
+ if (token === undefined)
71
+ continue;
70
72
  if (token === "--summary") {
71
73
  return tokens[i + 1];
72
74
  }
@@ -96,7 +96,7 @@ function commandChain(command) {
96
96
  async function dispatchRegisteredCommand(commandObject, defaultRepoRoot, rawArgs) {
97
97
  const chain = commandChain(commandObject);
98
98
  const command = chain[0] ?? "";
99
- const [subcommand, ...rest] = chain.length <= 1 ? rawArgs : [chain[1], ...chain.slice(2), ...rawArgs];
99
+ const [subcommand, ...rest] = chain.length <= 1 ? rawArgs : [chain[1] ?? "", ...chain.slice(2), ...rawArgs];
100
100
  const options = collectGlobalOptions(commandObject);
101
101
  const quiet = (command === "doctor" &&
102
102
  [...rest, ...rawArgs].some((token) => token === "--json")) ||
@@ -397,6 +397,8 @@ function compactArgs(args) {
397
397
  function parsePlanSummaryFlag(tokens) {
398
398
  for (let i = 0; i < tokens.length; i += 1) {
399
399
  const token = tokens[i];
400
+ if (token === undefined)
401
+ continue;
400
402
  if (token === "--summary") {
401
403
  return tokens[i + 1];
402
404
  }
@@ -136,6 +136,8 @@ export function resolveInitSurfaceRepoRoot(argv, defaultRepoRoot) {
136
136
  let selected = defaultRepoRoot;
137
137
  for (let index = 0; index < argv.length; index += 1) {
138
138
  const arg = argv[index];
139
+ if (arg === undefined)
140
+ break;
139
141
  if (arg === "--repo-root") {
140
142
  const value = argv[index + 1];
141
143
  if (value && !value.startsWith("-"))
@@ -81,6 +81,8 @@ export function evaluateLatestVersion(input) {
81
81
  function firstCommand(argv) {
82
82
  for (let index = 0; index < argv.length; index += 1) {
83
83
  const arg = argv[index];
84
+ if (arg === undefined)
85
+ break;
84
86
  if (GLOBAL_VALUE_FLAGS.has(arg)) {
85
87
  index += 1;
86
88
  continue;
@@ -64,6 +64,8 @@ export function parseCursorPromptArgs(args) {
64
64
  continue;
65
65
  }
66
66
  const arg = args[i];
67
+ if (arg === undefined)
68
+ break;
67
69
  if (arg === "--stream") {
68
70
  stream = true;
69
71
  }
@@ -11,6 +11,8 @@ export function parseDagApproveArgs(args) {
11
11
  let notes;
12
12
  for (let i = 0; i < args.length; i += 1) {
13
13
  const arg = args[i];
14
+ if (arg === undefined)
15
+ break;
14
16
  if (arg === "--run-id") {
15
17
  runId = args[++i];
16
18
  continue;
@@ -10,6 +10,8 @@ export function parseDagFinalVerificationArgs(args) {
10
10
  let closeoutPath;
11
11
  for (let i = 0; i < args.length; i += 1) {
12
12
  const arg = args[i];
13
+ if (arg === undefined)
14
+ break;
13
15
  if (arg === '--output' || arg === '-o') {
14
16
  outputPath = requiredValue(args[++i], '--output');
15
17
  }
@@ -9,6 +9,8 @@ export function parseDagInitHybridArgs(args) {
9
9
  let outputPath;
10
10
  for (let i = 0; i < args.length; i += 1) {
11
11
  const arg = args[i];
12
+ if (arg === undefined)
13
+ break;
12
14
  if (arg === "--output" || arg === "-o") {
13
15
  outputPath = args[++i];
14
16
  if (!outputPath) {
@@ -20,6 +20,8 @@ export function parseDagReconcileTasksArgs(args) {
20
20
  let markdown = false;
21
21
  for (let i = 0; i < args.length; i += 1) {
22
22
  const arg = args[i];
23
+ if (arg === undefined)
24
+ break;
23
25
  if (arg === '--glob') {
24
26
  glob = requiredValue(args[++i], '--glob');
25
27
  }
@@ -8,6 +8,8 @@ export function parseDagRejectArgs(args) {
8
8
  let reason;
9
9
  for (let i = 0; i < args.length; i += 1) {
10
10
  const arg = args[i];
11
+ if (arg === undefined)
12
+ break;
11
13
  if (arg === "--run-id") {
12
14
  runId = args[++i];
13
15
  continue;
@@ -29,6 +29,8 @@ export function parseDagCloseoutDraftArgs(args) {
29
29
  let outputPath;
30
30
  for (let i = 0; i < args.length; i += 1) {
31
31
  const arg = args[i];
32
+ if (arg === undefined)
33
+ break;
32
34
  const requireValue = (flag) => {
33
35
  const value = args[++i];
34
36
  if (!value || value.startsWith("-")) {
@@ -22,6 +22,8 @@ export function parseDagRerunArgs(args) {
22
22
  const promptOverrideAppendSpecs = [];
23
23
  for (let index = 0; index < args.length; index += 1) {
24
24
  const arg = args[index];
25
+ if (arg === undefined)
26
+ break;
25
27
  if (arg === "--run-id")
26
28
  parentRunId = args[++index];
27
29
  else if (arg.startsWith("--run-id="))
@@ -6,6 +6,8 @@ export function parseDagResumeArgs(args) {
6
6
  let runId;
7
7
  for (let i = 0; i < args.length; i += 1) {
8
8
  const arg = args[i];
9
+ if (arg === undefined)
10
+ break;
9
11
  if (arg === "--run-id") {
10
12
  runId = args[++i];
11
13
  continue;
@@ -12,6 +12,8 @@ export function parseDagWorkflowCompileArgs(args) {
12
12
  let manifestPath;
13
13
  for (let i = 0; i < args.length; i += 1) {
14
14
  const arg = args[i];
15
+ if (arg === undefined)
16
+ break;
15
17
  if (arg === "--workflow") {
16
18
  workflowPath = args[++i];
17
19
  if (!workflowPath) {
@@ -21,6 +21,8 @@ export function parseDagWorkflowPlanArgs(args) {
21
21
  const changedFiles = [];
22
22
  for (let i = 0; i < rest.length; i += 1) {
23
23
  const arg = rest[i];
24
+ if (arg === undefined)
25
+ break;
24
26
  if (arg === "--profile") {
25
27
  const value = rest[++i];
26
28
  if (!value)
@@ -11,6 +11,8 @@ export function parseDagWorkflowValidateArgs(args) {
11
11
  let strictGovernance = false;
12
12
  for (let i = 0; i < args.length; i += 1) {
13
13
  const arg = args[i];
14
+ if (arg === undefined)
15
+ break;
14
16
  if (arg === "--workflow") {
15
17
  workflowPath = args[++i];
16
18
  if (!workflowPath) {
@@ -16,6 +16,8 @@ export function parseDelegateArgs(args) {
16
16
  let autoRun = false;
17
17
  for (let i = 0; i < args.length; i += 1) {
18
18
  const arg = args[i];
19
+ if (arg === undefined)
20
+ break;
19
21
  if (arg === "--base") {
20
22
  base = args[i + 1];
21
23
  if (!base)
@@ -57,6 +57,8 @@ function parseExamplesArgs(args) {
57
57
  let output;
58
58
  for (let i = 0; i < rest.length; i += 1) {
59
59
  const arg = rest[i];
60
+ if (arg === undefined)
61
+ break;
60
62
  if (arg === "--output" || arg === "-o") {
61
63
  output = rest[++i];
62
64
  continue;
@@ -5,6 +5,8 @@ export function parseImportPrdArgs(args) {
5
5
  const positional = [];
6
6
  for (let index = 0; index < args.length; index += 1) {
7
7
  const token = args[index];
8
+ if (token === undefined)
9
+ continue;
8
10
  if (token === "--file" || token === "-f") {
9
11
  options.file = args[index + 1];
10
12
  index += 1;
@@ -252,6 +252,8 @@ export function parseOpenCodeModelReferences(value, credentialProviders = new Se
252
252
  if (!match)
253
253
  continue;
254
254
  const [, provider, modelId] = match;
255
+ if (provider === undefined || modelId === undefined)
256
+ continue;
255
257
  const model = createCatalogEntry({
256
258
  source: "opencode",
257
259
  provider,
@@ -861,19 +861,23 @@ function mergeGitignoreManagedBlock(existing, block) {
861
861
  return `${existing.trimEnd()}\n\n${block}\n`;
862
862
  }
863
863
  /**
864
- * Shared ignore rules for loop-agent runtime facts. The four directories are
865
- * local, rebuildable runtime surface: every developer runs loop-agent init
866
- * after cloning, so nothing inside them is team-shareable by default.
867
- * `scripts/` and `ai_workspace/loop-agent/` stay on the shared commit surface.
864
+ * Shared ignore rules for loop-agent init surface: everything init regenerates
865
+ * in the target project is local and rebuildable, so none of it is
866
+ * team-shareable by default. `AGENTS.md` and `README.md` stay on the shared
867
+ * commit surface (they carry the governance handoff and are not ignored);
868
+ * `.opencode/` and `.pi/` project adapters are left to the user's discretion.
868
869
  */
869
- export function buildManagedGitignoreBlock() {
870
+ export function buildManagedGitignoreBlock(governanceRoot = DEFAULT_GOVERNANCE_ROOT) {
870
871
  return [
871
872
  GITIGNORE_BLOCK_START,
872
- "# loop-agent runtime: local, rebuildable facts; do not ignore scripts/ or ai_workspace/loop-agent/",
873
+ "# loop-agent init surface: rebuildable outputs; AGENTS.md and README.md stay shared",
873
874
  ".harness/",
874
875
  ".agents/",
875
876
  ".task-pool/",
876
877
  ".worktrees/",
878
+ `${governanceRoot}/`,
879
+ "scripts/",
880
+ "harness.json",
877
881
  GITIGNORE_BLOCK_END,
878
882
  ].join("\n");
879
883
  }
@@ -1312,7 +1316,7 @@ async function buildDesiredSurfaceContent(input) {
1312
1316
  };
1313
1317
  }
1314
1318
  if (manifestPath === ".gitignore") {
1315
- return { content: buildManagedGitignoreBlock() };
1319
+ return { content: buildManagedGitignoreBlock(input.governanceRoot) };
1316
1320
  }
1317
1321
  if (manifestPath === "harness.json") {
1318
1322
  const template = await readJsonIfExists(path.join(input.assetRoot, "harness.json"));
@@ -2554,7 +2558,7 @@ export function buildInitInstructions(input) {
2554
2558
  "- Enrich the root `README.md`: keep the deterministic project title and the loop-agent managed block intact, and fill the human-authored sections (项目概览, 技术栈与目录结构, 开发与验证) from the target project's actual files. The root README must serve both as a human-first project entry and as an agent work entry; replace the initialization-model supplement comments when the project files provide the information.",
2555
2559
  `- Populate \`${governanceRoot}/verification-matrix.md\` with the target project's actual quick, standard, and full verification commands derived from its real language and toolchain, keeping the governance rows intact.`,
2556
2560
  "- Project repo-local skills live in `.agents/skills/`. Do not create a root `skills/` directory in the target project; the package's bundled `skills/` remains the built-in fallback.",
2557
- "- Merge a loop-agent managed block into `.gitignore` that ignores exactly the four local, rebuildable runtime directories (`.harness/`, `.agents/`, `.task-pool/`, `.worktrees/`) while keeping `scripts/` and `ai_workspace/loop-agent/` on the shared commit surface; keep all user rules outside the block untouched.",
2561
+ "- Merge a loop-agent managed block into `.gitignore` that ignores the full rebuildable init surface (`.harness/`, `.agents/`, `.task-pool/`, `.worktrees/`, `ai_workspace/loop-agent/`, `scripts/`, `harness.json`); keep `AGENTS.md` and `README.md` on the shared commit surface and keep all user rules outside the block untouched.",
2558
2562
  "- Do not copy examples by default; examples stay bundled in the tool and are available through `loop-agent examples`.",
2559
2563
  "- Add or update a loop-agent managed block in AGENTS.md.",
2560
2564
  "- The generated AGENTS.md must include documentation convergence and structured DAG write-boundary rules so target projects keep the same working discipline as this repository.",
@@ -2676,7 +2680,7 @@ export async function initializeLoopAgentProject(options) {
2676
2680
  await writeText({
2677
2681
  repoRoot,
2678
2682
  relativePath: ".gitignore",
2679
- content: mergeGitignoreManagedBlock(existingGitignore, buildManagedGitignoreBlock()),
2683
+ content: mergeGitignoreManagedBlock(existingGitignore, buildManagedGitignoreBlock(governanceRoot)),
2680
2684
  merge: true,
2681
2685
  written,
2682
2686
  skipped,
@@ -2842,7 +2846,7 @@ function modelMergeTaskFor(pathName, state, allPaths, recordedState) {
2842
2846
  taskId: `init-merge-${sha256Text(pathName).slice(0, 12)}`,
2843
2847
  path: pathName,
2844
2848
  reason: "target file exists but does not match the current loop-agent initialization surface",
2845
- sourcePath: state.sourcePath,
2849
+ sourcePath: state?.sourcePath,
2846
2850
  allowedPaths: [pathName],
2847
2851
  forbiddenPaths: [
2848
2852
  ...allPaths.filter((candidate) => candidate !== pathName),
@@ -2861,9 +2865,9 @@ function modelMergeTaskFor(pathName, state, allPaths, recordedState) {
2861
2865
  ],
2862
2866
  evidence: {
2863
2867
  baseSha256: recordedState?.files[pathName]?.currentSha256,
2864
- currentSha256: state.currentSha256,
2865
- desiredSha256: state.sourceSha256,
2866
- sourceAnchorSha256: state.sourceAnchorSha256,
2868
+ currentSha256: state?.currentSha256,
2869
+ desiredSha256: state?.sourceSha256,
2870
+ sourceAnchorSha256: state?.sourceAnchorSha256,
2867
2871
  },
2868
2872
  };
2869
2873
  }
@@ -3743,6 +3747,8 @@ function parseInitArgs(repoRoot, args) {
3743
3747
  let versionChoice;
3744
3748
  for (let i = 0; i < args.length; i += 1) {
3745
3749
  const arg = args[i];
3750
+ if (arg === undefined)
3751
+ break;
3746
3752
  if ((arg === "instructions" ||
3747
3753
  arg === "doctor" ||
3748
3754
  arg === "model-catalog" ||
@@ -18,6 +18,8 @@ export function parseInstructionsArgs(args) {
18
18
  let json = false;
19
19
  for (let i = 0; i < rest.length; i += 1) {
20
20
  const arg = rest[i];
21
+ if (arg === undefined)
22
+ break;
21
23
  if (arg === "--task") {
22
24
  taskId = rest[++i];
23
25
  if (!taskId)
@@ -68,6 +68,8 @@ export function parseKnowledgeArgs(args) {
68
68
  let markdown = false;
69
69
  for (let i = 0; i < rest.length; i += 1) {
70
70
  const arg = rest[i];
71
+ if (arg === undefined)
72
+ break;
71
73
  if (arg === "--json") {
72
74
  json = true;
73
75
  continue;
@@ -6,6 +6,8 @@ export function parseLoopBenchmarkArgs(args) {
6
6
  let outputPath;
7
7
  for (let i = 0; i < args.length; i += 1) {
8
8
  const arg = args[i];
9
+ if (arg === undefined)
10
+ break;
9
11
  if (arg === "--json") {
10
12
  json = true;
11
13
  continue;
@@ -66,6 +66,8 @@ export function parsePiPromptArgs(args) {
66
66
  continue;
67
67
  }
68
68
  const arg = args[i];
69
+ if (arg === undefined)
70
+ break;
69
71
  if (arg === "--provider") {
70
72
  provider = args[i + 1];
71
73
  if (!provider)
@@ -11,6 +11,8 @@ export function parsePiReuseBenchmarkArgs(args) {
11
11
  let markdown = false;
12
12
  for (let i = 0; i < args.length; i += 1) {
13
13
  const arg = args[i];
14
+ if (arg === undefined)
15
+ break;
14
16
  if (arg === "--json") {
15
17
  json = true;
16
18
  continue;
@@ -6,6 +6,8 @@ export function parsePromoteRunArgs(args) {
6
6
  let runId;
7
7
  for (let i = 0; i < rest.length; i += 1) {
8
8
  const arg = rest[i];
9
+ if (arg === undefined)
10
+ break;
9
11
  if (arg === '--run-id') {
10
12
  runId = rest[++i];
11
13
  if (!runId)
@@ -6,7 +6,7 @@ function percentile(values, p) {
6
6
  return null;
7
7
  const sorted = [...values].sort((a, b) => a - b);
8
8
  const index = Math.ceil((p / 100) * sorted.length) - 1;
9
- return sorted[Math.max(0, index)];
9
+ return sorted[Math.max(0, index)] ?? null;
10
10
  }
11
11
  function formatMs(ms) {
12
12
  if (ms >= 60_000)
@@ -16,6 +16,8 @@ function parseStudyInitArgs(args) {
16
16
  const positional = [];
17
17
  for (let i = 0; i < args.length; i += 1) {
18
18
  const arg = args[i];
19
+ if (arg === undefined)
20
+ break;
19
21
  if (arg === '--reference-repo') {
20
22
  const value = args[i + 1];
21
23
  if (!value)
@@ -84,6 +84,8 @@ export function parseTaskAdvanceArgs(args) {
84
84
  const positional = [];
85
85
  for (let i = 0; i < args.length; i += 1) {
86
86
  const token = args[i];
87
+ if (token === undefined)
88
+ continue;
87
89
  const next = () => {
88
90
  const value = args[i + 1];
89
91
  if (value === undefined || value.startsWith("-")) {
@@ -136,6 +138,35 @@ export function parseTaskAdvanceArgs(args) {
136
138
  options.verify = pushList(options.verify, next());
137
139
  continue;
138
140
  }
141
+ if (token === "--interaction-ids") {
142
+ options.interactionIds = pushList(options.interactionIds, next());
143
+ continue;
144
+ }
145
+ if (token === "--capability-boundary") {
146
+ try {
147
+ const parsed = JSON.parse(next());
148
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
149
+ throw new Error("not an object");
150
+ }
151
+ options.capabilityBoundary = parsed;
152
+ }
153
+ catch (error) {
154
+ throw new Error(`--capability-boundary must be a JSON object {allowed?, forbidden?}: ${error.message}`);
155
+ }
156
+ continue;
157
+ }
158
+ if (token === "--requirement-ownership") {
159
+ try {
160
+ const parsed = JSON.parse(next());
161
+ if (!Array.isArray(parsed))
162
+ throw new Error("not an array");
163
+ options.requirementOwnership = parsed;
164
+ }
165
+ catch (error) {
166
+ throw new Error(`--requirement-ownership must be a JSON array of {requirementIds, implementationFiles?, verificationFiles?}: ${error.message}`);
167
+ }
168
+ continue;
169
+ }
139
170
  if (token === "--verify-timeout") {
140
171
  options.verifyTimeout = pushList(options.verifyTimeout, next());
141
172
  continue;
@@ -324,6 +355,9 @@ export function toUseCaseInput(repoRoot, taskId, options, observer) {
324
355
  allowedPaths: options.allowedPaths,
325
356
  forbiddenPaths: options.forbiddenPaths,
326
357
  verifyCommands: verifyCommands.length > 0 ? verifyCommands : undefined,
358
+ requirementOwnership: options.requirementOwnership,
359
+ capabilityBoundary: options.capabilityBoundary,
360
+ interactionIds: options.interactionIds?.length ? options.interactionIds : undefined,
327
361
  backendTest: options.backendTest,
328
362
  approveGateToken: options.approveGate,
329
363
  rejectGateToken: options.rejectGate,
@@ -43,6 +43,8 @@ export function parseTaskSourcePrepareArgs(args) {
43
43
  const positional = [];
44
44
  for (let i = 0; i < args.length; i += 1) {
45
45
  const token = args[i];
46
+ if (token === undefined)
47
+ continue;
46
48
  const next = () => {
47
49
  const value = args[i + 1];
48
50
  if (value === undefined || value.startsWith("-")) {
@@ -7,6 +7,8 @@ export async function runWorktreeCreate(repoRoot, args) {
7
7
  const positionalArgs = [];
8
8
  for (let i = 0; i < args.length; i++) {
9
9
  const token = args[i];
10
+ if (token === undefined)
11
+ continue;
10
12
  if (token === '--base') {
11
13
  base = args[++i];
12
14
  if (!base)
@@ -6,6 +6,8 @@ export async function runWorktreeRemove(repoRoot, args) {
6
6
  const positionalArgs = [];
7
7
  for (let i = 0; i < args.length; i++) {
8
8
  const token = args[i];
9
+ if (token === undefined)
10
+ continue;
9
11
  if (token === '--force') {
10
12
  force = true;
11
13
  }