@caupulican/pi-adaptative 0.81.39 → 0.81.40

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 (667) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +2 -0
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +2 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +2 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +3 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +9 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +290 -107
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +357 -122
  13. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +2 -2
  14. package/dist/cli/args.d.ts +2 -0
  15. package/dist/cli/args.d.ts.map +1 -1
  16. package/dist/cli/args.js +9 -0
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/core/agent-directory-layout.d.ts +15 -0
  19. package/dist/core/agent-directory-layout.d.ts.map +1 -0
  20. package/dist/core/agent-directory-layout.js +72 -0
  21. package/dist/core/agent-directory-layout.js.map +1 -0
  22. package/dist/core/agent-paths.d.ts +19 -2
  23. package/dist/core/agent-paths.d.ts.map +1 -1
  24. package/dist/core/agent-paths.js +67 -4
  25. package/dist/core/agent-paths.js.map +1 -1
  26. package/dist/core/agent-session-runtime.d.ts +52 -8
  27. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  28. package/dist/core/agent-session-runtime.js +397 -79
  29. package/dist/core/agent-session-runtime.js.map +1 -1
  30. package/dist/core/agent-session-services.d.ts +1 -0
  31. package/dist/core/agent-session-services.d.ts.map +1 -1
  32. package/dist/core/agent-session-services.js +1 -0
  33. package/dist/core/agent-session-services.js.map +1 -1
  34. package/dist/core/agent-session.d.ts +71 -136
  35. package/dist/core/agent-session.d.ts.map +1 -1
  36. package/dist/core/agent-session.js +477 -1318
  37. package/dist/core/agent-session.js.map +1 -1
  38. package/dist/core/autonomy/approval-gate.d.ts +3 -2
  39. package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
  40. package/dist/core/autonomy/approval-gate.js +6 -28
  41. package/dist/core/autonomy/approval-gate.js.map +1 -1
  42. package/dist/core/autonomy/bounded-completion.d.ts +1 -1
  43. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  44. package/dist/core/autonomy/bounded-completion.js +1 -1
  45. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  46. package/dist/core/autonomy/contracts.d.ts +20 -12
  47. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  48. package/dist/core/autonomy/contracts.js.map +1 -1
  49. package/dist/core/autonomy/foreground-envelope.d.ts +8 -2
  50. package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
  51. package/dist/core/autonomy/foreground-envelope.js +8 -25
  52. package/dist/core/autonomy/foreground-envelope.js.map +1 -1
  53. package/dist/core/autonomy/gates.d.ts.map +1 -1
  54. package/dist/core/autonomy/gates.js +8 -10
  55. package/dist/core/autonomy/gates.js.map +1 -1
  56. package/dist/core/autonomy/lane-private-paths.d.ts +2 -0
  57. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -0
  58. package/dist/core/autonomy/lane-private-paths.js +16 -0
  59. package/dist/core/autonomy/lane-private-paths.js.map +1 -0
  60. package/dist/core/autonomy/lane-tool-surface.d.ts +10 -0
  61. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  62. package/dist/core/autonomy/lane-tool-surface.js +46 -8
  63. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  64. package/dist/core/autonomy/lane-tracker.d.ts +14 -0
  65. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  66. package/dist/core/autonomy/lane-tracker.js +38 -0
  67. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  68. package/dist/core/autonomy/risk-assessment.d.ts +1 -2
  69. package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
  70. package/dist/core/autonomy/risk-assessment.js +1 -123
  71. package/dist/core/autonomy/risk-assessment.js.map +1 -1
  72. package/dist/core/autonomy/session-lane-record.d.ts +4 -4
  73. package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
  74. package/dist/core/autonomy/session-lane-record.js +16 -29
  75. package/dist/core/autonomy/session-lane-record.js.map +1 -1
  76. package/dist/core/autonomy/telemetry-events.d.ts +1 -1
  77. package/dist/core/autonomy/telemetry-events.d.ts.map +1 -1
  78. package/dist/core/autonomy/telemetry-events.js +1 -1
  79. package/dist/core/autonomy/telemetry-events.js.map +1 -1
  80. package/dist/core/autonomy-telemetry.d.ts +7 -7
  81. package/dist/core/autonomy-telemetry.d.ts.map +1 -1
  82. package/dist/core/autonomy-telemetry.js +9 -9
  83. package/dist/core/autonomy-telemetry.js.map +1 -1
  84. package/dist/core/background-lane-controller.d.ts +54 -236
  85. package/dist/core/background-lane-controller.d.ts.map +1 -1
  86. package/dist/core/background-lane-controller.js +140 -1273
  87. package/dist/core/background-lane-controller.js.map +1 -1
  88. package/dist/core/capability-contract.d.ts +4 -0
  89. package/dist/core/capability-contract.d.ts.map +1 -0
  90. package/dist/core/capability-contract.js +28 -0
  91. package/dist/core/capability-contract.js.map +1 -0
  92. package/dist/core/compaction-controller.d.ts +90 -0
  93. package/dist/core/compaction-controller.d.ts.map +1 -0
  94. package/dist/core/compaction-controller.js +452 -0
  95. package/dist/core/compaction-controller.js.map +1 -0
  96. package/dist/core/compaction-support.d.ts +12 -11
  97. package/dist/core/compaction-support.d.ts.map +1 -1
  98. package/dist/core/compaction-support.js.map +1 -1
  99. package/dist/core/context/context-artifacts.d.ts +6 -2
  100. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  101. package/dist/core/context/context-artifacts.js +34 -2
  102. package/dist/core/context/context-artifacts.js.map +1 -1
  103. package/dist/core/context/context-store-retention.d.ts +8 -2
  104. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  105. package/dist/core/context/context-store-retention.js +158 -35
  106. package/dist/core/context/context-store-retention.js.map +1 -1
  107. package/dist/core/context/okf-memory.d.ts.map +1 -1
  108. package/dist/core/context/okf-memory.js +9 -11
  109. package/dist/core/context/okf-memory.js.map +1 -1
  110. package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
  111. package/dist/core/context/sqlite-runtime-index.js +6 -8
  112. package/dist/core/context/sqlite-runtime-index.js.map +1 -1
  113. package/dist/core/context-gc.d.ts +3 -0
  114. package/dist/core/context-gc.d.ts.map +1 -1
  115. package/dist/core/context-gc.js +10 -5
  116. package/dist/core/context-gc.js.map +1 -1
  117. package/dist/core/context-pipeline.d.ts.map +1 -1
  118. package/dist/core/context-pipeline.js +9 -4
  119. package/dist/core/context-pipeline.js.map +1 -1
  120. package/dist/core/default-tool-surface.d.ts.map +1 -1
  121. package/dist/core/default-tool-surface.js +1 -0
  122. package/dist/core/default-tool-surface.js.map +1 -1
  123. package/dist/core/delegation/managed-lane-controller.d.ts +34 -0
  124. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -0
  125. package/dist/core/delegation/managed-lane-controller.js +217 -0
  126. package/dist/core/delegation/managed-lane-controller.js.map +1 -0
  127. package/dist/core/delegation/session-worker-claim.d.ts +44 -0
  128. package/dist/core/delegation/session-worker-claim.d.ts.map +1 -0
  129. package/dist/core/delegation/session-worker-claim.js +98 -0
  130. package/dist/core/delegation/session-worker-claim.js.map +1 -0
  131. package/dist/core/delegation/worker-actions.d.ts +7 -5
  132. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  133. package/dist/core/delegation/worker-actions.js +20 -4
  134. package/dist/core/delegation/worker-actions.js.map +1 -1
  135. package/dist/core/delegation/{worker-result.d.ts → worker-claim.d.ts} +13 -13
  136. package/dist/core/delegation/worker-claim.d.ts.map +1 -0
  137. package/dist/core/delegation/{worker-result.js → worker-claim.js} +61 -51
  138. package/dist/core/delegation/worker-claim.js.map +1 -0
  139. package/dist/core/delegation/worker-delegation-controller.d.ts +110 -0
  140. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -0
  141. package/dist/core/delegation/worker-delegation-controller.js +861 -0
  142. package/dist/core/delegation/worker-delegation-controller.js.map +1 -0
  143. package/dist/core/delegation/worker-delegation-request.d.ts +11 -0
  144. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -0
  145. package/dist/core/delegation/worker-delegation-request.js +2 -0
  146. package/dist/core/delegation/worker-delegation-request.js.map +1 -0
  147. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +40 -0
  148. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -0
  149. package/dist/core/delegation/worker-dispatch-scheduler.js +93 -0
  150. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -0
  151. package/dist/core/delegation/worker-execution-policy.d.ts +62 -0
  152. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -0
  153. package/dist/core/delegation/worker-execution-policy.js +160 -0
  154. package/dist/core/delegation/worker-execution-policy.js.map +1 -0
  155. package/dist/core/delegation/worker-lane-projection.d.ts +14 -0
  156. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -0
  157. package/dist/core/delegation/worker-lane-projection.js +100 -0
  158. package/dist/core/delegation/worker-lane-projection.js.map +1 -0
  159. package/dist/core/delegation/worker-lifecycle.d.ts +97 -0
  160. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -0
  161. package/dist/core/delegation/worker-lifecycle.js +339 -0
  162. package/dist/core/delegation/worker-lifecycle.js.map +1 -0
  163. package/dist/core/delegation/worker-notification-coordinator.d.ts +36 -0
  164. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -0
  165. package/dist/core/delegation/worker-notification-coordinator.js +90 -0
  166. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -0
  167. package/dist/core/delegation/worker-profile-resolver.d.ts +55 -0
  168. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -0
  169. package/dist/core/delegation/worker-profile-resolver.js +113 -0
  170. package/dist/core/delegation/worker-profile-resolver.js.map +1 -0
  171. package/dist/core/delegation/worker-runner.d.ts +25 -14
  172. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  173. package/dist/core/delegation/worker-runner.js +122 -53
  174. package/dist/core/delegation/worker-runner.js.map +1 -1
  175. package/dist/core/delegation/worker-task-label.d.ts +3 -0
  176. package/dist/core/delegation/worker-task-label.d.ts.map +1 -0
  177. package/dist/core/delegation/worker-task-label.js +11 -0
  178. package/dist/core/delegation/worker-task-label.js.map +1 -0
  179. package/dist/core/doctor.d.ts +8 -0
  180. package/dist/core/doctor.d.ts.map +1 -1
  181. package/dist/core/doctor.js +32 -1
  182. package/dist/core/doctor.js.map +1 -1
  183. package/dist/core/extensions/index.d.ts +1 -1
  184. package/dist/core/extensions/index.d.ts.map +1 -1
  185. package/dist/core/extensions/index.js.map +1 -1
  186. package/dist/core/extensions/loader.d.ts +5 -1
  187. package/dist/core/extensions/loader.d.ts.map +1 -1
  188. package/dist/core/extensions/loader.js +50 -15
  189. package/dist/core/extensions/loader.js.map +1 -1
  190. package/dist/core/extensions/runner.d.ts.map +1 -1
  191. package/dist/core/extensions/runner.js +6 -0
  192. package/dist/core/extensions/runner.js.map +1 -1
  193. package/dist/core/extensions/storage.d.ts +8 -0
  194. package/dist/core/extensions/storage.d.ts.map +1 -0
  195. package/dist/core/extensions/storage.js +28 -0
  196. package/dist/core/extensions/storage.js.map +1 -0
  197. package/dist/core/extensions/types.d.ts +70 -21
  198. package/dist/core/extensions/types.d.ts.map +1 -1
  199. package/dist/core/extensions/types.js.map +1 -1
  200. package/dist/core/failure-corpus.d.ts +1 -15
  201. package/dist/core/failure-corpus.d.ts.map +1 -1
  202. package/dist/core/failure-corpus.js +9 -37
  203. package/dist/core/failure-corpus.js.map +1 -1
  204. package/dist/core/foreground-recovery-controller.d.ts +52 -0
  205. package/dist/core/foreground-recovery-controller.d.ts.map +1 -0
  206. package/dist/core/foreground-recovery-controller.js +111 -0
  207. package/dist/core/foreground-recovery-controller.js.map +1 -0
  208. package/dist/core/gateways/channel-provider.d.ts +3 -0
  209. package/dist/core/gateways/channel-provider.d.ts.map +1 -1
  210. package/dist/core/gateways/channel-provider.js +31 -6
  211. package/dist/core/gateways/channel-provider.js.map +1 -1
  212. package/dist/core/goals/goal-acceptance.d.ts +11 -0
  213. package/dist/core/goals/goal-acceptance.d.ts.map +1 -0
  214. package/dist/core/goals/goal-acceptance.js +25 -0
  215. package/dist/core/goals/goal-acceptance.js.map +1 -0
  216. package/dist/core/goals/goal-auto-continue-controller.d.ts +27 -0
  217. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -0
  218. package/dist/core/goals/goal-auto-continue-controller.js +93 -0
  219. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -0
  220. package/dist/core/goals/goal-continuation-controller.d.ts +1 -1
  221. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  222. package/dist/core/goals/goal-continuation-controller.js +10 -0
  223. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  224. package/dist/core/goals/goal-continuation-prompt.d.ts +1 -1
  225. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  226. package/dist/core/goals/goal-continuation-prompt.js +6 -6
  227. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  228. package/dist/core/goals/goal-lifecycle.d.ts +20 -0
  229. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -0
  230. package/dist/core/goals/goal-lifecycle.js +17 -0
  231. package/dist/core/goals/goal-lifecycle.js.map +1 -0
  232. package/dist/core/goals/goal-runtime-snapshot.d.ts +11 -9
  233. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  234. package/dist/core/goals/goal-runtime-snapshot.js +10 -8
  235. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  236. package/dist/core/goals/goal-state.d.ts +1 -0
  237. package/dist/core/goals/goal-state.d.ts.map +1 -1
  238. package/dist/core/goals/goal-state.js +7 -10
  239. package/dist/core/goals/goal-state.js.map +1 -1
  240. package/dist/core/goals/goal-tool-core.d.ts +8 -6
  241. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  242. package/dist/core/goals/goal-tool-core.js +11 -41
  243. package/dist/core/goals/goal-tool-core.js.map +1 -1
  244. package/dist/core/goals/session-goal-state.d.ts +2 -4
  245. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  246. package/dist/core/goals/session-goal-state.js +10 -33
  247. package/dist/core/goals/session-goal-state.js.map +1 -1
  248. package/dist/core/human-input.d.ts +100 -0
  249. package/dist/core/human-input.d.ts.map +1 -0
  250. package/dist/core/human-input.js +362 -0
  251. package/dist/core/human-input.js.map +1 -0
  252. package/dist/core/index.d.ts +9 -1
  253. package/dist/core/index.d.ts.map +1 -1
  254. package/dist/core/index.js +9 -1
  255. package/dist/core/index.js.map +1 -1
  256. package/dist/core/{telemetry.d.ts → install-telemetry.d.ts} +1 -1
  257. package/dist/core/install-telemetry.d.ts.map +1 -0
  258. package/dist/core/{telemetry.js → install-telemetry.js} +1 -1
  259. package/dist/core/install-telemetry.js.map +1 -0
  260. package/dist/core/keybindings.d.ts +17 -1
  261. package/dist/core/keybindings.d.ts.map +1 -1
  262. package/dist/core/keybindings.js +24 -6
  263. package/dist/core/keybindings.js.map +1 -1
  264. package/dist/core/learning/learning-audit.d.ts +2 -4
  265. package/dist/core/learning/learning-audit.d.ts.map +1 -1
  266. package/dist/core/learning/learning-audit.js +9 -29
  267. package/dist/core/learning/learning-audit.js.map +1 -1
  268. package/dist/core/learning/learning-gate.d.ts.map +1 -1
  269. package/dist/core/learning/learning-gate.js +1 -6
  270. package/dist/core/learning/learning-gate.js.map +1 -1
  271. package/dist/core/learning/session-learning-decision.d.ts +2 -4
  272. package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
  273. package/dist/core/learning/session-learning-decision.js +9 -29
  274. package/dist/core/learning/session-learning-decision.js.map +1 -1
  275. package/dist/core/memory-controller.d.ts.map +1 -1
  276. package/dist/core/memory-controller.js +4 -4
  277. package/dist/core/memory-controller.js.map +1 -1
  278. package/dist/core/model-capability.d.ts.map +1 -1
  279. package/dist/core/model-capability.js +1 -0
  280. package/dist/core/model-capability.js.map +1 -1
  281. package/dist/core/model-resolver.d.ts +1 -1
  282. package/dist/core/model-resolver.d.ts.map +1 -1
  283. package/dist/core/model-resolver.js +6 -9
  284. package/dist/core/model-resolver.js.map +1 -1
  285. package/dist/core/model-router/intent-classifier.d.ts +1 -4
  286. package/dist/core/model-router/intent-classifier.d.ts.map +1 -1
  287. package/dist/core/model-router/intent-classifier.js +1 -156
  288. package/dist/core/model-router/intent-classifier.js.map +1 -1
  289. package/dist/core/model-router-controller.d.ts.map +1 -1
  290. package/dist/core/model-router-controller.js +2 -2
  291. package/dist/core/model-router-controller.js.map +1 -1
  292. package/dist/core/model-selection-controller.d.ts +4 -4
  293. package/dist/core/model-selection-controller.d.ts.map +1 -1
  294. package/dist/core/model-selection-controller.js.map +1 -1
  295. package/dist/core/model-tool-protocol.d.ts +23 -0
  296. package/dist/core/model-tool-protocol.d.ts.map +1 -0
  297. package/dist/core/model-tool-protocol.js +43 -0
  298. package/dist/core/model-tool-protocol.js.map +1 -0
  299. package/dist/core/models/adaptation-store.d.ts +4 -6
  300. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  301. package/dist/core/models/adaptation-store.js +95 -83
  302. package/dist/core/models/adaptation-store.js.map +1 -1
  303. package/dist/core/models/fitness-store.d.ts +2 -12
  304. package/dist/core/models/fitness-store.d.ts.map +1 -1
  305. package/dist/core/models/fitness-store.js +84 -57
  306. package/dist/core/models/fitness-store.js.map +1 -1
  307. package/dist/core/models/host-state-store.d.ts +34 -0
  308. package/dist/core/models/host-state-store.d.ts.map +1 -0
  309. package/dist/core/models/host-state-store.js +86 -0
  310. package/dist/core/models/host-state-store.js.map +1 -0
  311. package/dist/core/orchestration/agent-resume.d.ts +24 -0
  312. package/dist/core/orchestration/agent-resume.d.ts.map +1 -0
  313. package/dist/core/orchestration/agent-resume.js +90 -0
  314. package/dist/core/orchestration/agent-resume.js.map +1 -0
  315. package/dist/core/orchestration/capability-gateway.d.ts +61 -0
  316. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -0
  317. package/dist/core/orchestration/capability-gateway.js +152 -0
  318. package/dist/core/orchestration/capability-gateway.js.map +1 -0
  319. package/dist/core/orchestration/contracts.d.ts +343 -0
  320. package/dist/core/orchestration/contracts.d.ts.map +1 -0
  321. package/dist/core/orchestration/contracts.js +135 -0
  322. package/dist/core/orchestration/contracts.js.map +1 -0
  323. package/dist/core/orchestration/delegation-ledger.d.ts +56 -0
  324. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -0
  325. package/dist/core/orchestration/delegation-ledger.js +197 -0
  326. package/dist/core/orchestration/delegation-ledger.js.map +1 -0
  327. package/dist/core/orchestration/event-store.d.ts +83 -0
  328. package/dist/core/orchestration/event-store.d.ts.map +1 -0
  329. package/dist/core/orchestration/event-store.js +560 -0
  330. package/dist/core/orchestration/event-store.js.map +1 -0
  331. package/dist/core/orchestration/lane-tool-manifests.d.ts +9 -0
  332. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -0
  333. package/dist/core/orchestration/lane-tool-manifests.js +37 -0
  334. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -0
  335. package/dist/core/orchestration/model-binding.d.ts +15 -0
  336. package/dist/core/orchestration/model-binding.d.ts.map +1 -0
  337. package/dist/core/orchestration/model-binding.js +29 -0
  338. package/dist/core/orchestration/model-binding.js.map +1 -0
  339. package/dist/core/orchestration/policy-compiler.d.ts +49 -0
  340. package/dist/core/orchestration/policy-compiler.d.ts.map +1 -0
  341. package/dist/core/orchestration/policy-compiler.js +191 -0
  342. package/dist/core/orchestration/policy-compiler.js.map +1 -0
  343. package/dist/core/orchestration/policy-gate.d.ts +18 -0
  344. package/dist/core/orchestration/policy-gate.d.ts.map +1 -0
  345. package/dist/core/orchestration/policy-gate.js +24 -0
  346. package/dist/core/orchestration/policy-gate.js.map +1 -0
  347. package/dist/core/orchestration/profile-registry.d.ts +51 -0
  348. package/dist/core/orchestration/profile-registry.d.ts.map +1 -0
  349. package/dist/core/orchestration/profile-registry.js +393 -0
  350. package/dist/core/orchestration/profile-registry.js.map +1 -0
  351. package/dist/core/orchestration/profile-store.d.ts +31 -0
  352. package/dist/core/orchestration/profile-store.d.ts.map +1 -0
  353. package/dist/core/orchestration/profile-store.js +136 -0
  354. package/dist/core/orchestration/profile-store.js.map +1 -0
  355. package/dist/core/orchestration/risk-budget.d.ts +9 -0
  356. package/dist/core/orchestration/risk-budget.d.ts.map +1 -0
  357. package/dist/core/orchestration/risk-budget.js +48 -0
  358. package/dist/core/orchestration/risk-budget.js.map +1 -0
  359. package/dist/core/orchestration/task-runtime.d.ts +168 -0
  360. package/dist/core/orchestration/task-runtime.d.ts.map +1 -0
  361. package/dist/core/orchestration/task-runtime.js +1600 -0
  362. package/dist/core/orchestration/task-runtime.js.map +1 -0
  363. package/dist/core/orchestration/work-state-projection.d.ts +32 -0
  364. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -0
  365. package/dist/core/orchestration/work-state-projection.js +116 -0
  366. package/dist/core/orchestration/work-state-projection.js.map +1 -0
  367. package/dist/core/orchestration/worker-execution-contract.d.ts +21 -0
  368. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -0
  369. package/dist/core/orchestration/worker-execution-contract.js +179 -0
  370. package/dist/core/orchestration/worker-execution-contract.js.map +1 -0
  371. package/dist/core/orchestration/worker-result-adapter.d.ts +21 -0
  372. package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -0
  373. package/dist/core/orchestration/worker-result-adapter.js +109 -0
  374. package/dist/core/orchestration/worker-result-adapter.js.map +1 -0
  375. package/dist/core/process-identity.d.ts +11 -0
  376. package/dist/core/process-identity.d.ts.map +1 -0
  377. package/dist/core/process-identity.js +26 -0
  378. package/dist/core/process-identity.js.map +1 -0
  379. package/dist/core/process-matrix/codes.d.ts +14 -3
  380. package/dist/core/process-matrix/codes.d.ts.map +1 -1
  381. package/dist/core/process-matrix/codes.js.map +1 -1
  382. package/dist/core/process-matrix/resume-launcher.d.ts +26 -0
  383. package/dist/core/process-matrix/resume-launcher.d.ts.map +1 -0
  384. package/dist/core/process-matrix/resume-launcher.js +62 -0
  385. package/dist/core/process-matrix/resume-launcher.js.map +1 -0
  386. package/dist/core/process-matrix/runtime.d.ts +37 -22
  387. package/dist/core/process-matrix/runtime.d.ts.map +1 -1
  388. package/dist/core/process-matrix/runtime.js +399 -76
  389. package/dist/core/process-matrix/runtime.js.map +1 -1
  390. package/dist/core/process-matrix/store.d.ts +5 -2
  391. package/dist/core/process-matrix/store.d.ts.map +1 -1
  392. package/dist/core/process-matrix/store.js +123 -14
  393. package/dist/core/process-matrix/store.js.map +1 -1
  394. package/dist/core/process-matrix/supervisor.d.ts +10 -7
  395. package/dist/core/process-matrix/supervisor.d.ts.map +1 -1
  396. package/dist/core/process-matrix/supervisor.js +45 -14
  397. package/dist/core/process-matrix/supervisor.js.map +1 -1
  398. package/dist/core/profile-registry.d.ts.map +1 -1
  399. package/dist/core/profile-registry.js +6 -8
  400. package/dist/core/profile-registry.js.map +1 -1
  401. package/dist/core/reflection-controller.d.ts +4 -4
  402. package/dist/core/reflection-controller.d.ts.map +1 -1
  403. package/dist/core/reflection-controller.js +2 -1
  404. package/dist/core/reflection-controller.js.map +1 -1
  405. package/dist/core/reload-blockers.d.ts.map +1 -1
  406. package/dist/core/reload-blockers.js +6 -8
  407. package/dist/core/reload-blockers.js.map +1 -1
  408. package/dist/core/research/evidence-bundle.d.ts.map +1 -1
  409. package/dist/core/research/evidence-bundle.js +1 -6
  410. package/dist/core/research/evidence-bundle.js.map +1 -1
  411. package/dist/core/research/lane-model-resolver.d.ts +33 -0
  412. package/dist/core/research/lane-model-resolver.d.ts.map +1 -0
  413. package/dist/core/research/lane-model-resolver.js +65 -0
  414. package/dist/core/research/lane-model-resolver.js.map +1 -0
  415. package/dist/core/research/model-fitness-controller.d.ts +38 -0
  416. package/dist/core/research/model-fitness-controller.d.ts.map +1 -0
  417. package/dist/core/research/model-fitness-controller.js +106 -0
  418. package/dist/core/research/model-fitness-controller.js.map +1 -0
  419. package/dist/core/research/model-fitness.d.ts +1 -1
  420. package/dist/core/research/model-fitness.d.ts.map +1 -1
  421. package/dist/core/research/model-fitness.js +4 -4
  422. package/dist/core/research/model-fitness.js.map +1 -1
  423. package/dist/core/research/research-gate.d.ts.map +1 -1
  424. package/dist/core/research/research-gate.js +7 -7
  425. package/dist/core/research/research-gate.js.map +1 -1
  426. package/dist/core/research/research-lane-controller.d.ts +62 -0
  427. package/dist/core/research/research-lane-controller.d.ts.map +1 -0
  428. package/dist/core/research/research-lane-controller.js +292 -0
  429. package/dist/core/research/research-lane-controller.js.map +1 -0
  430. package/dist/core/research/session-evidence-bundle.d.ts +2 -4
  431. package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
  432. package/dist/core/research/session-evidence-bundle.js +10 -46
  433. package/dist/core/research/session-evidence-bundle.js.map +1 -1
  434. package/dist/core/resource-loader.d.ts.map +1 -1
  435. package/dist/core/resource-loader.js +7 -2
  436. package/dist/core/resource-loader.js.map +1 -1
  437. package/dist/core/risk-classifier.d.ts +6 -0
  438. package/dist/core/risk-classifier.d.ts.map +1 -0
  439. package/dist/core/risk-classifier.js +225 -0
  440. package/dist/core/risk-classifier.js.map +1 -0
  441. package/dist/core/runtime-builder.d.ts +26 -20
  442. package/dist/core/runtime-builder.d.ts.map +1 -1
  443. package/dist/core/runtime-builder.js +237 -178
  444. package/dist/core/runtime-builder.js.map +1 -1
  445. package/dist/core/sdk.d.ts +6 -3
  446. package/dist/core/sdk.d.ts.map +1 -1
  447. package/dist/core/sdk.js +61 -24
  448. package/dist/core/sdk.js.map +1 -1
  449. package/dist/core/session-analytics.d.ts.map +1 -1
  450. package/dist/core/session-analytics.js +28 -1
  451. package/dist/core/session-analytics.js.map +1 -1
  452. package/dist/core/session-image-store.d.ts +33 -0
  453. package/dist/core/session-image-store.d.ts.map +1 -0
  454. package/dist/core/session-image-store.js +283 -0
  455. package/dist/core/session-image-store.js.map +1 -0
  456. package/dist/core/session-role.d.ts +6 -4
  457. package/dist/core/session-role.d.ts.map +1 -1
  458. package/dist/core/session-role.js +10 -4
  459. package/dist/core/session-role.js.map +1 -1
  460. package/dist/core/session-snapshot.d.ts +34 -0
  461. package/dist/core/session-snapshot.d.ts.map +1 -0
  462. package/dist/core/session-snapshot.js +68 -0
  463. package/dist/core/session-snapshot.js.map +1 -0
  464. package/dist/core/session-supervision-runtime.d.ts +31 -0
  465. package/dist/core/session-supervision-runtime.d.ts.map +1 -0
  466. package/dist/core/session-supervision-runtime.js +97 -0
  467. package/dist/core/session-supervision-runtime.js.map +1 -0
  468. package/dist/core/settings-manager.d.ts +9 -4
  469. package/dist/core/settings-manager.d.ts.map +1 -1
  470. package/dist/core/settings-manager.js +80 -28
  471. package/dist/core/settings-manager.js.map +1 -1
  472. package/dist/core/tasks/session-task-state.d.ts +2 -4
  473. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  474. package/dist/core/tasks/session-task-state.js +10 -28
  475. package/dist/core/tasks/session-task-state.js.map +1 -1
  476. package/dist/core/tasks/task-projection.d.ts +20 -0
  477. package/dist/core/tasks/task-projection.d.ts.map +1 -0
  478. package/dist/core/tasks/task-projection.js +47 -0
  479. package/dist/core/tasks/task-projection.js.map +1 -0
  480. package/dist/core/tasks/task-state.d.ts +4 -0
  481. package/dist/core/tasks/task-state.d.ts.map +1 -1
  482. package/dist/core/tasks/task-state.js +28 -11
  483. package/dist/core/tasks/task-state.js.map +1 -1
  484. package/dist/core/tool-capability-policy.d.ts +13 -0
  485. package/dist/core/tool-capability-policy.d.ts.map +1 -0
  486. package/dist/core/tool-capability-policy.js +85 -0
  487. package/dist/core/tool-capability-policy.js.map +1 -0
  488. package/dist/core/tool-protocol-controller.d.ts +91 -0
  489. package/dist/core/tool-protocol-controller.d.ts.map +1 -0
  490. package/dist/core/tool-protocol-controller.js +512 -0
  491. package/dist/core/tool-protocol-controller.js.map +1 -0
  492. package/dist/core/tool-recovery-log-records.d.ts +2 -3
  493. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  494. package/dist/core/tool-recovery-log-records.js +9 -35
  495. package/dist/core/tool-recovery-log-records.js.map +1 -1
  496. package/dist/core/tool-selection/tool-performance-store.d.ts +3 -7
  497. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  498. package/dist/core/tool-selection/tool-performance-store.js +97 -138
  499. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  500. package/dist/core/tools/ask-question.d.ts +124 -0
  501. package/dist/core/tools/ask-question.d.ts.map +1 -0
  502. package/dist/core/tools/ask-question.js +693 -0
  503. package/dist/core/tools/ask-question.js.map +1 -0
  504. package/dist/core/tools/delegate-status.d.ts +31 -3
  505. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  506. package/dist/core/tools/delegate-status.js +149 -29
  507. package/dist/core/tools/delegate-status.js.map +1 -1
  508. package/dist/core/tools/delegate.d.ts +15 -13
  509. package/dist/core/tools/delegate.d.ts.map +1 -1
  510. package/dist/core/tools/delegate.js +108 -23
  511. package/dist/core/tools/delegate.js.map +1 -1
  512. package/dist/core/tools/extensionify.d.ts.map +1 -1
  513. package/dist/core/tools/extensionify.js +1 -0
  514. package/dist/core/tools/extensionify.js.map +1 -1
  515. package/dist/core/tools/goal.d.ts +5 -5
  516. package/dist/core/tools/goal.d.ts.map +1 -1
  517. package/dist/core/tools/goal.js +10 -10
  518. package/dist/core/tools/goal.js.map +1 -1
  519. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  520. package/dist/core/tools/model-fitness.js +2 -2
  521. package/dist/core/tools/model-fitness.js.map +1 -1
  522. package/dist/core/tools/orchestration-panel.d.ts +43 -0
  523. package/dist/core/tools/orchestration-panel.d.ts.map +1 -0
  524. package/dist/core/tools/orchestration-panel.js +168 -0
  525. package/dist/core/tools/orchestration-panel.js.map +1 -0
  526. package/dist/core/tools/run-process.d.ts +26 -0
  527. package/dist/core/tools/run-process.d.ts.map +1 -0
  528. package/dist/core/tools/run-process.js +138 -0
  529. package/dist/core/tools/run-process.js.map +1 -0
  530. package/dist/core/tools/task-steps.d.ts +2 -0
  531. package/dist/core/tools/task-steps.d.ts.map +1 -1
  532. package/dist/core/tools/task-steps.js +102 -0
  533. package/dist/core/tools/task-steps.js.map +1 -1
  534. package/dist/core/tools/tmux-dispatch.d.ts +3 -5
  535. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  536. package/dist/core/tools/tmux-dispatch.js +4 -4
  537. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  538. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
  539. package/dist/core/tools/windows-shell-engine.js +4 -6
  540. package/dist/core/tools/windows-shell-engine.js.map +1 -1
  541. package/dist/core/util/bounded-jsonl.d.ts +10 -0
  542. package/dist/core/util/bounded-jsonl.d.ts.map +1 -0
  543. package/dist/core/util/bounded-jsonl.js +75 -0
  544. package/dist/core/util/bounded-jsonl.js.map +1 -0
  545. package/dist/core/util/value-guards.d.ts +5 -0
  546. package/dist/core/util/value-guards.d.ts.map +1 -0
  547. package/dist/core/util/value-guards.js +12 -0
  548. package/dist/core/util/value-guards.js.map +1 -0
  549. package/dist/core/worktree-sync/store.d.ts +3 -3
  550. package/dist/core/worktree-sync/store.d.ts.map +1 -1
  551. package/dist/core/worktree-sync/store.js +10 -5
  552. package/dist/core/worktree-sync/store.js.map +1 -1
  553. package/dist/index.d.ts +13 -3
  554. package/dist/index.d.ts.map +1 -1
  555. package/dist/index.js +12 -2
  556. package/dist/index.js.map +1 -1
  557. package/dist/main.d.ts.map +1 -1
  558. package/dist/main.js +128 -44
  559. package/dist/main.js.map +1 -1
  560. package/dist/migrations.d.ts +4 -6
  561. package/dist/migrations.d.ts.map +1 -1
  562. package/dist/migrations.js +186 -28
  563. package/dist/migrations.js.map +1 -1
  564. package/dist/modes/interactive/clipboard-input.d.ts +7 -1
  565. package/dist/modes/interactive/clipboard-input.d.ts.map +1 -1
  566. package/dist/modes/interactive/clipboard-input.js +44 -6
  567. package/dist/modes/interactive/clipboard-input.js.map +1 -1
  568. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  569. package/dist/modes/interactive/components/settings-selector.js +2 -2
  570. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  571. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  572. package/dist/modes/interactive/config-backup.js +5 -4
  573. package/dist/modes/interactive/config-backup.js.map +1 -1
  574. package/dist/modes/interactive/extension-ui-host.d.ts +14 -0
  575. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  576. package/dist/modes/interactive/extension-ui-host.js +76 -15
  577. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  578. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  579. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  580. package/dist/modes/interactive/interactive-mode.js +63 -1
  581. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  582. package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
  583. package/dist/modes/interactive/key-handlers.js +1 -1
  584. package/dist/modes/interactive/key-handlers.js.map +1 -1
  585. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  586. package/dist/modes/interactive/profile-menu-controller.js +7 -7
  587. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  588. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  589. package/dist/modes/interactive/report-commands.js +21 -0
  590. package/dist/modes/interactive/report-commands.js.map +1 -1
  591. package/dist/modes/interactive/session-flow-commands.d.ts +17 -2
  592. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  593. package/dist/modes/interactive/session-flow-commands.js +50 -17
  594. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  595. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
  596. package/dist/modes/interactive/session-io-commands.js +16 -6
  597. package/dist/modes/interactive/session-io-commands.js.map +1 -1
  598. package/dist/modes/interactive/session-replacement-errors.d.ts +7 -0
  599. package/dist/modes/interactive/session-replacement-errors.d.ts.map +1 -0
  600. package/dist/modes/interactive/session-replacement-errors.js +15 -0
  601. package/dist/modes/interactive/session-replacement-errors.js.map +1 -0
  602. package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
  603. package/dist/modes/interactive/startup-checks.js +1 -1
  604. package/dist/modes/interactive/startup-checks.js.map +1 -1
  605. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  606. package/dist/modes/rpc/rpc-mode.js +82 -23
  607. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  608. package/dist/modes/rpc/rpc-types.d.ts +15 -0
  609. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  610. package/dist/modes/rpc/rpc-types.js +138 -1
  611. package/dist/modes/rpc/rpc-types.js.map +1 -1
  612. package/dist/utils/clipboard-image.d.ts.map +1 -1
  613. package/dist/utils/clipboard-image.js +2 -13
  614. package/dist/utils/clipboard-image.js.map +1 -1
  615. package/dist/utils/clipboard-native.d.ts +1 -0
  616. package/dist/utils/clipboard-native.d.ts.map +1 -1
  617. package/dist/utils/clipboard-native.js.map +1 -1
  618. package/dist/utils/clipboard.d.ts +1 -0
  619. package/dist/utils/clipboard.d.ts.map +1 -1
  620. package/dist/utils/clipboard.js +52 -1
  621. package/dist/utils/clipboard.js.map +1 -1
  622. package/dist/utils/platform.d.ts +3 -0
  623. package/dist/utils/platform.d.ts.map +1 -0
  624. package/dist/utils/platform.js +8 -0
  625. package/dist/utils/platform.js.map +1 -0
  626. package/dist/utils/work-directory.d.ts +11 -0
  627. package/dist/utils/work-directory.d.ts.map +1 -1
  628. package/dist/utils/work-directory.js +30 -9
  629. package/dist/utils/work-directory.js.map +1 -1
  630. package/docs/UI_POLISH_ORCHESTRATION.md +44 -0
  631. package/docs/UI_QUALITY_ORCHESTRATION.md +30 -0
  632. package/docs/docs.json +4 -0
  633. package/docs/extensions.md +62 -2
  634. package/docs/harness-architecture.md +156 -0
  635. package/docs/keybindings.md +11 -1
  636. package/docs/process-matrix.md +59 -26
  637. package/docs/rpc.md +45 -2
  638. package/docs/sessions.md +15 -0
  639. package/docs/settings.md +125 -11
  640. package/docs/task-steps.md +8 -0
  641. package/docs/telemetry.md +19 -0
  642. package/docs/tmux-agent-manager.md +10 -3
  643. package/docs/ui-reference/README.md +9 -0
  644. package/docs/ui-reference/orchestration-after.txt +7 -0
  645. package/docs/ui-reference/orchestration-before.txt +7 -0
  646. package/docs/ui-reference/orchestration-reference.txt +6 -0
  647. package/docs/usage.md +14 -2
  648. package/docs/work-directory.md +19 -8
  649. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  650. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  651. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  652. package/examples/extensions/question.ts +34 -245
  653. package/examples/extensions/questionnaire.ts +41 -407
  654. package/examples/extensions/sandbox/package-lock.json +2 -2
  655. package/examples/extensions/sandbox/package.json +1 -1
  656. package/examples/extensions/with-deps/package-lock.json +2 -2
  657. package/examples/extensions/with-deps/package.json +1 -1
  658. package/npm-shrinkwrap.json +12 -12
  659. package/package.json +4 -4
  660. package/dist/core/delegation/session-worker-result.d.ts +0 -46
  661. package/dist/core/delegation/session-worker-result.d.ts.map +0 -1
  662. package/dist/core/delegation/session-worker-result.js +0 -113
  663. package/dist/core/delegation/session-worker-result.js.map +0 -1
  664. package/dist/core/delegation/worker-result.d.ts.map +0 -1
  665. package/dist/core/delegation/worker-result.js.map +0 -1
  666. package/dist/core/telemetry.d.ts.map +0 -1
  667. package/dist/core/telemetry.js.map +0 -1
