@stigmer/runner 3.0.9-dev.20260615153829 → 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 (329) 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 +16 -3
  74. package/dist/activities/execute-deep-agent/hitl.js +11 -3
  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 +393 -33
  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 +17 -5
  92. package/dist/activities/execute-deep-agent/status-builder.js +44 -3
  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 +32 -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 +284 -0
  243. package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +14 -36
  244. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +31 -13
  245. package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +349 -0
  246. package/src/activities/execute-deep-agent/__tests__/stamp-flowed-rows.test.ts +119 -0
  247. package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +91 -10
  248. package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +9 -9
  249. package/src/activities/execute-deep-agent/__tests__/subagent-approval-propagation.test.ts +160 -0
  250. package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +213 -0
  251. package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +3 -6
  252. package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +84 -1
  253. package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +4 -1
  254. package/src/activities/execute-deep-agent/approval-file-change.ts +80 -0
  255. package/src/activities/execute-deep-agent/attachment-injector.ts +20 -11
  256. package/src/activities/execute-deep-agent/cas-capture-backend.ts +66 -0
  257. package/src/activities/execute-deep-agent/cas-capture-observer.ts +125 -0
  258. package/src/activities/execute-deep-agent/hitl.ts +23 -7
  259. package/src/activities/execute-deep-agent/index.ts +463 -40
  260. package/src/activities/execute-deep-agent/inline-publisher.ts +27 -4
  261. package/src/activities/execute-deep-agent/setup.ts +223 -125
  262. package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +64 -0
  263. package/src/activities/execute-deep-agent/status-builder-shared.ts +62 -23
  264. package/src/activities/execute-deep-agent/status-builder.ts +63 -8
  265. package/src/activities/execute-deep-agent/streaming-side-effects.ts +2 -16
  266. package/src/activities/execute-deep-agent/streaming.ts +3 -13
  267. package/src/activities/execute-deep-agent/subagent-transformer.ts +53 -13
  268. package/src/activities/execute-deep-agent/subagent-wiring.ts +50 -3
  269. package/src/activities/execute-deep-agent/v3-status-builder.ts +36 -2
  270. package/src/claimcheck/payload-codec.ts +8 -8
  271. package/src/client/stigmer-client.ts +9 -1
  272. package/src/middleware/__tests__/approval-gate.test.ts +488 -4
  273. package/src/middleware/approval-gate.ts +247 -38
  274. package/src/middleware/types.ts +5 -5
  275. package/src/shared/__tests__/activity-input.test.ts +78 -0
  276. package/src/shared/__tests__/approval-canonicalize.test.ts +106 -0
  277. package/src/shared/__tests__/approval-fingerprint.test.ts +115 -0
  278. package/src/shared/__tests__/approval-policy.test.ts +274 -40
  279. package/src/shared/__tests__/args-preview.test.ts +78 -0
  280. package/src/shared/__tests__/artifact-storage-extended.test.ts +62 -10
  281. package/src/shared/__tests__/artifact-storage.test.ts +123 -11
  282. package/src/shared/__tests__/file-change.test.ts +85 -0
  283. package/src/shared/__tests__/file-tools.test.ts +90 -0
  284. package/src/shared/__tests__/fingerprint-secret.test.ts +51 -0
  285. package/src/shared/__tests__/lease-scope-corpus.test.ts +56 -0
  286. package/src/shared/__tests__/model-client.test.ts +162 -0
  287. package/src/shared/__tests__/plan-artifact.test.ts +11 -26
  288. package/src/shared/__tests__/policy-source-corpus.test.ts +58 -0
  289. package/src/shared/__tests__/status-offload.test.ts +573 -16
  290. package/src/shared/__tests__/status.test.ts +4 -5
  291. package/src/shared/__tests__/tool-kind.test.ts +24 -1
  292. package/src/shared/__tests__/tool-row.test.ts +221 -0
  293. package/src/shared/activity-input.ts +57 -0
  294. package/src/shared/approval-canonicalize.ts +159 -0
  295. package/src/shared/approval-fingerprint.ts +148 -0
  296. package/src/shared/approval-policy.ts +303 -27
  297. package/src/shared/args-preview.ts +98 -0
  298. package/src/shared/artifact-storage.ts +62 -11
  299. package/src/shared/checkpointer/__tests__/http-saver.test.ts +1 -2
  300. package/src/shared/file-change.ts +64 -0
  301. package/src/shared/file-tools.ts +169 -0
  302. package/src/shared/filereview/__tests__/capture.test.ts +856 -0
  303. package/src/shared/filereview/__tests__/cas-substrate.test.ts +404 -0
  304. package/src/shared/filereview/__tests__/digest.test.ts +100 -0
  305. package/src/shared/filereview/__tests__/events.test.ts +245 -0
  306. package/src/shared/filereview/__tests__/git-substrate.test.ts +362 -0
  307. package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +286 -0
  308. package/src/shared/filereview/__tests__/secret-paths.test.ts +121 -0
  309. package/src/shared/filereview/capture.ts +727 -0
  310. package/src/shared/filereview/cas-substrate.ts +401 -0
  311. package/src/shared/filereview/digest.ts +83 -0
  312. package/src/shared/filereview/events.ts +449 -0
  313. package/src/shared/filereview/git-substrate.ts +555 -0
  314. package/src/shared/filereview/index.ts +60 -0
  315. package/src/shared/filereview/secret-paths.ts +121 -0
  316. package/src/shared/fingerprint-secret.ts +53 -0
  317. package/src/shared/model-client.ts +122 -0
  318. package/src/shared/plan-artifact.ts +0 -2
  319. package/src/shared/status-offload.ts +433 -77
  320. package/src/shared/status.ts +13 -0
  321. package/src/shared/tool-kind.ts +33 -0
  322. package/src/shared/tool-row.ts +135 -0
  323. package/src/shared/workspace/platform-dir.ts +41 -2
  324. package/src/workflow-engine/__tests__/golden-execution.test.ts +35 -18
  325. package/src/workflow-engine/__tests__/tasks/try.test.ts +1 -1
  326. package/src/workflows/__tests__/connect-mcp-server.test.ts +304 -29
  327. package/src/workflows/call-agent-orchestrator.ts +53 -6
  328. package/src/workflows/connect-mcp-server.ts +179 -24
  329. package/src/workflows/types.ts +8 -0
