@relayflows/sdk 2.0.8 → 2.0.10

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 (474) hide show
  1. package/dist/adapters/base.d.ts +46 -0
  2. package/dist/adapters/base.d.ts.map +1 -0
  3. package/dist/adapters/base.js +15 -0
  4. package/dist/adapters/base.js.map +1 -0
  5. package/dist/adapters/claude.d.ts +5 -0
  6. package/dist/adapters/claude.d.ts.map +1 -0
  7. package/dist/adapters/claude.js +44 -0
  8. package/dist/adapters/claude.js.map +1 -0
  9. package/dist/adapters/codex.d.ts +5 -0
  10. package/dist/adapters/codex.d.ts.map +1 -0
  11. package/dist/adapters/codex.js +45 -0
  12. package/dist/adapters/codex.js.map +1 -0
  13. package/dist/adapters/index.d.ts +14 -0
  14. package/dist/adapters/index.d.ts.map +1 -0
  15. package/dist/adapters/index.js +29 -0
  16. package/dist/adapters/index.js.map +1 -0
  17. package/dist/adapters/wrapper.d.ts +12 -0
  18. package/dist/adapters/wrapper.d.ts.map +1 -0
  19. package/dist/adapters/wrapper.js +31 -0
  20. package/dist/adapters/wrapper.js.map +1 -0
  21. package/dist/agent-relay-transport.d.ts +84 -0
  22. package/dist/agent-relay-transport.d.ts.map +1 -0
  23. package/dist/agent-relay-transport.js +134 -0
  24. package/dist/agent-relay-transport.js.map +1 -0
  25. package/dist/authored-budget.d.ts +13 -0
  26. package/dist/authored-budget.d.ts.map +1 -0
  27. package/dist/authored-budget.js +78 -0
  28. package/dist/authored-budget.js.map +1 -0
  29. package/dist/authored-flow-error.d.ts +1 -1
  30. package/dist/authored-flow-error.d.ts.map +1 -1
  31. package/dist/authored-flow-error.js.map +1 -1
  32. package/dist/authored-flow-executor.d.ts +13 -7
  33. package/dist/authored-flow-executor.d.ts.map +1 -1
  34. package/dist/authored-flow-executor.js +115 -194
  35. package/dist/authored-flow-executor.js.map +1 -1
  36. package/dist/authored-flow-loader.d.ts +10 -1
  37. package/dist/authored-flow-loader.d.ts.map +1 -1
  38. package/dist/authored-flow-loader.js +56 -3
  39. package/dist/authored-flow-loader.js.map +1 -1
  40. package/dist/authored-flow-operation.d.ts +9 -1
  41. package/dist/authored-flow-operation.d.ts.map +1 -1
  42. package/dist/authored-flow-operation.js +35 -4
  43. package/dist/authored-flow-operation.js.map +1 -1
  44. package/dist/authored-helper-effect.d.ts +12 -0
  45. package/dist/authored-helper-effect.d.ts.map +1 -0
  46. package/dist/authored-helper-effect.js +144 -0
  47. package/dist/authored-helper-effect.js.map +1 -0
  48. package/dist/authored-mcp.d.ts +17 -0
  49. package/dist/authored-mcp.d.ts.map +1 -0
  50. package/dist/authored-mcp.js +171 -0
  51. package/dist/authored-mcp.js.map +1 -0
  52. package/dist/authored-memory.d.ts +7 -0
  53. package/dist/authored-memory.d.ts.map +1 -0
  54. package/dist/authored-memory.js +60 -0
  55. package/dist/authored-memory.js.map +1 -0
  56. package/dist/authored-plugin-effect.d.ts +16 -0
  57. package/dist/authored-plugin-effect.d.ts.map +1 -0
  58. package/dist/authored-plugin-effect.js +163 -0
  59. package/dist/authored-plugin-effect.js.map +1 -0
  60. package/dist/authored-step-output.d.ts +23 -0
  61. package/dist/authored-step-output.d.ts.map +1 -0
  62. package/dist/authored-step-output.js +67 -0
  63. package/dist/authored-step-output.js.map +1 -0
  64. package/dist/authored-worker-step.d.ts +15 -0
  65. package/dist/authored-worker-step.d.ts.map +1 -0
  66. package/dist/authored-worker-step.js +136 -0
  67. package/dist/authored-worker-step.js.map +1 -0
  68. package/dist/budget-preflight.d.ts +5 -0
  69. package/dist/budget-preflight.d.ts.map +1 -0
  70. package/dist/budget-preflight.js +33 -0
  71. package/dist/budget-preflight.js.map +1 -0
  72. package/dist/budget.d.ts +14 -0
  73. package/dist/budget.d.ts.map +1 -0
  74. package/dist/budget.js +52 -0
  75. package/dist/budget.js.map +1 -0
  76. package/dist/bundle-transport.d.ts +18 -0
  77. package/dist/bundle-transport.d.ts.map +1 -0
  78. package/dist/bundle-transport.js +111 -0
  79. package/dist/bundle-transport.js.map +1 -0
  80. package/dist/bundle-typescript.d.ts +8 -0
  81. package/dist/bundle-typescript.d.ts.map +1 -0
  82. package/dist/bundle-typescript.js +108 -0
  83. package/dist/bundle-typescript.js.map +1 -0
  84. package/dist/bundle.d.ts +25 -0
  85. package/dist/bundle.d.ts.map +1 -0
  86. package/dist/bundle.js +199 -0
  87. package/dist/bundle.js.map +1 -0
  88. package/dist/child-stop.d.ts +59 -0
  89. package/dist/child-stop.d.ts.map +1 -0
  90. package/dist/child-stop.js +94 -0
  91. package/dist/child-stop.js.map +1 -0
  92. package/dist/cli/add.d.ts +6 -0
  93. package/dist/cli/add.d.ts.map +1 -0
  94. package/dist/cli/add.js +47 -0
  95. package/dist/cli/add.js.map +1 -0
  96. package/dist/cli/build.d.ts +13 -0
  97. package/dist/cli/build.d.ts.map +1 -0
  98. package/dist/cli/build.js +224 -0
  99. package/dist/cli/build.js.map +1 -0
  100. package/dist/cli/bundle-preflight.d.ts +5 -0
  101. package/dist/cli/bundle-preflight.d.ts.map +1 -0
  102. package/dist/cli/bundle-preflight.js +28 -0
  103. package/dist/cli/bundle-preflight.js.map +1 -0
  104. package/dist/cli/check-helper-body.d.ts +4 -0
  105. package/dist/cli/check-helper-body.d.ts.map +1 -0
  106. package/dist/cli/check-helper-body.js +15 -0
  107. package/dist/cli/check-helper-body.js.map +1 -0
  108. package/dist/cli/check-triggers.d.ts +14 -0
  109. package/dist/cli/check-triggers.d.ts.map +1 -0
  110. package/dist/cli/check-triggers.js +37 -0
  111. package/dist/cli/check-triggers.js.map +1 -0
  112. package/dist/cli/check-typescript.d.ts +20 -0
  113. package/dist/cli/check-typescript.d.ts.map +1 -0
  114. package/dist/cli/check-typescript.js +54 -0
  115. package/dist/cli/check-typescript.js.map +1 -0
  116. package/dist/cli/check.d.ts +36 -3
  117. package/dist/cli/check.d.ts.map +1 -1
  118. package/dist/cli/check.js +122 -11
  119. package/dist/cli/check.js.map +1 -1
  120. package/dist/cli/cloud-run.d.ts +8 -0
  121. package/dist/cli/cloud-run.d.ts.map +1 -0
  122. package/dist/cli/cloud-run.js +50 -0
  123. package/dist/cli/cloud-run.js.map +1 -0
  124. package/dist/cli/deploy.d.ts +9 -0
  125. package/dist/cli/deploy.d.ts.map +1 -0
  126. package/dist/cli/deploy.js +58 -0
  127. package/dist/cli/deploy.js.map +1 -0
  128. package/dist/cli/deterministic-failure.d.ts +5 -0
  129. package/dist/cli/deterministic-failure.d.ts.map +1 -0
  130. package/dist/cli/deterministic-failure.js +66 -0
  131. package/dist/cli/deterministic-failure.js.map +1 -0
  132. package/dist/cli/direct-run.d.ts.map +1 -1
  133. package/dist/cli/direct-run.js +83 -7
  134. package/dist/cli/direct-run.js.map +1 -1
  135. package/dist/cli/hn-monitor.d.ts.map +1 -1
  136. package/dist/cli/hn-monitor.js +2 -1
  137. package/dist/cli/hn-monitor.js.map +1 -1
  138. package/dist/cli/replay.d.ts +12 -0
  139. package/dist/cli/replay.d.ts.map +1 -0
  140. package/dist/cli/replay.js +82 -0
  141. package/dist/cli/replay.js.map +1 -0
  142. package/dist/cli/reuse.d.ts +8 -0
  143. package/dist/cli/reuse.d.ts.map +1 -0
  144. package/dist/cli/reuse.js +25 -0
  145. package/dist/cli/reuse.js.map +1 -0
  146. package/dist/cli/run-digest.d.ts +4 -0
  147. package/dist/cli/run-digest.d.ts.map +1 -0
  148. package/dist/cli/run-digest.js +24 -0
  149. package/dist/cli/run-digest.js.map +1 -0
  150. package/dist/cli/run.d.ts +16 -5
  151. package/dist/cli/run.d.ts.map +1 -1
  152. package/dist/cli/run.js +99 -17
  153. package/dist/cli/run.js.map +1 -1
  154. package/dist/cli/serve-webhook.d.ts +40 -0
  155. package/dist/cli/serve-webhook.d.ts.map +1 -0
  156. package/dist/cli/serve-webhook.js +233 -0
  157. package/dist/cli/serve-webhook.js.map +1 -0
  158. package/dist/cli/tick-runner.d.ts.map +1 -1
  159. package/dist/cli/tick-runner.js +2 -1
  160. package/dist/cli/tick-runner.js.map +1 -1
  161. package/dist/cli-adapter.d.ts +8 -14
  162. package/dist/cli-adapter.d.ts.map +1 -1
  163. package/dist/cli-adapter.js +19 -64
  164. package/dist/cli-adapter.js.map +1 -1
  165. package/dist/cli-watch.d.ts +13 -0
  166. package/dist/cli-watch.d.ts.map +1 -0
  167. package/dist/cli-watch.js +185 -0
  168. package/dist/cli-watch.js.map +1 -0
  169. package/dist/cli.d.ts +4 -0
  170. package/dist/cli.d.ts.map +1 -1
  171. package/dist/cli.js +387 -14
  172. package/dist/cli.js.map +1 -1
  173. package/dist/cloud-http.d.ts +22 -0
  174. package/dist/cloud-http.d.ts.map +1 -0
  175. package/dist/cloud-http.js +84 -0
  176. package/dist/cloud-http.js.map +1 -0
  177. package/dist/cloud-run.d.ts +38 -0
  178. package/dist/cloud-run.d.ts.map +1 -0
  179. package/dist/cloud-run.js +112 -0
  180. package/dist/cloud-run.js.map +1 -0
  181. package/dist/compile.d.ts +21 -3
  182. package/dist/compile.d.ts.map +1 -1
  183. package/dist/compile.js +97 -23
  184. package/dist/compile.js.map +1 -1
  185. package/dist/create-flow.d.ts +17 -0
  186. package/dist/create-flow.d.ts.map +1 -0
  187. package/dist/create-flow.js +72 -0
  188. package/dist/create-flow.js.map +1 -0
  189. package/dist/daemon-connection.d.ts +14 -0
  190. package/dist/daemon-connection.d.ts.map +1 -1
  191. package/dist/daemon-connection.js +33 -1
  192. package/dist/daemon-connection.js.map +1 -1
  193. package/dist/demo-hn-monitor.js +2 -1
  194. package/dist/demo-hn-monitor.js.map +1 -1
  195. package/dist/effect-channel.d.ts +30 -0
  196. package/dist/effect-channel.d.ts.map +1 -0
  197. package/dist/effect-channel.js +71 -0
  198. package/dist/effect-channel.js.map +1 -0
  199. package/dist/failure-kinds.d.ts +14 -3
  200. package/dist/failure-kinds.d.ts.map +1 -1
  201. package/dist/failure-kinds.js +27 -0
  202. package/dist/failure-kinds.js.map +1 -1
  203. package/dist/gate-contract.d.ts.map +1 -1
  204. package/dist/gate-contract.js +9 -0
  205. package/dist/gate-contract.js.map +1 -1
  206. package/dist/helper-preflight.d.ts +18 -0
  207. package/dist/helper-preflight.d.ts.map +1 -0
  208. package/dist/helper-preflight.js +32 -0
  209. package/dist/helper-preflight.js.map +1 -0
  210. package/dist/helper-storage.d.ts +5 -0
  211. package/dist/helper-storage.d.ts.map +1 -0
  212. package/dist/helper-storage.js +31 -0
  213. package/dist/helper-storage.js.map +1 -0
  214. package/dist/helper-writeback.d.ts +12 -0
  215. package/dist/helper-writeback.d.ts.map +1 -0
  216. package/dist/helper-writeback.js +95 -0
  217. package/dist/helper-writeback.js.map +1 -0
  218. package/dist/index.d.ts +10 -2
  219. package/dist/index.d.ts.map +1 -1
  220. package/dist/index.js +7 -1
  221. package/dist/index.js.map +1 -1
  222. package/dist/input-binding.d.ts +4 -0
  223. package/dist/input-binding.d.ts.map +1 -0
  224. package/dist/input-binding.js +78 -0
  225. package/dist/input-binding.js.map +1 -0
  226. package/dist/journal-client.d.ts +12 -4
  227. package/dist/journal-client.d.ts.map +1 -1
  228. package/dist/journal-client.js +17 -6
  229. package/dist/journal-client.js.map +1 -1
  230. package/dist/journal-offset.d.ts +3 -0
  231. package/dist/journal-offset.d.ts.map +1 -0
  232. package/dist/journal-offset.js +69 -0
  233. package/dist/journal-offset.js.map +1 -0
  234. package/dist/journal-reader.d.ts +30 -0
  235. package/dist/journal-reader.d.ts.map +1 -0
  236. package/dist/journal-reader.js +156 -0
  237. package/dist/journal-reader.js.map +1 -0
  238. package/dist/json-schema.d.ts +2 -0
  239. package/dist/json-schema.d.ts.map +1 -1
  240. package/dist/json-schema.js +38 -22
  241. package/dist/json-schema.js.map +1 -1
  242. package/dist/llm-worker.d.ts +16 -0
  243. package/dist/llm-worker.d.ts.map +1 -0
  244. package/dist/llm-worker.js +79 -0
  245. package/dist/llm-worker.js.map +1 -0
  246. package/dist/local-agent.d.ts +8 -0
  247. package/dist/local-agent.d.ts.map +1 -0
  248. package/dist/local-agent.js +25 -0
  249. package/dist/local-agent.js.map +1 -0
  250. package/dist/mcp-client.d.ts +15 -0
  251. package/dist/mcp-client.d.ts.map +1 -0
  252. package/dist/mcp-client.js +104 -0
  253. package/dist/mcp-client.js.map +1 -0
  254. package/dist/mcp-config.d.ts +4 -0
  255. package/dist/mcp-config.d.ts.map +1 -0
  256. package/dist/mcp-config.js +61 -0
  257. package/dist/mcp-config.js.map +1 -0
  258. package/dist/mcp-stdio.d.ts +24 -0
  259. package/dist/mcp-stdio.d.ts.map +1 -0
  260. package/dist/mcp-stdio.js +89 -0
  261. package/dist/mcp-stdio.js.map +1 -0
  262. package/dist/model-pricing.d.ts +22 -0
  263. package/dist/model-pricing.d.ts.map +1 -0
  264. package/dist/model-pricing.js +30 -0
  265. package/dist/model-pricing.js.map +1 -0
  266. package/dist/mount-registry.d.ts +9 -0
  267. package/dist/mount-registry.d.ts.map +1 -0
  268. package/dist/mount-registry.js +47 -0
  269. package/dist/mount-registry.js.map +1 -0
  270. package/dist/named-gate-lowering.d.ts +9 -0
  271. package/dist/named-gate-lowering.d.ts.map +1 -0
  272. package/dist/named-gate-lowering.js +152 -0
  273. package/dist/named-gate-lowering.js.map +1 -0
  274. package/dist/named-gates.d.ts +10 -0
  275. package/dist/named-gates.d.ts.map +1 -0
  276. package/dist/named-gates.js +69 -0
  277. package/dist/named-gates.js.map +1 -0
  278. package/dist/observer-link.d.ts +129 -0
  279. package/dist/observer-link.d.ts.map +1 -0
  280. package/dist/observer-link.js +274 -0
  281. package/dist/observer-link.js.map +1 -0
  282. package/dist/plugin-loader.d.ts +13 -0
  283. package/dist/plugin-loader.d.ts.map +1 -0
  284. package/dist/plugin-loader.js +110 -0
  285. package/dist/plugin-loader.js.map +1 -0
  286. package/dist/plugin-manifest.d.ts +27 -0
  287. package/dist/plugin-manifest.d.ts.map +1 -0
  288. package/dist/plugin-manifest.js +89 -0
  289. package/dist/plugin-manifest.js.map +1 -0
  290. package/dist/preflight.d.ts +26 -2
  291. package/dist/preflight.d.ts.map +1 -1
  292. package/dist/preflight.js +175 -1
  293. package/dist/preflight.js.map +1 -1
  294. package/dist/progress.d.ts +14 -0
  295. package/dist/progress.d.ts.map +1 -0
  296. package/dist/progress.js +39 -0
  297. package/dist/progress.js.map +1 -0
  298. package/dist/protocol.d.ts +11 -0
  299. package/dist/protocol.d.ts.map +1 -1
  300. package/dist/pty-sidechannel.d.ts +14 -0
  301. package/dist/pty-sidechannel.d.ts.map +1 -0
  302. package/dist/pty-sidechannel.js +103 -0
  303. package/dist/pty-sidechannel.js.map +1 -0
  304. package/dist/scope-compiler.d.ts +52 -0
  305. package/dist/scope-compiler.d.ts.map +1 -0
  306. package/dist/scope-compiler.js +62 -0
  307. package/dist/scope-compiler.js.map +1 -0
  308. package/dist/slack-preflight.d.ts +6 -0
  309. package/dist/slack-preflight.d.ts.map +1 -0
  310. package/dist/slack-preflight.js +28 -0
  311. package/dist/slack-preflight.js.map +1 -0
  312. package/dist/slack-writeback.d.ts +40 -0
  313. package/dist/slack-writeback.d.ts.map +1 -0
  314. package/dist/slack-writeback.js +60 -0
  315. package/dist/slack-writeback.js.map +1 -0
  316. package/dist/spec.d.ts +134 -4
  317. package/dist/spec.d.ts.map +1 -1
  318. package/dist/spec.js.map +1 -1
  319. package/dist/step-dependencies.d.ts.map +1 -1
  320. package/dist/step-dependencies.js +2 -1
  321. package/dist/step-dependencies.js.map +1 -1
  322. package/dist/step-fields.d.ts +4 -4
  323. package/dist/step-fields.d.ts.map +1 -1
  324. package/dist/step-fields.js +5 -2
  325. package/dist/step-fields.js.map +1 -1
  326. package/dist/trigger-executor.d.ts +7 -0
  327. package/dist/trigger-executor.d.ts.map +1 -0
  328. package/dist/trigger-executor.js +35 -0
  329. package/dist/trigger-executor.js.map +1 -0
  330. package/dist/validate.d.ts.map +1 -1
  331. package/dist/validate.js +53 -6
  332. package/dist/validate.js.map +1 -1
  333. package/dist/webhook-rate-limit.d.ts +29 -0
  334. package/dist/webhook-rate-limit.d.ts.map +1 -0
  335. package/dist/webhook-rate-limit.js +38 -0
  336. package/dist/webhook-rate-limit.js.map +1 -0
  337. package/dist/webhook-signature.d.ts +22 -0
  338. package/dist/webhook-signature.d.ts.map +1 -0
  339. package/dist/webhook-signature.js +53 -0
  340. package/dist/webhook-signature.js.map +1 -0
  341. package/dist/worker-cli.d.ts +13 -1
  342. package/dist/worker-cli.d.ts.map +1 -1
  343. package/dist/worker-cli.js +133 -12
  344. package/dist/worker-cli.js.map +1 -1
  345. package/dist/worker-input.d.ts +4 -0
  346. package/dist/worker-input.d.ts.map +1 -0
  347. package/dist/worker-input.js +14 -0
  348. package/dist/worker-input.js.map +1 -0
  349. package/dist/worker-lease.d.ts +5 -0
  350. package/dist/worker-lease.d.ts.map +1 -0
  351. package/dist/worker-lease.js +80 -0
  352. package/dist/worker-lease.js.map +1 -0
  353. package/dist/worker-spend.d.ts +19 -0
  354. package/dist/worker-spend.d.ts.map +1 -0
  355. package/dist/worker-spend.js +22 -0
  356. package/dist/worker-spend.js.map +1 -0
  357. package/dist/worker-usage.d.ts +7 -0
  358. package/dist/worker-usage.d.ts.map +1 -0
  359. package/dist/worker-usage.js +54 -0
  360. package/dist/worker-usage.js.map +1 -0
  361. package/dist/worker.d.ts +2 -0
  362. package/dist/worker.d.ts.map +1 -1
  363. package/dist/worker.js +22 -8
  364. package/dist/worker.js.map +1 -1
  365. package/dist/wrapper-session.d.ts +1 -1
  366. package/dist/wrapper-session.d.ts.map +1 -1
  367. package/dist/wrapper-session.js +56 -19
  368. package/dist/wrapper-session.js.map +1 -1
  369. package/dist/yaml-helper-effect.d.ts +8 -0
  370. package/dist/yaml-helper-effect.d.ts.map +1 -0
  371. package/dist/yaml-helper-effect.js +79 -0
  372. package/dist/yaml-helper-effect.js.map +1 -0
  373. package/dist/yaml-helpers.d.ts +18 -0
  374. package/dist/yaml-helpers.d.ts.map +1 -0
  375. package/dist/yaml-helpers.js +116 -0
  376. package/dist/yaml-helpers.js.map +1 -0
  377. package/package.json +19 -2
  378. package/src/adapters/base.ts +53 -0
  379. package/src/adapters/claude.ts +55 -0
  380. package/src/adapters/codex.ts +56 -0
  381. package/src/adapters/index.ts +36 -0
  382. package/src/adapters/wrapper.ts +42 -0
  383. package/src/agent-relay-transport.ts +187 -0
  384. package/src/authored-budget.ts +69 -0
  385. package/src/authored-flow-error.ts +10 -0
  386. package/src/authored-flow-executor.ts +170 -293
  387. package/src/authored-flow-loader.ts +60 -3
  388. package/src/authored-flow-operation.ts +38 -5
  389. package/src/authored-helper-effect.ts +143 -0
  390. package/src/authored-mcp.ts +166 -0
  391. package/src/authored-memory.ts +55 -0
  392. package/src/authored-plugin-effect.ts +152 -0
  393. package/src/authored-step-output.ts +107 -0
  394. package/src/authored-worker-step.ts +181 -0
  395. package/src/budget-preflight.ts +31 -0
  396. package/src/budget.ts +49 -0
  397. package/src/bundle-transport.ts +79 -0
  398. package/src/bundle-typescript.ts +98 -0
  399. package/src/bundle.ts +182 -0
  400. package/src/child-stop.ts +138 -0
  401. package/src/cli/add.ts +45 -0
  402. package/src/cli/build.ts +214 -0
  403. package/src/cli/bundle-preflight.ts +28 -0
  404. package/src/cli/check-helper-body.ts +14 -0
  405. package/src/cli/check-triggers.ts +41 -0
  406. package/src/cli/check-typescript.ts +63 -0
  407. package/src/cli/check.ts +132 -14
  408. package/src/cli/cloud-run.ts +47 -0
  409. package/src/cli/deploy.ts +52 -0
  410. package/src/cli/deterministic-failure.ts +69 -0
  411. package/src/cli/direct-run.ts +79 -7
  412. package/src/cli/hn-monitor.ts +2 -1
  413. package/src/cli/replay.ts +81 -0
  414. package/src/cli/reuse.ts +23 -0
  415. package/src/cli/run-digest.ts +24 -0
  416. package/src/cli/run.ts +104 -21
  417. package/src/cli/serve-webhook.ts +246 -0
  418. package/src/cli/tick-runner.ts +2 -1
  419. package/src/cli-adapter.ts +31 -74
  420. package/src/cli-watch.ts +174 -0
  421. package/src/cli.ts +396 -17
  422. package/src/cloud-http.ts +100 -0
  423. package/src/cloud-run.ts +137 -0
  424. package/src/compile.ts +102 -23
  425. package/src/create-flow.ts +82 -0
  426. package/src/daemon-connection.ts +32 -1
  427. package/src/demo-hn-monitor.ts +2 -1
  428. package/src/effect-channel.ts +97 -0
  429. package/src/failure-kinds.ts +38 -0
  430. package/src/gate-contract.ts +7 -0
  431. package/src/helper-preflight.ts +34 -0
  432. package/src/helper-storage.ts +23 -0
  433. package/src/helper-writeback.ts +83 -0
  434. package/src/index.ts +26 -0
  435. package/src/input-binding.ts +76 -0
  436. package/src/journal-client.ts +20 -7
  437. package/src/journal-offset.ts +60 -0
  438. package/src/journal-reader.ts +165 -0
  439. package/src/json-schema.ts +34 -18
  440. package/src/llm-worker.ts +82 -0
  441. package/src/local-agent.ts +30 -0
  442. package/src/mcp-client.ts +97 -0
  443. package/src/mcp-config.ts +42 -0
  444. package/src/mcp-stdio.ts +84 -0
  445. package/src/model-pricing.ts +32 -0
  446. package/src/mount-registry.ts +44 -0
  447. package/src/named-gate-lowering.ts +147 -0
  448. package/src/named-gates.ts +76 -0
  449. package/src/observer-link.ts +368 -0
  450. package/src/plugin-loader.ts +88 -0
  451. package/src/plugin-manifest.ts +76 -0
  452. package/src/preflight.ts +178 -4
  453. package/src/progress.ts +51 -0
  454. package/src/protocol.ts +12 -0
  455. package/src/pty-sidechannel.ts +92 -0
  456. package/src/scope-compiler.ts +105 -0
  457. package/src/slack-preflight.ts +25 -0
  458. package/src/slack-writeback.ts +63 -0
  459. package/src/spec.ts +112 -4
  460. package/src/step-dependencies.ts +3 -1
  461. package/src/step-fields.ts +5 -2
  462. package/src/trigger-executor.ts +34 -0
  463. package/src/validate.ts +47 -6
  464. package/src/webhook-rate-limit.ts +69 -0
  465. package/src/webhook-signature.ts +74 -0
  466. package/src/worker-cli.ts +156 -11
  467. package/src/worker-input.ts +15 -0
  468. package/src/worker-lease.ts +85 -0
  469. package/src/worker-spend.ts +23 -0
  470. package/src/worker-usage.ts +48 -0
  471. package/src/worker.ts +27 -9
  472. package/src/wrapper-session.ts +50 -15
  473. package/src/yaml-helper-effect.ts +78 -0
  474. package/src/yaml-helpers.ts +131 -0