@@ -0,0 +1,168 @@
1
+ import { truncateToWidth, visibleWidth } from "@caupulican/pi-tui";
2
+ import { renderTitleBadge } from "../../modes/interactive/components/tool-title.js";
3
+ const ROW_STYLES = {
4
+ pending: { icon: "○", color: "muted" },
5
+ queued: { icon: "◌", color: "warning" },
6
+ running: { icon: "●", color: "accent", bold: true },
7
+ in_progress: { icon: "●", color: "accent", bold: true },
8
+ completed: { icon: "✓", color: "success", strike: true },
9
+ succeeded: { icon: "✓", color: "success" },
10
+ blocked: { icon: "!", color: "warning", bold: true },
11
+ failed: { icon: "×", color: "error", bold: true },
12
+ timeout: { icon: "×", color: "warning" },
13
+ budget_exhausted: { icon: "!", color: "warning" },
14
+ cancelled: { icon: "–", color: "muted", strike: true },
15
+ canceled: { icon: "–", color: "muted", strike: true },
16
+ reviewed: { icon: "✓", color: "success" },
17
+ info: { icon: "·", color: "muted" },
18
+ };
19
+ const NOTICE_STYLES = {
20
+ info: { icon: "·", color: "muted" },
21
+ success: { icon: "✓", color: "success" },
22
+ warning: { icon: "!", color: "warning" },
23
+ error: { icon: "×", color: "error" },
24
+ };
25
+ export function taskStepPanelRow(step) {
26
+ const meta = [
27
+ step.priority === "high" ? "high priority" : undefined,
28
+ step.owner ? `@${step.owner}` : undefined,
29
+ step.requirementIds?.length
30
+ ? `${step.requirementIds.length} requirement${step.requirementIds.length === 1 ? "" : "s"}`
31
+ : undefined,
32
+ step.evidence.length ? `${step.evidence.length} evidence` : undefined,
33
+ ].filter((value) => value !== undefined);
34
+ const details = [
35
+ ...step.notes.slice(-2).map((note) => `note: ${note}`),
36
+ ...step.evidence.slice(-2).map((evidence) => `evidence: ${evidence}`),
37
+ ];
38
+ return {
39
+ status: step.status,
40
+ label: step.status === "in_progress" ? (step.activeForm ?? step.content) : step.content,
41
+ meta,
42
+ details,
43
+ };
44
+ }
45
+ /** Build the quiet below-editor view from native session truth. No active work means no widget. */
46
+ export function createOrchestrationActivityModel(taskState, laneRecords) {
47
+ const openSteps = taskState?.steps.filter((step) => step.status !== "completed" && step.status !== "cancelled") ?? [];
48
+ const orderedSteps = [
49
+ ...openSteps.filter((step) => step.status === "in_progress"),
50
+ ...openSteps.filter((step) => step.status === "blocked"),
51
+ ...openSteps.filter((step) => step.status === "pending"),
52
+ ];
53
+ const activeLanes = laneRecords.filter((lane) => (lane.type === "worker" || lane.type === "tmux-worker") &&
54
+ (lane.status === "running" || lane.status === "queued"));
55
+ if (openSteps.length === 0 && activeLanes.length === 0)
56
+ return undefined;
57
+ const taskRows = orderedSteps.slice(0, 5).map((step) => ({ ...taskStepPanelRow(step), section: "Steps" }));
58
+ const laneRows = activeLanes.slice(0, 3).map((lane) => ({
59
+ status: lane.status,
60
+ label: lane.label ?? lane.laneId,
61
+ section: "Agents",
62
+ meta: [
63
+ lane.label ? lane.laneId : undefined,
64
+ lane.profileId ? `profile ${lane.profileId}` : undefined,
65
+ lane.type === "tmux-worker" ? "tmux" : undefined,
66
+ ].filter((value) => value !== undefined),
67
+ }));
68
+ const runningLanes = activeLanes.filter((lane) => lane.status === "running").length;
69
+ const queuedLanes = activeLanes.length - runningLanes;
70
+ const blockedSteps = openSteps.filter((step) => step.status === "blocked").length;
71
+ const workingSteps = openSteps.filter((step) => step.status === "in_progress").length;
72
+ const evidenceMissing = taskState?.steps.some((step) => step.status === "completed" && step.evidence.length === 0);
73
+ return {
74
+ label: "work",
75
+ action: workingSteps + runningLanes > 0 ? "active" : "ready",
76
+ status: blockedSteps > 0 ? "warning" : workingSteps + runningLanes > 0 ? "running" : "idle",
77
+ summary: [
78
+ openSteps.length ? `${openSteps.length} step${openSteps.length === 1 ? "" : "s"}` : undefined,
79
+ runningLanes ? `${runningLanes} agent${runningLanes === 1 ? "" : "s"}` : undefined,
80
+ queuedLanes ? `${queuedLanes} queued` : undefined,
81
+ ].filter((value) => value !== undefined),
82
+ rows: [...taskRows, ...laneRows],
83
+ hiddenRowCount: Math.max(0, openSteps.length + activeLanes.length - taskRows.length - laneRows.length),
84
+ notices: evidenceMissing
85
+ ? [{ status: "warning", text: "Completed work still needs attached evidence." }]
86
+ : undefined,
87
+ };
88
+ }
89
+ function renderRow(theme, row, width, expanded) {
90
+ const style = ROW_STYLES[row.status];
91
+ const prefix = ` ${theme.fg(style.color, style.icon)} `;
92
+ const meta = row.meta?.filter(Boolean).join(" · ") ?? "";
93
+ const suffix = meta ? ` ${theme.fg("dim", meta)}` : "";
94
+ const labelWidth = Math.max(4, width - visibleWidth(prefix) - visibleWidth(suffix));
95
+ const clippedLabel = truncateToWidth(row.label, labelWidth, "…");
96
+ let label = style.bold ? theme.bold(clippedLabel) : clippedLabel;
97
+ if (style.strike)
98
+ label = theme.strikethrough(label);
99
+ const lines = [`${prefix}${theme.fg(style.strike ? "dim" : "text", label)}${suffix}`];
100
+ if (expanded) {
101
+ for (const detail of row.details ?? []) {
102
+ lines.push(` ${theme.fg("dim", truncateToWidth(detail, Math.max(4, width - 4), "…"))}`);
103
+ }
104
+ }
105
+ return lines;
106
+ }
107
+ export function renderOrchestrationPanelLines(theme, model, width, expanded = false) {
108
+ const safeWidth = Math.max(1, width);
109
+ const title = renderTitleBadge(theme, {
110
+ label: model.label,
111
+ action: model.action,
112
+ status: model.status ?? "info",
113
+ });
114
+ const summary = model.summary?.filter(Boolean).join(theme.fg("dim", " · ")) ?? "";
115
+ const lines = [summary ? `${title} ${theme.fg("dim", summary)}` : title];
116
+ const rows = model.rows ?? [];
117
+ if (rows.length > 0) {
118
+ let section;
119
+ for (const row of rows) {
120
+ if (row.section && row.section !== section) {
121
+ section = row.section;
122
+ lines.push(` ${theme.fg("muted", theme.bold(row.section))}`);
123
+ }
124
+ lines.push(...renderRow(theme, row, safeWidth, expanded));
125
+ }
126
+ }
127
+ else if (model.emptyText) {
128
+ lines.push(` ${theme.fg("muted", model.emptyText)}`);
129
+ }
130
+ if ((model.hiddenRowCount ?? 0) > 0) {
131
+ lines.push(` ${theme.fg("dim", `… ${model.hiddenRowCount} more`)}`);
132
+ }
133
+ for (const notice of model.notices ?? []) {
134
+ const style = NOTICE_STYLES[notice.status];
135
+ lines.push(` ${theme.fg(style.color, style.icon)} ${theme.fg("dim", notice.text)}`);
136
+ }
137
+ return lines.map((line) => truncateToWidth(line, safeWidth, ""));
138
+ }
139
+ export class OrchestrationPanelComponent {
140
+ cachedWidth;
141
+ cachedLines;
142
+ theme;
143
+ model;
144
+ expanded;
145
+ constructor(theme, model, expanded = false) {
146
+ this.theme = theme;
147
+ this.model = model;
148
+ this.expanded = expanded;
149
+ }
150
+ render(width) {
151
+ if (this.cachedWidth === width && this.cachedLines)
152
+ return this.cachedLines;
153
+ this.cachedWidth = width;
154
+ this.cachedLines = renderOrchestrationPanelLines(this.theme, this.model, width, this.expanded);
155
+ return this.cachedLines;
156
+ }
157
+ invalidate() {
158
+ this.cachedWidth = undefined;
159
+ this.cachedLines = undefined;
160
+ }
161
+ }
162
+ export function emptyOrchestrationCall() {
163
+ return {
164
+ render: () => [],
165
+ invalidate() { },
166
+ };
167
+ }
168
+ //# sourceMappingURL=orchestration-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration-panel.js","sourceRoot":"","sources":["../../../src/core/tools/orchestration-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"@caupulican/pi-tui\";\nimport { truncateToWidth, visibleWidth } from \"@caupulican/pi-tui\";\nimport { renderTitleBadge, type TitleBadgeStatus } from \"../../modes/interactive/components/tool-title.ts\";\nimport type { Theme, ThemeColor } from \"../../modes/interactive/theme/theme.ts\";\nimport type { LaneRecord } from \"../autonomy/lane-tracker.ts\";\nimport type { TaskStep, TaskStepsState } from \"../tasks/task-state.ts\";\n\nexport type OrchestrationRowStatus =\n\t| \"pending\"\n\t| \"queued\"\n\t| \"running\"\n\t| \"in_progress\"\n\t| \"completed\"\n\t| \"succeeded\"\n\t| \"blocked\"\n\t| \"failed\"\n\t| \"timeout\"\n\t| \"budget_exhausted\"\n\t| \"cancelled\"\n\t| \"canceled\"\n\t| \"reviewed\"\n\t| \"info\";\n\nexport interface OrchestrationPanelRow {\n\tstatus: OrchestrationRowStatus;\n\tlabel: string;\n\tsection?: string;\n\tmeta?: readonly string[];\n\tdetails?: readonly string[];\n}\n\nexport interface OrchestrationPanelNotice {\n\tstatus: \"info\" | \"success\" | \"warning\" | \"error\";\n\ttext: string;\n}\n\nexport interface OrchestrationPanelModel {\n\tlabel: string;\n\taction?: string;\n\tstatus?: TitleBadgeStatus;\n\tsummary?: readonly string[];\n\trows?: readonly OrchestrationPanelRow[];\n\tnotices?: readonly OrchestrationPanelNotice[];\n\temptyText?: string;\n\thiddenRowCount?: number;\n}\n\ninterface RowStyle {\n\ticon: string;\n\tcolor: ThemeColor;\n\tstrike?: boolean;\n\tbold?: boolean;\n}\n\nconst ROW_STYLES: Record<OrchestrationRowStatus, RowStyle> = {\n\tpending: { icon: \"○\", color: \"muted\" },\n\tqueued: { icon: \"◌\", color: \"warning\" },\n\trunning: { icon: \"●\", color: \"accent\", bold: true },\n\tin_progress: { icon: \"●\", color: \"accent\", bold: true },\n\tcompleted: { icon: \"✓\", color: \"success\", strike: true },\n\tsucceeded: { icon: \"✓\", color: \"success\" },\n\tblocked: { icon: \"!\", color: \"warning\", bold: true },\n\tfailed: { icon: \"×\", color: \"error\", bold: true },\n\ttimeout: { icon: \"×\", color: \"warning\" },\n\tbudget_exhausted: { icon: \"!\", color: \"warning\" },\n\tcancelled: { icon: \"–\", color: \"muted\", strike: true },\n\tcanceled: { icon: \"–\", color: \"muted\", strike: true },\n\treviewed: { icon: \"✓\", color: \"success\" },\n\tinfo: { icon: \"·\", color: \"muted\" },\n};\n\nconst NOTICE_STYLES: Record<OrchestrationPanelNotice[\"status\"], { icon: string; color: ThemeColor }> = {\n\tinfo: { icon: \"·\", color: \"muted\" },\n\tsuccess: { icon: \"✓\", color: \"success\" },\n\twarning: { icon: \"!\", color: \"warning\" },\n\terror: { icon: \"×\", color: \"error\" },\n};\n\nexport function taskStepPanelRow(step: TaskStep): OrchestrationPanelRow {\n\tconst meta = [\n\t\tstep.priority === \"high\" ? \"high priority\" : undefined,\n\t\tstep.owner ? `@${step.owner}` : undefined,\n\t\tstep.requirementIds?.length\n\t\t\t? `${step.requirementIds.length} requirement${step.requirementIds.length === 1 ? \"\" : \"s\"}`\n\t\t\t: undefined,\n\t\tstep.evidence.length ? `${step.evidence.length} evidence` : undefined,\n\t].filter((value): value is string => value !== undefined);\n\tconst details = [\n\t\t...step.notes.slice(-2).map((note) => `note: ${note}`),\n\t\t...step.evidence.slice(-2).map((evidence) => `evidence: ${evidence}`),\n\t];\n\treturn {\n\t\tstatus: step.status,\n\t\tlabel: step.status === \"in_progress\" ? (step.activeForm ?? step.content) : step.content,\n\t\tmeta,\n\t\tdetails,\n\t};\n}\n\n/** Build the quiet below-editor view from native session truth. No active work means no widget. */\nexport function createOrchestrationActivityModel(\n\ttaskState: TaskStepsState | undefined,\n\tlaneRecords: readonly LaneRecord[],\n): OrchestrationPanelModel | undefined {\n\tconst openSteps =\n\t\ttaskState?.steps.filter((step) => step.status !== \"completed\" && step.status !== \"cancelled\") ?? [];\n\tconst orderedSteps = [\n\t\t...openSteps.filter((step) => step.status === \"in_progress\"),\n\t\t...openSteps.filter((step) => step.status === \"blocked\"),\n\t\t...openSteps.filter((step) => step.status === \"pending\"),\n\t];\n\tconst activeLanes = laneRecords.filter(\n\t\t(lane) =>\n\t\t\t(lane.type === \"worker\" || lane.type === \"tmux-worker\") &&\n\t\t\t(lane.status === \"running\" || lane.status === \"queued\"),\n\t);\n\tif (openSteps.length === 0 && activeLanes.length === 0) return undefined;\n\n\tconst taskRows = orderedSteps.slice(0, 5).map((step) => ({ ...taskStepPanelRow(step), section: \"Steps\" }));\n\tconst laneRows: OrchestrationPanelRow[] = activeLanes.slice(0, 3).map((lane) => ({\n\t\tstatus: lane.status,\n\t\tlabel: lane.label ?? lane.laneId,\n\t\tsection: \"Agents\",\n\t\tmeta: [\n\t\t\tlane.label ? lane.laneId : undefined,\n\t\t\tlane.profileId ? `profile ${lane.profileId}` : undefined,\n\t\t\tlane.type === \"tmux-worker\" ? \"tmux\" : undefined,\n\t\t].filter((value): value is string => value !== undefined),\n\t}));\n\tconst runningLanes = activeLanes.filter((lane) => lane.status === \"running\").length;\n\tconst queuedLanes = activeLanes.length - runningLanes;\n\tconst blockedSteps = openSteps.filter((step) => step.status === \"blocked\").length;\n\tconst workingSteps = openSteps.filter((step) => step.status === \"in_progress\").length;\n\tconst evidenceMissing = taskState?.steps.some((step) => step.status === \"completed\" && step.evidence.length === 0);\n\treturn {\n\t\tlabel: \"work\",\n\t\taction: workingSteps + runningLanes > 0 ? \"active\" : \"ready\",\n\t\tstatus: blockedSteps > 0 ? \"warning\" : workingSteps + runningLanes > 0 ? \"running\" : \"idle\",\n\t\tsummary: [\n\t\t\topenSteps.length ? `${openSteps.length} step${openSteps.length === 1 ? \"\" : \"s\"}` : undefined,\n\t\t\trunningLanes ? `${runningLanes} agent${runningLanes === 1 ? \"\" : \"s\"}` : undefined,\n\t\t\tqueuedLanes ? `${queuedLanes} queued` : undefined,\n\t\t].filter((value): value is string => value !== undefined),\n\t\trows: [...taskRows, ...laneRows],\n\t\thiddenRowCount: Math.max(0, openSteps.length + activeLanes.length - taskRows.length - laneRows.length),\n\t\tnotices: evidenceMissing\n\t\t\t? [{ status: \"warning\", text: \"Completed work still needs attached evidence.\" }]\n\t\t\t: undefined,\n\t};\n}\n\nfunction renderRow(theme: Theme, row: OrchestrationPanelRow, width: number, expanded: boolean): string[] {\n\tconst style = ROW_STYLES[row.status];\n\tconst prefix = ` ${theme.fg(style.color, style.icon)} `;\n\tconst meta = row.meta?.filter(Boolean).join(\" · \") ?? \"\";\n\tconst suffix = meta ? ` ${theme.fg(\"dim\", meta)}` : \"\";\n\tconst labelWidth = Math.max(4, width - visibleWidth(prefix) - visibleWidth(suffix));\n\tconst clippedLabel = truncateToWidth(row.label, labelWidth, \"…\");\n\tlet label = style.bold ? theme.bold(clippedLabel) : clippedLabel;\n\tif (style.strike) label = theme.strikethrough(label);\n\tconst lines = [`${prefix}${theme.fg(style.strike ? \"dim\" : \"text\", label)}${suffix}`];\n\tif (expanded) {\n\t\tfor (const detail of row.details ?? []) {\n\t\t\tlines.push(` ${theme.fg(\"dim\", truncateToWidth(detail, Math.max(4, width - 4), \"…\"))}`);\n\t\t}\n\t}\n\treturn lines;\n}\n\nexport function renderOrchestrationPanelLines(\n\ttheme: Theme,\n\tmodel: OrchestrationPanelModel,\n\twidth: number,\n\texpanded = false,\n): string[] {\n\tconst safeWidth = Math.max(1, width);\n\tconst title = renderTitleBadge(theme, {\n\t\tlabel: model.label,\n\t\taction: model.action,\n\t\tstatus: model.status ?? \"info\",\n\t});\n\tconst summary = model.summary?.filter(Boolean).join(theme.fg(\"dim\", \" · \")) ?? \"\";\n\tconst lines = [summary ? `${title} ${theme.fg(\"dim\", summary)}` : title];\n\tconst rows = model.rows ?? [];\n\tif (rows.length > 0) {\n\t\tlet section: string | undefined;\n\t\tfor (const row of rows) {\n\t\t\tif (row.section && row.section !== section) {\n\t\t\t\tsection = row.section;\n\t\t\t\tlines.push(` ${theme.fg(\"muted\", theme.bold(row.section))}`);\n\t\t\t}\n\t\t\tlines.push(...renderRow(theme, row, safeWidth, expanded));\n\t\t}\n\t} else if (model.emptyText) {\n\t\tlines.push(` ${theme.fg(\"muted\", model.emptyText)}`);\n\t}\n\tif ((model.hiddenRowCount ?? 0) > 0) {\n\t\tlines.push(` ${theme.fg(\"dim\", `… ${model.hiddenRowCount} more`)}`);\n\t}\n\tfor (const notice of model.notices ?? []) {\n\t\tconst style = NOTICE_STYLES[notice.status];\n\t\tlines.push(` ${theme.fg(style.color, style.icon)} ${theme.fg(\"dim\", notice.text)}`);\n\t}\n\treturn lines.map((line) => truncateToWidth(line, safeWidth, \"\"));\n}\n\nexport class OrchestrationPanelComponent implements Component {\n\tprivate cachedWidth?: number;\n\tprivate cachedLines?: string[];\n\tprivate readonly theme: Theme;\n\tprivate readonly model: OrchestrationPanelModel;\n\tprivate readonly expanded: boolean;\n\n\tconstructor(theme: Theme, model: OrchestrationPanelModel, expanded = false) {\n\t\tthis.theme = theme;\n\t\tthis.model = model;\n\t\tthis.expanded = expanded;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedWidth === width && this.cachedLines) return this.cachedLines;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedLines = renderOrchestrationPanelLines(this.theme, this.model, width, this.expanded);\n\t\treturn this.cachedLines;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n}\n\nexport function emptyOrchestrationCall(): Component {\n\treturn {\n\t\trender: () => [],\n\t\tinvalidate() {},\n\t};\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import type { AgentTool } from "@caupulican/pi-agent-core";
2
+ import { type Static, Type } from "typebox";
3
+ import { spawnProcess } from "../../utils/child-process.ts";
4
+ import type { ToolDefinition } from "../extensions/types.ts";
5
+ import type { OrchestrationExecutionPolicy } from "../orchestration/contracts.ts";
6
+ declare const runProcessSchema: Type.TObject<{
7
+ executable: Type.TString;
8
+ args: Type.TOptional<Type.TArray<Type.TString>>;
9
+ }>;
10
+ export type RunProcessInput = Static<typeof runProcessSchema>;
11
+ export interface RunProcessDetails {
12
+ outcome: "exited" | "failed" | "aborted" | "timeout" | "output_limit";
13
+ executable: string;
14
+ exitCode: number | null;
15
+ durationMs: number;
16
+ truncated: boolean;
17
+ }
18
+ export interface RunProcessToolOptions {
19
+ policy: OrchestrationExecutionPolicy;
20
+ maxWallClockMs: number;
21
+ spawn?: typeof spawnProcess;
22
+ }
23
+ export declare function createRunProcessToolDefinition(cwd: string, options: RunProcessToolOptions): ToolDefinition;
24
+ export declare function createRunProcessTool(cwd: string, options: RunProcessToolOptions): AgentTool;
25
+ export {};
26
+ //# sourceMappingURL=run-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-process.d.ts","sourceRoot":"","sources":["../../../src/core/tools/run-process.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAsC,MAAM,8BAA8B,CAAC;AAChG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAGlF,QAAA,MAAM,gBAAgB;;;EAMrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,CAAC;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,4BAA4B,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,YAAY,CAAC;CAC5B;AAuDD,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,cAAc,CA8E1G;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,SAAS,CAE3F","sourcesContent":["import type { ChildProcess } from \"node:child_process\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { spawnProcess, waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport type { OrchestrationExecutionPolicy } from \"../orchestration/contracts.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst runProcessSchema = Type.Object(\n\t{\n\t\texecutable: Type.String({ description: \"Exact owner-allowed executable name or path.\" }),\n\t\targs: Type.Optional(Type.Array(Type.String(), { description: \"Direct argv entries. No shell parsing occurs.\" })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type RunProcessInput = Static<typeof runProcessSchema>;\n\nexport interface RunProcessDetails {\n\toutcome: \"exited\" | \"failed\" | \"aborted\" | \"timeout\" | \"output_limit\";\n\texecutable: string;\n\texitCode: number | null;\n\tdurationMs: number;\n\ttruncated: boolean;\n}\n\nexport interface RunProcessToolOptions {\n\tpolicy: OrchestrationExecutionPolicy;\n\tmaxWallClockMs: number;\n\tspawn?: typeof spawnProcess;\n}\n\nconst SAFE_ENVIRONMENT_VARIABLES = [\n\t\"PATH\",\n\t\"PATHEXT\",\n\t\"SystemRoot\",\n\t\"WINDIR\",\n\t\"COMSPEC\",\n\t\"TMPDIR\",\n\t\"TMP\",\n\t\"TEMP\",\n] as const;\n\nfunction scopedEnvironment(allowedNames: readonly string[]): NodeJS.ProcessEnv {\n\tconst names = new Set<string>([...SAFE_ENVIRONMENT_VARIABLES, ...allowedNames]);\n\tconst environment: NodeJS.ProcessEnv = {};\n\tfor (const name of names) {\n\t\tconst value = process.env[name];\n\t\tif (value !== undefined) environment[name] = value;\n\t}\n\treturn environment;\n}\n\nfunction collectBoundedOutput(\n\tchild: ChildProcess,\n\tmaxBytes: number,\n\tabort: () => void,\n): {\n\tread(): { stdout: string; stderr: string; truncated: boolean };\n} {\n\tlet remaining = maxBytes;\n\tlet truncated = false;\n\tconst stdout: Buffer[] = [];\n\tconst stderr: Buffer[] = [];\n\tconst collect = (target: Buffer[]) => (chunk: Buffer) => {\n\t\tif (remaining <= 0) return;\n\t\tconst retained = chunk.subarray(0, remaining);\n\t\ttarget.push(retained);\n\t\tremaining -= retained.length;\n\t\tif (retained.length < chunk.length || remaining === 0) {\n\t\t\ttruncated = true;\n\t\t\tabort();\n\t\t}\n\t};\n\tchild.stdout?.on(\"data\", collect(stdout));\n\tchild.stderr?.on(\"data\", collect(stderr));\n\treturn {\n\t\tread: () => ({\n\t\t\tstdout: Buffer.concat(stdout).toString(\"utf-8\"),\n\t\t\tstderr: Buffer.concat(stderr).toString(\"utf-8\"),\n\t\t\ttruncated,\n\t\t}),\n\t};\n}\n\nexport function createRunProcessToolDefinition(cwd: string, options: RunProcessToolOptions): ToolDefinition {\n\tconst allowedExecutables = new Set(options.policy.allowedExecutables);\n\treturn {\n\t\tname: \"run_process\",\n\t\tlabel: \"Run Process\",\n\t\tdescription: `Run one owner-allowed executable using direct argv without a shell. Allowed: ${options.policy.allowedExecutables.join(\", \")}.`,\n\t\tpromptSnippet: \"Run an owner-allowed executable through a constrained direct-argv launcher (not OS isolation).\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use only an executable listed by the profile. Arguments are passed literally; shell operators and interpolation are unavailable.\",\n\t\t\t\"Treat a non-zero exit code, timeout, abort, or output-limit termination as failure.\",\n\t\t],\n\t\tparameters: runProcessSchema,\n\t\tasync execute(_toolCallId, input: RunProcessInput, signal) {\n\t\t\tif (!allowedExecutables.has(input.executable)) {\n\t\t\t\tthrow new Error(`process_executable_denied: '${input.executable}' is not owner-allowed.`);\n\t\t\t}\n\t\t\tconst args = input.args ?? [];\n\t\t\tif (input.executable.includes(\"\\0\") || args.some((argument) => argument.includes(\"\\0\"))) {\n\t\t\t\tthrow new Error(\"process_argument_invalid: executable and argv must not contain NUL bytes.\");\n\t\t\t}\n\t\t\tconst startedAt = Date.now();\n\t\t\tconst outputLimitAbort = new AbortController();\n\t\t\tlet outputLimitReached = false;\n\t\t\tconst child = (options.spawn ?? spawnProcess)(input.executable, [...args], {\n\t\t\t\tcwd,\n\t\t\t\tenv: scopedEnvironment(options.policy.allowedEnvironmentVariables),\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tconst output = collectBoundedOutput(child, options.policy.maxOutputBytes, () => {\n\t\t\t\toutputLimitReached = true;\n\t\t\t\toutputLimitAbort.abort();\n\t\t\t});\n\t\t\tconst combinedAbort = new AbortController();\n\t\t\tconst abort = () => combinedAbort.abort();\n\t\t\tif (signal?.aborted || outputLimitAbort.signal.aborted) abort();\n\t\t\telse {\n\t\t\t\tsignal?.addEventListener(\"abort\", abort, { once: true });\n\t\t\t\toutputLimitAbort.signal.addEventListener(\"abort\", abort, { once: true });\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\t\t\tsignal: combinedAbort.signal,\n\t\t\t\t\ttimeoutMs: options.maxWallClockMs > 0 ? options.maxWallClockMs : undefined,\n\t\t\t\t\tkillGraceMs: 2_000,\n\t\t\t\t});\n\t\t\t\tconst captured = output.read();\n\t\t\t\tconst outcome: RunProcessDetails[\"outcome\"] = outputLimitReached\n\t\t\t\t\t? \"output_limit\"\n\t\t\t\t\t: terminal.reason === \"timeout\"\n\t\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t\t: terminal.reason === \"aborted\"\n\t\t\t\t\t\t\t? \"aborted\"\n\t\t\t\t\t\t\t: terminal.code === 0\n\t\t\t\t\t\t\t\t? \"exited\"\n\t\t\t\t\t\t\t\t: \"failed\";\n\t\t\t\tconst body = [\n\t\t\t\t\t`outcome: ${outcome}`,\n\t\t\t\t\t`exitCode: ${terminal.code ?? \"null\"}`,\n\t\t\t\t\tcaptured.stdout ? `stdout:\\n${captured.stdout}` : \"stdout: (empty)\",\n\t\t\t\t\tcaptured.stderr ? `stderr:\\n${captured.stderr}` : \"stderr: (empty)\",\n\t\t\t\t].join(\"\\n\");\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: body }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\toutcome,\n\t\t\t\t\t\texecutable: input.executable,\n\t\t\t\t\t\texitCode: terminal.code,\n\t\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t\t\ttruncated: captured.truncated,\n\t\t\t\t\t} satisfies RunProcessDetails,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tsignal?.removeEventListener(\"abort\", abort);\n\t\t\t\toutputLimitAbort.signal.removeEventListener(\"abort\", abort);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function createRunProcessTool(cwd: string, options: RunProcessToolOptions): AgentTool {\n\treturn wrapToolDefinition(createRunProcessToolDefinition(cwd, options));\n}\n"]}
@@ -0,0 +1,138 @@
1
+ import { Type } from "typebox";
2
+ import { spawnProcess, waitForChildProcessWithTermination } from "../../utils/child-process.js";
3
+ import { wrapToolDefinition } from "./tool-definition-wrapper.js";
4
+ const runProcessSchema = Type.Object({
5
+ executable: Type.String({ description: "Exact owner-allowed executable name or path." }),
6
+ args: Type.Optional(Type.Array(Type.String(), { description: "Direct argv entries. No shell parsing occurs." })),
7
+ }, { additionalProperties: false });
8
+ const SAFE_ENVIRONMENT_VARIABLES = [
9
+ "PATH",
10
+ "PATHEXT",
11
+ "SystemRoot",
12
+ "WINDIR",
13
+ "COMSPEC",
14
+ "TMPDIR",
15
+ "TMP",
16
+ "TEMP",
17
+ ];
18
+ function scopedEnvironment(allowedNames) {
19
+ const names = new Set([...SAFE_ENVIRONMENT_VARIABLES, ...allowedNames]);
20
+ const environment = {};
21
+ for (const name of names) {
22
+ const value = process.env[name];
23
+ if (value !== undefined)
24
+ environment[name] = value;
25
+ }
26
+ return environment;
27
+ }
28
+ function collectBoundedOutput(child, maxBytes, abort) {
29
+ let remaining = maxBytes;
30
+ let truncated = false;
31
+ const stdout = [];
32
+ const stderr = [];
33
+ const collect = (target) => (chunk) => {
34
+ if (remaining <= 0)
35
+ return;
36
+ const retained = chunk.subarray(0, remaining);
37
+ target.push(retained);
38
+ remaining -= retained.length;
39
+ if (retained.length < chunk.length || remaining === 0) {
40
+ truncated = true;
41
+ abort();
42
+ }
43
+ };
44
+ child.stdout?.on("data", collect(stdout));
45
+ child.stderr?.on("data", collect(stderr));
46
+ return {
47
+ read: () => ({
48
+ stdout: Buffer.concat(stdout).toString("utf-8"),
49
+ stderr: Buffer.concat(stderr).toString("utf-8"),
50
+ truncated,
51
+ }),
52
+ };
53
+ }
54
+ export function createRunProcessToolDefinition(cwd, options) {
55
+ const allowedExecutables = new Set(options.policy.allowedExecutables);
56
+ return {
57
+ name: "run_process",
58
+ label: "Run Process",
59
+ description: `Run one owner-allowed executable using direct argv without a shell. Allowed: ${options.policy.allowedExecutables.join(", ")}.`,
60
+ promptSnippet: "Run an owner-allowed executable through a constrained direct-argv launcher (not OS isolation).",
61
+ promptGuidelines: [
62
+ "Use only an executable listed by the profile. Arguments are passed literally; shell operators and interpolation are unavailable.",
63
+ "Treat a non-zero exit code, timeout, abort, or output-limit termination as failure.",
64
+ ],
65
+ parameters: runProcessSchema,
66
+ async execute(_toolCallId, input, signal) {
67
+ if (!allowedExecutables.has(input.executable)) {
68
+ throw new Error(`process_executable_denied: '${input.executable}' is not owner-allowed.`);
69
+ }
70
+ const args = input.args ?? [];
71
+ if (input.executable.includes("\0") || args.some((argument) => argument.includes("\0"))) {
72
+ throw new Error("process_argument_invalid: executable and argv must not contain NUL bytes.");
73
+ }
74
+ const startedAt = Date.now();
75
+ const outputLimitAbort = new AbortController();
76
+ let outputLimitReached = false;
77
+ const child = (options.spawn ?? spawnProcess)(input.executable, [...args], {
78
+ cwd,
79
+ env: scopedEnvironment(options.policy.allowedEnvironmentVariables),
80
+ stdio: ["ignore", "pipe", "pipe"],
81
+ windowsHide: true,
82
+ });
83
+ const output = collectBoundedOutput(child, options.policy.maxOutputBytes, () => {
84
+ outputLimitReached = true;
85
+ outputLimitAbort.abort();
86
+ });
87
+ const combinedAbort = new AbortController();
88
+ const abort = () => combinedAbort.abort();
89
+ if (signal?.aborted || outputLimitAbort.signal.aborted)
90
+ abort();
91
+ else {
92
+ signal?.addEventListener("abort", abort, { once: true });
93
+ outputLimitAbort.signal.addEventListener("abort", abort, { once: true });
94
+ }
95
+ try {
96
+ const terminal = await waitForChildProcessWithTermination(child, {
97
+ signal: combinedAbort.signal,
98
+ timeoutMs: options.maxWallClockMs > 0 ? options.maxWallClockMs : undefined,
99
+ killGraceMs: 2_000,
100
+ });
101
+ const captured = output.read();
102
+ const outcome = outputLimitReached
103
+ ? "output_limit"
104
+ : terminal.reason === "timeout"
105
+ ? "timeout"
106
+ : terminal.reason === "aborted"
107
+ ? "aborted"
108
+ : terminal.code === 0
109
+ ? "exited"
110
+ : "failed";
111
+ const body = [
112
+ `outcome: ${outcome}`,
113
+ `exitCode: ${terminal.code ?? "null"}`,
114
+ captured.stdout ? `stdout:\n${captured.stdout}` : "stdout: (empty)",
115
+ captured.stderr ? `stderr:\n${captured.stderr}` : "stderr: (empty)",
116
+ ].join("\n");
117
+ return {
118
+ content: [{ type: "text", text: body }],
119
+ details: {
120
+ outcome,
121
+ executable: input.executable,
122
+ exitCode: terminal.code,
123
+ durationMs: Date.now() - startedAt,
124
+ truncated: captured.truncated,
125
+ },
126
+ };
127
+ }
128
+ finally {
129
+ signal?.removeEventListener("abort", abort);
130
+ outputLimitAbort.signal.removeEventListener("abort", abort);
131
+ }
132
+ },
133
+ };
134
+ }
135
+ export function createRunProcessTool(cwd, options) {
136
+ return wrapToolDefinition(createRunProcessToolDefinition(cwd, options));
137
+ }
138
+ //# sourceMappingURL=run-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-process.js","sourceRoot":"","sources":["../../../src/core/tools/run-process.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChildProcess } from \"node:child_process\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { spawnProcess, waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport type { OrchestrationExecutionPolicy } from \"../orchestration/contracts.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst runProcessSchema = Type.Object(\n\t{\n\t\texecutable: Type.String({ description: \"Exact owner-allowed executable name or path.\" }),\n\t\targs: Type.Optional(Type.Array(Type.String(), { description: \"Direct argv entries. No shell parsing occurs.\" })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type RunProcessInput = Static<typeof runProcessSchema>;\n\nexport interface RunProcessDetails {\n\toutcome: \"exited\" | \"failed\" | \"aborted\" | \"timeout\" | \"output_limit\";\n\texecutable: string;\n\texitCode: number | null;\n\tdurationMs: number;\n\ttruncated: boolean;\n}\n\nexport interface RunProcessToolOptions {\n\tpolicy: OrchestrationExecutionPolicy;\n\tmaxWallClockMs: number;\n\tspawn?: typeof spawnProcess;\n}\n\nconst SAFE_ENVIRONMENT_VARIABLES = [\n\t\"PATH\",\n\t\"PATHEXT\",\n\t\"SystemRoot\",\n\t\"WINDIR\",\n\t\"COMSPEC\",\n\t\"TMPDIR\",\n\t\"TMP\",\n\t\"TEMP\",\n] as const;\n\nfunction scopedEnvironment(allowedNames: readonly string[]): NodeJS.ProcessEnv {\n\tconst names = new Set<string>([...SAFE_ENVIRONMENT_VARIABLES, ...allowedNames]);\n\tconst environment: NodeJS.ProcessEnv = {};\n\tfor (const name of names) {\n\t\tconst value = process.env[name];\n\t\tif (value !== undefined) environment[name] = value;\n\t}\n\treturn environment;\n}\n\nfunction collectBoundedOutput(\n\tchild: ChildProcess,\n\tmaxBytes: number,\n\tabort: () => void,\n): {\n\tread(): { stdout: string; stderr: string; truncated: boolean };\n} {\n\tlet remaining = maxBytes;\n\tlet truncated = false;\n\tconst stdout: Buffer[] = [];\n\tconst stderr: Buffer[] = [];\n\tconst collect = (target: Buffer[]) => (chunk: Buffer) => {\n\t\tif (remaining <= 0) return;\n\t\tconst retained = chunk.subarray(0, remaining);\n\t\ttarget.push(retained);\n\t\tremaining -= retained.length;\n\t\tif (retained.length < chunk.length || remaining === 0) {\n\t\t\ttruncated = true;\n\t\t\tabort();\n\t\t}\n\t};\n\tchild.stdout?.on(\"data\", collect(stdout));\n\tchild.stderr?.on(\"data\", collect(stderr));\n\treturn {\n\t\tread: () => ({\n\t\t\tstdout: Buffer.concat(stdout).toString(\"utf-8\"),\n\t\t\tstderr: Buffer.concat(stderr).toString(\"utf-8\"),\n\t\t\ttruncated,\n\t\t}),\n\t};\n}\n\nexport function createRunProcessToolDefinition(cwd: string, options: RunProcessToolOptions): ToolDefinition {\n\tconst allowedExecutables = new Set(options.policy.allowedExecutables);\n\treturn {\n\t\tname: \"run_process\",\n\t\tlabel: \"Run Process\",\n\t\tdescription: `Run one owner-allowed executable using direct argv without a shell. Allowed: ${options.policy.allowedExecutables.join(\", \")}.`,\n\t\tpromptSnippet: \"Run an owner-allowed executable through a constrained direct-argv launcher (not OS isolation).\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use only an executable listed by the profile. Arguments are passed literally; shell operators and interpolation are unavailable.\",\n\t\t\t\"Treat a non-zero exit code, timeout, abort, or output-limit termination as failure.\",\n\t\t],\n\t\tparameters: runProcessSchema,\n\t\tasync execute(_toolCallId, input: RunProcessInput, signal) {\n\t\t\tif (!allowedExecutables.has(input.executable)) {\n\t\t\t\tthrow new Error(`process_executable_denied: '${input.executable}' is not owner-allowed.`);\n\t\t\t}\n\t\t\tconst args = input.args ?? [];\n\t\t\tif (input.executable.includes(\"\\0\") || args.some((argument) => argument.includes(\"\\0\"))) {\n\t\t\t\tthrow new Error(\"process_argument_invalid: executable and argv must not contain NUL bytes.\");\n\t\t\t}\n\t\t\tconst startedAt = Date.now();\n\t\t\tconst outputLimitAbort = new AbortController();\n\t\t\tlet outputLimitReached = false;\n\t\t\tconst child = (options.spawn ?? spawnProcess)(input.executable, [...args], {\n\t\t\t\tcwd,\n\t\t\t\tenv: scopedEnvironment(options.policy.allowedEnvironmentVariables),\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t\tconst output = collectBoundedOutput(child, options.policy.maxOutputBytes, () => {\n\t\t\t\toutputLimitReached = true;\n\t\t\t\toutputLimitAbort.abort();\n\t\t\t});\n\t\t\tconst combinedAbort = new AbortController();\n\t\t\tconst abort = () => combinedAbort.abort();\n\t\t\tif (signal?.aborted || outputLimitAbort.signal.aborted) abort();\n\t\t\telse {\n\t\t\t\tsignal?.addEventListener(\"abort\", abort, { once: true });\n\t\t\t\toutputLimitAbort.signal.addEventListener(\"abort\", abort, { once: true });\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\t\t\tsignal: combinedAbort.signal,\n\t\t\t\t\ttimeoutMs: options.maxWallClockMs > 0 ? options.maxWallClockMs : undefined,\n\t\t\t\t\tkillGraceMs: 2_000,\n\t\t\t\t});\n\t\t\t\tconst captured = output.read();\n\t\t\t\tconst outcome: RunProcessDetails[\"outcome\"] = outputLimitReached\n\t\t\t\t\t? \"output_limit\"\n\t\t\t\t\t: terminal.reason === \"timeout\"\n\t\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t\t: terminal.reason === \"aborted\"\n\t\t\t\t\t\t\t? \"aborted\"\n\t\t\t\t\t\t\t: terminal.code === 0\n\t\t\t\t\t\t\t\t? \"exited\"\n\t\t\t\t\t\t\t\t: \"failed\";\n\t\t\t\tconst body = [\n\t\t\t\t\t`outcome: ${outcome}`,\n\t\t\t\t\t`exitCode: ${terminal.code ?? \"null\"}`,\n\t\t\t\t\tcaptured.stdout ? `stdout:\\n${captured.stdout}` : \"stdout: (empty)\",\n\t\t\t\t\tcaptured.stderr ? `stderr:\\n${captured.stderr}` : \"stderr: (empty)\",\n\t\t\t\t].join(\"\\n\");\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: body }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\toutcome,\n\t\t\t\t\t\texecutable: input.executable,\n\t\t\t\t\t\texitCode: terminal.code,\n\t\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t\t\ttruncated: captured.truncated,\n\t\t\t\t\t} satisfies RunProcessDetails,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tsignal?.removeEventListener(\"abort\", abort);\n\t\t\t\toutputLimitAbort.signal.removeEventListener(\"abort\", abort);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function createRunProcessTool(cwd: string, options: RunProcessToolOptions): AgentTool {\n\treturn wrapToolDefinition(createRunProcessToolDefinition(cwd, options));\n}\n"]}
@@ -9,6 +9,7 @@ declare const taskStepsSchema: Type.TObject<{
9
9
  status: Type.TOptional<Type.TUnion<[Type.TLiteral<"pending">, Type.TLiteral<"in_progress">, Type.TLiteral<"completed">, Type.TLiteral<"blocked">, Type.TLiteral<"cancelled">]>>;
10
10
  priority: Type.TOptional<Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"normal">, Type.TLiteral<"high">]>>;
