@tea-agent/loop-agent 0.43.0-next.9 → 0.43.0

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 (287) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +31 -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/client-recovery.js +20 -55
  12. package/dist/commands/cursor-prompt.js +2 -0
  13. package/dist/commands/dag-approve.js +2 -0
  14. package/dist/commands/dag-final-verification.js +2 -0
  15. package/dist/commands/dag-init-hybrid.js +2 -0
  16. package/dist/commands/dag-reconcile-tasks.js +2 -0
  17. package/dist/commands/dag-reject.js +2 -0
  18. package/dist/commands/dag-report.js +2 -0
  19. package/dist/commands/dag-rerun.js +2 -0
  20. package/dist/commands/dag-resume.js +2 -0
  21. package/dist/commands/dag-workflow-compile.js +2 -0
  22. package/dist/commands/dag-workflow-plan.js +2 -0
  23. package/dist/commands/dag-workflow-validate.js +2 -0
  24. package/dist/commands/delegate.js +2 -0
  25. package/dist/commands/examples.js +2 -0
  26. package/dist/commands/import-prd.js +2 -0
  27. package/dist/commands/init-model-catalog.js +2 -0
  28. package/dist/commands/init.js +19 -13
  29. package/dist/commands/instructions.js +2 -0
  30. package/dist/commands/knowledge.js +2 -0
  31. package/dist/commands/loop-benchmark.js +2 -0
  32. package/dist/commands/pi-prompt.js +2 -0
  33. package/dist/commands/pi-reuse-benchmark.js +2 -0
  34. package/dist/commands/promote-run.js +2 -0
  35. package/dist/commands/stats.js +1 -1
  36. package/dist/commands/study-init.js +2 -0
  37. package/dist/commands/task-advance.js +34 -0
  38. package/dist/commands/task-source-prepare.js +2 -0
  39. package/dist/commands/worktree-create.js +2 -0
  40. package/dist/commands/worktree-remove.js +2 -0
  41. package/dist/executors/dag-pi-executor.js +1650 -198
  42. package/dist/executors/pi-executor.js +85 -3
  43. package/dist/executors/pi-sdk-executor.js +18 -0
  44. package/dist/executors/shell-executor.js +93 -7
  45. package/dist/executors/shell-verification.js +3 -0
  46. package/dist/executors/shell-write-guard.js +27 -32
  47. package/dist/governance/exec-plans.js +6 -3
  48. package/dist/infrastructure/console/app-data.js +6 -0
  49. package/dist/shared/artifacts-core.js +2 -0
  50. package/dist/shared/backend-dogfood-preflight.js +47 -0
  51. package/dist/shared/dag-failure-category.js +3 -0
  52. package/dist/shared/git-progress.js +2 -0
  53. package/dist/shared/one-shot-prompt-args.js +2 -0
  54. package/dist/shared/operator/capabilities.js +180 -0
  55. package/dist/shared/package-metadata.js +6 -4
  56. package/dist/shared/pi-context-pressure/extension.js +26 -16
  57. package/dist/shared/pi-context-pressure/sift-bridge.js +1 -1
  58. package/dist/shared/pi-provider-recovery.js +182 -0
  59. package/dist/shared/pi-retry-settings.js +40 -0
  60. package/dist/shared/reference-context.js +2 -0
  61. package/dist/task/config-types.js +29 -0
  62. package/dist/task/contract/project.js +9 -0
  63. package/dist/task/contract/recover.js +6 -0
  64. package/dist/task/contract/schema.js +17 -0
  65. package/dist/task/source-prepare/artifact-meta.js +9 -2
  66. package/dist/task/source-prepare/build-draft.js +60 -0
  67. package/dist/task/source-prepare/fragment-inventory.js +4 -1
  68. package/dist/task/source-prepare/parse-intent.js +36 -11
  69. package/dist/task/task-demand-routing.js +5 -2
  70. package/dist/worker/console/chat/browser-automation.js +523 -0
  71. package/dist/worker/console/chat/browser-policy.js +6 -36
  72. package/dist/worker/console/chat/browser-routes.js +188 -56
  73. package/dist/worker/console/chat/explore-tools.js +5 -2
  74. package/dist/worker/console/chat/pi-mode-loop-isolation.js +155 -0
  75. package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +44 -0
  76. package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +184 -0
  77. package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +202 -0
  78. package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +79 -0
  79. package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +94 -0
  80. package/dist/worker/console/chat/pi-runtime/custom-tools/scheduled-goal-tools.js +22 -0
  81. package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +38 -0
  82. package/dist/worker/console/chat/pi-runtime/inspection-types.js +28 -0
  83. package/dist/worker/console/chat/pi-runtime/inspection.js +439 -0
  84. package/dist/worker/console/chat/pi-runtime/progressive-tools.js +195 -0
  85. package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +153 -0
  86. package/dist/worker/console/chat/pi-runtime/sdk-session.js +5 -0
  87. package/dist/worker/console/chat/pi-runtime.js +208 -1138
  88. package/dist/worker/console/chat/routes.js +27 -7
  89. package/dist/worker/console/chat/scheduled-goal-booking.js +59 -0
  90. package/dist/worker/console/chat/scheduled-goal-delivery.js +27 -0
  91. package/dist/worker/console/chat/scheduled-goal-request.js +190 -0
  92. package/dist/worker/console/chat/sdd-data-alignment.js +1 -1
  93. package/dist/worker/console/chat/session-mode-view.js +5 -4
  94. package/dist/worker/console/chat/session-mode.js +18 -12
  95. package/dist/worker/console/chat/session-store.js +42 -9
  96. package/dist/worker/console/chat/tool-preview.js +115 -0
  97. package/dist/worker/console/chat/tools.js +10 -0
  98. package/dist/worker/console/chat/turn-order.js +13 -0
  99. package/dist/worker/console/chat/turn-process.js +32 -30
  100. package/dist/worker/console/console-update-and-init.js +1 -19
  101. package/dist/worker/console/console-update-runtime.js +5 -20
  102. package/dist/worker/console/operator-actions.js +63 -1
  103. package/dist/worker/console/prd-intake-bridge.js +54 -1
  104. package/dist/worker/console/routes.js +8 -0
  105. package/dist/worker/console/scheduled-goal-host.js +98 -0
  106. package/dist/worker/console/scheduled-goal-operation-adapter.js +127 -0
  107. package/dist/worker/console/server.js +24 -1
  108. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-D_fNbWc_.js → abnfDiagram-N423BO3Z-8-j6y-sd.js} +1 -1
  109. package/dist/worker/console/static/assets/{arc-_HuqLW6m.js → arc-eoQiMvuk.js} +1 -1
  110. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-Djy2qY1m.js → architectureDiagram-T3A2C74G-C4A3uMcI.js} +1 -1
  111. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-bB-1TSyY.js → blockDiagram-VBNYF7ZC-D4zD2F-Q.js} +1 -1
  112. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-C5Hmghrz.js → c4Diagram-5PPSVZJV-j1RkJziL.js} +1 -1
  113. package/dist/worker/console/static/assets/channel-ChE7y-cx.js +1 -0
  114. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-Duyl39oy.js → chunk-2GRJ4B5K-YBHmhik1.js} +1 -1
  115. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-x6mdnSyf.js → chunk-2Q5K7J3B-COfWyo9P.js} +1 -1
  116. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-WlBuFj7W.js → chunk-5RXB4S5H-I99OUkHY.js} +1 -1
  117. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-CTF429HX.js → chunk-5VM5RSS4-XKxoJNJ4.js} +1 -1
  118. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Dwd6r-SF.js → chunk-6Q2QTUOP-DLT_cYx1.js} +1 -1
  119. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C-Br82D1.js → chunk-GF5L2VYU-CxcKZ9mV.js} +1 -1
  120. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CuGp0DeE.js → chunk-JWPE2WC7-V1EqXdjY.js} +1 -1
  121. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CJhFX6Lh.js → chunk-KBJHAD2P-DebTtdFp.js} +1 -1
  122. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DpGOa_jT.js → chunk-RYQCIY6F-B-ivNRDf.js} +1 -1
  123. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DXJaTynd.js → chunk-XXDRQBXY-DC_Ds11b.js} +1 -1
  124. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C01TCf2X.js +1 -0
  125. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C01TCf2X.js +1 -0
  126. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CRBZWjE4.js → cose-bilkent-JH36ORCC-sWEqKwIb.js} +1 -1
  127. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BdXcxtlb.js → cynefin-VYW2F7L2-BXa_dcu4.js} +1 -1
  128. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-07UKsOts.js → cynefinDiagram-MW4NZA55-C-Mle84F.js} +1 -1
  129. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-D38p9__S.js → dagre-VZM6K2ZE-CXPDBITe.js} +1 -1
  130. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-nSiBNNjH.js → diagram-7IWD3JNH-CC-WJQfa.js} +1 -1
  131. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BFOTot5D.js → diagram-B4RE2ZJO-CDAV5Vs4.js} +1 -1
  132. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DypKaZ6k.js → diagram-LBJQPF4R-CmFiAcNz.js} +1 -1
  133. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-B6yoOQeW.js → diagram-Q27KOJAE-DPBZHuyn.js} +1 -1
  134. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BHYS6viX.js → diagram-UB23O5K3-jUlm_Ds3.js} +1 -1
  135. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-D2VD5Snj.js → ebnfDiagram-BXEA7PRR-DWhQ3mfY.js} +1 -1
  136. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-E98mWxN1.js → erDiagram-JOGREHBK-Tr2gMqet.js} +1 -1
  137. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CT1zxhqP.js → flowDiagram-UKHOOZJN-DJjVQHPA.js} +1 -1
  138. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-6GcngNcy.js → ganttDiagram-PKOTCBZU-D74dQ4u0.js} +1 -1
  139. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DCL6NvKe.js → gitGraphDiagram-DS77QQ5N-DwW0tZ0X.js} +1 -1
  140. package/dist/worker/console/static/assets/index-BWkIfcrK.css +1 -0
  141. package/dist/worker/console/static/assets/index-Cdkvw_H6.js +469 -0
  142. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-C0627e-9.js → infoDiagram-6WML65LV-ILCbxJyb.js} +1 -1
  143. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-C_u3P6Ik.js → ishikawaDiagram-WSZJBQD7-DeuWBQ89.js} +1 -1
  144. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DPDPv9HL.js → journeyDiagram-NVQOT4AX-CF5ih8Fk.js} +1 -1
  145. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-D3OHdWiO.js → kanban-definition-27J2QSJJ-C7yOSuRO.js} +1 -1
  146. package/dist/worker/console/static/assets/{linear-DI88zD7n.js → linear-BDZ9riWi.js} +1 -1
  147. package/dist/worker/console/static/assets/{mermaid.core-p2l8IrWY.js → mermaid.core-7pKqYtpZ.js} +5 -5
  148. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-B1bAX-oS.js → mindmap-definition-FAOFIHXS-LeJDybSU.js} +1 -1
  149. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DwOnWxdD.js → pegDiagram-VL7TDLO6-BJvT3pMD.js} +1 -1
  150. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-xRkTXnJC.js → pieDiagram-7S7Q4E2Y-_rGqpMan.js} +1 -1
  151. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-_9UC5Zio.js → quadrantDiagram-CIZ2JOQS-DPcSv5aA.js} +1 -1
  152. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CgEUirWJ.js → railroadDiagram-AXF67PYL-Drxx4hkJ.js} +1 -1
  153. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-Czbpwiyz.js → requirementDiagram-LRYGKXZP-BCTUdU4z.js} +1 -1
  154. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-_j7_KiqY.js → sankeyDiagram-W5VNT64P-B6wzbZmB.js} +1 -1
  155. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BNJa6Hyi.js → sequenceDiagram-SI44F4Z6-BGt8d3QQ.js} +1 -1
  156. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DedpKtOc.js → sizeCapture-X5ZJPWSS-7nlhJKo7.js} +1 -1
  157. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BBvthr7c.js → stateDiagram-OKZ733FA-Cv2stqMA.js} +1 -1
  158. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DC7V5vcq.js +1 -0
  159. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-Ds7umgEM.js → swimlanes-SLNWSIFB-qDAo4Yc1.js} +2 -2
  160. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bwy4QUTO.js +8 -0
  161. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CKa-p1nF.js → timeline-definition-Z64GVDOM-CKbDNKTr.js} +1 -1
  162. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-LoUNR56o.js → vennDiagram-T6HMQDX7-DI-9EHic.js} +1 -1
  163. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-Bqbl6ym7.js → wardleyDiagram-T6FBY63Y-BrzzRDpX.js} +1 -1
  164. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-B8dUg4lf.js → xychartDiagram-ELKLHX3M-BclH5hGh.js} +1 -1
  165. package/dist/worker/console/static/index.html +2 -2
  166. package/dist/worker/console/static-src/operator-chat/chat-scroll-position.js +24 -0
  167. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +41 -11
  168. package/dist/worker/console/static-src/operator-chat/compaction-message.js +3 -17
  169. package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +192 -0
  170. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +9 -1
  171. package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +15 -5
  172. package/dist/worker/console/static-src/operator-chat/timeline-merge.js +29 -0
  173. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +92 -38
  174. package/dist/worker/console/static-src/operator-chat/useChatStream.js +145 -70
  175. package/dist/worker/console/static-src/operator-chat/useChatThread.js +38 -55
  176. package/dist/worker/console/static-src/operator-chat/useComposer.js +182 -69
  177. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +2 -0
  178. package/dist/worker/console/static-src/prd-file-import.js +3 -1
  179. package/dist/worker/console/workspace-context.js +22 -0
  180. package/dist/worker/console/workspace-initialization.js +209 -0
  181. package/dist/worker/delivery/git-transaction.js +2 -0
  182. package/dist/worker/feature/fullstack-validate.js +2 -0
  183. package/dist/worker/loop-agent/loop-agent-client.js +8 -2
  184. package/dist/worker/materialize/harness-task-materializer.js +4 -1
  185. package/dist/worker/metrics/projector.js +1 -1
  186. package/dist/worker/observability/event-store.js +4 -1
  187. package/dist/worker/observability/read-model.js +4 -1
  188. package/dist/worker/observe/node-transparency.js +23 -1
  189. package/dist/worker/observe/routes.js +4 -0
  190. package/dist/worker/observe/static/operator-chrome.js +3 -1
  191. package/dist/worker/observe/static/styles.css +7 -4
  192. package/dist/worker/observe/static/views/dag-inspector.js +5 -19
  193. package/dist/worker/outcomes/declared-artifacts.js +2 -0
  194. package/dist/worker/preflight.js +3 -0
  195. package/dist/worker/scheduler/scheduled-goal-dispatch.js +117 -0
  196. package/dist/worker/scheduler/scheduled-goal-evidence.js +167 -0
  197. package/dist/worker/scheduler/scheduled-goal-recovery.js +62 -0
  198. package/dist/worker/scheduler/scheduled-goal-store.js +699 -0
  199. package/dist/worker/scheduler/scheduled-goal-supervisor.js +132 -0
  200. package/dist/worker/scheduler/scheduled-goal-time.js +102 -0
  201. package/dist/worker/scheduler/scheduled-goal-types.js +95 -0
  202. package/dist/worker/task-spec/validate.js +4 -1
  203. package/dist/workflows/dag/backend-test-markdown-workflow.js +6 -24
  204. package/dist/workflows/dag/backend-test-plan-protocol.js +82 -5
  205. package/dist/workflows/dag/dag-retry-schema.js +11 -0
  206. package/dist/workflows/dag/decision-envelope.js +2 -0
  207. package/dist/workflows/dag/dynamic-runtime/shared.js +2 -2
  208. package/dist/workflows/dag/frontend-closeout.js +3 -1
  209. package/dist/workflows/dag/frontend-committed-facts.js +461 -0
  210. package/dist/workflows/dag/frontend-durable-tools.js +15 -3
  211. package/dist/workflows/dag/frontend-implementation-contract.js +369 -12
  212. package/dist/workflows/dag/frontend-plan-canary.js +53 -0
  213. package/dist/workflows/dag/frontend-plan-decision-contract.js +803 -0
  214. package/dist/workflows/dag/frontend-plan-render.js +0 -2
  215. package/dist/workflows/dag/frontend-provider-capability-matrix.js +8 -61
  216. package/dist/workflows/dag/frontend-recovery-run.js +57 -0
  217. package/dist/workflows/dag/frontend-repair.js +55 -76
  218. package/dist/workflows/dag/frontend-review-context.js +42 -68
  219. package/dist/workflows/dag/frontend-review-scopes.js +2 -2
  220. package/dist/workflows/dag/frontend-risk.js +92 -10
  221. package/dist/workflows/dag/frontend-session-budget.js +117 -3
  222. package/dist/workflows/dag/frontend-shape.js +11 -55
  223. package/dist/workflows/dag/frontend-test-execution-evidence.js +35 -10
  224. package/dist/workflows/dag/frontend-typed-event-store.js +32 -25
  225. package/dist/workflows/dag/frontend-verification-trace.js +33 -54
  226. package/dist/workflows/dag/frontend-writer-admission.js +3 -47
  227. package/dist/workflows/dag/frontend-writer-status.js +0 -23
  228. package/dist/workflows/dag/init-hybrid.js +47 -19
  229. package/dist/workflows/dag/interrupt-request.js +2 -0
  230. package/dist/workflows/dag/lifecycle.js +11 -2
  231. package/dist/workflows/dag/node-execution.js +50 -13
  232. package/dist/workflows/dag/reconcile-run.js +2 -0
  233. package/dist/workflows/dag/repair-artifact.js +3 -1
  234. package/dist/workflows/dag/report.js +2 -0
  235. package/dist/workflows/dag/rerun-plan.js +10 -0
  236. package/dist/workflows/dag/rerun-task.js +79 -1
  237. package/dist/workflows/dag/retry-policy.js +18 -0
  238. package/dist/workflows/dag/scheduler.js +2 -4
  239. package/dist/workflows/dag/types.js +44 -6
  240. package/dist/workflows/dag/validate.js +4 -0
  241. package/docs/README.md +1 -0
  242. package/docs/architecture/runtime-boundaries.md +3 -3
  243. package/docs/governance/README.md +1 -0
  244. package/docs/init-surface.manifest.json +1 -0
  245. package/docs/operations/README.md +2 -0
  246. package/docs/templates/README.md +1 -1
  247. package/docs/templates/agent-dag.schema.json +2 -2
  248. package/docs/templates/backend-test-dag.json +14 -10
  249. package/docs/templates/frontend-implementation-contract.schema.json +0 -7
  250. package/package.json +9 -3
  251. package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
  252. package/skills/frontend-contract/references/contract-protocol.md +3 -1
  253. package/skills/frontend-plan/SKILL.md +8 -6
  254. package/skills/frontend-plan/references/decision-contract.md +3 -3
  255. package/skills/frontend-review/SKILL.md +18 -28
  256. package/skills/frontend-review/references/review-findings.md +8 -3
  257. package/dist/commands/new-task.js +0 -5
  258. package/dist/commands/status.js +0 -57
  259. package/dist/commands/task-contract.js +0 -269
  260. package/dist/shared/prompts.js +0 -26
  261. package/dist/task/config.js +0 -2
  262. package/dist/task/contract/validate-draft.js +0 -106
  263. package/dist/task/goal.js +0 -3
  264. package/dist/task/index.js +0 -12
  265. package/dist/task/lifecycle.js +0 -1
  266. package/dist/task/operator/capabilities.js +0 -6
  267. package/dist/task/operator/envelope.js +0 -2
  268. package/dist/task/operator/index.js +0 -5
  269. package/dist/task/operator/registry.js +0 -2
  270. package/dist/task/operator/types.js +0 -1
  271. package/dist/task/paths.js +0 -1
  272. package/dist/task/source-state.js +0 -1
  273. package/dist/task/subagent-guidance.js +0 -1
  274. package/dist/worker/console/chat/sift-bridge.js +0 -1
  275. package/dist/worker/console/index.js +0 -20
  276. package/dist/worker/console/static/assets/channel-C0A6UEIa.js +0 -1
  277. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DzguNppy.js +0 -1
  278. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DzguNppy.js +0 -1
  279. package/dist/worker/console/static/assets/index-24jp3aBh.js +0 -468
  280. package/dist/worker/console/static/assets/index-CY6y6I8M.css +0 -1
  281. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BABVQnfM.js +0 -1
  282. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D0qsLaxR.js +0 -8
  283. package/dist/worker/scheduler/index.js +0 -25
  284. package/dist/workflows/dag/facts.js +0 -4
  285. package/dist/workflows/dag/frontend-shadow-dual-write.js +0 -975
  286. package/dist/workflows/dag/index.js +0 -6
  287. package/dist/workflows/dynamic/index.js +0 -7
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Session-independent Playwright browser tools shared by workflow and Pi chat
3
+ * modes. Actions use refs from the AI-mode aria snapshot and return a fresh
4
+ * snapshot. Screenshots are captured only by the explicit screenshot tool.
5
+ */
6
+ const BROWSER_TOOLS_DESCRIPTION = "Operate the workspace-controlled visible external browser. The Console sidebar stays an iframe and does not proxy page input. `browser_navigate` opens a URL in the external window; `browser_snapshot` returns the current aria snapshot with element refs; `browser_act` clicks/fills/presses/hovers a ref; `browser_search` fills and submits the real search form; `browser_tabs`, `browser_scroll`, `browser_press`, `browser_dialog`, `browser_wait`, and `browser_screenshot` manage state. Use refs only from the immediately preceding snapshot. It never edits workspace files and does not execute page JavaScript.";
7
+ export async function buildBrowserTools(options) {
8
+ const [{ Type }, { defineTool }] = await Promise.all([
9
+ import("typebox"),
10
+ import("@earendil-works/pi-coding-agent"),
11
+ ]);
12
+ const automation = options.automation;
13
+ const urlParameter = Type.String({
14
+ description: "Absolute http(s) URL.",
15
+ });
16
+ const refParameter = Type.String({
17
+ description: "Element ref from the most recent browser_snapshot (for example e12).",
18
+ });
19
+ async function execute(operation) {
20
+ try {
21
+ const result = await operation();
22
+ return {
23
+ content: [{ type: "text", text: JSON.stringify(result) }],
24
+ details: result,
25
+ };
26
+ }
27
+ catch (error) {
28
+ const payload = {
29
+ error: error instanceof Error ? error.message : String(error),
30
+ code: error instanceof Error && "code" in error
31
+ ? String(error.code)
32
+ : "BROWSER_OPERATION_FAILED",
33
+ };
34
+ return {
35
+ content: [{ type: "text", text: JSON.stringify(payload) }],
36
+ details: payload,
37
+ };
38
+ }
39
+ }
40
+ return [
41
+ defineTool({
42
+ name: "browser_navigate",
43
+ label: "Browser navigate",
44
+ description: BROWSER_TOOLS_DESCRIPTION,
45
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
46
+ parameters: Type.Object({ url: urlParameter }, { additionalProperties: false }),
47
+ async execute(_toolCallId, params) {
48
+ return execute(() => automation.navigate(params.url));
49
+ },
50
+ }),
51
+ defineTool({
52
+ name: "browser_search",
53
+ label: "Browser search",
54
+ description: BROWSER_TOOLS_DESCRIPTION,
55
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
56
+ parameters: Type.Object({
57
+ query: Type.String({ description: "Search query." }),
58
+ engineUrl: Type.Optional(urlParameter),
59
+ }, { additionalProperties: false }),
60
+ async execute(_toolCallId, params) {
61
+ return execute(() => automation.search(params.query, params.engineUrl));
62
+ },
63
+ }),
64
+ defineTool({
65
+ name: "browser_snapshot",
66
+ label: "Browser snapshot",
67
+ description: BROWSER_TOOLS_DESCRIPTION,
68
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
69
+ parameters: Type.Object({}, { additionalProperties: false }),
70
+ async execute() {
71
+ return execute(() => automation.snapshot({ screenshot: false }));
72
+ },
73
+ }),
74
+ defineTool({
75
+ name: "browser_act",
76
+ label: "Browser act",
77
+ description: BROWSER_TOOLS_DESCRIPTION,
78
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
79
+ parameters: Type.Object({
80
+ type: Type.Union([
81
+ Type.Literal("click"),
82
+ Type.Literal("fill"),
83
+ Type.Literal("press"),
84
+ Type.Literal("hover"),
85
+ ]),
86
+ ref: refParameter,
87
+ value: Type.Optional(Type.String()),
88
+ key: Type.Optional(Type.String()),
89
+ }, { additionalProperties: false }),
90
+ async execute(_toolCallId, params) {
91
+ return execute(() => automation.act(params.type === "fill"
92
+ ? { type: "fill", ref: params.ref, value: params.value ?? "" }
93
+ : params.type === "press"
94
+ ? { type: "press", ref: params.ref, key: params.key ?? "Enter" }
95
+ : { type: params.type, ref: params.ref }));
96
+ },
97
+ }),
98
+ defineTool({
99
+ name: "browser_tabs",
100
+ label: "Browser tabs",
101
+ description: BROWSER_TOOLS_DESCRIPTION,
102
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
103
+ parameters: Type.Object({
104
+ action: Type.Union([
105
+ Type.Literal("list"),
106
+ Type.Literal("new"),
107
+ Type.Literal("select"),
108
+ Type.Literal("close"),
109
+ ]),
110
+ tabId: Type.Optional(Type.Integer()),
111
+ url: Type.Optional(urlParameter),
112
+ }, { additionalProperties: false }),
113
+ async execute(_toolCallId, params) {
114
+ return execute(() => {
115
+ if (params.action === "list")
116
+ return automation.snapshot({ screenshot: false });
117
+ if (params.action === "new")
118
+ return automation.newTab(params.url);
119
+ if (params.tabId === undefined)
120
+ throw new Error("tabId is required");
121
+ return params.action === "select"
122
+ ? automation.selectTab(params.tabId)
123
+ : automation.closeTab(params.tabId);
124
+ });
125
+ },
126
+ }),
127
+ defineTool({
128
+ name: "browser_scroll",
129
+ label: "Browser scroll",
130
+ description: BROWSER_TOOLS_DESCRIPTION,
131
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
132
+ parameters: Type.Object({
133
+ direction: Type.Union([Type.Literal("up"), Type.Literal("down")]),
134
+ amount: Type.Optional(Type.Integer({ minimum: 50, maximum: 3000 })),
135
+ }, { additionalProperties: false }),
136
+ async execute(_toolCallId, params) {
137
+ return execute(() => automation.scroll(params));
138
+ },
139
+ }),
140
+ defineTool({
141
+ name: "browser_press",
142
+ label: "Browser press key",
143
+ description: BROWSER_TOOLS_DESCRIPTION,
144
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
145
+ parameters: Type.Object({ key: Type.String() }, { additionalProperties: false }),
146
+ async execute(_toolCallId, params) {
147
+ return execute(() => automation.pressKey(params.key));
148
+ },
149
+ }),
150
+ defineTool({
151
+ name: "browser_dialog",
152
+ label: "Browser dialog",
153
+ description: BROWSER_TOOLS_DESCRIPTION,
154
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
155
+ parameters: Type.Object({
156
+ action: Type.Union([Type.Literal("accept"), Type.Literal("dismiss")]),
157
+ promptText: Type.Optional(Type.String()),
158
+ }, { additionalProperties: false }),
159
+ async execute(_toolCallId, params) {
160
+ return execute(() => automation.handleDialog(params.action, params.promptText));
161
+ },
162
+ }),
163
+ defineTool({
164
+ name: "browser_wait",
165
+ label: "Browser wait",
166
+ description: BROWSER_TOOLS_DESCRIPTION,
167
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
168
+ parameters: Type.Object({ ms: Type.Integer({ minimum: 0, maximum: 10_000 }) }, { additionalProperties: false }),
169
+ async execute(_toolCallId, params) {
170
+ return execute(() => automation.waitFor(params.ms));
171
+ },
172
+ }),
173
+ defineTool({
174
+ name: "browser_screenshot",
175
+ label: "Browser screenshot",
176
+ description: BROWSER_TOOLS_DESCRIPTION,
177
+ promptSnippet: BROWSER_TOOLS_DESCRIPTION,
178
+ parameters: Type.Object({}, { additionalProperties: false }),
179
+ async execute() {
180
+ return execute(() => automation.screenshot());
181
+ },
182
+ }),
183
+ ];
184
+ }
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Session-less safe explore custom tools (safe-read / safe-grep / git-status /
3
+ * git-diff). Execution uses explore-tools.ts path guards and secret scrubbing.
4
+ * ConsolePiRuntime owns the sessionless cache.
5
+ */
6
+ /**
7
+ * Build the safe explore custom tools (roadmap M0-A / G16): safe-read,
8
+ * safe-grep, gitStatus, gitDiff. These replace the bare SDK bash/read/grep so
9
+ * the model can probe the repo WITHOUT write escapes (echo redirect, tee,
10
+ * sed -i, node -e) and WITHOUT reading sensitive files (env files, key/pem,
11
+ * auth.json, sessions dir) — and every returned byte is secret-scrubbed
12
+ * before reaching the model context.
13
+ *
14
+ * gitStatus/gitDiff use a FIXED argv (typed, no shell) so they cannot be
15
+ * turned into an arbitrary-shell vector.
16
+ */
17
+ export async function buildExploreCustomTools(options) {
18
+ const [{ Type }, { defineTool }] = await Promise.all([
19
+ import("typebox"),
20
+ import("@earendil-works/pi-coding-agent"),
21
+ ]);
22
+ const { execFileSync } = await import("node:child_process");
23
+ const repoRoot = options.repoRoot;
24
+ const { safeReadFile, safeGrep, scrubSecrets } = await import("../../explore-tools.js");
25
+ function safeGit(args) {
26
+ try {
27
+ const stdout = execFileSync("git", args, {
28
+ cwd: repoRoot,
29
+ encoding: "utf8",
30
+ // Fixed argv, no shell, bounded output.
31
+ maxBuffer: 512 * 1024,
32
+ timeout: 10_000,
33
+ windowsHide: true,
34
+ });
35
+ return { ok: true, stdout };
36
+ }
37
+ catch (e) {
38
+ return {
39
+ ok: false,
40
+ code: "GIT_FAILED",
41
+ message: e instanceof Error ? e.message : String(e),
42
+ };
43
+ }
44
+ }
45
+ const safeReadTool = defineTool({
46
+ name: "safe-read",
47
+ label: "safe-read",
48
+ description: "Read a repo-relative file with sensitive-file denylist (.env*/*.key/*.pem/.git/**/auth.json/sessions/**) and secret scrubbing. Absolute paths and .. are rejected.",
49
+ promptSnippet: "safe-read: read a repo file (safe; secrets scrubbed)",
50
+ parameters: Type.Object({
51
+ path: Type.String({ description: "repo-relative file path" }),
52
+ }, { additionalProperties: false }),
53
+ async execute(_toolCallId, params) {
54
+ const raw = String(params.path ?? "");
55
+ try {
56
+ const result = await safeReadFile(repoRoot, raw);
57
+ return {
58
+ content: [{ type: "text", text: JSON.stringify(result) }],
59
+ details: result,
60
+ };
61
+ }
62
+ catch (e) {
63
+ const err = e;
64
+ return {
65
+ content: [
66
+ {
67
+ type: "text",
68
+ text: JSON.stringify({
69
+ error: err.message ?? String(e),
70
+ code: err.code ?? "READ_FAILED",
71
+ }),
72
+ },
73
+ ],
74
+ details: {
75
+ error: err.message ?? String(e),
76
+ code: err.code ?? "READ_FAILED",
77
+ },
78
+ };
79
+ }
80
+ },
81
+ });
82
+ const safeGrepTool = defineTool({
83
+ name: "safe-grep",
84
+ label: "safe-grep",
85
+ description: "Line search across the repo working tree with sensitive-file denylist and secret scrubbing. pattern is a JS regex source; optional glob filters paths.",
86
+ promptSnippet: "safe-grep: search repo files (safe; secrets scrubbed)",
87
+ parameters: Type.Object({
88
+ pattern: Type.String({ description: "regex source (no shell)" }),
89
+ caseInsensitive: Type.Optional(Type.Boolean()),
90
+ glob: Type.Optional(Type.String({ description: "optional glob filter e.g. *.ts" })),
91
+ }, { additionalProperties: false }),
92
+ async execute(_toolCallId, params) {
93
+ try {
94
+ const result = await safeGrep(repoRoot, String(params.pattern ?? ""), {
95
+ caseInsensitive: Boolean(params.caseInsensitive),
96
+ glob: params.glob ? String(params.glob) : undefined,
97
+ });
98
+ return {
99
+ content: [{ type: "text", text: JSON.stringify(result) }],
100
+ details: result,
101
+ };
102
+ }
103
+ catch (e) {
104
+ const err = e;
105
+ return {
106
+ content: [
107
+ {
108
+ type: "text",
109
+ text: JSON.stringify({
110
+ error: err.message ?? String(e),
111
+ code: err.code ?? "GREP_FAILED",
112
+ }),
113
+ },
114
+ ],
115
+ details: {
116
+ error: err.message ?? String(e),
117
+ code: err.code ?? "GREP_FAILED",
118
+ },
119
+ };
120
+ }
121
+ },
122
+ });
123
+ const gitStatusTool = defineTool({
124
+ name: "git-status",
125
+ label: "git-status",
126
+ description: "Typed `git status --porcelain` (fixed argv, no shell). Returns scrubbed working-tree status.",
127
+ promptSnippet: "git-status: working tree status (read-only)",
128
+ parameters: Type.Object({}, { additionalProperties: false }),
129
+ async execute() {
130
+ const r = safeGit(["status", "--porcelain"]);
131
+ if (!r.ok) {
132
+ return {
133
+ content: [
134
+ {
135
+ type: "text",
136
+ text: JSON.stringify({ error: r.message, code: r.code }),
137
+ },
138
+ ],
139
+ details: { error: r.message, code: r.code },
140
+ };
141
+ }
142
+ const { scrubbed, redactions } = scrubSecrets(r.stdout);
143
+ const payload = { status: scrubbed, redactions };
144
+ return {
145
+ content: [{ type: "text", text: JSON.stringify(payload) }],
146
+ details: payload,
147
+ };
148
+ },
149
+ });
150
+ const gitDiffTool = defineTool({
151
+ name: "git-diff",
152
+ label: "git-diff",
153
+ description: "Typed `git diff` (fixed argv: --stat or a single -- path; no shell). Returns scrubbed diff. path must be repo-relative and not sensitive.",
154
+ promptSnippet: "git-diff: diff (read-only, scrubbed)",
155
+ parameters: Type.Object({
156
+ path: Type.Optional(Type.String({
157
+ description: "optional repo-relative path to diff (default: whole tree --stat)",
158
+ })),
159
+ }, { additionalProperties: false }),
160
+ async execute(_toolCallId, params) {
161
+ let rawPath = params.path ? String(params.path) : undefined;
162
+ // If a path is supplied, validate it via the read-path guard so git diff
163
+ // cannot be aimed at sensitive files (.env* / auth.json / sessions).
164
+ if (rawPath) {
165
+ const { guardReadPath } = await import("../../explore-tools.js");
166
+ const g = await guardReadPath(repoRoot, rawPath);
167
+ if (!g.ok) {
168
+ return {
169
+ content: [
170
+ {
171
+ type: "text",
172
+ text: JSON.stringify({ error: g.message, code: g.code }),
173
+ },
174
+ ],
175
+ details: { error: g.message, code: g.code },
176
+ };
177
+ }
178
+ rawPath = g.repoRelative;
179
+ }
180
+ const args = rawPath ? ["diff", "--", rawPath] : ["diff", "--stat"];
181
+ const r = safeGit(args);
182
+ if (!r.ok) {
183
+ return {
184
+ content: [
185
+ {
186
+ type: "text",
187
+ text: JSON.stringify({ error: r.message, code: r.code }),
188
+ },
189
+ ],
190
+ details: { error: r.message, code: r.code },
191
+ };
192
+ }
193
+ const { scrubbed, redactions } = scrubSecrets(r.stdout);
194
+ const payload = { diff: scrubbed, redactions };
195
+ return {
196
+ content: [{ type: "text", text: JSON.stringify(payload) }],
197
+ details: payload,
198
+ };
199
+ },
200
+ });
201
+ return [safeReadTool, safeGrepTool, gitStatusTool, gitDiffTool];
202
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Session-bound Goal tools (shared by workflow and Pi modes since
3
+ * 2026-09-10; see exec-plan 2026-09-10-console-chat-goal-for-pi-mode).
4
+ * create_goal still requires a consumed model-create grant from the registry.
5
+ */
6
+ const GET_GOAL_DESCRIPTION = "Read the current session's durable cross-turn Goal, including revision, status, round limit, and whether this Console process is authorized to continue it.";
7
+ const CREATE_GOAL_DESCRIPTION = "Create a durable cross-turn Goal only when the user explicitly asks to start or create a Goal. Never silently upgrade an ordinary request. A session may have only one unfinished Goal.";
8
+ const UPDATE_GOAL_DESCRIPTION = "Finish or block the current durable Goal using its exact goalId and revision. Set complete only when the objective is genuinely achieved and no required work remains. Set blocked only when safe progress cannot continue; include the blocker.";
9
+ export async function buildGoalTools(options) {
10
+ const [{ Type }, { defineTool }] = await Promise.all([
11
+ import("typebox"),
12
+ import("@earendil-works/pi-coding-agent"),
13
+ ]);
14
+ const textResult = (value) => ({
15
+ content: [{ type: "text", text: JSON.stringify(value) }],
16
+ details: value,
17
+ });
18
+ return [
19
+ defineTool({
20
+ name: "get_goal",
21
+ label: "Get goal",
22
+ description: GET_GOAL_DESCRIPTION,
23
+ promptSnippet: GET_GOAL_DESCRIPTION,
24
+ parameters: Type.Object({}, { additionalProperties: false }),
25
+ async execute() {
26
+ return textResult({ goal: options.registry.get(options.sessionId) });
27
+ },
28
+ }),
29
+ defineTool({
30
+ name: "create_goal",
31
+ label: "Create goal",
32
+ description: CREATE_GOAL_DESCRIPTION,
33
+ promptSnippet: CREATE_GOAL_DESCRIPTION,
34
+ parameters: Type.Object({
35
+ objective: Type.String({
36
+ description: "Concrete final objective and completion standard explicitly requested by the user.",
37
+ }),
38
+ }, { additionalProperties: false }),
39
+ async execute(_toolCallId, params) {
40
+ if (!options.registry.consumeModelCreateGrant(options.sessionId)) {
41
+ return textResult({
42
+ ok: false,
43
+ code: "GOAL_EXPLICIT_REQUEST_REQUIRED",
44
+ message: "create_goal requires an explicit user request to create or start a Goal",
45
+ });
46
+ }
47
+ return textResult(options.registry.create({
48
+ sessionId: options.sessionId,
49
+ objective: params.objective,
50
+ }));
51
+ },
52
+ }),
53
+ defineTool({
54
+ name: "update_goal",
55
+ label: "Update goal",
56
+ description: UPDATE_GOAL_DESCRIPTION,
57
+ promptSnippet: UPDATE_GOAL_DESCRIPTION,
58
+ parameters: Type.Object({
59
+ goalId: Type.String(),
60
+ revision: Type.Number({ minimum: 1 }),
61
+ status: Type.Union([
62
+ Type.Literal("complete"),
63
+ Type.Literal("blocked"),
64
+ ]),
65
+ blocker: Type.Optional(Type.String()),
66
+ }, { additionalProperties: false }),
67
+ async execute(_toolCallId, params) {
68
+ return textResult(options.registry.update({
69
+ sessionId: options.sessionId,
70
+ goalId: params.goalId,
71
+ expectedRevision: params.revision,
72
+ phase: params.status,
73
+ blocker: params.blocker,
74
+ arm: false,
75
+ }));
76
+ },
77
+ }),
78
+ ];
79
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Session-less operator-action custom tools (workflow-mode business tools).
3
+ * Definitions and execute() live here; ConsolePiRuntime owns caching and
4
+ * composition with session-bound tools.
5
+ */
6
+ import { zodToJsonSchema } from "zod-to-json-schema";
7
+ import { scheduledGoalBookingSchema } from "../../scheduled-goal-booking.js";
8
+ import { authorizeChatSessionTool, DEFAULT_CONSOLE_CHAT_SESSION_MODE, } from "../../session-mode.js";
9
+ import { buildModelCallableToolSchemas } from "../../tool-adapter.js";
10
+ /**
11
+ * Build Pi custom ToolDefinition objects for every whitelisted operator action.
12
+ * Each tool's execute() routes into the operator action dispatcher (Gate 3).
13
+ * Requires the `typebox` + `defineTool` packages (both bundled with the SDK).
14
+ */
15
+ export async function buildCustomOperatorTools(options) {
16
+ // typebox is a transitive dep of @earendil-works/pi-coding-agent; Node's
17
+ // resolver hoists to the SDK's nested copy. defineTool is re-exported by SDK.
18
+ const [{ Type }, { defineTool }] = await Promise.all([
19
+ import("typebox"),
20
+ import("@earendil-works/pi-coding-agent"),
21
+ ]);
22
+ const schemas = buildModelCallableToolSchemas().filter((schema) => schema.toolId !== "prepareScheduledTask");
23
+ const ctx = options.actionContext;
24
+ return schemas.map((schema) => {
25
+ // TypeBox schema is built dynamically; cast through unknown to the builder
26
+ // since Static<TParams> is structural and cannot be statically inferred here.
27
+ const parameters = Type.Object(schema.inputParams.reduce((acc, param) => {
28
+ // Carry the registry's param description into the tool schema so
29
+ // the model sees parameter semantics, not just names/types.
30
+ const desc = param.description?.trim()
31
+ ? { description: param.description }
32
+ : {};
33
+ let t;
34
+ if (schema.toolId === "prepareScheduledGoal" && param.name === "booking") {
35
+ // Provider adapters need every nested type (not an opaque object).
36
+ // Keep the strict service schema as the single input contract.
37
+ t = zodToJsonSchema(scheduledGoalBookingSchema, { $refStrategy: "none" });
38
+ }
39
+ else
40
+ switch (param.type) {
41
+ case "string":
42
+ t = Type.String(desc);
43
+ break;
44
+ case "boolean":
45
+ t = Type.Boolean(desc);
46
+ break;
47
+ case "number":
48
+ t = Type.Number(desc);
49
+ break;
50
+ case "array":
51
+ t = Type.Array(Type.String({}), Object.keys(desc).length ? desc : {});
52
+ break;
53
+ default:
54
+ t = Type.Object({}, { additionalProperties: true });
55
+ }
56
+ acc[param.name] = param.required ? t : Type.Optional(t);
57
+ return acc;
58
+ }, {}), { additionalProperties: false });
59
+ return defineTool({
60
+ name: schema.toolId,
61
+ label: schema.toolId,
62
+ description: `${schema.description} (kind=${schema.kind}; cli: ${schema.cli})`,
63
+ promptSnippet: schema.description,
64
+ parameters: parameters,
65
+ async execute(toolCallId, params) {
66
+ const decision = authorizeChatSessionTool(schema.toolId, options.sessionMode ?? DEFAULT_CONSOLE_CHAT_SESSION_MODE);
67
+ if (!decision.ok) {
68
+ return {
69
+ content: [
70
+ {
71
+ type: "text",
72
+ text: JSON.stringify({
73
+ error: decision.message,
74
+ code: decision.code,
75
+ }),
76
+ },
77
+ ],
78
+ details: { error: decision.message, code: decision.code },
79
+ };
80
+ }
81
+ // Defer require to avoid circular import at module load.
82
+ const { dispatchChatToolCall } = await import("../../session-store.js");
83
+ const result = await dispatchChatToolCall(ctx, decision.toolId, params, toolCallId, options.sessionMode);
84
+ const payload = result.ok
85
+ ? result.result
86
+ : { error: result.message, code: result.errorCode };
87
+ return {
88
+ content: [{ type: "text", text: JSON.stringify(payload) }],
89
+ details: payload,
90
+ };
91
+ },
92
+ });
93
+ });
94
+ }
@@ -0,0 +1,22 @@
1
+ import { zodToJsonSchema } from "zod-to-json-schema";
2
+ import { scheduledTaskRequestSchema } from "../../scheduled-goal-request.js";
3
+ import { buildModelCallableToolSchemas } from "../../tool-adapter.js";
4
+ /** Host-bound identity is not a model parameter and cannot leak across sessions. */
5
+ export async function buildScheduledGoalTools(options) {
6
+ const { Type } = await import("typebox");
7
+ const { defineTool } = await import("@earendil-works/pi-coding-agent");
8
+ const schema = buildModelCallableToolSchemas().find((tool) => tool.action === "prepareScheduledTask");
9
+ if (!schema)
10
+ throw new Error("scheduled task capability missing");
11
+ return [defineTool({
12
+ name: schema.toolId, label: "准备定时任务", description: schema.description, promptSnippet: schema.description,
13
+ parameters: Type.Object({ request: zodToJsonSchema(scheduledTaskRequestSchema, { $refStrategy: "none" }) }, { additionalProperties: false }),
14
+ async execute(callId, params) {
15
+ const { dispatchChatToolCall } = await import("../../session-store.js");
16
+ const result = await dispatchChatToolCall({ ...options.actionContext, chatSessionRef: options.sessionId }, schema.toolId, params, callId, "workflow");
17
+ const value = result.ok ? result.result : { ok: false, error: result.message, code: result.errorCode,
18
+ nextAction: "Correct the business request and retry prepareScheduledTask. Do not edit PRD/runtime files, substitute sleep/immediate execution, or claim a booking exists." };
19
+ return { isError: !result.ok, content: [{ type: "text", text: JSON.stringify(value) }], details: value };
20
+ },
21
+ })];
22
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Session-bound todo_write custom tool.
3
+ * Description is mode-aware; ConsolePiRuntime owns when to register it.
4
+ */
5
+ import { PI_TODO_WRITE_DESCRIPTION, } from "../../session-mode.js";
6
+ const TODO_WRITE_DESCRIPTION = "Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (no partial updates, no per-item edits). Before starting multi-step work, add one todo per concrete step. Keep at least one todo `in_progress` while work remains. Mark a todo `completed` immediately when it is done (do not batch completions) and resend the full list as progress or DAG state advances. Skip the list for simple Q&A, read-only lookups, and single-step tasks. Use it for multi-step implementation and whenever you prepare, run, or supervise a DAG — call `todo_write` before entering the DAG tool chain. Phrase DAG todos as user-facing phases users can understand, not copies of internal DAG nodes. Statuses: `pending` / `in_progress` / `completed`.";
7
+ export async function buildTodoWriteTool(options) {
8
+ const [{ Type }, { defineTool }] = await Promise.all([
9
+ import("typebox"),
10
+ import("@earendil-works/pi-coding-agent"),
11
+ ]);
12
+ const description = options.sessionMode === "pi"
13
+ ? PI_TODO_WRITE_DESCRIPTION
14
+ : TODO_WRITE_DESCRIPTION;
15
+ return defineTool({
16
+ name: "todo_write",
17
+ label: "Update todo list",
18
+ description,
19
+ promptSnippet: description,
20
+ parameters: Type.Object({
21
+ todos: Type.Array(Type.Object({
22
+ content: Type.String({ description: "Short imperative task description." }),
23
+ status: Type.Union([
24
+ Type.Literal("pending"),
25
+ Type.Literal("in_progress"),
26
+ Type.Literal("completed"),
27
+ ]),
28
+ }, { additionalProperties: false })),
29
+ }, { additionalProperties: false }),
30
+ async execute(toolCallId, params) {
31
+ const result = options.registry.write(options.sessionId, toolCallId, params.todos);
32
+ return {
33
+ content: [{ type: "text", text: JSON.stringify(result) }],
34
+ details: result,
35
+ };
36
+ },
37
+ });
38
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Live runtime snapshot types and the structured critical-failure error.
3
+ * Projection and inventory collection live in inspection.ts; ConsolePiRuntime
4
+ * remains the owner of live session lookup and preference-cache refresh.
5
+ */
6
+ export const THINKING_LEVELS = [
7
+ "off",
8
+ "minimal",
9
+ "low",
10
+ "medium",
11
+ "high",
12
+ "xhigh",
13
+ "max",
14
+ ];
15
+ /**
16
+ * Structured critical-failure error for snapshot projection (RF-02). Model
17
+ * enumeration or system prompt projection failures throw this so consuming
18
+ * routes can return 503 PI_RUNTIME_UNAVAILABLE instead of a fake-empty 200.
19
+ * Partial ResourceLoader / package-inventory failures are NOT critical — they
20
+ * keep the 200 snapshot and surface as structured diagnostics instead.
21
+ */
22
+ export class RuntimeSnapshotUnavailableError extends Error {
23
+ code = "PI_RUNTIME_UNAVAILABLE";
24
+ constructor(message) {
25
+ super(message);
26
+ this.name = "RuntimeSnapshotUnavailableError";
27
+ }
28
+ }