@@ -9,21 +9,36 @@
9
9
  * State file format (JSON):
10
10
  * {
11
11
  * "autoApproveAll": false,
12
+ * "leasedCategories": ["shell"],
12
13
  * "mcpToolPolicies": {
13
14
  * "apply_cloud_resource": { "requiresApproval": true, "message": "..." }
14
15
  * },
15
- * "approvedGrants": [{ "toolName": "edit", "mcpServerSlug": "", "key": "write", "salient": "a.txt" }],
16
- * "approvedGrantTokens": ["d3JpdGUKYS50eHQ="]
16
+ * "approvedGrants": [{ "toolName": "edit", "mcpServerSlug": "", "key": "write", "salient": "a.txt", "contentDigest": "<sha256>" }],
17
+ * "approvedGrantTokens": ["<base64(key\nsalient[\ncontentDigest])>"]
17
18
  * }
18
19
  *
20
+ * A grant token is the action's PRIMARY token: base64(key \n salient \n digest)
21
+ * for a content-identified file edit (so a DIFFERENT edit to the same file does
22
+ * not match), or base64(key \n salient) for shell/delete/MCP and the rare
23
+ * content-less fallback. See {@link primaryToken}.
24
+ *
19
25
  * The hook gates the dangerous built-in set and the MCP tools that require
20
26
  * approval (mcpToolPolicies, which by construction holds only require-approval
21
27
  * entries); every other tool is allowed. The gated built-in set and its
22
28
  * name->category mapping are baked into the generated hook script (from
23
29
  * approval-policy.ts), not carried in the state file — only the dynamic inputs
24
- * (autoApproveAll, mcpToolPolicies, approvedGrantTokens) live here. This mirrors
25
- * the native harness and avoids denying auto-approved MCP tools, which are
26
- * absent from the policy map and indistinguishable from unknown tools by name.
30
+ * (autoApproveAll, leasedCategories, mcpToolPolicies, approvedGrantTokens) live
31
+ * here. This mirrors the native harness and avoids denying auto-approved MCP
32
+ * tools, which are absent from the policy map and indistinguishable from unknown
33
+ * tools by name.
34
+ *
35
+ * Approval leases (the scoped successor to autoApproveAll): `autoApproveAll` is
36
+ * now ONLY the pre-armed spec.auto_approve_all global bypass. An interactive
37
+ * "approve all" of a given class becomes a run-lifetime lease: a built-in
38
+ * category lease is listed in `leasedCategories` (the hook allows any built-in of
39
+ * that category), and an MCP-server lease is applied upstream by dropping the
40
+ * server's tools from mcpToolPolicies (so the hook allows them as auto-approved)
41
+ * — the hook is not server-aware, so omission is the lever there.
27
42
  *