@@ -1,22 +1,34 @@
1
+ import { pluginHelpers } from './plugin-loader.js';
2
+ import { runPluginEffect } from './authored-plugin-effect.js';
3
+ import { randomUUID } from 'node:crypto';
4
+ import { dirname } from 'node:path';
5
+ import { runHelperEffect } from './authored-helper-effect.js';
6
+ import { checkSlackHelpers } from './slack-preflight.js';
7
+ import { snapshotJsonValue } from './json-value.js';
8
+ import type { SlackCall } from './slack-writeback.js';
9
+ import { checkMcpHeader, McpPreflightError } from './cli/check-typescript.js';
10
+ import { buildMcpProxy, runMcpEffect } from './authored-mcp.js';
11
+ import { AuthoredBudget } from './authored-budget.js';
12
+ import { assertMemoryReachable, authoredMemory, scriptMemoryScope } from './authored-memory.js';
13
+ import { authoredDeterministicRunner, authoredWorkerRunner } from './authored-worker-step.js';
14
+ import { isSurfaceRunCompletionReason } from './authored-step-output.js';
1
15
  import {
2
- COMPLETION_REASONS,
3
- RUN_COMPLETION_REASONS,
4
- type AgentOptions,
5
16
  type AgentResult,
17
+ type LlmOptions,
6
18
  type CloudHelper,
7
19
  type CompletionReason as SurfaceCompletionReason,
8
20
  type Ctx,
21
+ type FlowCompletionReason,
9
22
  type RunCompletionReason as SurfaceRunCompletionReason,
10
23
  type Step,
11
24
  } from '@relayflows/surface';
