@stigmer/runner 3.0.9-dev.20260616060535 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/dist/.build-fingerprint +1 -1
  2. package/dist/__test-utils__/approval-contract/types.d.ts +174 -0
  3. package/dist/__test-utils__/approval-contract/types.js +24 -0
  4. package/dist/__test-utils__/approval-contract/types.js.map +1 -0
  5. package/dist/activities/call-agent-status.d.ts +19 -1
  6. package/dist/activities/call-agent-status.js +64 -5
  7. package/dist/activities/call-agent-status.js.map +1 -1
  8. package/dist/activities/call-llm.js +19 -53
  9. package/dist/activities/call-llm.js.map +1 -1
  10. package/dist/activities/classify-tool-approvals.d.ts +24 -0
  11. package/dist/activities/classify-tool-approvals.js +69 -17
  12. package/dist/activities/classify-tool-approvals.js.map +1 -1
  13. package/dist/activities/discover-mcp-server.d.ts +7 -0
  14. package/dist/activities/discover-mcp-server.js +11 -1
  15. package/dist/activities/discover-mcp-server.js.map +1 -1
  16. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +140 -0
  17. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +130 -0
  18. package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -0
  19. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.d.ts +18 -0
  20. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +123 -0
  21. package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -0
  22. package/dist/activities/execute-cursor/approval-policy.d.ts +17 -61
  23. package/dist/activities/execute-cursor/approval-policy.js +8 -120
  24. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  25. package/dist/activities/execute-cursor/approval-state.d.ts +219 -9
  26. package/dist/activities/execute-cursor/approval-state.js +233 -17
  27. package/dist/activities/execute-cursor/approval-state.js.map +1 -1
  28. package/dist/activities/execute-cursor/capture-flow.d.ts +127 -0
  29. package/dist/activities/execute-cursor/capture-flow.js +234 -0
  30. package/dist/activities/execute-cursor/capture-flow.js.map +1 -0
  31. package/dist/activities/execute-cursor/cas-observations.d.ts +96 -0
  32. package/dist/activities/execute-cursor/cas-observations.js +184 -0
  33. package/dist/activities/execute-cursor/cas-observations.js.map +1 -0
  34. package/dist/activities/execute-cursor/command-provenance.d.ts +62 -0
  35. package/dist/activities/execute-cursor/command-provenance.js +128 -0
  36. package/dist/activities/execute-cursor/command-provenance.js.map +1 -0
  37. package/dist/activities/execute-cursor/exact-apply.d.ts +110 -0
  38. package/dist/activities/execute-cursor/exact-apply.js +204 -0
  39. package/dist/activities/execute-cursor/exact-apply.js.map +1 -0
  40. package/dist/activities/execute-cursor/hook-script.d.ts +53 -24
  41. package/dist/activities/execute-cursor/hook-script.js +310 -47
  42. package/dist/activities/execute-cursor/hook-script.js.map +1 -1
  43. package/dist/activities/execute-cursor/index.d.ts +8 -1
  44. package/dist/activities/execute-cursor/index.js +500 -64
  45. package/dist/activities/execute-cursor/index.js.map +1 -1
  46. package/dist/activities/execute-cursor/message-translator.d.ts +258 -11
  47. package/dist/activities/execute-cursor/message-translator.js +836 -90
  48. package/dist/activities/execute-cursor/message-translator.js.map +1 -1
  49. package/dist/activities/execute-cursor/prompt-builder.d.ts +20 -23
  50. package/dist/activities/execute-cursor/prompt-builder.js +74 -15
  51. package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
  52. package/dist/activities/execute-cursor/workspace-setup.d.ts +17 -0
  53. package/dist/activities/execute-cursor/workspace-setup.js +212 -33
  54. package/dist/activities/execute-cursor/workspace-setup.js.map +1 -1
  55. package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.d.ts +19 -0
  56. package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js +143 -0
  57. package/dist/activities/execute-deep-agent/__test-utils__/gateway-substrate.js.map +1 -0
  58. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +88 -0
  59. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +81 -0
  60. package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -0
  61. package/dist/activities/execute-deep-agent/approval-file-change.d.ts +47 -0
  62. package/dist/activities/execute-deep-agent/approval-file-change.js +68 -0
  63. package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -0
  64. package/dist/activities/execute-deep-agent/attachment-injector.d.ts +8 -1
  65. package/dist/activities/execute-deep-agent/attachment-injector.js +7 -7
  66. package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
  67. package/dist/activities/execute-deep-agent/cas-capture-backend.d.ts +42 -0
  68. package/dist/activities/execute-deep-agent/cas-capture-backend.js +47 -0
  69. package/dist/activities/execute-deep-agent/cas-capture-backend.js.map +1 -0
  70. package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +79 -0
  71. package/dist/activities/execute-deep-agent/cas-capture-observer.js +112 -0
  72. package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -0
  73. package/dist/activities/execute-deep-agent/hitl.d.ts +10 -0
  74. package/dist/activities/execute-deep-agent/hitl.js +5 -1
  75. package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
  76. package/dist/activities/execute-deep-agent/index.d.ts +2 -1
  77. package/dist/activities/execute-deep-agent/index.js +370 -56
  78. package/dist/activities/execute-deep-agent/index.js.map +1 -1
  79. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +7 -1
  80. package/dist/activities/execute-deep-agent/inline-publisher.js +23 -2
  81. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  82. package/dist/activities/execute-deep-agent/setup.d.ts +53 -2
  83. package/dist/activities/execute-deep-agent/setup.js +149 -92
  84. package/dist/activities/execute-deep-agent/setup.js.map +1 -1
  85. package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +36 -0
  86. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +56 -0
  87. package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +1 -0
  88. package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +34 -1
  89. package/dist/activities/execute-deep-agent/status-builder-shared.js +26 -25
  90. package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
  91. package/dist/activities/execute-deep-agent/status-builder.d.ts +11 -5
  92. package/dist/activities/execute-deep-agent/status-builder.js +6 -2
  93. package/dist/activities/execute-deep-agent/status-builder.js.map +1 -1
  94. package/dist/activities/execute-deep-agent/streaming-side-effects.js +2 -19
  95. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  96. package/dist/activities/execute-deep-agent/streaming.js +3 -15
  97. package/dist/activities/execute-deep-agent/streaming.js.map +1 -1
  98. package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -7
  99. package/dist/activities/execute-deep-agent/subagent-transformer.js +23 -7
  100. package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
  101. package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +30 -3
  102. package/dist/activities/execute-deep-agent/subagent-wiring.js +29 -3
  103. package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
  104. package/dist/activities/execute-deep-agent/v3-status-builder.js +6 -2
  105. package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
  106. package/dist/claimcheck/payload-codec.js +9 -5
  107. package/dist/claimcheck/payload-codec.js.map +1 -1
  108. package/dist/client/stigmer-client.d.ts +2 -0
  109. package/dist/client/stigmer-client.js +2 -0
  110. package/dist/client/stigmer-client.js.map +1 -1
  111. package/dist/middleware/approval-gate.d.ts +85 -4
  112. package/dist/middleware/approval-gate.js +165 -38
  113. package/dist/middleware/approval-gate.js.map +1 -1
  114. package/dist/middleware/types.d.ts +2 -5
  115. package/dist/shared/activity-input.d.ts +43 -0
  116. package/dist/shared/activity-input.js +17 -0
  117. package/dist/shared/activity-input.js.map +1 -0
  118. package/dist/shared/approval-canonicalize.d.ts +19 -0
  119. package/dist/shared/approval-canonicalize.js +119 -0
  120. package/dist/shared/approval-canonicalize.js.map +1 -0
  121. package/dist/shared/approval-fingerprint.d.ts +106 -0
  122. package/dist/shared/approval-fingerprint.js +113 -0
  123. package/dist/shared/approval-fingerprint.js.map +1 -0
  124. package/dist/shared/approval-policy.d.ts +182 -12
  125. package/dist/shared/approval-policy.js +213 -27
  126. package/dist/shared/approval-policy.js.map +1 -1
  127. package/dist/shared/args-preview.d.ts +52 -0
  128. package/dist/shared/args-preview.js +93 -0
  129. package/dist/shared/args-preview.js.map +1 -0
  130. package/dist/shared/artifact-storage.d.ts +19 -1
  131. package/dist/shared/artifact-storage.js +48 -11
  132. package/dist/shared/artifact-storage.js.map +1 -1
  133. package/dist/shared/file-change.d.ts +44 -0
  134. package/dist/shared/file-change.js +57 -0
  135. package/dist/shared/file-change.js.map +1 -0
  136. package/dist/shared/file-tools.d.ts +107 -0
  137. package/dist/shared/file-tools.js +168 -0
  138. package/dist/shared/file-tools.js.map +1 -0
  139. package/dist/shared/filereview/capture.d.ts +202 -0
  140. package/dist/shared/filereview/capture.js +498 -0
  141. package/dist/shared/filereview/capture.js.map +1 -0
  142. package/dist/shared/filereview/cas-substrate.d.ts +190 -0
  143. package/dist/shared/filereview/cas-substrate.js +284 -0
  144. package/dist/shared/filereview/cas-substrate.js.map +1 -0
  145. package/dist/shared/filereview/digest.d.ts +40 -0
  146. package/dist/shared/filereview/digest.js +66 -0
  147. package/dist/shared/filereview/digest.js.map +1 -0
  148. package/dist/shared/filereview/events.d.ts +170 -0
  149. package/dist/shared/filereview/events.js +298 -0
  150. package/dist/shared/filereview/events.js.map +1 -0
  151. package/dist/shared/filereview/git-substrate.d.ts +175 -0
  152. package/dist/shared/filereview/git-substrate.js +439 -0
  153. package/dist/shared/filereview/git-substrate.js.map +1 -0
  154. package/dist/shared/filereview/index.d.ts +11 -0
  155. package/dist/shared/filereview/index.js +12 -0
  156. package/dist/shared/filereview/index.js.map +1 -0
  157. package/dist/shared/filereview/secret-paths.d.ts +63 -0
  158. package/dist/shared/filereview/secret-paths.js +105 -0
  159. package/dist/shared/filereview/secret-paths.js.map +1 -0
  160. package/dist/shared/fingerprint-secret.d.ts +26 -0
  161. package/dist/shared/fingerprint-secret.js +47 -0
  162. package/dist/shared/fingerprint-secret.js.map +1 -0
  163. package/dist/shared/model-client.d.ts +51 -0
  164. package/dist/shared/model-client.js +77 -0
  165. package/dist/shared/model-client.js.map +1 -0
  166. package/dist/shared/plan-artifact.js +0 -2
  167. package/dist/shared/plan-artifact.js.map +1 -1
  168. package/dist/shared/status-offload.d.ts +83 -9
  169. package/dist/shared/status-offload.js +399 -79
  170. package/dist/shared/status-offload.js.map +1 -1
  171. package/dist/shared/status.js +14 -1
  172. package/dist/shared/status.js.map +1 -1
  173. package/dist/shared/tool-kind.d.ts +19 -0
  174. package/dist/shared/tool-kind.js +13 -0
  175. package/dist/shared/tool-kind.js.map +1 -1
  176. package/dist/shared/tool-row.d.ts +88 -0
  177. package/dist/shared/tool-row.js +127 -0
  178. package/dist/shared/tool-row.js.map +1 -0
  179. package/dist/shared/workspace/platform-dir.d.ts +25 -0
  180. package/dist/shared/workspace/platform-dir.js +38 -2
  181. package/dist/shared/workspace/platform-dir.js.map +1 -1
  182. package/dist/workflows/call-agent-orchestrator.js +56 -7
  183. package/dist/workflows/call-agent-orchestrator.js.map +1 -1
  184. package/dist/workflows/connect-mcp-server.d.ts +50 -0
  185. package/dist/workflows/connect-mcp-server.js +136 -15
  186. package/dist/workflows/connect-mcp-server.js.map +1 -1
  187. package/dist/workflows/types.d.ts +8 -0
  188. package/package.json +2 -2
  189. package/src/__test-utils__/approval-contract/contract.ts +224 -0
  190. package/src/__test-utils__/approval-contract/types.ts +179 -0
  191. package/src/__test-utils__/fake-artifact-storage.ts +72 -0
  192. package/src/__tests__/approval-gateway-contract.test.ts +29 -0
  193. package/src/__tests__/claimcheck-codec.test.ts +16 -53
  194. package/src/__tests__/golden-e2e.test.ts +2 -0
  195. package/src/__tests__/runner-token-coordinator.test.ts +3 -3
  196. package/src/activities/__tests__/call-agent-status.test.ts +135 -0
  197. package/src/activities/__tests__/call-llm.test.ts +1 -1
  198. package/src/activities/__tests__/classify-tool-approvals.test.ts +208 -1
  199. package/src/activities/__tests__/discover-mcp-server.test.ts +30 -0
  200. package/src/activities/__tests__/workflow-event-activities.test.ts +2 -1
  201. package/src/activities/call-agent-status.ts +74 -4
  202. package/src/activities/call-llm.ts +18 -63
  203. package/src/activities/classify-tool-approvals.ts +101 -19
  204. package/src/activities/discover-mcp-server.ts +29 -1
  205. package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +216 -0
  206. package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +148 -0
  207. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +41 -9
  208. package/src/activities/execute-cursor/__tests__/approval-state.test.ts +292 -0
  209. package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +68 -1
  210. package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +1005 -0
  211. package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +187 -0
  212. package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +97 -0
  213. package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +240 -0
  214. package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +203 -0
  215. package/src/activities/execute-cursor/__tests__/exact-apply.test.ts +375 -0
  216. package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +1294 -24
  217. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +446 -0
  218. package/src/activities/execute-cursor/__tests__/hook-script.test.ts +384 -110
  219. package/src/activities/execute-cursor/__tests__/message-translator.test.ts +171 -25
  220. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +189 -0
  221. package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +44 -23
  222. package/src/activities/execute-cursor/__tests__/workspace-setup.test.ts +190 -10
  223. package/src/activities/execute-cursor/approval-policy.ts +28 -159
  224. package/src/activities/execute-cursor/approval-state.ts +366 -18
  225. package/src/activities/execute-cursor/capture-flow.ts +323 -0
  226. package/src/activities/execute-cursor/cas-observations.ts +204 -0
  227. package/src/activities/execute-cursor/command-provenance.ts +168 -0
  228. package/src/activities/execute-cursor/exact-apply.ts +253 -0
  229. package/src/activities/execute-cursor/hook-script.ts +317 -51
  230. package/src/activities/execute-cursor/index.ts +575 -67
  231. package/src/activities/execute-cursor/message-translator.ts +963 -89
  232. package/src/activities/execute-cursor/prompt-builder.ts +80 -14
  233. package/src/activities/execute-cursor/workspace-setup.ts +257 -42
  234. package/src/activities/execute-deep-agent/__test-utils__/gateway-substrate.ts +180 -0
  235. package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +134 -0
  236. package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +84 -0
  237. package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +11 -24
  238. package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +64 -0
  239. package/src/activities/execute-deep-agent/__tests__/cas-capture-observer.test.ts +163 -0
  240. package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +8 -5
  241. package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +342 -0
  242. package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +2 -5
  243. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +31 -13
  244. package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +349 -0
  245. package/src/activities/execute-deep-agent/__tests__/stamp-flowed-rows.test.ts +119 -0
  246. package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +12 -11
  247. package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +9 -9
  248. package/src/activities/execute-deep-agent/__tests__/subagent-approval-propagation.test.ts +160 -0
  249. package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +213 -0
  250. package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +3 -6
  251. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +84 -1
  252. package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +4 -1
  253. package/src/activities/execute-deep-agent/approval-file-change.ts +80 -0
  254. package/src/activities/execute-deep-agent/attachment-injector.ts +20 -11
  255. package/src/activities/execute-deep-agent/cas-capture-backend.ts +66 -0
  256. package/src/activities/execute-deep-agent/cas-capture-observer.ts +125 -0
  257. package/src/activities/execute-deep-agent/hitl.ts +15 -1
  258. package/src/activities/execute-deep-agent/index.ts +434 -64
  259. package/src/activities/execute-deep-agent/inline-publisher.ts +27 -4
  260. package/src/activities/execute-deep-agent/setup.ts +223 -125
  261. package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +64 -0
  262. package/src/activities/execute-deep-agent/status-builder-shared.ts +62 -23
  263. package/src/activities/execute-deep-agent/status-builder.ts +19 -7
  264. package/src/activities/execute-deep-agent/streaming-side-effects.ts +2 -16
  265. package/src/activities/execute-deep-agent/streaming.ts +3 -13
  266. package/src/activities/execute-deep-agent/subagent-transformer.ts +53 -13
  267. package/src/activities/execute-deep-agent/subagent-wiring.ts +50 -3
  268. package/src/activities/execute-deep-agent/v3-status-builder.ts +8 -2
  269. package/src/claimcheck/payload-codec.ts +8 -8
  270. package/src/client/stigmer-client.ts +9 -1
  271. package/src/middleware/__tests__/approval-gate.test.ts +488 -4
  272. package/src/middleware/approval-gate.ts +247 -38
  273. package/src/middleware/types.ts +5 -5
  274. package/src/shared/__tests__/activity-input.test.ts +78 -0
  275. package/src/shared/__tests__/approval-canonicalize.test.ts +106 -0
  276. package/src/shared/__tests__/approval-fingerprint.test.ts +115 -0
  277. package/src/shared/__tests__/approval-policy.test.ts +274 -40
  278. package/src/shared/__tests__/args-preview.test.ts +78 -0
  279. package/src/shared/__tests__/artifact-storage-extended.test.ts +62 -10
  280. package/src/shared/__tests__/artifact-storage.test.ts +123 -11
  281. package/src/shared/__tests__/file-change.test.ts +85 -0
  282. package/src/shared/__tests__/file-tools.test.ts +90 -0
  283. package/src/shared/__tests__/fingerprint-secret.test.ts +51 -0
  284. package/src/shared/__tests__/lease-scope-corpus.test.ts +56 -0
  285. package/src/shared/__tests__/model-client.test.ts +162 -0
  286. package/src/shared/__tests__/plan-artifact.test.ts +11 -26
  287. package/src/shared/__tests__/policy-source-corpus.test.ts +58 -0
  288. package/src/shared/__tests__/status-offload.test.ts +573 -16
  289. package/src/shared/__tests__/status.test.ts +4 -5
  290. package/src/shared/__tests__/tool-kind.test.ts +24 -1
  291. package/src/shared/__tests__/tool-row.test.ts +221 -0
  292. package/src/shared/activity-input.ts +57 -0
  293. package/src/shared/approval-canonicalize.ts +159 -0
  294. package/src/shared/approval-fingerprint.ts +148 -0
  295. package/src/shared/approval-policy.ts +303 -27
  296. package/src/shared/args-preview.ts +98 -0
  297. package/src/shared/artifact-storage.ts +62 -11
  298. package/src/shared/checkpointer/__tests__/http-saver.test.ts +1 -2
  299. package/src/shared/file-change.ts +64 -0
  300. package/src/shared/file-tools.ts +169 -0
  301. package/src/shared/filereview/__tests__/capture.test.ts +856 -0
  302. package/src/shared/filereview/__tests__/cas-substrate.test.ts +404 -0
  303. package/src/shared/filereview/__tests__/digest.test.ts +100 -0
  304. package/src/shared/filereview/__tests__/events.test.ts +245 -0
  305. package/src/shared/filereview/__tests__/git-substrate.test.ts +362 -0
  306. package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +286 -0
  307. package/src/shared/filereview/__tests__/secret-paths.test.ts +121 -0
  308. package/src/shared/filereview/capture.ts +727 -0
  309. package/src/shared/filereview/cas-substrate.ts +401 -0
  310. package/src/shared/filereview/digest.ts +83 -0
  311. package/src/shared/filereview/events.ts +449 -0
  312. package/src/shared/filereview/git-substrate.ts +555 -0
  313. package/src/shared/filereview/index.ts +60 -0
  314. package/src/shared/filereview/secret-paths.ts +121 -0
  315. package/src/shared/fingerprint-secret.ts +53 -0
  316. package/src/shared/model-client.ts +122 -0
  317. package/src/shared/plan-artifact.ts +0 -2
  318. package/src/shared/status-offload.ts +433 -77
  319. package/src/shared/status.ts +13 -0
  320. package/src/shared/tool-kind.ts +33 -0
  321. package/src/shared/tool-row.ts +135 -0
  322. package/src/shared/workspace/platform-dir.ts +41 -2
  323. package/src/workflow-engine/__tests__/golden-execution.test.ts +35 -18
  324. package/src/workflow-engine/__tests__/tasks/try.test.ts +1 -1
  325. package/src/workflows/__tests__/connect-mcp-server.test.ts +304 -29
  326. package/src/workflows/call-agent-orchestrator.ts +53 -6
  327. package/src/workflows/connect-mcp-server.ts +179 -24
  328. package/src/workflows/types.ts +8 -0