11
11
  owner: Type.TOptional<Type.TString>;
12
+ requirementIds: Type.TOptional<Type.TArray<Type.TString>>;
12
13
  note: Type.TOptional<Type.TString>;
13
14
  evidence: Type.TOptional<Type.TArray<Type.TString>>;
14
15
  }>>>;
@@ -18,6 +19,7 @@ declare const taskStepsSchema: Type.TObject<{
18
19
  status: Type.TOptional<Type.TUnion<[Type.TLiteral<"pending">, Type.TLiteral<"in_progress">, Type.TLiteral<"completed">, Type.TLiteral<"blocked">, Type.TLiteral<"cancelled">]>>;
19
20
  priority: Type.TOptional<Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"normal">, Type.TLiteral<"high">]>>;
20
21
  owner: Type.TOptional<Type.TString>;
22
+ requirementIds: Type.TOptional<Type.TArray<Type.TString>>;
21
23
  note: Type.TOptional<Type.TString>;
22
24
  evidence: Type.TOptional<Type.TArray<Type.TString>>;
23
25
  clearCompleted: Type.TOptional<Type.TBoolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"task-steps.d.ts","sourceRoot":"","sources":["../../../src/core/tools/task-steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAaN,KAAK,cAAc,EAEnB,MAAM,wBAAwB,CAAC;AA2BhC,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;EAuCpB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4FAA4F;IAC5F,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,yBAAyB;IACzC,iBAAiB,EAAE,MAAM,cAAc,GAAG,SAAS,CAAC;IACpD,kBAAkB,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AA6DD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,yBAAyB,GAAG,cAAc,CAyI7F","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport {\n\taddTaskStep,\n\tclearTaskSteps,\n\tcompactTaskSteps,\n\tcreateTaskStepsState,\n\tfindOpenDuplicateStep,\n\tformatTaskSteps,\n\thasUnverifiedCompletedStep,\n\tMAX_TASK_STEPS,\n\tresolveTaskStepSelector,\n\tsetTaskSteps,\n\ttype TaskStep,\n\ttype TaskStepInput,\n\ttype TaskStepsState,\n\tupdateTaskStep,\n} from \"../tasks/task-state.ts\";\n\nconst statusSchema = Type.Union([\n\tType.Literal(\"pending\"),\n\tType.Literal(\"in_progress\"),\n\tType.Literal(\"completed\"),\n\tType.Literal(\"blocked\"),\n\tType.Literal(\"cancelled\"),\n]);\n\nconst prioritySchema = Type.Union([Type.Literal(\"low\"), Type.Literal(\"normal\"), Type.Literal(\"high\")]);\n\nconst stepInputSchema = Type.Object(\n\t{\n\t\tcontent: Type.String({ minLength: 1, maxLength: 2_000, description: \"Imperative task step text.\" }),\n\t\tactiveForm: Type.Optional(\n\t\t\tType.String({ minLength: 1, maxLength: 2_000, description: \"Short present-progress label for active UI.\" }),\n\t\t),\n\t\tstatus: Type.Optional(statusSchema),\n\t\tpriority: Type.Optional(prioritySchema),\n\t\towner: Type.Optional(Type.String({ maxLength: 200 })),\n\t\tnote: Type.Optional(Type.String({ maxLength: 4_000 })),\n\t\tevidence: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 2_000 }), { maxItems: 32 })),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst taskStepsSchema = Type.Object(\n\t{\n\t\taction: Type.Union(\n\t\t\t[\n\t\t\t\tType.Literal(\"set\"),\n\t\t\t\tType.Literal(\"add\"),\n\t\t\t\tType.Literal(\"update\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"clear\"),\n\t\t\t\tType.Literal(\"compact\"),\n\t\t\t\tType.Literal(\"intake\"),\n\t\t\t],\n\t\t\t{ description: \"Checklist action. Use list to read without mutation.\" },\n\t\t),\n\t\tsteps: Type.Optional(\n\t\t\tType.Array(stepInputSchema, {\n\t\t\t\tmaxItems: MAX_TASK_STEPS,\n\t\t\t\tdescription: \"Complete replacement list for set/intake. Intake preserves every supplied item in order.\",\n\t\t\t}),\n\t\t),\n\t\tid: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription: \"For update: current/active, exact step id, unique id prefix, or unique content selector.\",\n\t\t\t}),\n\t\t),\n\t\tcontent: Type.Optional(Type.String({ minLength: 1, maxLength: 2_000 })),\n\t\tactiveForm: Type.Optional(Type.String({ maxLength: 2_000 })),\n\t\tstatus: Type.Optional(statusSchema),\n\t\tpriority: Type.Optional(prioritySchema),\n\t\towner: Type.Optional(Type.String({ maxLength: 200 })),\n\t\tnote: Type.Optional(Type.String({ maxLength: 4_000 })),\n\t\tevidence: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 2_000 }), { maxItems: 32 })),\n\t\tclearCompleted: Type.Optional(\n\t\t\tType.Boolean({ description: \"For list: compact completed and cancelled steps before rendering.\" }),\n\t\t),\n\t\tshowCompleted: Type.Optional(Type.Boolean({ description: \"Include completed and cancelled steps in output.\" })),\n\t\tmaxItems: Type.Optional(Type.Integer({ minimum: 1, maximum: MAX_TASK_STEPS })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type TaskStepsToolInput = Static<typeof taskStepsSchema>;\nexport type TaskStepsAction = TaskStepsToolInput[\"action\"];\n\nexport interface TaskStepsToolDetails {\n\taction: TaskStepsAction;\n\tapplied: boolean;\n\terror?: string;\n\tstate?: TaskStepsState;\n\tstepCount?: number;\n\topenStepCount?: number;\n\tverificationNudgeNeeded?: boolean;\n\tshowCompleted?: boolean;\n\t/** Set when `add` was a no-op because an open step already carries this content. */\n\tduplicateOfStepId?: string;\n\t/** Step ids silently demoted to pending because another step became active in this call. */\n\tdemotedStepIds?: readonly string[];\n}\n\nexport interface TaskStepsToolDependencies {\n\tgetTaskStepsState: () => TaskStepsState | undefined;\n\tsaveTaskStepsState: (state: TaskStepsState) => void;\n\tnow?: () => string;\n}\n\nfunction toTaskStepInput(input: TaskStepsToolInput): TaskStepInput {\n\treturn {\n\t\tcontent: input.content ?? \"\",\n\t\tactiveForm: input.activeForm,\n\t\tstatus: input.status,\n\t\tpriority: input.priority,\n\t\towner: input.owner,\n\t\tnote: input.note,\n\t\tevidence: input.evidence,\n\t};\n}\n\nfunction counts(\n\tstate: TaskStepsState,\n): Pick<TaskStepsToolDetails, \"stepCount\" | \"openStepCount\" | \"verificationNudgeNeeded\"> {\n\tconst openStepCount = state.steps.filter(\n\t\t(step) => step.status !== \"completed\" && step.status !== \"cancelled\",\n\t).length;\n\treturn {\n\t\tstepCount: state.steps.length,\n\t\topenStepCount,\n\t\tverificationNudgeNeeded: hasUnverifiedCompletedStep(state),\n\t};\n}\n\n/** Ids (from `resultSteps`, index-aligned with `inputs`) whose status was set explicitly by the caller. */\nfunction explicitStatusStepIds(inputs: readonly TaskStepInput[], resultSteps: readonly TaskStep[]): Set<string> {\n\tconst ids = new Set<string>();\n\tinputs.forEach((stepInput, index) => {\n\t\tif (stepInput.status !== undefined) {\n\t\t\tconst id = resultSteps[index]?.id;\n\t\t\tif (id) ids.add(id);\n\t\t}\n\t});\n\treturn ids;\n}\n\n/**\n * Steps that were in_progress before this call and are pending after, excluding any step whose\n * new status was set explicitly by the caller (an explicit change is not a \"silent\" demotion).\n */\nfunction computeDemotedStepIds(\n\tbefore: TaskStepsState,\n\tafter: TaskStepsState,\n\texcludeIds: ReadonlySet<string>,\n): string[] {\n\tconst beforeActiveIds = new Set(before.steps.filter((step) => step.status === \"in_progress\").map((step) => step.id));\n\treturn after.steps\n\t\t.filter((step) => beforeActiveIds.has(step.id) && step.status === \"pending\" && !excludeIds.has(step.id))\n\t\t.map((step) => step.id);\n}\n\nfunction errorResult(action: TaskStepsAction, error: string, state?: TaskStepsState) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text: `task_steps ${action} failed: ${error}` }],\n\t\tdetails: { action, applied: false, error, state, ...(state ? counts(state) : {}) } satisfies TaskStepsToolDetails,\n\t};\n}\n\nexport function createTaskStepsToolDefinition(deps: TaskStepsToolDependencies): ToolDefinition {\n\tconst now = deps.now ?? (() => new Date().toISOString());\n\treturn {\n\t\tname: \"task_steps\",\n\t\tlabel: \"Task Steps\",\n\t\tdescription:\n\t\t\t\"Maintain the current session's native ordered checklist for multi-step work. Supports pending, in_progress, completed, blocked, and cancelled steps with notes and evidence. State is isolated to and persisted with the active session; use native goal for durable outcome requirements and native delegate/delegate_status for background workers.\",\n\t\tpromptSnippet: \"Track and drain multi-step work with a native session checklist.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use task_steps for complex work, explicit task-tracking requests, and harness/self-improvement work; keep exactly one step in_progress while actively working.\",\n\t\t\t\"Always address the first open task step before unrelated work: start it, complete/block/cancel it with evidence, ask one clarifying question, or explicitly defer or reorder it.\",\n\t\t\t\"Mark steps completed as soon as evidence is gathered, and attach concise evidence or a blocker reason through update.\",\n\t\t\t\"Use action=intake with a complete steps array when preserving a raw multi-item dump; retain every item and do not silently drop entries.\",\n\t\t\t\"Drain task_steps before final responses: leave no stale in_progress step, and explicitly discuss or defer remaining pending or blocked work.\",\n\t\t\t\"Use goal for the durable goal ledger and delegate/delegate_status for worker lanes; do not emulate background execution inside task_steps.\",\n\t\t],\n\t\tparameters: taskStepsSchema,\n\t\tasync execute(_toolCallId, input: TaskStepsToolInput) {\n\t\t\tconst timestamp = now();\n\t\t\tconst current = deps.getTaskStepsState();\n\t\t\tconst before = current ?? createTaskStepsState(timestamp);\n\t\t\tlet state = before;\n\t\t\tlet duplicateStepId: string | undefined;\n\t\t\tlet demotedStepIds: readonly string[] = [];\n\t\t\ttry {\n\t\t\t\tswitch (input.action) {\n\t\t\t\t\tcase \"set\":\n\t\t\t\t\t\tif (!input.steps) return errorResult(input.action, \"set requires steps[].\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"intake\":\n\t\t\t\t\t\tif (!input.steps)\n\t\t\t\t\t\t\treturn errorResult(input.action, \"intake requires a complete steps[] list.\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"add\":\n\t\t\t\t\t\tstate = addTaskStep(state, toTaskStepInput(input), timestamp);\n\t\t\t\t\t\tif (state === before) {\n\t\t\t\t\t\t\t// The reducer returned the unchanged state: an open step already carries this\n\t\t\t\t\t\t\t// content, so nothing was created. Name the existing step in the response.\n\t\t\t\t\t\t\tduplicateStepId = findOpenDuplicateStep(before.steps, input.content ?? \"\")?.id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\tif (!input.id?.trim())\n\t\t\t\t\t\t\treturn errorResult(input.action, \"update requires id or a unique selector.\", current);\n\t\t\t\t\t\tconst selected = resolveTaskStepSelector(before.steps, input.id);\n\t\t\t\t\t\tstate = updateTaskStep(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tinput.id,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontent: input.content,\n\t\t\t\t\t\t\t\tactiveForm: input.activeForm,\n\t\t\t\t\t\t\t\tstatus: input.status,\n\t\t\t\t\t\t\t\tpriority: input.priority,\n\t\t\t\t\t\t\t\towner: input.owner,\n\t\t\t\t\t\t\t\tnote: input.note,\n\t\t\t\t\t\t\t\tevidence: input.evidence,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttimestamp,\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Exclude the explicitly targeted step: its own status change was requested by\n\t\t\t\t\t\t// the caller, so it is never a \"silent\" demotion even if it moved to pending.\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(before, state, new Set([selected.id]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"clear\":\n\t\t\t\t\t\tstate = clearTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"compact\":\n\t\t\t\t\t\tstate = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"list\":\n\t\t\t\t\t\tif (input.clearCompleted) state = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst isNoopDuplicateAdd = input.action === \"add\" && state === before;\n\t\t\t\tconst mutated = (input.action !== \"list\" || input.clearCompleted === true) && !isNoopDuplicateAdd;\n\t\t\t\tif (mutated) deps.saveTaskStepsState(state);\n\n\t\t\t\tconst stateCounts = counts(state);\n\t\t\t\tconst noticeLines: string[] = [];\n\t\t\t\tif (duplicateStepId) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t`Duplicate open step ignored; existing ${duplicateStepId} already tracks this content.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (demotedStepIds.length > 0) {\n\t\t\t\t\tnoticeLines.push(`Demoted to pending because another step became active: ${demotedStepIds.join(\", \")}.`);\n\t\t\t\t}\n\t\t\t\tif (stateCounts.verificationNudgeNeeded) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t\"Reminder: a completed step has no evidence attached; attach evidence via update before treating it as verified.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst notices = noticeLines.length > 0 ? `\\n${noticeLines.join(\"\\n\")}` : \"\";\n\n\t\t\t\tconst headerAction =\n\t\t\t\t\tinput.action === \"list\"\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: `task_steps ${input.action} ${duplicateStepId ? \"ignored (duplicate)\" : \"recorded\"}.\\n`;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${headerAction}${formatTaskSteps(state, {\n\t\t\t\t\t\t\t\tincludeTerminal: input.showCompleted,\n\t\t\t\t\t\t\t\tmaxItems: input.maxItems,\n\t\t\t\t\t\t\t})}${notices}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\taction: input.action,\n\t\t\t\t\t\tapplied: true,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t...stateCounts,\n\t\t\t\t\t\tshowCompleted: input.showCompleted,\n\t\t\t\t\t\tduplicateOfStepId: duplicateStepId,\n\t\t\t\t\t\tdemotedStepIds: demotedStepIds.length > 0 ? demotedStepIds : undefined,\n\t\t\t\t\t} satisfies TaskStepsToolDetails,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn errorResult(input.action, error instanceof Error ? error.message : String(error), current);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"task-steps.d.ts","sourceRoot":"","sources":["../../../src/core/tools/task-steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAaN,KAAK,cAAc,EAEnB,MAAM,wBAAwB,CAAC;AAuChC,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;EA6CpB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4FAA4F;IAC5F,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,yBAAyB;IACzC,iBAAiB,EAAE,MAAM,cAAc,GAAG,SAAS,CAAC;IACpD,kBAAkB,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAmID,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,yBAAyB,GAAG,cAAc,CAiK7F","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport {\n\taddTaskStep,\n\tclearTaskSteps,\n\tcompactTaskSteps,\n\tcreateTaskStepsState,\n\tfindOpenDuplicateStep,\n\tformatTaskSteps,\n\thasUnverifiedCompletedStep,\n\tMAX_TASK_STEPS,\n\tresolveTaskStepSelector,\n\tsetTaskSteps,\n\ttype TaskStep,\n\ttype TaskStepInput,\n\ttype TaskStepsState,\n\tupdateTaskStep,\n} from \"../tasks/task-state.ts\";\nimport {\n\temptyOrchestrationCall,\n\tOrchestrationPanelComponent,\n\ttype OrchestrationPanelModel,\n\ttaskStepPanelRow,\n} from \"./orchestration-panel.ts\";\n\nconst statusSchema = Type.Union([\n\tType.Literal(\"pending\"),\n\tType.Literal(\"in_progress\"),\n\tType.Literal(\"completed\"),\n\tType.Literal(\"blocked\"),\n\tType.Literal(\"cancelled\"),\n]);\n\nconst prioritySchema = Type.Union([Type.Literal(\"low\"), Type.Literal(\"normal\"), Type.Literal(\"high\")]);\n\nconst stepInputSchema = Type.Object(\n\t{\n\t\tcontent: Type.String({ minLength: 1, maxLength: 2_000, description: \"Imperative task step text.\" }),\n\t\tactiveForm: Type.Optional(\n\t\t\tType.String({ minLength: 1, maxLength: 2_000, description: \"Short present-progress label for active UI.\" }),\n\t\t),\n\t\tstatus: Type.Optional(statusSchema),\n\t\tpriority: Type.Optional(prioritySchema),\n\t\towner: Type.Optional(Type.String({ maxLength: 200 })),\n\t\trequirementIds: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1, maxLength: 200 }), {\n\t\t\t\tmaxItems: 32,\n\t\t\t\tdescription: \"Goal requirement ids this foreground step advances.\",\n\t\t\t}),\n\t\t),\n\t\tnote: Type.Optional(Type.String({ maxLength: 4_000 })),\n\t\tevidence: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 2_000 }), { maxItems: 32 })),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst taskStepsSchema = Type.Object(\n\t{\n\t\taction: Type.Union(\n\t\t\t[\n\t\t\t\tType.Literal(\"set\"),\n\t\t\t\tType.Literal(\"add\"),\n\t\t\t\tType.Literal(\"update\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"clear\"),\n\t\t\t\tType.Literal(\"compact\"),\n\t\t\t\tType.Literal(\"intake\"),\n\t\t\t],\n\t\t\t{ description: \"Checklist action. Use list to read without mutation.\" },\n\t\t),\n\t\tsteps: Type.Optional(\n\t\t\tType.Array(stepInputSchema, {\n\t\t\t\tmaxItems: MAX_TASK_STEPS,\n\t\t\t\tdescription: \"Complete replacement list for set/intake. Intake preserves every supplied item in order.\",\n\t\t\t}),\n\t\t),\n\t\tid: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription: \"For update: current/active, exact step id, unique id prefix, or unique content selector.\",\n\t\t\t}),\n\t\t),\n\t\tcontent: Type.Optional(Type.String({ minLength: 1, maxLength: 2_000 })),\n\t\tactiveForm: Type.Optional(Type.String({ maxLength: 2_000 })),\n\t\tstatus: Type.Optional(statusSchema),\n\t\tpriority: Type.Optional(prioritySchema),\n\t\towner: Type.Optional(Type.String({ maxLength: 200 })),\n\t\trequirementIds: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1, maxLength: 200 }), {\n\t\t\t\tmaxItems: 32,\n\t\t\t\tdescription: \"Goal requirement ids this foreground step advances; [] clears existing links.\",\n\t\t\t}),\n\t\t),\n\t\tnote: Type.Optional(Type.String({ maxLength: 4_000 })),\n\t\tevidence: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 2_000 }), { maxItems: 32 })),\n\t\tclearCompleted: Type.Optional(\n\t\t\tType.Boolean({ description: \"For list: compact completed and cancelled steps before rendering.\" }),\n\t\t),\n\t\tshowCompleted: Type.Optional(Type.Boolean({ description: \"Include completed and cancelled steps in output.\" })),\n\t\tmaxItems: Type.Optional(Type.Integer({ minimum: 1, maximum: MAX_TASK_STEPS })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type TaskStepsToolInput = Static<typeof taskStepsSchema>;\nexport type TaskStepsAction = TaskStepsToolInput[\"action\"];\n\nexport interface TaskStepsToolDetails {\n\taction: TaskStepsAction;\n\tapplied: boolean;\n\terror?: string;\n\tstate?: TaskStepsState;\n\tstepCount?: number;\n\topenStepCount?: number;\n\tverificationNudgeNeeded?: boolean;\n\tshowCompleted?: boolean;\n\t/** Set when `add` was a no-op because an open step already carries this content. */\n\tduplicateOfStepId?: string;\n\t/** Step ids silently demoted to pending because another step became active in this call. */\n\tdemotedStepIds?: readonly string[];\n}\n\nexport interface TaskStepsToolDependencies {\n\tgetTaskStepsState: () => TaskStepsState | undefined;\n\tsaveTaskStepsState: (state: TaskStepsState) => void;\n\tnow?: () => string;\n}\n\nfunction toTaskStepInput(input: TaskStepsToolInput): TaskStepInput {\n\treturn {\n\t\tcontent: input.content ?? \"\",\n\t\tactiveForm: input.activeForm,\n\t\tstatus: input.status,\n\t\tpriority: input.priority,\n\t\towner: input.owner,\n\t\trequirementIds: input.requirementIds,\n\t\tnote: input.note,\n\t\tevidence: input.evidence,\n\t};\n}\n\nfunction counts(\n\tstate: TaskStepsState,\n): Pick<TaskStepsToolDetails, \"stepCount\" | \"openStepCount\" | \"verificationNudgeNeeded\"> {\n\tconst openStepCount = state.steps.filter(\n\t\t(step) => step.status !== \"completed\" && step.status !== \"cancelled\",\n\t).length;\n\treturn {\n\t\tstepCount: state.steps.length,\n\t\topenStepCount,\n\t\tverificationNudgeNeeded: hasUnverifiedCompletedStep(state),\n\t};\n}\n\n/** Ids (from `resultSteps`, index-aligned with `inputs`) whose status was set explicitly by the caller. */\nfunction explicitStatusStepIds(inputs: readonly TaskStepInput[], resultSteps: readonly TaskStep[]): Set<string> {\n\tconst ids = new Set<string>();\n\tinputs.forEach((stepInput, index) => {\n\t\tif (stepInput.status !== undefined) {\n\t\t\tconst id = resultSteps[index]?.id;\n\t\t\tif (id) ids.add(id);\n\t\t}\n\t});\n\treturn ids;\n}\n\n/**\n * Steps that were in_progress before this call and are pending after, excluding any step whose\n * new status was set explicitly by the caller (an explicit change is not a \"silent\" demotion).\n */\nfunction computeDemotedStepIds(\n\tbefore: TaskStepsState,\n\tafter: TaskStepsState,\n\texcludeIds: ReadonlySet<string>,\n): string[] {\n\tconst beforeActiveIds = new Set(before.steps.filter((step) => step.status === \"in_progress\").map((step) => step.id));\n\treturn after.steps\n\t\t.filter((step) => beforeActiveIds.has(step.id) && step.status === \"pending\" && !excludeIds.has(step.id))\n\t\t.map((step) => step.id);\n}\n\nfunction errorResult(action: TaskStepsAction, error: string, state?: TaskStepsState) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text: `task_steps ${action} failed: ${error}` }],\n\t\tdetails: { action, applied: false, error, state, ...(state ? counts(state) : {}) } satisfies TaskStepsToolDetails,\n\t};\n}\n\nfunction taskStepsPanelModel(details: TaskStepsToolDetails, expanded: boolean): OrchestrationPanelModel {\n\tconst state = details.state;\n\tif (!state) {\n\t\treturn {\n\t\t\tlabel: \"task steps\",\n\t\t\taction: details.action,\n\t\t\tstatus: details.error ? \"error\" : \"idle\",\n\t\t\temptyText: details.error ?? \"No checklist state.\",\n\t\t};\n\t}\n\tconst active = state.steps.filter((step) => step.status === \"in_progress\");\n\tconst blocked = state.steps.filter((step) => step.status === \"blocked\");\n\tconst pending = state.steps.filter((step) => step.status === \"pending\");\n\tconst completed = state.steps.filter((step) => step.status === \"completed\");\n\tconst cancelled = state.steps.filter((step) => step.status === \"cancelled\");\n\tconst open = [...active, ...blocked, ...pending];\n\tconst terminal = details.showCompleted ? [...completed, ...cancelled] : [];\n\tconst candidates = [...open, ...terminal];\n\tconst limit = expanded ? 24 : 8;\n\tconst rows = candidates.slice(0, limit).map(taskStepPanelRow);\n\tconst archivedDone = state.archive.completed + state.archive.cancelled;\n\tconst done = completed.length + state.archive.completed;\n\tconst summary = [\n\t\tactive.length ? `${active.length} working` : undefined,\n\t\t`${open.length} open`,\n\t\t`${done} done`,\n\t\tblocked.length ? `${blocked.length} blocked` : undefined,\n\t\tarchivedDone ? `${archivedDone} archived` : undefined,\n\t].filter((value): value is string => value !== undefined);\n\tconst notices = [];\n\tif (!details.showCompleted && completed.length + cancelled.length > 0) {\n\t\tnotices.push({\n\t\t\tstatus: \"info\" as const,\n\t\t\ttext: `${completed.length + cancelled.length} finished step${completed.length + cancelled.length === 1 ? \"\" : \"s\"} hidden`,\n\t\t});\n\t}\n\tif (details.duplicateOfStepId) {\n\t\tnotices.push({ status: \"info\" as const, text: \"Duplicate open step ignored.\" });\n\t}\n\tif (details.demotedStepIds?.length) {\n\t\tnotices.push({\n\t\t\tstatus: \"info\" as const,\n\t\t\ttext: `${details.demotedStepIds.length} previous working step${details.demotedStepIds.length === 1 ? \"\" : \"s\"} returned to pending.`,\n\t\t});\n\t}\n\tif (details.verificationNudgeNeeded) {\n\t\tnotices.push({ status: \"warning\" as const, text: \"Completed work still needs attached evidence.\" });\n\t}\n\tconst status = details.error\n\t\t? \"error\"\n\t\t: blocked.length > 0\n\t\t\t? \"warning\"\n\t\t\t: active.length > 0\n\t\t\t\t? \"running\"\n\t\t\t\t: open.length === 0 && state.steps.length > 0\n\t\t\t\t\t? \"success\"\n\t\t\t\t\t: \"idle\";\n\treturn {\n\t\tlabel: \"task steps\",\n\t\taction: details.action,\n\t\tstatus,\n\t\tsummary,\n\t\trows,\n\t\tnotices,\n\t\temptyText: state.steps.length === 0 ? \"No tracked steps.\" : \"All open steps are done.\",\n\t\thiddenRowCount: Math.max(0, candidates.length - rows.length),\n\t};\n}\n\nexport function createTaskStepsToolDefinition(deps: TaskStepsToolDependencies): ToolDefinition {\n\tconst now = deps.now ?? (() => new Date().toISOString());\n\treturn {\n\t\tname: \"task_steps\",\n\t\tlabel: \"Task Steps\",\n\t\tdescription:\n\t\t\t\"Maintain the current session's native ordered checklist for multi-step work. Supports pending, in_progress, completed, blocked, and cancelled steps with notes and evidence. State is isolated to and persisted with the active session; use native goal for durable outcome requirements and native delegate/delegate_status for background workers.\",\n\t\tpromptSnippet: \"Track and drain multi-step work with a native session checklist.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use task_steps for complex work, explicit task-tracking requests, and harness/self-improvement work; keep exactly one step in_progress while actively working.\",\n\t\t\t\"Always address the first open task step before unrelated work: start it, complete/block/cancel it with evidence, ask one clarifying question, or explicitly defer or reorder it.\",\n\t\t\t\"Mark steps completed as soon as evidence is gathered, and attach concise evidence or a blocker reason through update.\",\n\t\t\t\"Use action=intake with a complete steps array when preserving a raw multi-item dump; retain every item and do not silently drop entries.\",\n\t\t\t\"When a goal is active, set requirementIds on each step that advances a goal requirement; do not rely on repeating requirement text.\",\n\t\t\t\"Drain task_steps before final responses: leave no stale in_progress step, and explicitly discuss or defer remaining pending or blocked work.\",\n\t\t\t\"Use goal for the durable goal ledger and delegate/delegate_status for worker lanes; do not emulate background execution inside task_steps.\",\n\t\t],\n\t\tparameters: taskStepsSchema,\n\t\trenderShell: \"self\",\n\t\trenderCall() {\n\t\t\treturn emptyOrchestrationCall();\n\t\t},\n\t\trenderResult(result, { expanded, isPartial }, theme) {\n\t\t\tif (isPartial) {\n\t\t\t\treturn new OrchestrationPanelComponent(theme, {\n\t\t\t\t\tlabel: \"task steps\",\n\t\t\t\t\taction: \"updating\",\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst details = result.details as TaskStepsToolDetails | undefined;\n\t\t\tif (!details) {\n\t\t\t\treturn new OrchestrationPanelComponent(theme, {\n\t\t\t\t\tlabel: \"task steps\",\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\temptyText: \"No task-step details were returned.\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn new OrchestrationPanelComponent(theme, taskStepsPanelModel(details, expanded), expanded);\n\t\t},\n\t\tasync execute(_toolCallId, input: TaskStepsToolInput) {\n\t\t\tconst timestamp = now();\n\t\t\tconst current = deps.getTaskStepsState();\n\t\t\tconst before = current ?? createTaskStepsState(timestamp);\n\t\t\tlet state = before;\n\t\t\tlet duplicateStepId: string | undefined;\n\t\t\tlet demotedStepIds: readonly string[] = [];\n\t\t\ttry {\n\t\t\t\tswitch (input.action) {\n\t\t\t\t\tcase \"set\":\n\t\t\t\t\t\tif (!input.steps) return errorResult(input.action, \"set requires steps[].\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"intake\":\n\t\t\t\t\t\tif (!input.steps)\n\t\t\t\t\t\t\treturn errorResult(input.action, \"intake requires a complete steps[] list.\", current);\n\t\t\t\t\t\tstate = setTaskSteps(state, input.steps, timestamp);\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\texplicitStatusStepIds(input.steps, state.steps),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"add\":\n\t\t\t\t\t\tstate = addTaskStep(state, toTaskStepInput(input), timestamp);\n\t\t\t\t\t\tif (state === before) {\n\t\t\t\t\t\t\t// The reducer returned the unchanged state: an open step already carries this\n\t\t\t\t\t\t\t// content, so nothing was created. Name the existing step in the response.\n\t\t\t\t\t\t\tduplicateStepId = findOpenDuplicateStep(before.steps, input.content ?? \"\")?.id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\tif (!input.id?.trim())\n\t\t\t\t\t\t\treturn errorResult(input.action, \"update requires id or a unique selector.\", current);\n\t\t\t\t\t\tconst selected = resolveTaskStepSelector(before.steps, input.id);\n\t\t\t\t\t\tstate = updateTaskStep(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tinput.id,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontent: input.content,\n\t\t\t\t\t\t\t\tactiveForm: input.activeForm,\n\t\t\t\t\t\t\t\tstatus: input.status,\n\t\t\t\t\t\t\t\tpriority: input.priority,\n\t\t\t\t\t\t\t\towner: input.owner,\n\t\t\t\t\t\t\t\trequirementIds: input.requirementIds,\n\t\t\t\t\t\t\t\tnote: input.note,\n\t\t\t\t\t\t\t\tevidence: input.evidence,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttimestamp,\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Exclude the explicitly targeted step: its own status change was requested by\n\t\t\t\t\t\t// the caller, so it is never a \"silent\" demotion even if it moved to pending.\n\t\t\t\t\t\tdemotedStepIds = computeDemotedStepIds(before, state, new Set([selected.id]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"clear\":\n\t\t\t\t\t\tstate = clearTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"compact\":\n\t\t\t\t\t\tstate = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"list\":\n\t\t\t\t\t\tif (input.clearCompleted) state = compactTaskSteps(state, timestamp);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst isNoopDuplicateAdd = input.action === \"add\" && state === before;\n\t\t\t\tconst mutated = (input.action !== \"list\" || input.clearCompleted === true) && !isNoopDuplicateAdd;\n\t\t\t\tif (mutated) deps.saveTaskStepsState(state);\n\n\t\t\t\tconst stateCounts = counts(state);\n\t\t\t\tconst noticeLines: string[] = [];\n\t\t\t\tif (duplicateStepId) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t`Duplicate open step ignored; existing ${duplicateStepId} already tracks this content.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (demotedStepIds.length > 0) {\n\t\t\t\t\tnoticeLines.push(`Demoted to pending because another step became active: ${demotedStepIds.join(\", \")}.`);\n\t\t\t\t}\n\t\t\t\tif (stateCounts.verificationNudgeNeeded) {\n\t\t\t\t\tnoticeLines.push(\n\t\t\t\t\t\t\"Reminder: a completed step has no evidence attached; attach evidence via update before treating it as verified.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst notices = noticeLines.length > 0 ? `\\n${noticeLines.join(\"\\n\")}` : \"\";\n\n\t\t\t\tconst headerAction =\n\t\t\t\t\tinput.action === \"list\"\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: `task_steps ${input.action} ${duplicateStepId ? \"ignored (duplicate)\" : \"recorded\"}.\\n`;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${headerAction}${formatTaskSteps(state, {\n\t\t\t\t\t\t\t\tincludeTerminal: input.showCompleted,\n\t\t\t\t\t\t\t\tmaxItems: input.maxItems,\n\t\t\t\t\t\t\t})}${notices}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\taction: input.action,\n\t\t\t\t\t\tapplied: true,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t...stateCounts,\n\t\t\t\t\t\tshowCompleted: input.showCompleted,\n\t\t\t\t\t\tduplicateOfStepId: duplicateStepId,\n\t\t\t\t\t\tdemotedStepIds: demotedStepIds.length > 0 ? demotedStepIds : undefined,\n\t\t\t\t\t} satisfies TaskStepsToolDetails,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn errorResult(input.action, error instanceof Error ? error.message : String(error), current);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}