28
43
  * Why grants instead of tool-call ids: a resumed Cursor agent re-issues the
29
44
  * approved tool with a BRAND NEW call id, so matching on the original call id
@@ -53,7 +68,8 @@
53
68
  import { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
54
69
  import type { PendingApproval } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb";
55
70
  import type { AgentMessage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
56
- import type { MergedToolPolicy } from "./approval-policy.js";
71
+ import type { MergedToolPolicy, ApprovalCategory } from "./approval-policy.js";
72
+ import { type FingerprintKey } from "../../shared/approval-fingerprint.js";
57
73
  export interface McpToolPolicyEntry {
58
74
  requiresApproval: boolean;
59
75
  message?: string;
@@ -93,12 +109,77 @@ export interface ApprovalGrant {
93
109
  mcpServerSlug: string;
94
110
  key: string;
95
111
  salient: string;
112
+ /**
113
+ * Content digest of the approved edit (see {@link contentDigest}), or "" when
114
+ * the action is not content-identified (shell/delete/MCP, or a content-less
115
+ * fallback). When present, the grant authorizes the {@link contentToken} so a
116
+ * DIFFERENT edit to the same path does NOT match; when "", it authorizes the
117
+ * coarse {@link grantToken} (the documented degrade).
118
+ */
119
+ contentDigest: string;
120
+ /**
121
+ * Id of the adjudicated tool call this grant was minted from — the transcript
122
+ * row carrying the SERVER-authored approval_action. The approved-command
123
+ * auto-keep provenance (DD-28) cites this row as the consent the backend can
124
+ * verify; the hook itself never reads it.
125
+ */
126
+ sourceToolCallId: string;
96
127
  }
97
128
  export interface ApprovalStateFile {
129
+ /** Pre-armed spec.auto_approve_all: the whole-run global bypass. */
98
130
  autoApproveAll: boolean;
131
+ /**
132
+ * Built-in approval categories with a run-lifetime lease (the scoped successor
133
+ * to a global "approve all"). The hook allows any built-in whose category is
134
+ * listed. MCP-server leases are NOT listed here — they are applied by dropping
135
+ * the server's tools from mcpToolPolicies, since the hook is not server-aware.
136
+ */
137
+ leasedCategories: string[];
99
138
  mcpToolPolicies: Record<string, McpToolPolicyEntry>;
100
139
  approvedGrants: ApprovalGrant[];
101
140
  approvedGrantTokens: string[];
141
+ /**
142
+ * Capture mode (git workspaces): when true, the hook ALLOWS file mutations
143
+ * (write/edit/delete) to flow during the turn, because the runner captures the
144
+ * whole change set with git at the turn boundary and gates it per-file for
145
+ * review (see shared/filereview/git-substrate.ts). The ONLY exception is a
146
+ * write/delete whose
147
+ * path is gitignored — the git snapshot cannot capture or revert it, so the
148
+ * hook keeps gating those (it runs `git check-ignore`). shell and MCP stay
149
+ * gated as always. False (the default) keeps the classic deny-gate behavior
150
+ * for every file mutation (non-git workspaces / the fallback path).
151
+ */
152
+ captureMode: boolean;
153
+ /**
154
+ * CAS capture for gitignored writes (the deep-agent parity switch). When true,
155
+ * a non-secret gitignored write/edit no longer stays on the deny-gate: the hook
156
+ * stages its pre-write bytes into the runner-owned cas-observations sidecar and
157
+ * ALLOWS it to flow, and the turn boundary captures it into content-addressable
158
+ * storage as a `GIT_IGNORED_CAPTURED` change for per-file review (mirroring the
159
+ * deep-agent `CasCaptureFilesystemBackend` observer). A secret-like gitignored
160
+ * path is instead hard-blocked (denied, nothing written) and recorded as an
161
+ * unreviewable observation, so its bytes never reach durable storage.
162
+ *
163
+ * Set only when `captureMode` AND an artifact storage is configured — CAS blob
164
+ * persistence requires it. When false, gitignored writes keep the classic
165
+ * deny-gate behavior (gitignored deletes and shell/MCP always do). Independent
166
+ * of `autoApproveAll`: capture is a property of the turn, not authorization, so
167
+ * the hook honors this switch even under the global bypass.
168
+ */
169
+ captureIgnored: boolean;
170
+ /**
171
+ * Whether the primary workspace is a git work tree (Slice 2c). Selects the
172
+ * hook's capture substrate:
173
+ * - `true` (default): git tree — git-tracked write/edit/delete flow freely
174
+ * (the runner captures them from the git diff at the turn boundary); only a
175
+ * GITIGNORED write is CAS-staged (when `captureIgnored`), a gitignored delete
176
+ * stays gated.
177
+ * - `false`: non-git workspace — there is no git snapshot, so EVERY file write
178
+ * is CAS-staged and flowed for review (`captureIgnored` is on in this mode),
179
+ * a delete stays gated (no CAS delete-capture path, parity with the
180
+ * deep-agent), and shell/MCP gate as always.
181
+ */
182
+ gitWorkspace: boolean;
102
183
  }
103
184
  /**
104
185
  * Compute the flat token the bash hook matches on. The hook recomputes the same
@@ -107,26 +188,75 @@ export interface ApprovalStateFile {
107
188
  * hook script in hook-script.ts.
108
189
  */
109
190
  export declare function grantToken(key: string, salient: string): string;
191
+ /**
192
+ * The content-exact wire token: `base64(key \n salient \n contentDigest)`. This
193
+ * is the exact-identity grant the hook matches for a file-mutating tool, so an
194
+ * approval of one edit does NOT authorize a DIFFERENT edit to the same file (a
195
+ * different digest yields a different token). The hook recomputes the identical
196
+ * token from `tool_input` (it appends the same `\n<digest>` only when the digest
197
+ * is non-empty — see hook-script.ts), so this encoding must stay byte-identical
198
+ * to the hook's, exactly as {@link grantToken} already is.
199
+ */
200
+ export declare function contentToken(key: string, salient: string, contentDigest: string): string;
201
+ /**
202
+ * The single token a tool call authorizes (as a grant) and is recorded under (as
203
+ * a denial): the {@link contentToken} when a content digest is present (file
204
+ * edits/writes), else the coarse {@link grantToken} (shell, delete, MCP, or a
205
+ * content-less grep-fallback). One definition, used by the runner for both grant
206
+ * building and denial correlation and mirrored by the hook, so the deny-time and
207
+ * reinvoke-time identities can never drift.
208
+ */
209
+ export declare function primaryToken(key: string, salient: string, contentDigest: string): string;
210
+ /**
211
+ * The shared HMAC coarse fingerprint of an approval grant.
212
+ *
213
+ * This is the SAME canonical coarse identity the wire token (grantToken) encodes
214
+ * — `(key, salient)` plus the MCP slug — run through the one shared HMAC+canonical
215
+ * path ({@link fingerprintCoarseIdentity}). It is NOT the hook's wire-match value:
216
+ * the hook matches on the mechanically-reproducible base64 token (a bash script
217
+ * can recompute base64 but not a keyed HMAC over a workspace-root-normalized
218
+ * salient). This fingerprint is the cross-substrate, anti-forgery identity used
219
+ * for the runner-side shadow receipt today and as the successor wire token once a
220
+ * lease becomes a server-issued bearer token (Phase 7). Because it shares the
221
+ * exact category + salient the token uses, the hook-side and stream-side
222
+ * fingerprints of one action are equal by construction (see the parity tests).
223
+ */
224
+ export declare function grantFingerprint(key: FingerprintKey, grant: ApprovalGrant): string;
225
+ /**
226
+ * Emit a best-effort shadow ExecutionReceipt for each grant the runner issues
227
+ * this turn (Phase 2, mirror of the deep-agent gateway's receipt).
228
+ *
229
+ * Cursor executes tools out-of-process, so unlike the in-process deep-agent
230
+ * gateway the runner cannot observe the actual side effect — the receipt is
231
+ * issued when the authorization GRANT is written (best-effort, `verified:false`),
232
+ * not at execution. Structured log only: never persisted, no proto. Shares the
233
+ * one HMAC+canonical fingerprint path so the value matches the deep-agent and
234
+ * cross-language corpus definitions.
235
+ */
236
+ export declare function emitCursorGrantReceipts(grants: readonly ApprovalGrant[], fingerprintKey: FingerprintKey, executionId: string): void;
110
237
  /**
111
238
  * Build approval grants from the pending approvals the user adjudicated and
112
239
  * their decisions. Only APPROVE / APPROVE_ALL decisions produce grants. Each
113
240
  * grant carries the canonical {@link ToolIdentity} (category + salient resource)
114
241
  * so the hook allows the exact approved resource on the resumed turn.
115
242
  */
116
- export declare function buildApprovalGrants(pendingApprovals: PendingApproval[], decisions: Map<string, ApprovalAction>): ApprovalGrant[];
243
+ export declare function buildApprovalGrants(pendingApprovals: PendingApproval[], decisions: Map<string, ApprovalAction>, contentDigests?: Map<string, string>): ApprovalGrant[];
117
244
  /**
118
245
  * Build the approval state file content from merged policies and any approval
119
246
  * grants from a previous HITL cycle.
120
247
  *
121
248
  * The state file carries the hook script's DYNAMIC inputs:
122
- * - mcpToolPolicies: per-tool policy for MCP tools requiring approval
249
+ * - globalBypass: the pre-armed spec.auto_approve_all (written as autoApproveAll)
250
+ * - leasedCategories: built-in categories with a run-lifetime lease
251
+ * - mcpToolPolicies: per-tool policy for MCP tools requiring approval (leased
252
+ * servers are already absent — dropped upstream by mergeApprovalPolicies)
123
253
  * - approvedGrants / approvedGrantTokens: tools approved in the current HITL
124
254
  * cycle, allowed through on reinvocation
125
255
  *
126
256
  * The static gated built-in set and its category mapping are baked into the
127
257
  * generated hook script (from approval-policy.ts), not carried here.
128
258
  */
129
- export declare function buildApprovalState(mergedPolicies: Map<string, MergedToolPolicy>, autoApproveAll: boolean, grants?: ApprovalGrant[]): ApprovalStateFile;
259
+ export declare function buildApprovalState(mergedPolicies: Map<string, MergedToolPolicy>, globalBypass: boolean, leasedCategories: ReadonlySet<ApprovalCategory>, grants?: ApprovalGrant[], captureMode?: boolean, captureIgnored?: boolean, gitWorkspace?: boolean): ApprovalStateFile;
130
260
  /**
131
261
  * Write the approval state file into the session's HITL directory for the hook
132
262
  * script to read.
@@ -148,10 +278,21 @@ export declare function writeApprovalStateFile(hitlDir: string, state: ApprovalS
148
278
  * the same space as grantToken() (base64 of `toolName \n salientArg`), used to
149
279
  * correlate the denial back to the streamed tool call. `toolName` is carried raw
150
280
  * for human-readable debugging of the ledger file.
281
+ *
282
+ * `input` is the authoritative pre-execution tool arguments the hook captured
283
+ * from the Cursor `tool_input` payload (decoded from the ledger's base64 form).
284
+ * It is the cursor analog of the native harness reading the AI-message tool-call
285
+ * args out of graph state at the LangGraph interrupt — the one place the COMPLETE
286
+ * proposed change is in hand before the tool runs. The runner overlays it onto
287
+ * the gated tool call so the approval card can show the proposed content/diff
288
+ * before the user approves. Absent when the hook ran its grep fallback (the Node
289
+ * binary was unavailable), in which case the gate degrades to stream-recovered
290
+ * args exactly as before.
151
291
  */
152
292
  export interface DeniedLedgerEntry {
153
293
  toolName: string;
154
294
  token: string;
295
+ input?: Record<string, unknown>;
155
296
  }
156
297
  /**
157
298
  * Absolute path of the per-turn denial ledger the hook appends to, inside the
@@ -168,6 +309,26 @@ export declare function denialLedgerPath(hitlDir: string): string;
168
309
  * retries.
169
310
  */
170
311
  export declare function resetDenialLedger(hitlDir: string): Promise<string>;
312
+ /**
313
+ * Watch the denial ledger so the stream loop learns about a hook denial the
314
+ * moment it is written — not on the next tool_call event.
315
+ *
316
+ * The hook appends to denials.jsonl BEFORE Cursor surfaces the failure to the
317
+ * model, so a filesystem notification is the earliest possible signal that a
318
+ * turn must pause. The watcher deliberately does NOT read the file itself: it
319
+ * only flips the caller's dirty flag, and the stream loop confirms with a
320
+ * readDenialLedger() — a notification can fire for the per-turn reset
321
+ * truncation too, and only a read distinguishes "reset to empty" from "denial
322
+ * appended". Watching the DIRECTORY (not the file) survives the file being
323
+ * replaced/truncated between turns.
324
+ *
325
+ * fs.watch is best-effort by platform contract, so this is an accelerator,
326
+ * never the only trigger: the stream loop keeps its tool_call-event read as
327
+ * the backstop. On any watcher error we fall back to that backstop silently.
328
+ *
329
+ * Returns a close function, idempotent and safe to call on every exit path.
330
+ */
331
+ export declare function watchDenialLedger(hitlDir: string, onDirty: () => void): () => void;
171
332
  /**
172
333
  * Read the denial ledger written by the hook during the turn. Missing file →
173
334
  * no denials. Blank or partially-written lines are tolerated (the hook appends
@@ -175,6 +336,46 @@ export declare function resetDenialLedger(hitlDir: string): Promise<string>;
175
336
  * the valid denials before it.
176
337
  */
177
338
  export declare function readDenialLedger(hitlDir: string): Promise<DeniedLedgerEntry[]>;
339
+ /**
340
+ * The current turn's artifact paths, written by the runner into the WORKSPACE's
341
+ * gate directory and read by the stable hook script on every invocation.
342
+ *
343
+ * Why this exists: the Cursor SDK caches `.cursor/hooks.json` (the hook script
344
+ * PATH) for the runner process, so the script must be STABLE across executions
345
+ * (a per-session script gets cached at the first execution and reused for all
346
+ * later ones — recording their denials to the FIRST session's ledger, leaving the
347
+ * current runner's ledger empty so it completes instead of pausing). The stable
348
+ * script bakes in NO per-session paths; it reads this pointer instead, which the
349
+ * runner repoints every turn to the current execution's state file, denial
350
+ * ledger, and runner PID.
351
+ */
352
+ export interface ActiveTurnPointer {
353
+ /** Absolute path of THIS turn's approval-state file (hook input). */
354
+ stateFile: string;
355
+ /** Absolute path of THIS turn's denial ledger (hook output the runner reads). */
356
+ ledgerFile: string;
357
+ /** PID of the runner that owns THIS turn (the hook's scope-guard anchor). */
358
+ runnerPid: number;
359
+ }
360
+ /** Absolute path of the active-turn pointer inside a workspace's gate directory. */
361
+ export declare function activePointerPath(gateDir: string): string;
362
+ /**
363
+ * Atomically point the workspace's stable hook at the current turn's artifacts.
364
+ *
365
+ * Written compactly (the hook's grep fallback parses `"key":"value"` with no
366
+ * spaces) and atomically (write a temp sibling, then rename) so a hook firing
367
+ * concurrently with the write never reads a half-written pointer. Returns the
368
+ * pointer path.
369
+ */
370
+ export declare function writeActiveTurnPointer(gateDir: string, pointer: ActiveTurnPointer): Promise<string>;
371
+ /**
372
+ * Remove the active-turn pointer on teardown so the gate is INERT between turns:
373
+ * a hook that fires when no turn is active (a leftover cached hooks.json, the
374
+ * user's own IDE) reads no pointer and allows immediately. Best-effort — a
375
+ * teardown failure must never fail the execution, and a stale pointer is itself
376
+ * inert once its runnerPid is gone (the scope guard fails closed to allow).
377
+ */
378
+ export declare function removeActiveTurnPointer(gateDir: string): Promise<void>;
178
379
  /**
179
380
  * Reconstruct the adjudicated approvals for a HITL reinvocation directly from
180
381
  * the tool calls in messages.
@@ -193,5 +394,14 @@ export declare function readDenialLedger(hitlDir: string): Promise<DeniedLedgerE
193
394
  export interface AdjudicatedApprovals {
194
395
  pendingApprovals: PendingApproval[];
195
396
  decisions: Map<string, ApprovalAction>;
397
+ /**
398
+ * tool-call id -> content digest of the approved edit, for the content-exact
399
+ * grant. Sourced from the persisted `approval_content_digest` field (stable,
400
+ * immune to the size-limit elision that can drop `args`), falling back to a
401
+ * recompute from `args` only when the field is absent (an execution that
402
+ * predates the field). Empty for a non-content tool — the grant then degrades
403
+ * to the coarse token.
404
+ */
405
+ contentDigests: Map<string, string>;
196
406
  }
197
407
  export declare function reconstructAdjudicatedApprovals(messages: AgentMessage[]): AdjudicatedApprovals;