@@ -18,8 +18,15 @@
18
18
 
19
19
  import { proxyActivities, log } from "@temporalio/workflow";
20
20
 
21
- import type { createDiscoverMcpServerActivities } from "../activities/discover-mcp-server.js";
22
- import type { createClassifyToolApprovalsActivities } from "../activities/classify-tool-approvals.js";
21
+ import type {
22
+ createDiscoverMcpServerActivities,
23
+ DiscoveredToolResult,
24
+ ToolApprovalDict,
25
+ } from "../activities/discover-mcp-server.js";
26
+ import type {
27
+ createClassifyToolApprovalsActivities,
28
+ ToolApprovalResult,
29
+ } from "../activities/classify-tool-approvals.js";
23
30
 
24
31
  import type {
25
32
  ConnectMcpServerWorkflowInput,
@@ -48,6 +55,135 @@ function classifyWithTimeout(numTools: number) {
48
55
  });
49
56
  }
50
57
 
58
+ // ─────────────────────────────────────────────────────────────────────────────
59
+ // Incremental classification planner (pure, deterministic, sandbox-safe)
60
+ // ─────────────────────────────────────────────────────────────────────────────
61
+
62
+ /**
63
+ * Canonical, order-stable signature of a single tool's definition.
64
+ *
65
+ * Mirrors the shape `toolsFingerprint` hashes (name + description + input_schema)
66
+ * so "unchanged" here means the same thing it means for the whole-server
67
+ * fingerprint. Uses only JSON — no `node:crypto` — so it is safe to call from
68
+ * inside the Temporal deterministic V8 isolate.
69
+ */
70
+ function toolSignature(tool: DiscoveredToolResult): string {
71
+ return JSON.stringify({
72
+ name: tool.name,
73
+ description: tool.description,
74
+ input_schema: tool.inputSchema ?? null,
75
+ });
76
+ }
77
+
78
+ /**
79
+ * Partition the freshly discovered tools into those that must be classified and
80
+ * the prior approval decisions that can be carried forward verbatim.
81
+ *
82
+ * Reuse is **content-addressed**: a prior decision is kept only when a tool's
83
+ * name AND full definition are byte-identical to the previous connect. This is
84
+ * deliberately stricter than reusing by name alone — a tool can keep its name
85
+ * while its schema changes from benign to destructive, and such a tool MUST be
86
+ * re-evaluated rather than left with a stale "auto-approve". Tools that are
87
+ * unchanged are never re-classified (stable, deterministic, no LLM cost; no
88
+ * flapping for borderline tools), and a tool present last time but gone now is
89
+ * simply absent from both outputs (dropped).
90
+ *
91
+ * The previous approval list is a presence-set of *gated* tools (a tool in
92
+ * `previousToolApprovals` requires approval; a known tool absent from it was
93
+ * auto-approved). So a reused tool emits a carried-forward entry only when it
94
+ * was gated; reused auto-approved tools emit nothing, which correctly keeps them
95
+ * un-gated. `ClassifyToolApprovals` likewise returns only gated entries, so the
96
+ * union `[...carriedForward, ...classified]` is the complete gated set.
97
+ *
98
+ * Pure and free of Temporal APIs so it can be exhaustively unit-tested and is
99
+ * safe to evaluate inside the workflow sandbox.
100
+ */
101
+ export function planIncrementalClassification(
102
+ previousTools: DiscoveredToolResult[],
103
+ previousToolApprovals: ToolApprovalDict[],
104
+ currentTools: DiscoveredToolResult[],
105
+ ): { toolsToClassify: DiscoveredToolResult[]; carriedForward: ToolApprovalResult[] } {
106
+ const prevSigByName = new Map<string, string>();
107
+ for (const tool of previousTools) {
108
+ prevSigByName.set(tool.name, toolSignature(tool));
109
+ }
110
+
111
+ const prevGatedByName = new Map<string, ToolApprovalDict>();
112
+ for (const approval of previousToolApprovals) {
113
+ prevGatedByName.set(approval.toolName, approval);
114
+ }
115
+
116
+ const toolsToClassify: DiscoveredToolResult[] = [];
117
+ const carriedForward: ToolApprovalResult[] = [];
118
+
119
+ for (const tool of currentTools) {
120
+ const prevSig = prevSigByName.get(tool.name);
121
+ const unchanged = prevSig !== undefined && prevSig === toolSignature(tool);
122
+
123
+ if (!unchanged) {
124
+ toolsToClassify.push(tool);
125
+ continue;
126
+ }
127
+
128
+ const gated = prevGatedByName.get(tool.name);
129
+ if (gated) {
130
+ carriedForward.push({
131
+ tool_name: gated.toolName,
132
+ requires_approval: true,
133
+ message: gated.message,
134
+ });
135
+ }
136
+ // An unchanged tool that was not gated stays auto-approved — emit nothing.
137
+ }
138
+
139
+ return { toolsToClassify, carriedForward };
140
+ }
141
+
142
+ // ─────────────────────────────────────────────────────────────────────────────
143
+ // destructiveHint fail-closed tightener (pure, deterministic, sandbox-safe)
144
+ // ─────────────────────────────────────────────────────────────────────────────
145
+
146
+ /**
147
+ * Force-gate any tool whose live MCP annotation declares `destructiveHint:true`
148
+ * but that the classifier (or carry-forward) left un-gated.
149
+ *
150
+ * This is the ONLY way annotations influence policy, and it is deliberately
151
+ * one-directional. The MCP spec warns that clients must never make tool-use
152
+ * decisions on annotations from untrusted servers; trusting a server's
153
+ * "I am destructive" claim only ever ADDS an approval prompt (the safe
154
+ * direction), so it cannot be abused. The inverse — trusting `readOnlyHint` to
155
+ * AUTO-APPROVE — is exactly the unsafe direction the spec forbids, so a spoofed
156
+ * `readOnlyHint:true` on a destructive tool must never relax it. Read-only
157
+ * auto-approval authority lives solely with the trusted LLM classifier.
158
+ *
159
+ * Recomputed from live discovery on every connect, so it has zero coupling to
160
+ * `toolSignature`/incremental reuse and needs no persistence. Pure JS so it is
161
+ * safe to evaluate inside the Temporal deterministic isolate.
162
+ */
163
+ export function applyDestructiveHintTightener(
164
+ gated: ToolApprovalResult[],
165
+ currentTools: DiscoveredToolResult[],
166
+ ): { tightened: ToolApprovalResult[]; addedCount: number } {
167
+ const gatedNames = new Set(gated.map((g) => g.tool_name));
168
+ const tightened = [...gated];
169
+ let addedCount = 0;
170
+
171
+ for (const tool of currentTools) {
172
+ if (tool.annotations?.destructiveHint === true && !gatedNames.has(tool.name)) {
173
+ tightened.push({
174
+ tool_name: tool.name,
175
+ requires_approval: true,
176
+ message: `Execute ${tool.name}`,
177
+ from_destructive_hint: true,
178
+ });
179
+ gatedNames.add(tool.name);
180
+ addedCount++;
181
+ }
182
+ }
183
+
184
+ return { tightened, addedCount };
185
+ }
186
+
51
187
  // ─────────────────────────────────────────────────────────────────────────────