12
- import type { FlowHandle } from '@relayflows/surface/runtime';
25
+ import { createHelpers, helperProviders, type HelperCall, type FlowHandle } from '@relayflows/surface/runtime';
13
26
  import { join } from 'node:path';
14
- import { compileSpec, toKernelSpec } from './compile.js';
27
+ import { observeStep, type ProgressEvent } from './progress.js';
28
+ import { parseStepTimeout } from './compile.js';
15
29
  import { getAuthoredFlowDefinition } from './authored-flow.js';
16
30
  import type { GetFlowDefinition } from './authored-flow-loader.js';
17
- import { checkAuthoredFlow } from './cli/check.js';
18
- import { classifyOutcome, type RunLifecycleOptions } from './cli/run.js';
19
- import type { PreflightDiagnostic } from './preflight.js';
31
+ import type { RunLifecycleOptions } from './cli/run.js';
20
32
  import {
21
33
  AuthoredFlowExecutionError,
22
34
  type AuthoredFlowExecutionErrorCode,
@@ -31,9 +43,7 @@ import { JournalClient } from './journal-client.js';
31
43
  import type {
32
44
  CompletionReason as ProtocolCompletionReason,
33
45
  RunCompletionReason as ProtocolRunCompletionReason,
34
- RunOutcome,
35
46
  } from './protocol.js';
36
- import { SPEC_SCHEMA_VERSION, type FlowSpec } from './spec.js';
37
47
 
38
48
  type Assert<T extends true> = T;
39
49
  type Equal<A, B> = [A] extends [B]
@@ -46,8 +56,8 @@ type RunCompletionVocabularyMatchesProtocol = Assert<
46
56
  Equal<SurfaceRunCompletionReason, ProtocolRunCompletionReason>
47
57
  >;
48
58
  type DoneCompletionReason = Parameters<Ctx['done']>[0];
49
- type DoneAcceptsOnlyRunCompletionReasons = Assert<
50
- DoneCompletionReason extends SurfaceRunCompletionReason ? true : false
59
+ type DoneAcceptsOnlyFlowCompletionReasons = Assert<
60
+ Equal<DoneCompletionReason, FlowCompletionReason>
51
61
  >;
52
62
  type EveryRunCompletionReasonIsAcceptedByDone = Assert<
53
63
  SurfaceRunCompletionReason extends DoneCompletionReason ? true : false
@@ -55,15 +65,6 @@ type EveryRunCompletionReasonIsAcceptedByDone = Assert<
55
65
 
56
66
  export { AuthoredFlowExecutionError, type AuthoredFlowExecutionErrorCode };
57
67
 
58
- /**
59
- * Matches the `"path/glob: readonly"` / `"path/glob: readwrite"` shorthand
60
- * shown in docs/SURFACE.md and the examples — the only shape a workspace
61
- * string could plausibly declare a permission in. No parser anywhere in this
62
- * package turns that annotation into a real restriction, so `lowerAgent`
63
- * refuses rather than silently accepting and ignoring it.
64
- */
65
- const WORKSPACE_PERMISSION_ANNOTATION = /:\s*(readonly|readwrite)\s*$/i;
66
-
67
68
  export interface AuthoredFlowJournalStep {
68
69
  readonly id: string;
69
70
  readonly runId: string;
@@ -72,12 +73,12 @@ export interface AuthoredFlowJournalStep {
72
73
 
73
74
  export interface AuthoredFlowExecutionResult {
74
75
  readonly name: string;
75
- readonly completionReason: ProtocolRunCompletionReason;
76
+ readonly completionReason: FlowCompletionReason;
76
77
  readonly journalSteps: readonly AuthoredFlowJournalStep[];
77
78
  }
78
79
 
79
- type ExecutionResultUsesRunCompletionReason = Assert<
80
- Equal<AuthoredFlowExecutionResult['completionReason'], ProtocolRunCompletionReason>
80
+ type ExecutionResultUsesFlowCompletionReason = Assert<
81
+ Equal<AuthoredFlowExecutionResult['completionReason'], FlowCompletionReason>
81
82
  >;
82
83
  type JournalStepUsesStepCompletionReason = Assert<
83
84
  Equal<AuthoredFlowJournalStep['completionReason'], ProtocolCompletionReason>
@@ -88,9 +89,9 @@ type JournalStepUsesStepCompletionReason = Assert<
88
89
  *
89
90
  * This is deliberately not exported by the SDK package: without a durable
90
91
  * authored root, it is not a resumable public runner. The seam is narrow: an
91
- * empty-header flow may await plain `f.run(...)` steps and must finish with
92
- * `f.done("success")`. Every run and
93
- * the terminal marker is a compiled deterministic spec submitted through
92
+ * flow with an optional budget may await `f.run`, `f.llm`, and `f.agent` steps and must
93
+ * finish with `f.done("success")` or `f.done("needs_human")`. Each step and the terminal marker is
94
+ * a compiled spec submitted through
94
95
  * `JournalClient`; values are read back from `step.completed` journal entries.
95
96
  * Unsupported headers, verbs, gates, or completion lowering fail closed.
96
97
  */
@@ -102,6 +103,8 @@ export interface ExecuteAuthoredFlowOptions {
102
103
  * `getDefinition` instead; see authored-flow-loader.ts's comment on why.
103
104
  */
104
105
  readonly getDefinition?: GetFlowDefinition;
106
+ /** Helper receipt and mock-writeback storage; CLI passes its daemon data directory. */
107
+ readonly dataDir?: string;
105
108
  /**
106
109
  * The flow file's own path — passed straight to `checkAuthoredFlow`
107
110
  * (cli/check.ts) so `f.agent` resolves a CLI the same way a declarative
@@ -117,6 +120,8 @@ export interface ExecuteAuthoredFlowOptions {
117
120
  /** Passed straight through to classifyOutcome (cli/run.ts) for f.agent's wait. */
118
121
  readonly signal?: RunLifecycleOptions['signal'];
119
122
  readonly onWait?: RunLifecycleOptions['onWait'];
123
+ readonly onProgress?: (event: ProgressEvent) => void;
124
+ readonly localAgentStream?: string;
120
125
  }
121
126
 
122
127
  export async function executeAuthoredFlow<Input = undefined>(
@@ -126,15 +131,22 @@ export async function executeAuthoredFlow<Input = undefined>(
126
131
  options: ExecuteAuthoredFlowOptions = {},
127
132
  ): Promise<AuthoredFlowExecutionResult> {
128
133
  const getDefinition = options.getDefinition ?? getAuthoredFlowDefinition;
134
+ const localAgentStream = options.localAgentStream;
135
+ const onProgress = options.onProgress;
129
136
  const flowPath = options.flowPath ?? join(process.cwd(), 'flow.ts');
130
- // Named separately from `options` because `lowerAgent` below has its own,
131
- // differently-typed `options: AgentOptions` parameter that shadows this one.
132
137
  const waitOptions: RunLifecycleOptions = {
133
138
  ...(options.signal !== undefined ? { signal: options.signal } : {}),
134
139
  ...(options.onWait !== undefined ? { onWait: options.onWait } : {}),
135
140
  };
136
141
  const definition = getDefinition<Input>(handle);
137
- const headerFields = Object.keys(definition.header);
142
+ const headerFields = Object.keys(definition.header).filter(key => key !== 'tools' && key !== 'budget' && key !== 'memory');
143
+ if (definition.header.tools && Object.keys(definition.header.tools).some(key => !['mcp', ...helperProviders.map(p => p.namespace)].includes(key))) headerFields.push('tools');
144
+ if (definition.header.tools?.relayfile !== undefined) headerFields.push('tools.relayfile');
145
+ const helperPreflight = checkSlackHelpers(definition);
146
+ if (!helperPreflight.ok) {
147
+ const diagnostic = helperPreflight.diagnostics[0]!;
148
+ throw new AuthoredFlowExecutionError(diagnostic.kind as AuthoredFlowExecutionErrorCode, diagnostic.message);
149
+ }
138
150
  if (headerFields.length > 0) {
139
151
  throw new AuthoredFlowExecutionError(
140
152
  'unsupported_header',
@@ -142,149 +154,136 @@ export async function executeAuthoredFlow<Input = undefined>(
142
154
  );
143
155
  }
144
156
 
157
+ const checkedMcp = await checkMcpHeader(definition, flowPath);
158
+ if (!checkedMcp.report.ok) throw new McpPreflightError(checkedMcp.report);
159
+
160
+ const budget = new AuthoredBudget(definition.header.budget);
161
+ if (definition.header.memory?.agent === true) {
162
+ throw new AuthoredFlowExecutionError('unsupported_header', 'memory.agent requires the follow-up identity-scoped agent memory adapter');
163
+ }
164
+ // Direct member use is checked before any body effects; aliases are checked
165
+ // by the helper itself, without executing the body during discovery.
166
+ if (definition.header.memory !== undefined || /\.memory\b/.test(String(definition.body))) {
167
+ await assertMemoryReachable();
168
+ }
169
+
145
170
  const journalSteps: AuthoredFlowJournalStep[] = [];
146
171
  const authoredSteps: AuthoredFlowOperation<unknown>[] = [];
147
172
  const lifecycle = new AuthoredFlowLifecycle();
148
173
  let nextStep = 1;
149
- let requestedCompletion: SurfaceRunCompletionReason | undefined;
174
+ let requestedCompletion: FlowCompletionReason | undefined;
150
175
 
151
- const lowerDeterministic = async (
152
- id: string,
153
- command: string,
154
- ): Promise<string> => {
155
- const spec = toKernelSpec(compileSpec({
156
- version: SPEC_SCHEMA_VERSION,
157
- name: `${definition.name}/${id}`,
158
- steps: [{ id, type: 'deterministic', command }],
159
- }));
160
- const outcome = await journal.runStart(spec);
161
- return readSuccessfulOutput(journal, outcome, id, journalSteps);
162
- };
176
+ const lowerDeterministic = authoredDeterministicRunner(definition.name, journal, journalSteps, budget);
163
177
 
164
- // `name` (the first f.agent argument, e.g. "fixer") is not wired to the
165
- // kernel's `agent` field: that field selects a NAMED declaration from
166
- // `FlowSpec.agents`, and this executor refuses every non-empty header
167
- // (see the top of this function) — an authored flow has no way to declare
168
- // one today. `name` is kept only for step-id readability; CLI selection
169
- // goes through the project's flows.json default below, same as it does
170
- // for a bare `type: agent` YAML step with no explicit `cli`.
171
- const lowerAgent = async (
172
- id: string,
173
- options: AgentOptions,
174
- ): Promise<AgentResult> => {
175
- if (options.workspace !== undefined && WORKSPACE_PERMISSION_ANNOTATION.test(options.workspace)) {
176
- throw new AuthoredFlowExecutionError(
177
- 'unsupported_workspace_permission',
178
- `flow "${definition.name}" step "${id}": workspace "${options.workspace}" declares a `
179
- + 'permission annotation ("...: readonly" / "...: readwrite"), but nothing enforces it — '
180
- + 'no parser anywhere in this package turns that annotation into a real restriction '
181
- + '(kernel/DAEMON-LIFECYCLE.md\'s permission model is untouched by f.agent). '
182
- + 'Silently accepting and ignoring it would let a flow believe a restriction is in effect '
183
- + "when it is not. Declare a bare surface name (no trailing \": readonly\"/\": readwrite\") "
184
- + 'if you do not need enforcement, or use the declarative spec\'s `permissions` field, which is real.',
185
- );
186
- }
187
- const authoring: FlowSpec = {
188
- version: SPEC_SCHEMA_VERSION,
189
- name: `${definition.name}/${id}`,
190
- steps: [{
191
- id,
192
- type: 'agent',
193
- instruction: options.task,
194
- ...(options.workspace === undefined ? {} : {
195
- surfaces: { workspace: [{ surface: options.workspace }] },
196
- }),
197
- }],
198
- };
199
- // The kernel never resolves a `cli` on its own — every declarative
200
- // `flows run`/`flows check` binds it first via this exact function
201
- // (cli/check.ts), searching for the nearest flows.json from `flowPath`
202
- // and real-probing auth/model readiness. An authored agent step gets
203
- // nothing for free just because it was declared in TS instead of YAML.
204
- const { report, flow: resolved } = checkAuthoredFlow(authoring, flowPath);
205
- if (!report.ok || resolved === undefined) {
206
- const refusal = report.diagnostics.find(
207
- (diagnostic): diagnostic is PreflightDiagnostic & { severity: 'refusal' } =>
208
- diagnostic.severity === 'refusal',
209
- );
210
- throw new AuthoredFlowExecutionError(
211
- 'agent_cli_unresolved',
212
- refusal?.message
213
- ?? `flow "${definition.name}" step "${id}": no CLI could be resolved for f.agent `
214
- + `(searched for flows.json from "${flowPath}")`,
215
- );
216
- }
217
- const spec = toKernelSpec(resolved);
218
- const outcome = await journal.runStart(spec);
219
- // Reuse the declarative CLI's own wait/classification (cli/run.ts) rather
220
- // than a hand-rolled poll: `step.completed` and the run's own terminal
221
- // state are appended as two SEPARATE actions (kernel/relayflowd-core/src/machine.rs
222
- // completion_actions vs complete_run_actions), so a naive read right
223
- // after runStart can race a real, valid completion — and a genuinely
224
- // long-running agent has no reason to be bounded by anything other than
225
- // its own worker's lease, which classifyOutcome already follows
226
- // (renewing as the lease renews, per docs/SURFACE.md §5's WAITING
227
- // [worker_lease] contract), never an unrelated fixed deadline.
228
- const execution = await classifyOutcome(journal, 'run', outcome, report, '', waitOptions);
229
- if (execution.exitCode === 3) {
230
- const parked = execution.report.parkedStep;
231
- throw new AuthoredFlowExecutionError(
232
- 'agent_parked',
233
- execution.report.diagnostics.at(-1)?.message
234
- ?? `flow "${definition.name}" step "${id}" parked`
235
- + (parked !== undefined ? ` (${parked.type})` : '')
236
- + ': no worker is attached to run it.',
237
- undefined,
238
- outcome.run_id,
239
- );
240
- }
241
- if (execution.exitCode !== 0) {
242
- const reason = execution.report.completionReason;
243
- throw new AuthoredFlowExecutionError(
244
- 'step_failed',
245
- execution.report.diagnostics.at(-1)?.message
246
- ?? `flow "${definition.name}" step "${id}" did not complete successfully `
247
- + `(status: ${execution.report.status ?? 'unknown'})`,
248
- isSurfaceCompletionReason(reason) ? reason : undefined,
249
- outcome.run_id,
250
- );
251
- }
252
- return readSuccessfulAgentOutput(journal, outcome.run_id, id, journalSteps);
253
- };
178
+ const worker = authoredWorkerRunner(definition, journal, flowPath, journalSteps, waitOptions, localAgentStream, budget, definition.header.budget);
179
+
180
+ function llmOperation(strings: TemplateStringsArray, ...values: unknown[]): Step<string>;
181
+ function llmOperation(prompt: string, options: LlmOptions): Step<unknown>;
182
+ function llmOperation(prompt: string | TemplateStringsArray, ...values: unknown[]): Step<unknown> {
183
+ assertOperationAllowed('llm', definition.name, requestedCompletion);
184
+ const id = `llm-${nextStep++}`;
185
+ // Hoist the operation reference so the start closure can read the
186
+ // caller's `.gate(config)` at spec-build time. AuthoredFlowOperation
187
+ // begins after construction returns, so `llmOp` is defined by then.
188
+ let llmOp!: AuthoredFlowOperation<unknown>;
189
+ llmOp = new AuthoredFlowOperation(
190
+ id, 'llm',
191
+ () => assertOperationAllowed('llm', definition.name, requestedCompletion),
192
+ () => observeStep(id, 'llm', () => {
193
+ if (typeof prompt === 'string') {
194
+ if (values.length !== 1 || values[0] === undefined) {
195
+ throw new AuthoredFlowExecutionError('llm_cli_unresolved', 'f.llm(prompt, options) requires an output JSON Schema.');
196
+ }
197
+ return worker.llm(id, prompt, values[0] as LlmOptions, llmOp.namedGate);
198
+ }
199
+ const text = prompt.reduce((result, part, index) => result + part
200
+ + (index < values.length ? String(values[index]) : ''), '');
201
+ return worker.llm(id, text, undefined, llmOp.namedGate);
202
+ }, onProgress),
203
+ lifecycle,
204
+ );
205
+ return trackStep(authoredSteps, llmOp);
206
+ }
207
+
208
+ const slackRun = randomUUID();
209
+ function slackOperation<T>(call: SlackCall): Step<T> {
210
+ assertOperationAllowed(`slack.${call.verb}`, definition.name, requestedCompletion);
211
+ const snapshot = snapshotJsonValue(call, 'f.slack call') as unknown as SlackCall;
212
+ const id = `slack-${slackRun}-${nextStep++}`;
213
+ return trackStep(authoredSteps, new AuthoredFlowOperation<T>(
214
+ id, `slack.${call.verb}`,
215
+ () => assertOperationAllowed(`slack.${call.verb}`, definition.name, requestedCompletion),
216
+ async () => {
217
+ const receipt = await runHelperEffect(journal, definition.name, id, snapshot,
218
+ options.dataDir ?? dirname(journal.socketPath), journalSteps);
219
+ return (call.verb === 'react' ? undefined : receipt) as T;
220
+ },
221
+ lifecycle,
222
+ ));
223
+ }
254
224
 
255
225
  const context: Ctx = {
256
- run(command) {
226
+ ...createHelpers(<T>(call: HelperCall): Step<T> => {
227
+ const verb = `${call.provider}.${call.verb}`;
228
+ assertOperationAllowed(verb, definition.name, requestedCompletion);
229
+ const snapshot = snapshotJsonValue(call, `f.${verb} call`) as unknown as HelperCall;
230
+ const id = `${call.provider}-${slackRun}-${nextStep++}`;
231
+ return trackStep(authoredSteps, new AuthoredFlowOperation<T>(id, verb,
232
+ () => assertOperationAllowed(verb, definition.name, requestedCompletion),
233
+ async () => await runHelperEffect(journal, definition.name, id, snapshot,
234
+ options.dataDir ?? dirname(journal.socketPath), journalSteps) as T,
235
+ lifecycle));
236
+ }),
237
+ slack: {
238
+ post: (channel, text, opts) => slackOperation({ type: 'effect', provider: 'slack', verb: 'post', params: { channel, text, ...(opts === undefined ? {} : { opts }) } }),
239
+ dm: (user, text) => slackOperation({ type: 'effect', provider: 'slack', verb: 'dm', params: { user, text } }),
240
+ reply: (channel, threadTs, text) => slackOperation({ type: 'effect', provider: 'slack', verb: 'reply', params: { channel, threadTs, text } }),
241
+ react: (channel, messageTs, emoji) => slackOperation({ type: 'effect', provider: 'slack', verb: 'react', params: { channel, messageTs, emoji } }),
242
+ },
243
+ mcp: buildMcpProxy(checkedMcp.inventory, (server, tool, args, known) => {
244
+ assertOperationAllowed('mcp', definition.name, requestedCompletion);
245
+ const id = `mcp-${nextStep++}`;
246
+ return trackStep(authoredSteps, new AuthoredFlowOperation(
247
+ id, 'mcp',
248
+ () => assertOperationAllowed('mcp', definition.name, requestedCompletion),
249
+ () => runMcpEffect(journal, definition.name, id, server, tool, args,
250
+ known, checkedMcp.servers[server]!, journalSteps),
251
+ lifecycle,
252
+ ));
253
+ }),
254
+ memory: authoredMemory(
255
+ scriptMemoryScope(flowPath, definition.name),
256
+ () => assertOperationAllowed('memory', definition.name, requestedCompletion),
257
+ definition.header.memory?.script !== false,
258
+ ),
259
+ run(command, runOptions) {
257
260
  assertOperationAllowed('run', definition.name, requestedCompletion);
261
+ const leaseMs = runOptions?.timeout === undefined ? undefined : parseStepTimeout(runOptions.timeout);
258
262
  const id = `run-${nextStep++}`;
259
- return trackStep(authoredSteps, new AuthoredFlowOperation(
263
+ let runOp!: AuthoredFlowOperation<string>;
264
+ runOp = new AuthoredFlowOperation<string>(
260
265
  id,
261
266
  'run',
262
267
  () => assertOperationAllowed('run', definition.name, requestedCompletion),
263
- () => lowerDeterministic(id, command),
268
+ () => observeStep(id, 'deterministic', () => lowerDeterministic(id, command, false, leaseMs, runOp.namedGate), options.onProgress),
264
269
  lifecycle,
265
- ));
266
- },
267
- llm() {
268
- assertOperationAllowed('llm', definition.name, requestedCompletion);
269
- const id = `llm-${nextStep++}`;
270
- return trackStep(authoredSteps, unsupportedStep(
271
- id,
272
- 'llm',
273
- () => assertOperationAllowed('llm', definition.name, requestedCompletion),
274
- lifecycle,
275
- ));
270
+ );
271
+ return trackStep(authoredSteps, runOp);
276
272
  },
273
+ llm: llmOperation,
277
274
  agent(name, options) {
278
275
  assertOperationAllowed('agent', definition.name, requestedCompletion);
279
- void name; // step-id readability only see the comment on lowerAgent.
276
+ void name; // Authored headers do not yet declare reusable named agents.
280
277
  const id = `agent-${nextStep++}`;
281
- return trackStep(authoredSteps, new AuthoredFlowOperation(
278
+ let agentOp!: AuthoredFlowOperation<AgentResult>;
279
+ agentOp = new AuthoredFlowOperation<AgentResult>(
282
280
  id,
283
281
  'agent',
284
282
  () => assertOperationAllowed('agent', definition.name, requestedCompletion),
285
- () => lowerAgent(id, options),
283
+ () => observeStep(id, 'agent', () => worker.agent(id, options, agentOp.namedGate), onProgress),
286
284
  lifecycle,
287
- ));
285
+ );
286
+ return trackStep(authoredSteps, agentOp);
288
287
  },
289
288
  human() {
290
289
  assertOperationAllowed('human', definition.name, requestedCompletion);
@@ -295,7 +294,7 @@ export async function executeAuthoredFlow<Input = undefined>(
295
294
  throw unsupportedVerb('dispatch');
296
295
  },
297
296
  done(reason) {
298
- if (!isSurfaceRunCompletionReason(reason)) {
297
+ if (reason !== 'needs_human' && !isSurfaceRunCompletionReason(reason)) {
299
298
  throw new AuthoredFlowExecutionError(
300
299
  'unsupported_completion',
301
300
  `unknown completion reason: ${String(reason)}`,
@@ -307,7 +306,7 @@ export async function executeAuthoredFlow<Input = undefined>(
307
306
  `flow "${definition.name}" called done() more than once`,
308
307
  );
309
308
  }
310
- if (reason !== 'success') {
309
+ if (reason !== 'success' && reason !== 'needs_human') {
311
310
  throw new AuthoredFlowExecutionError(
312
311
  'unsupported_completion',
313
312
  `the initial authored executor cannot lower done("${reason}")`,
@@ -322,6 +321,17 @@ export async function executeAuthoredFlow<Input = undefined>(
322
321
  ),
323
322
  };
324
323
 
324
+ Object.assign(context, pluginHelpers(checkedMcp.plugins ?? [], (plugin, verb, args) => {
325
+ const label = `${verb.namespace}.${verb.method}`;
326
+ assertOperationAllowed(label, definition.name, requestedCompletion);
327
+ const id = `plugin-${nextStep++}`;
328
+ return trackStep(authoredSteps, new AuthoredFlowOperation(
329
+ id, label, () => assertOperationAllowed(label, definition.name, requestedCompletion),
330
+ () => runPluginEffect(journal, definition.name, id, plugin, verb, args, journalSteps, budget),
331
+ lifecycle,
332
+ ));
333
+ }));
334
+
325
335
  let bodyFailed = false;
326
336
  let bodyFailure: unknown;
327
337
  try {
@@ -371,7 +381,11 @@ export async function executeAuthoredFlow<Input = undefined>(
371
381
  lifecycle.close();
372
382
  }
373
383
 
374
- await lowerDeterministic(`complete-${nextStep}`, ':');
384
+ // The authored runner has no durable root yet. Record the handoff as a
385
+ // successful effect containing the authored outcome, not a fabricated kernel
386
+ // run.completed reason. The CLI reports this outcome as parked (exit 3).
387
+ await lowerDeterministic(`complete-${nextStep}`, requestedCompletion === 'needs_human'
388
+ ? `printf '%s' '{"completionReason":"needs_human"}'` : ':', true);
375
389
  return Object.freeze({
376
390
  name: definition.name,
377
391
  completionReason: requestedCompletion,
@@ -387,17 +401,6 @@ function trackStep<T>(
387
401
  return operation.step;
388
402
  }
389
403
 
390
- function unsupportedStep<T>(
391
- id: string,
392
- verb: string,
393
- assertCanStart: () => void,
394
- lifecycle: AuthoredFlowLifecycle,
395
- ): AuthoredFlowOperation<T> {
396
- return new AuthoredFlowOperation<T>(id, verb, assertCanStart, async () => {
397
- throw unsupportedVerb(verb);
398
- }, lifecycle);
399
- }
400
-
401
404
  function unsupportedVerb(verb: string): AuthoredFlowExecutionError {
402
405
  return new AuthoredFlowExecutionError(
403
406
  'unsupported_verb',
@@ -408,13 +411,13 @@ function unsupportedVerb(verb: string): AuthoredFlowExecutionError {
408
411
  function assertOperationAllowed(
409
412
  verb: string,
410
413
  flowName: string,
411
- completion: SurfaceRunCompletionReason | undefined,
414
+ completion: FlowCompletionReason | undefined,
412
415
  ): void {
413
416
  if (completion !== undefined) {
414
417
  throw new AuthoredFlowExecutionError(
415
418
  'operation_after_completion',
416
419
  `flow "${flowName}" called f.${verb} after done()`,
417
- completion,
420
+ completion === 'needs_human' ? undefined : completion,
418
421
  );
419
422
  }
420
423
  }
@@ -427,129 +430,3 @@ function unsupportedCloud(assertOpen: () => void): CloudHelper {
427
430
  },
428
431
  }) as CloudHelper;
429
432
  }
430
-
431
- /**
432
- * Shared by every `f.*` verb that lowers to one kernel step run in isolation:
433
- * find its `step.completed` entry, record it, and refuse anything but a
434
- * clean success before handing the raw `output` back for verb-specific
435
- * extraction (a plain string for `f.run`, an `AgentResult` for `f.agent`).
436
- *
437
- * Callers are responsible for having already established that the RUN
438
- * reached a terminal, successful state before calling this — `f.run`'s
439
- * caller relies on `runStart`'s own immediate response (the kernel drives a
440
- * deterministic step to completion inline, no race); `f.agent`'s caller
441
- * relies on `classifyOutcome` (cli/run.ts) having already polled to a true
442
- * terminal state. Given that, a single read from the start of this run's
443
- * (small, single-step) journal is enough — no polling here, and no run
444
- * outcome ever needs re-checking.
445
- */
446
- async function readCompletedStepOutput(
447
- journal: JournalClient,
448
- runId: string,
449
- stepId: string,
450
- journalSteps: AuthoredFlowJournalStep[],
451
- ): Promise<unknown> {
452
- const entries = (await journal.journalRead(runId, 1)).entries;
453
- const completed = entries.find((entry) => isStepCompleted(entry, stepId));
454
- if (!isStepCompleted(completed, stepId)) {
455
- throw protocolViolation(runId, `journal has no step.completed for "${stepId}"`);
456
- }
457
-
458
- const reason = completed.payload.completionReason;
459
- journalSteps.push(Object.freeze({ id: stepId, runId, completionReason: reason }));
460
- if (reason !== 'success') {
461
- throw new AuthoredFlowExecutionError(
462
- 'step_failed',
463
- `journal step "${stepId}" completed with ${reason}`,
464
- reason,
465
- runId,
466
- );
467
- }
468
- return completed.payload.output;
469
- }
470
-
471
- async function readSuccessfulOutput(
472
- journal: JournalClient,
473
- outcome: RunOutcome,
474
- stepId: string,
475
- journalSteps: AuthoredFlowJournalStep[],
476
- ): Promise<string> {
477
- const output = await readCompletedStepOutput(journal, outcome.run_id, stepId, journalSteps);
478
- if (!isRecord(output) || typeof output['stdout_tail'] !== 'string') {
479
- throw protocolViolation(outcome.run_id, `step "${stepId}" has no string stdout_tail`);
480
- }
481
- return output['stdout_tail'];
482
- }
483
-
484
- /**
485
- * The kernel journals an agent step's raw `CliResult` shape
486
- * (`exit_code`/`stdout_tail`/`stderr_tail`) — same as a deterministic step —
487
- * UNLESS the CLI's stdout parsed as JSON, in which case `output` is that
488
- * parsed object directly (worker.ts: `parseJsonOutput(result.stdout_tail) ??
489
- * result`). Neither shape carries a real `artifacts` list today: nothing in
490
- * the kernel or worker enumerates files an agent wrote, and `f.agent`'s
491
- * `AgentOptions` has no `output` schema parameter for a CLI to target either
492
- * (unlike the declarative `AgentStepSpec.output` field). `artifacts` is
493
- * therefore always empty here — honest about what data exists, not a
494
- * placeholder for something not yet wired.
495
- */
496
- async function readSuccessfulAgentOutput(
497
- journal: JournalClient,
498
- runId: string,
499
- stepId: string,
500
- journalSteps: AuthoredFlowJournalStep[],
501
- ): Promise<AgentResult> {
502
- const output = await readCompletedStepOutput(journal, runId, stepId, journalSteps);
503
- if (!isRecord(output)) {
504
- throw protocolViolation(runId, `step "${stepId}" produced a non-object output`);
505
- }
506
- if (typeof output['stdout_tail'] === 'string') {
507
- return { summary: output['stdout_tail'], artifacts: [] };
508
- }
509
- // The CLI's stdout parsed as JSON, so `output` is that value, not a
510
- // CliResult. Fall back to a stable, inspectable summary rather than
511
- // refusing a run whose agent step genuinely succeeded.
512
- return { summary: JSON.stringify(output), artifacts: [] };
513
- }
514
-
515
- interface StepCompletedEntry {
516
- entry_type: 'step.completed';
517
- step_id: string;
518
- payload: {
519
- completionReason: ProtocolCompletionReason;
520
- output: unknown;
521
- };
522
- }
523
-
524
- function isStepCompleted(value: unknown, stepId: string): value is StepCompletedEntry {
525
- if (!isRecord(value) || value['entry_type'] !== 'step.completed' || value['step_id'] !== stepId) {
526
- return false;
527
- }
528
- const payload = value['payload'];
529
- return isRecord(payload)
530
- && isSurfaceCompletionReason(payload['completionReason'])
531
- && 'output' in payload;
532
- }
533
-
534
- function isSurfaceCompletionReason(value: unknown): value is ProtocolCompletionReason {
535
- return typeof value === 'string'
536
- && (COMPLETION_REASONS as readonly string[]).includes(value);
537
- }
538
-
539
- function isSurfaceRunCompletionReason(value: unknown): value is ProtocolRunCompletionReason {
540
- return typeof value === 'string'
541
- && (RUN_COMPLETION_REASONS as readonly string[]).includes(value);
542
- }
543
-
544
- function isRecord(value: unknown): value is Record<string, unknown> {
545
- return typeof value === 'object' && value !== null && !Array.isArray(value);
546
- }
547
-
548
- function protocolViolation(runId: string, detail: string): AuthoredFlowExecutionError {
549
- return new AuthoredFlowExecutionError(
550
- 'journal_protocol_violation',
551
- detail,
552
- undefined,
553
- runId,
554
- );
555
- }