52
188
  // ConnectMcpServerWorkflow — primary connect flow
53
189
  // ─────────────────────────────────────────────────────────────────────────────
@@ -61,32 +197,32 @@ export async function connectMcpServer(
61
197
  invokerIdentityAccountId: input.invoker_identity_account_id ?? null,
62
198
  });
63
199
 
64
- const canReusePreviousApprovals =
65
- discovery.newToolsFingerprint !== "" &&
66
- discovery.newToolsFingerprint === discovery.previousToolsFingerprint &&
67
- discovery.previousToolApprovals.length > 0;
200
+ // Content-addressed incremental classification: reuse prior decisions for
201
+ // tools whose definition is unchanged, and classify only the new or changed
202
+ // ones. Keeps decisions stable/deterministic across reconnects and avoids
203
+ // redundant LLM calls, while still re-evaluating a tool whose schema changed.
204
+ const { toolsToClassify, carriedForward } = planIncrementalClassification(
205
+ discovery.previousTools,
206
+ discovery.previousToolApprovals,
207
+ discovery.tools,
208
+ );
68
209
 
69
- let toolApprovals: Array<{
70
- tool_name: string;
71
- requires_approval: boolean;
72
- message: string;
73
- }>;
210
+ let toolApprovals: ToolApprovalResult[];
74
211
 
75
- if (canReusePreviousApprovals) {
212
+ if (toolsToClassify.length === 0) {
76
213
  log.info(
77
- `Tools unchanged for '${input.mcp_server_id}' ` +
78
- `(fingerprint ${discovery.newToolsFingerprint.slice(0, 12)}) ` +
79
- `reusing ${discovery.previousToolApprovals.length} previous approval(s)`,
214
+ `Tools unchanged for '${input.mcp_server_id}' — reusing ` +
215
+ `${carriedForward.length} previous approval(s), no classification needed`,
80
216
  );
81
-
82
- toolApprovals = discovery.previousToolApprovals.map((a) => ({
83
- tool_name: a.toolName,
84
- requires_approval: a.requiresApproval,
85
- message: a.message,
86
- }));
217
+ toolApprovals = carriedForward;
87
218
  } else {
219
+ log.info(
220
+ `Classifying ${toolsToClassify.length} new/changed tool(s) for ` +
221
+ `'${input.mcp_server_id}', reusing ${carriedForward.length} prior decision(s)`,
222
+ );
223
+
88
224
  const classifyInput = {
89
- tools: discovery.tools.map((t) => ({
225
+ tools: toolsToClassify.map((t) => ({
90
226
  name: t.name,
91
227
  description: t.description,
92
228
  input_schema: t.inputSchema ?? null,
@@ -96,9 +232,28 @@ export async function connectMcpServer(
96
232
  mcpServerId: input.mcp_server_id,
97
233
  };
98
234
 
99
- const classify = classifyWithTimeout(discovery.tools.length);
100
- toolApprovals = await classify.ClassifyToolApprovals(classifyInput);
235
+ const classify = classifyWithTimeout(toolsToClassify.length);
236
+ const classified = await classify.ClassifyToolApprovals(classifyInput);
237
+ toolApprovals = [...carriedForward, ...classified];
238
+ }
239
+
240
+ // Fail-closed tightener over the FULL live tool set: a tool the server's own
241
+ // annotation marks destructiveHint=true is force-gated if it slipped through
242
+ // un-gated. Runs on live discovery (not the reused/classified subset), so it
243
+ // also re-asserts gating for carried-forward tools whose server later flips a
244
+ // tool to destructive. We never trust readOnlyHint to relax — see the
245
+ // tightener's contract for the MCP untrusted-hints rationale.
246
+ const { tightened, addedCount } = applyDestructiveHintTightener(
247
+ toolApprovals,
248
+ discovery.tools,
249
+ );
250
+ if (addedCount > 0) {
251
+ log.info(
252
+ `Force-gated ${addedCount} tool(s) via destructiveHint annotation for ` +
253
+ `'${input.mcp_server_id}'`,
254
+ );
101
255
  }
256
+ toolApprovals = tightened;
102
257
 
103
258
  return {
104
259
  tools: discovery.tools.map((t) => ({
@@ -49,6 +49,14 @@ export interface WireToolApproval {
49
49
  tool_name: string;
50
50
  requires_approval: boolean;
51
51
  message: string;
52
+ /**
53
+ * True when the connect-time destructiveHint tightener force-gated this tool
54
+ * (see applyDestructiveHintTightener). Persisted to
55
+ * ToolApprovalPolicy.from_destructive_hint so the runner attributes the gate to
56
+ * the annotation rather than the classifier. Omitted on classifier/pinned
57
+ * entries.
58
+ */
59
+ from_destructive_hint?: boolean;
52
60
  }
53
61
 
54
62
  // ─────────────────────────────────────────────────────────────────────────────