@swirls/looms 0.0.2 → 0.2.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 (375) hide show
  1. package/CHANGELOG.md +24 -2
  2. package/dist/actor/cell.d.ts +9 -4
  3. package/dist/actor/cell.js +7 -11
  4. package/dist/actor/host.d.ts +7 -3
  5. package/dist/actor/host.js +57 -33
  6. package/dist/actor/index.d.ts +1 -1
  7. package/dist/actor/index.js +1 -1
  8. package/dist/actor/routing.d.ts +12 -1
  9. package/dist/actor/routing.js +57 -51
  10. package/dist/agent/agent-session.d.ts +5 -0
  11. package/dist/agent/agent-session.js +270 -0
  12. package/dist/agent/debugger/agent-chat.d.ts +2 -0
  13. package/dist/agent/debugger/agent-chat.js +176 -0
  14. package/dist/agent/debugger/index.d.ts +5 -0
  15. package/dist/agent/debugger/index.js +19 -0
  16. package/dist/agent/debugger/summarize.d.ts +2 -0
  17. package/dist/agent/debugger/summarize.js +51 -0
  18. package/dist/agent/debugger/token-usage.d.ts +3 -0
  19. package/dist/agent/debugger/token-usage.js +11 -0
  20. package/dist/agent/definitions-store.d.ts +2 -3
  21. package/dist/agent/definitions-store.js +2 -4
  22. package/dist/agent/definitions.d.ts +47 -29
  23. package/dist/agent/definitions.js +39 -12
  24. package/dist/agent/effects.d.ts +359 -2
  25. package/dist/agent/effects.js +60 -34
  26. package/dist/agent/events.d.ts +175 -19
  27. package/dist/agent/events.js +45 -10
  28. package/dist/agent/index.d.ts +1 -0
  29. package/dist/agent/index.js +1 -0
  30. package/dist/agent/llm.d.ts +11 -2
  31. package/dist/agent/llm.js +13 -3
  32. package/dist/agent/module.d.ts +812 -78
  33. package/dist/agent/module.js +16 -4
  34. package/dist/agent/scope.d.ts +174 -18
  35. package/dist/agent/signals.d.ts +26 -1
  36. package/dist/agent/signals.js +79 -0
  37. package/dist/agent/threads.d.ts +3 -33
  38. package/dist/agent/threads.js +20 -25
  39. package/dist/agent/tool-schema.d.ts +1 -17
  40. package/dist/agent/tool-schema.js +3 -43
  41. package/dist/agent/types.d.ts +49 -4
  42. package/dist/agent/types.js +5 -5
  43. package/dist/ai-vercel/index.d.ts +1 -0
  44. package/dist/ai-vercel/index.js +1 -0
  45. package/dist/ai-vercel/messages.js +22 -7
  46. package/dist/ai-vercel/vercel-evaluator.d.ts +36 -0
  47. package/dist/ai-vercel/vercel-evaluator.js +73 -0
  48. package/dist/ai-vercel/vercel-llm.js +64 -44
  49. package/dist/approval/debugger/approvals-view.d.ts +3 -0
  50. package/dist/approval/debugger/approvals-view.js +16 -0
  51. package/dist/approval/debugger/index.d.ts +4 -0
  52. package/dist/approval/debugger/index.js +11 -0
  53. package/dist/approval/debugger/summarize.d.ts +2 -0
  54. package/dist/approval/debugger/summarize.js +17 -0
  55. package/dist/approval/effects.d.ts +89 -0
  56. package/dist/approval/module.d.ts +179 -29
  57. package/dist/approval/projections.d.ts +0 -14
  58. package/dist/approval/projections.js +20 -3
  59. package/dist/approval/signals.d.ts +2 -0
  60. package/dist/approval/signals.js +18 -2
  61. package/dist/cli/cli.js +2 -0
  62. package/dist/cli/commands.js +12 -16
  63. package/dist/client/client.d.ts +1213 -18
  64. package/dist/client/client.js +120 -120
  65. package/dist/client/index.d.ts +1 -1
  66. package/dist/client/index.js +1 -1
  67. package/dist/client/sse.d.ts +13 -0
  68. package/dist/client/sse.js +38 -44
  69. package/dist/cloudflare/alarm-scheduler.d.ts +12 -2
  70. package/dist/cloudflare/alarm-scheduler.js +34 -7
  71. package/dist/cloudflare/durable-object.d.ts +10 -2
  72. package/dist/cloudflare/durable-object.js +59 -28
  73. package/dist/cloudflare/event-store.d.ts +7 -2
  74. package/dist/cloudflare/event-store.js +8 -7
  75. package/dist/cloudflare/index.d.ts +2 -2
  76. package/dist/cloudflare/index.js +2 -2
  77. package/dist/cloudflare/router.d.ts +1 -1
  78. package/dist/cloudflare/router.js +15 -16
  79. package/dist/core/catalog.d.ts +3 -3
  80. package/dist/core/catalog.js +2 -5
  81. package/dist/core/coalesce.js +5 -3
  82. package/dist/core/compose.d.ts +2 -1
  83. package/dist/core/compose.js +19 -2
  84. package/dist/core/debugger-host.d.ts +16 -0
  85. package/dist/core/debugger-host.js +1 -0
  86. package/dist/core/definition-store.d.ts +11 -0
  87. package/dist/core/definition-store.js +6 -0
  88. package/dist/core/effects.d.ts +127 -15
  89. package/dist/core/effects.js +89 -17
  90. package/dist/core/envelope.d.ts +27 -7
  91. package/dist/core/envelope.js +20 -6
  92. package/dist/core/event-codec.d.ts +4 -2
  93. package/dist/core/event-codec.js +10 -5
  94. package/dist/core/event-index.js +1 -3
  95. package/dist/core/fold.d.ts +3 -0
  96. package/dist/core/fold.js +171 -24
  97. package/dist/core/ids.d.ts +5 -0
  98. package/dist/core/ids.js +35 -2
  99. package/dist/core/index.d.ts +7 -1
  100. package/dist/core/index.js +6 -1
  101. package/dist/core/kind.d.ts +22 -0
  102. package/dist/core/kind.js +17 -0
  103. package/dist/core/limits.d.ts +34 -0
  104. package/dist/core/limits.js +46 -0
  105. package/dist/core/match.d.ts +1 -0
  106. package/dist/core/match.js +10 -1
  107. package/dist/core/module-scope.d.ts +22 -20
  108. package/dist/core/module-scope.js +38 -28
  109. package/dist/core/module.d.ts +18 -5
  110. package/dist/core/module.js +4 -0
  111. package/dist/core/projection.d.ts +13 -13
  112. package/dist/core/projection.js +9 -5
  113. package/dist/core/protocol.d.ts +68 -11
  114. package/dist/core/protocol.js +82 -11
  115. package/dist/core/published.d.ts +43 -0
  116. package/dist/core/published.js +44 -0
  117. package/dist/core/replay.d.ts +312 -3
  118. package/dist/core/replay.js +11 -1
  119. package/dist/core/schema.d.ts +11 -20
  120. package/dist/core/schema.js +63 -80
  121. package/dist/core/serialize.js +2 -4
  122. package/dist/core/snapshot-store.d.ts +6 -1
  123. package/dist/core/snapshot-store.js +15 -2
  124. package/dist/core/snapshots.d.ts +5 -1
  125. package/dist/core/snapshots.js +10 -15
  126. package/dist/core/sqlite-store.js +95 -11
  127. package/dist/core/state.d.ts +142 -4
  128. package/dist/core/state.js +78 -0
  129. package/dist/core/store.d.ts +38 -3
  130. package/dist/core/store.js +77 -22
  131. package/dist/core/thread.d.ts +10 -9
  132. package/dist/core/types.d.ts +5 -8
  133. package/dist/core/types.js +28 -24
  134. package/dist/core/validate-event.js +14 -4
  135. package/dist/core/worker-callback.d.ts +17 -0
  136. package/dist/core/worker-callback.js +1 -0
  137. package/dist/debugger/app/assets/index-B3Ah8WAE.css +2 -0
  138. package/dist/debugger/app/assets/index-Qb371t_O.js +22 -0
  139. package/dist/debugger/app/assets/rolldown-runtime-CbXtAM7H.js +1 -0
  140. package/dist/debugger/app/assets/routes-CjtEHgPQ.js +47 -0
  141. package/dist/debugger/app/index.html +14 -0
  142. package/dist/debugger/components/composer.d.ts +17 -0
  143. package/dist/debugger/components/composer.js +25 -0
  144. package/dist/debugger/components/debugger-split.d.ts +2 -1
  145. package/dist/debugger/components/debugger-split.js +2 -2
  146. package/dist/debugger/components/event-inspector.d.ts +2 -1
  147. package/dist/debugger/components/event-inspector.js +25 -16
  148. package/dist/debugger/components/event-stream.d.ts +2 -1
  149. package/dist/debugger/components/event-stream.js +14 -74
  150. package/dist/debugger/components/follow-list.d.ts +19 -0
  151. package/dist/debugger/components/follow-list.js +96 -0
  152. package/dist/debugger/components/json-tree.d.ts +11 -0
  153. package/dist/debugger/components/json-tree.js +120 -0
  154. package/dist/debugger/components/json-view.js +2 -2
  155. package/dist/debugger/components/run-tree.js +53 -20
  156. package/dist/debugger/components/status-dot.d.ts +4 -0
  157. package/dist/debugger/components/status-dot.js +6 -2
  158. package/dist/debugger/context.d.ts +14 -0
  159. package/dist/debugger/context.js +17 -0
  160. package/dist/debugger/contracts.d.ts +7 -4
  161. package/dist/debugger/events/builtin-families.d.ts +3 -0
  162. package/dist/debugger/events/builtin-families.js +9 -0
  163. package/dist/debugger/events/catalog.d.ts +3 -4
  164. package/dist/debugger/events/catalog.js +27 -17
  165. package/dist/debugger/events/protocol-summarize.d.ts +1 -2
  166. package/dist/debugger/events/protocol-summarize.js +42 -24
  167. package/dist/debugger/index.d.ts +20 -6
  168. package/dist/debugger/index.js +19 -5
  169. package/dist/debugger/lib/cn.d.ts +1 -0
  170. package/dist/debugger/lib/cn.js +3 -0
  171. package/dist/debugger/lib/event-meta.d.ts +2 -3
  172. package/dist/debugger/lib/event-meta.js +6 -12
  173. package/dist/debugger/lib/json.d.ts +25 -0
  174. package/dist/debugger/lib/json.js +87 -0
  175. package/dist/debugger/lib/payload.d.ts +7 -0
  176. package/dist/debugger/lib/payload.js +11 -0
  177. package/dist/debugger/lib/time.d.ts +3 -0
  178. package/dist/debugger/lib/time.js +24 -0
  179. package/dist/debugger/plugin.d.ts +36 -0
  180. package/dist/debugger/plugin.js +14 -0
  181. package/dist/debugger/server/index.d.ts +14 -0
  182. package/dist/debugger/server/index.js +114 -0
  183. package/dist/debugger/shell/debugger-shell.d.ts +15 -0
  184. package/dist/debugger/shell/debugger-shell.js +43 -0
  185. package/dist/debugger/shell/definition-key.d.ts +3 -0
  186. package/dist/debugger/shell/definition-key.js +4 -0
  187. package/dist/debugger/shell/events-pane.d.ts +12 -0
  188. package/dist/debugger/shell/events-pane.js +25 -0
  189. package/dist/debugger/shell/projections-panel.d.ts +4 -0
  190. package/dist/debugger/shell/projections-panel.js +59 -0
  191. package/dist/debugger/shell/run-controls.d.ts +4 -0
  192. package/dist/debugger/shell/run-controls.js +72 -0
  193. package/dist/debugger/shell/run-search.d.ts +6 -0
  194. package/dist/debugger/shell/run-search.js +102 -0
  195. package/dist/debugger/shell/run-type-menu.d.ts +6 -0
  196. package/dist/debugger/shell/run-type-menu.js +11 -0
  197. package/dist/debugger/shell/schema-form.d.ts +31 -0
  198. package/dist/debugger/shell/schema-form.js +117 -0
  199. package/dist/debugger/shell/start-form.d.ts +3 -0
  200. package/dist/debugger/shell/start-form.js +75 -0
  201. package/dist/debugger/shell/use-start-run.d.ts +14 -0
  202. package/dist/debugger/shell/use-start-run.js +32 -0
  203. package/dist/debugger/shell/workspace.d.ts +6 -0
  204. package/dist/debugger/shell/workspace.js +15 -0
  205. package/dist/debugger/styles.css +111 -27
  206. package/dist/debugger/ui/button.d.ts +24 -0
  207. package/dist/debugger/ui/button.js +24 -0
  208. package/dist/debugger/ui/command.d.ts +9 -0
  209. package/dist/debugger/ui/command.js +24 -0
  210. package/dist/debugger/ui/dropdown-menu.d.ts +13 -0
  211. package/dist/debugger/ui/dropdown-menu.js +37 -0
  212. package/dist/debugger/ui/panel.d.ts +14 -0
  213. package/dist/debugger/ui/panel.js +16 -0
  214. package/dist/debugger/ui/popover.d.ts +7 -0
  215. package/dist/debugger/ui/popover.js +17 -0
  216. package/dist/debugger/ui/resizable.d.ts +7 -0
  217. package/dist/debugger/ui/resizable.js +14 -0
  218. package/dist/debugger/ui/scroll-area.d.ts +2 -1
  219. package/dist/debugger/ui/scroll-area.js +5 -3
  220. package/dist/debugger/ui/select.d.ts +10 -0
  221. package/dist/debugger/ui/select.js +21 -0
  222. package/dist/debugger/ui/tabs.js +2 -2
  223. package/dist/debugger/ui/textarea.d.ts +3 -0
  224. package/dist/debugger/ui/textarea.js +7 -0
  225. package/dist/evaluator/definitions-store.d.ts +11 -0
  226. package/dist/evaluator/definitions-store.js +8 -0
  227. package/dist/evaluator/definitions.d.ts +18 -0
  228. package/dist/evaluator/definitions.js +4 -0
  229. package/dist/evaluator/effects.d.ts +226 -0
  230. package/dist/evaluator/effects.js +132 -0
  231. package/dist/evaluator/evaluator.d.ts +24 -0
  232. package/dist/evaluator/evaluator.js +67 -0
  233. package/dist/evaluator/events.d.ts +59 -0
  234. package/dist/evaluator/events.js +21 -0
  235. package/dist/evaluator/index.d.ts +11 -0
  236. package/dist/evaluator/index.js +11 -0
  237. package/dist/evaluator/module.d.ts +606 -0
  238. package/dist/evaluator/module.js +25 -0
  239. package/dist/evaluator/projections.d.ts +50 -0
  240. package/dist/evaluator/projections.js +20 -0
  241. package/dist/evaluator/scope.d.ts +59 -0
  242. package/dist/evaluator/scope.js +7 -0
  243. package/dist/evaluator/signals.d.ts +3 -0
  244. package/dist/evaluator/signals.js +17 -0
  245. package/dist/evaluator/threads.d.ts +62 -0
  246. package/dist/evaluator/threads.js +117 -0
  247. package/dist/evaluator/types.d.ts +125 -0
  248. package/dist/evaluator/types.js +51 -0
  249. package/dist/projectors/delivery.d.ts +83 -0
  250. package/dist/projectors/delivery.js +182 -0
  251. package/dist/projectors/index-model.d.ts +1 -1
  252. package/dist/projectors/index-model.js +4 -6
  253. package/dist/projectors/index.d.ts +2 -0
  254. package/dist/projectors/index.js +2 -0
  255. package/dist/projectors/memory.d.ts +1 -1
  256. package/dist/projectors/memory.js +10 -8
  257. package/dist/projectors/postgres.js +44 -58
  258. package/dist/projectors/projector.d.ts +17 -0
  259. package/dist/projectors/projector.js +26 -1
  260. package/dist/projectors/sqlite-delivery.d.ts +4 -0
  261. package/dist/projectors/sqlite-delivery.js +147 -0
  262. package/dist/projectors/sqlite.js +23 -23
  263. package/dist/projectors/with-projectors.d.ts +7 -2
  264. package/dist/projectors/with-projectors.js +27 -28
  265. package/dist/react/notify.js +11 -8
  266. package/dist/react/react.d.ts +2 -3
  267. package/dist/react/react.js +14 -30
  268. package/dist/react/sse.d.ts +1 -1
  269. package/dist/react/sse.js +1 -1
  270. package/dist/react/store.d.ts +3 -3
  271. package/dist/react/store.js +109 -119
  272. package/dist/runtime/cancellation.d.ts +16 -0
  273. package/dist/runtime/cancellation.js +129 -0
  274. package/dist/runtime/deadline-transition-planner.d.ts +31 -0
  275. package/dist/runtime/deadline-transition-planner.js +139 -0
  276. package/dist/runtime/dispatch-effect.d.ts +3 -2
  277. package/dist/runtime/dispatch-effect.js +7 -13
  278. package/dist/runtime/errors.d.ts +51 -0
  279. package/dist/runtime/errors.js +39 -0
  280. package/dist/runtime/{runtime-helpers.d.ts → helpers.d.ts} +24 -4
  281. package/dist/runtime/{runtime-helpers.js → helpers.js} +56 -19
  282. package/dist/runtime/index.d.ts +3 -3
  283. package/dist/runtime/index.js +3 -3
  284. package/dist/runtime/ingress.d.ts +15 -0
  285. package/dist/runtime/ingress.js +42 -0
  286. package/dist/runtime/local-effect-executor.d.ts +21 -0
  287. package/dist/runtime/local-effect-executor.js +137 -0
  288. package/dist/runtime/looms.d.ts +30 -4
  289. package/dist/runtime/looms.js +57 -37
  290. package/dist/runtime/observer.d.ts +45 -0
  291. package/dist/runtime/observer.js +11 -0
  292. package/dist/runtime/repository.d.ts +55 -0
  293. package/dist/runtime/repository.js +293 -0
  294. package/dist/runtime/retry-policy.d.ts +16 -0
  295. package/dist/runtime/retry-policy.js +29 -0
  296. package/dist/runtime/run-execution-context.d.ts +30 -0
  297. package/dist/runtime/run-execution-context.js +56 -0
  298. package/dist/runtime/run-start.d.ts +4 -0
  299. package/dist/runtime/run-start.js +44 -0
  300. package/dist/runtime/runtime.d.ts +6 -87
  301. package/dist/runtime/runtime.js +248 -470
  302. package/dist/runtime/server/auth.d.ts +41 -0
  303. package/dist/runtime/server/auth.js +45 -0
  304. package/dist/runtime/server/debugger-host.d.ts +11 -0
  305. package/dist/runtime/server/debugger-host.js +32 -0
  306. package/dist/runtime/server/fetch-handler.d.ts +18 -0
  307. package/dist/runtime/server/fetch-handler.js +62 -0
  308. package/dist/runtime/server/http.d.ts +38 -0
  309. package/dist/runtime/server/http.js +66 -0
  310. package/dist/runtime/server/route-table.d.ts +55 -0
  311. package/dist/runtime/server/route-table.js +74 -0
  312. package/dist/runtime/server/routes/definitions.d.ts +3 -0
  313. package/dist/runtime/server/routes/definitions.js +20 -0
  314. package/dist/runtime/server/routes/effects.d.ts +3 -0
  315. package/dist/runtime/server/routes/effects.js +59 -0
  316. package/dist/runtime/server/routes/operations.d.ts +3 -0
  317. package/dist/runtime/server/routes/operations.js +14 -0
  318. package/dist/runtime/server/routes/runs.d.ts +3 -0
  319. package/dist/runtime/server/routes/runs.js +199 -0
  320. package/dist/runtime/server.d.ts +4 -8
  321. package/dist/runtime/server.js +6 -211
  322. package/dist/runtime/sse.d.ts +2 -1
  323. package/dist/runtime/sse.js +24 -17
  324. package/dist/runtime/types.d.ts +117 -0
  325. package/dist/runtime/types.js +1 -0
  326. package/dist/runtime/wake-engine.d.ts +20 -0
  327. package/dist/runtime/wake-engine.js +311 -0
  328. package/dist/runtime/wake-scheduler.d.ts +3 -4
  329. package/dist/runtime/wake-scheduler.js +25 -31
  330. package/dist/runtime/worker-callbacks.d.ts +16 -0
  331. package/dist/runtime/worker-callbacks.js +167 -0
  332. package/dist/runtime/worker-effect-dispatch.d.ts +36 -0
  333. package/dist/runtime/worker-effect-dispatch.js +126 -0
  334. package/dist/s2/config.d.ts +1 -1
  335. package/dist/s2/config.js +1 -1
  336. package/dist/s2/lite.js +70 -82
  337. package/dist/s2/pagination.d.ts +15 -0
  338. package/dist/s2/pagination.js +36 -0
  339. package/dist/s2/projector.js +6 -5
  340. package/dist/s2/snapshot-store.js +188 -161
  341. package/dist/s2/store.d.ts +3 -21
  342. package/dist/s2/store.js +71 -165
  343. package/dist/testing/index.d.ts +15 -0
  344. package/dist/testing/index.js +53 -16
  345. package/dist/workflow/debugger/index.d.ts +4 -0
  346. package/dist/workflow/debugger/index.js +11 -0
  347. package/dist/workflow/debugger/nodes-view.d.ts +3 -0
  348. package/dist/workflow/debugger/nodes-view.js +13 -0
  349. package/dist/workflow/debugger/summarize.d.ts +2 -0
  350. package/dist/workflow/debugger/summarize.js +30 -0
  351. package/dist/workflow/definitions-store.d.ts +2 -3
  352. package/dist/workflow/definitions-store.js +2 -2
  353. package/dist/workflow/definitions.d.ts +78 -22
  354. package/dist/workflow/definitions.js +80 -14
  355. package/dist/workflow/effects.d.ts +453 -107
  356. package/dist/workflow/effects.js +214 -115
  357. package/dist/workflow/events.d.ts +149 -5
  358. package/dist/workflow/events.js +27 -5
  359. package/dist/workflow/graph.d.ts +56 -0
  360. package/dist/workflow/graph.js +207 -0
  361. package/dist/workflow/index.d.ts +1 -0
  362. package/dist/workflow/index.js +1 -0
  363. package/dist/workflow/module.d.ts +1047 -266
  364. package/dist/workflow/projections.d.ts +14 -12
  365. package/dist/workflow/projections.js +30 -8
  366. package/dist/workflow/scope.d.ts +146 -4
  367. package/dist/workflow/threads.d.ts +383 -155
  368. package/dist/workflow/threads.js +308 -110
  369. package/package.json +26 -2
  370. package/dist/debugger/events/domain-summarize.d.ts +0 -3
  371. package/dist/debugger/events/domain-summarize.js +0 -107
  372. package/dist/debugger/events/family.d.ts +0 -8
  373. package/dist/debugger/events/family.js +0 -44
  374. package/dist/runtime/events-api.d.ts +0 -4
  375. package/dist/runtime/events-api.js +0 -84
@@ -0,0 +1,3 @@
1
+ export declare function ApprovalsView({ runId }: {
2
+ runId: string;
3
+ }): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, StatusBadge, useDebugger } from '@swirls/looms/debugger';
3
+ import { useProjection, useRunStore } from '@swirls/looms/react';
4
+ import { pendingApprovals } from '../projections.js';
5
+ import { decision } from '../signals.js';
6
+ export function ApprovalsView({ runId }) {
7
+ const { client } = useDebugger();
8
+ const state = useProjection(useRunStore(runId), pendingApprovals);
9
+ if (state.items.length === 0) {
10
+ return _jsx("p", { className: "text-muted-foreground text-xs", children: "No approvals requested." });
11
+ }
12
+ function decide(approvalId, outcome) {
13
+ void client.signal(runId, [decision(approvalId, outcome)]);
14
+ }
15
+ return (_jsx("ul", { className: "grid gap-2", children: state.items.map((item) => (_jsxs("li", { className: "border-border bg-card/60 rounded-lg border p-2.5", children: [_jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: item.title || item.approvalId }), _jsx(StatusBadge, { status: item.status })] }), item.status === 'pending' ? (_jsxs("div", { className: "mt-2 flex gap-1.5", children: [_jsx(Button, { size: "xs", onClick: () => decide(item.approvalId, 'approve'), children: "Approve" }), _jsx(Button, { size: "xs", variant: "outline", onClick: () => decide(item.approvalId, 'reject'), children: "Reject" })] })) : null] }, item.approvalId))) }));
16
+ }
@@ -0,0 +1,4 @@
1
+ import type { DebuggerPlugin } from '@swirls/looms/debugger';
2
+ import { ApprovalsView } from './approvals-view';
3
+ export declare const approvalDebugger: DebuggerPlugin;
4
+ export { ApprovalsView };
@@ -0,0 +1,11 @@
1
+ import { pendingApprovals } from '../projections.js';
2
+ import { ApprovalsView } from './approvals-view.js';
3
+ import { summarizeApprovalEvent } from './summarize.js';
4
+ export const approvalDebugger = {
5
+ name: 'approval',
6
+ families: [
7
+ { family: 'approval', color: 'oklch(0.72 0.15 45)', summarize: summarizeApprovalEvent },
8
+ ],
9
+ projections: [{ name: pendingApprovals.name, component: ApprovalsView }],
10
+ };
11
+ export { ApprovalsView };
@@ -0,0 +1,2 @@
1
+ import { type DebuggerEvent, type EventSummary } from '@swirls/looms/debugger';
2
+ export declare function summarizeApprovalEvent(event: DebuggerEvent): EventSummary | undefined;
@@ -0,0 +1,17 @@
1
+ import { jsonFields, jsonText } from '@swirls/looms/debugger';
2
+ export function summarizeApprovalEvent(event) {
3
+ const payload = jsonFields(event.payload);
4
+ switch (event.type) {
5
+ case 'approval.requested':
6
+ return { title: 'approval requested', detail: jsonText(payload.title) };
7
+ case 'approval.decided':
8
+ return {
9
+ title: `approval ${jsonText(payload.outcome) ?? 'decided'}`,
10
+ detail: jsonText(payload.approvalId),
11
+ };
12
+ case 'approval.timed_out':
13
+ return { title: 'approval timed out', detail: jsonText(payload.approvalId) };
14
+ default:
15
+ return undefined;
16
+ }
17
+ }
@@ -34,12 +34,93 @@ export declare const requestApprovalEffect: NoInfer<import("@swirls/looms/core")
34
34
  readonly payload: {
35
35
  readonly approvalId: string;
36
36
  };
37
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
38
+ readonly type: "runtime.effect.ambiguous";
39
+ readonly payload: {
40
+ readonly effectId: string;
41
+ readonly attempt: number;
42
+ readonly error: string;
43
+ };
44
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
45
+ readonly type: "runtime.effect.attempt.started";
46
+ readonly payload: {
47
+ readonly effectId: string;
48
+ readonly attempt: number;
49
+ };
50
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
51
+ readonly type: "runtime.effect.cancel.requested";
52
+ readonly payload: {
53
+ readonly effectId: string;
54
+ readonly attempt: number;
55
+ readonly deadlineAt: number | null;
56
+ };
57
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
58
+ readonly type: "runtime.effect.cancelled";
59
+ readonly payload: {
60
+ readonly effectId: string;
61
+ readonly attempt: number;
62
+ };
63
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
64
+ readonly type: "runtime.effect.completed";
65
+ readonly payload: {
66
+ readonly effectId: string;
67
+ readonly attempt: number;
68
+ };
69
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
70
+ readonly type: "runtime.effect.dispatched";
71
+ readonly payload: {
72
+ readonly effectId: string;
73
+ readonly attempt: number;
74
+ readonly deadlineAt: number | null;
75
+ };
37
76
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
38
77
  readonly type: "runtime.effect.failed";
39
78
  readonly payload: {
40
79
  readonly effectId: string;
41
80
  readonly error: string;
42
81
  };
82
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
83
+ readonly type: "runtime.effect.heartbeat";
84
+ readonly payload: {
85
+ readonly effectId: string;
86
+ readonly attempt: number;
87
+ readonly heartbeatAt: number;
88
+ readonly deadlineAt: number | null;
89
+ };
90
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
91
+ readonly type: "runtime.effect.queued";
92
+ readonly payload: {
93
+ readonly effectId: string;
94
+ readonly attempt: number;
95
+ readonly deadlineAt: number | null;
96
+ };
97
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
98
+ readonly type: "runtime.effect.retry.scheduled";
99
+ readonly payload: {
100
+ readonly effectId: string;
101
+ readonly attempt: number;
102
+ readonly nextAttemptAt: number;
103
+ readonly error: string;
104
+ };
105
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
106
+ readonly type: "runtime.effect.timed_out";
107
+ readonly payload: {
108
+ readonly effectId: string;
109
+ readonly attempt: number;
110
+ readonly timeout: string;
111
+ };
112
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
113
+ readonly type: "runtime.effect.worker.started";
114
+ readonly payload: {
115
+ readonly effectId: string;
116
+ readonly attempt: number;
117
+ readonly deadlineAt: number | null;
118
+ };
119
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
120
+ readonly type: "runtime.run.cancelled";
121
+ readonly payload: {
122
+ readonly reason?: string | undefined;
123
+ };
43
124
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
44
125
  readonly type: "runtime.run.completed";
45
126
  readonly payload: {
@@ -52,7 +133,9 @@ export declare const requestApprovalEffect: NoInfer<import("@swirls/looms/core")
52
133
  readonly rootThreadId?: string | undefined;
53
134
  readonly kind: string;
54
135
  readonly definitionName: string;
136
+ readonly definitionVersion: string;
55
137
  readonly input: import("effect/Schema").Json;
138
+ readonly requestedThreadId?: string | null | undefined;
56
139
  };
57
140
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
58
141
  readonly type: "runtime.signal.received";
@@ -66,6 +149,11 @@ export declare const requestApprovalEffect: NoInfer<import("@swirls/looms/core")
66
149
  readonly stateHash: string;
67
150
  readonly state?: import("effect/Schema").Json | undefined;
68
151
  };
152
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
153
+ readonly type: "runtime.thread.cancel.requested";
154
+ readonly payload: {
155
+ readonly threadId: string;
156
+ };
69
157
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
70
158
  readonly type: "runtime.thread.cancelled";
71
159
  readonly payload: {
@@ -90,6 +178,7 @@ export declare const requestApprovalEffect: NoInfer<import("@swirls/looms/core")
90
178
  readonly threadId: string;
91
179
  readonly kind: string;
92
180
  readonly definitionName: string;
181
+ readonly definitionVersion: string;
93
182
  readonly input: import("effect/Schema").Json;
94
183
  readonly parentThreadId: string | null;
95
184
  };
@@ -56,12 +56,93 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
56
56
  readonly payload: {
57
57
  readonly approvalId: string;
58
58
  };
59
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
60
+ readonly type: "runtime.effect.ambiguous";
61
+ readonly payload: {
62
+ readonly effectId: string;
63
+ readonly attempt: number;
64
+ readonly error: string;
65
+ };
66
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
67
+ readonly type: "runtime.effect.attempt.started";
68
+ readonly payload: {
69
+ readonly effectId: string;
70
+ readonly attempt: number;
71
+ };
72
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
73
+ readonly type: "runtime.effect.cancel.requested";
74
+ readonly payload: {
75
+ readonly effectId: string;
76
+ readonly attempt: number;
77
+ readonly deadlineAt: number | null;
78
+ };
79
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
80
+ readonly type: "runtime.effect.cancelled";
81
+ readonly payload: {
82
+ readonly effectId: string;
83
+ readonly attempt: number;
84
+ };
85
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
86
+ readonly type: "runtime.effect.completed";
87
+ readonly payload: {
88
+ readonly effectId: string;
89
+ readonly attempt: number;
90
+ };
91
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
92
+ readonly type: "runtime.effect.dispatched";
93
+ readonly payload: {
94
+ readonly effectId: string;
95
+ readonly attempt: number;
96
+ readonly deadlineAt: number | null;
97
+ };
59
98
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
60
99
  readonly type: "runtime.effect.failed";
61
100
  readonly payload: {
62
101
  readonly effectId: string;
63
102
  readonly error: string;
64
103
  };
104
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
105
+ readonly type: "runtime.effect.heartbeat";
106
+ readonly payload: {
107
+ readonly effectId: string;
108
+ readonly attempt: number;
109
+ readonly heartbeatAt: number;
110
+ readonly deadlineAt: number | null;
111
+ };
112
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
113
+ readonly type: "runtime.effect.queued";
114
+ readonly payload: {
115
+ readonly effectId: string;
116
+ readonly attempt: number;
117
+ readonly deadlineAt: number | null;
118
+ };
119
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
120
+ readonly type: "runtime.effect.retry.scheduled";
121
+ readonly payload: {
122
+ readonly effectId: string;
123
+ readonly attempt: number;
124
+ readonly nextAttemptAt: number;
125
+ readonly error: string;
126
+ };
127
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
128
+ readonly type: "runtime.effect.timed_out";
129
+ readonly payload: {
130
+ readonly effectId: string;
131
+ readonly attempt: number;
132
+ readonly timeout: string;
133
+ };
134
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
135
+ readonly type: "runtime.effect.worker.started";
136
+ readonly payload: {
137
+ readonly effectId: string;
138
+ readonly attempt: number;
139
+ readonly deadlineAt: number | null;
140
+ };
141
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
142
+ readonly type: "runtime.run.cancelled";
143
+ readonly payload: {
144
+ readonly reason?: string | undefined;
145
+ };
65
146
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
66
147
  readonly type: "runtime.run.completed";
67
148
  readonly payload: {
@@ -74,7 +155,9 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
74
155
  readonly rootThreadId?: string | undefined;
75
156
  readonly kind: string;
76
157
  readonly definitionName: string;
158
+ readonly definitionVersion: string;
77
159
  readonly input: import("effect/Schema").Json;
160
+ readonly requestedThreadId?: string | null | undefined;
78
161
  };
79
162
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
80
163
  readonly type: "runtime.signal.received";
@@ -88,6 +171,11 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
88
171
  readonly stateHash: string;
89
172
  readonly state?: import("effect/Schema").Json | undefined;
90
173
  };
174
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
175
+ readonly type: "runtime.thread.cancel.requested";
176
+ readonly payload: {
177
+ readonly threadId: string;
178
+ };
91
179
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
92
180
  readonly type: "runtime.thread.cancelled";
93
181
  readonly payload: {
@@ -112,6 +200,7 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
112
200
  readonly threadId: string;
113
201
  readonly kind: string;
114
202
  readonly definitionName: string;
203
+ readonly definitionVersion: string;
115
204
  readonly input: import("effect/Schema").Json;
116
205
  readonly parentThreadId: string | null;
117
206
  };
@@ -162,22 +251,8 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
162
251
  readonly status: "approved" | "pending" | "rejected" | "timed_out";
163
252
  readonly threadId: string | null;
164
253
  }[];
165
- } | {
166
- items: ({
167
- readonly approvalId: string;
168
- readonly title: string;
169
- readonly description?: string | undefined;
170
- readonly status: "approved" | "pending" | "rejected" | "timed_out";
171
- readonly threadId: string | null;
172
- } | {
173
- approvalId: string;
174
- title: string;
175
- description?: string | undefined;
176
- threadId: string | null;
177
- status: string;
178
- })[];
179
254
  }>;
180
- }, any> & {
255
+ }, import("effect/Context").Service.Any> & {
181
256
  readonly effects: {
182
257
  request: import("@swirls/looms/core").EffectDefinition<{
183
258
  readonly approvalId: string;
@@ -215,12 +290,93 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
215
290
  readonly payload: {
216
291
  readonly approvalId: string;
217
292
  };
293
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
294
+ readonly type: "runtime.effect.ambiguous";
295
+ readonly payload: {
296
+ readonly effectId: string;
297
+ readonly attempt: number;
298
+ readonly error: string;
299
+ };
300
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
301
+ readonly type: "runtime.effect.attempt.started";
302
+ readonly payload: {
303
+ readonly effectId: string;
304
+ readonly attempt: number;
305
+ };
306
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
307
+ readonly type: "runtime.effect.cancel.requested";
308
+ readonly payload: {
309
+ readonly effectId: string;
310
+ readonly attempt: number;
311
+ readonly deadlineAt: number | null;
312
+ };
313
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
314
+ readonly type: "runtime.effect.cancelled";
315
+ readonly payload: {
316
+ readonly effectId: string;
317
+ readonly attempt: number;
318
+ };
319
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
320
+ readonly type: "runtime.effect.completed";
321
+ readonly payload: {
322
+ readonly effectId: string;
323
+ readonly attempt: number;
324
+ };
325
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
326
+ readonly type: "runtime.effect.dispatched";
327
+ readonly payload: {
328
+ readonly effectId: string;
329
+ readonly attempt: number;
330
+ readonly deadlineAt: number | null;
331
+ };
218
332
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
219
333
  readonly type: "runtime.effect.failed";
220
334
  readonly payload: {
221
335
  readonly effectId: string;
222
336
  readonly error: string;
223
337
  };
338
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
339
+ readonly type: "runtime.effect.heartbeat";
340
+ readonly payload: {
341
+ readonly effectId: string;
342
+ readonly attempt: number;
343
+ readonly heartbeatAt: number;
344
+ readonly deadlineAt: number | null;
345
+ };
346
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
347
+ readonly type: "runtime.effect.queued";
348
+ readonly payload: {
349
+ readonly effectId: string;
350
+ readonly attempt: number;
351
+ readonly deadlineAt: number | null;
352
+ };
353
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
354
+ readonly type: "runtime.effect.retry.scheduled";
355
+ readonly payload: {
356
+ readonly effectId: string;
357
+ readonly attempt: number;
358
+ readonly nextAttemptAt: number;
359
+ readonly error: string;
360
+ };
361
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
362
+ readonly type: "runtime.effect.timed_out";
363
+ readonly payload: {
364
+ readonly effectId: string;
365
+ readonly attempt: number;
366
+ readonly timeout: string;
367
+ };
368
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
369
+ readonly type: "runtime.effect.worker.started";
370
+ readonly payload: {
371
+ readonly effectId: string;
372
+ readonly attempt: number;
373
+ readonly deadlineAt: number | null;
374
+ };
375
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
376
+ readonly type: "runtime.run.cancelled";
377
+ readonly payload: {
378
+ readonly reason?: string | undefined;
379
+ };
224
380
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
225
381
  readonly type: "runtime.run.completed";
226
382
  readonly payload: {
@@ -233,7 +389,9 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
233
389
  readonly rootThreadId?: string | undefined;
234
390
  readonly kind: string;
235
391
  readonly definitionName: string;
392
+ readonly definitionVersion: string;
236
393
  readonly input: import("effect/Schema").Json;
394
+ readonly requestedThreadId?: string | null | undefined;
237
395
  };
238
396
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
239
397
  readonly type: "runtime.signal.received";
@@ -247,6 +405,11 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
247
405
  readonly stateHash: string;
248
406
  readonly state?: import("effect/Schema").Json | undefined;
249
407
  };
408
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
409
+ readonly type: "runtime.thread.cancel.requested";
410
+ readonly payload: {
411
+ readonly threadId: string;
412
+ };
250
413
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
251
414
  readonly type: "runtime.thread.cancelled";
252
415
  readonly payload: {
@@ -271,6 +434,7 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
271
434
  readonly threadId: string;
272
435
  readonly kind: string;
273
436
  readonly definitionName: string;
437
+ readonly definitionVersion: string;
274
438
  readonly input: import("effect/Schema").Json;
275
439
  readonly parentThreadId: string | null;
276
440
  };
@@ -323,20 +487,6 @@ export declare function approval(): import("@swirls/looms/core").RuntimeModule<"
323
487
  readonly status: "approved" | "pending" | "rejected" | "timed_out";
324
488
  readonly threadId: string | null;
325
489
  }[];
326
- } | {
327
- items: ({
328
- readonly approvalId: string;
329
- readonly title: string;
330
- readonly description?: string | undefined;
331
- readonly status: "approved" | "pending" | "rejected" | "timed_out";
332
- readonly threadId: string | null;
333
- } | {
334
- approvalId: string;
335
- title: string;
336
- description?: string | undefined;
337
- threadId: string | null;
338
- status: string;
339
- })[];
340
490
  }>;
341
491
  };
342
492
  };
@@ -25,18 +25,4 @@ export declare const pendingApprovals: import("@swirls/looms/core").ProjectionDe
25
25
  readonly status: "approved" | "pending" | "rejected" | "timed_out";
26
26
  readonly threadId: string | null;
27
27
  }[];
28
- } | {
29
- items: ({
30
- readonly approvalId: string;
31
- readonly title: string;
32
- readonly description?: string | undefined;
33
- readonly status: "approved" | "pending" | "rejected" | "timed_out";
34
- readonly threadId: string | null;
35
- } | {
36
- approvalId: string;
37
- title: string;
38
- description?: string | undefined;
39
- threadId: string | null;
40
- status: string;
41
- })[];
42
28
  }>;
@@ -1,4 +1,4 @@
1
- import { Schema } from 'effect';
1
+ import { Predicate, Schema } from 'effect';
2
2
  import { approvalModule } from './scope.js';
3
3
  export const PendingApprovalSchema = Schema.Struct({
4
4
  approvalId: Schema.String,
@@ -41,13 +41,30 @@ export const pendingApprovals = approvalModule.projection({
41
41
  const { approvalId, outcome } = event.payload;
42
42
  const status = outcome === 'reject' ? 'rejected' : 'approved';
43
43
  return {
44
- items: state.items.map((item) => item.approvalId === approvalId ? { ...item, status } : item),
44
+ items: state.items.map((item) => item.approvalId === approvalId && item.status === 'pending'
45
+ ? { ...item, status }
46
+ : item),
45
47
  };
46
48
  }
47
49
  case 'approval.timed_out': {
48
50
  const { approvalId } = event.payload;
49
51
  return {
50
- items: state.items.map((item) => item.approvalId === approvalId ? { ...item, status: 'timed_out' } : item),
52
+ items: state.items.map((item) => item.approvalId === approvalId && item.status === 'pending'
53
+ ? { ...item, status: 'timed_out' }
54
+ : item),
55
+ };
56
+ }
57
+ case 'runtime.wait.satisfied': {
58
+ const tag = event.payload.tag;
59
+ if (!Predicate.isObject(tag) ||
60
+ !Predicate.isString(tag.approvalId) ||
61
+ tag.outcome !== 'timeout') {
62
+ return state;
63
+ }
64
+ return {
65
+ items: state.items.map((item) => item.approvalId === tag.approvalId && item.status === 'pending'
66
+ ? { ...item, status: 'timed_out' }
67
+ : item),
51
68
  };
52
69
  }
53
70
  default:
@@ -6,6 +6,8 @@ export declare function gate(args: {
6
6
  approvalId?: string;
7
7
  actions?: ApprovalAction[];
8
8
  schema?: JsonValue;
9
+ /** Absolute epoch milliseconds. Decision and timer waits race; the first wins. */
10
+ timeoutAt?: number;
9
11
  }): RuntimeEffect[];
10
12
  export type ApprovalChoice = 'approve' | 'reject' | {
11
13
  actionId: string;
@@ -7,7 +7,7 @@ export function gate(args) {
7
7
  { id: 'approve', label: 'Approve', outcome: 'approve' },
8
8
  { id: 'reject', label: 'Reject', outcome: 'reject' },
9
9
  ];
10
- return [
10
+ const effects = [
11
11
  invoke(requestApprovalEffect, {
12
12
  approvalId,
13
13
  title: args.title,
@@ -18,9 +18,25 @@ export function gate(args) {
18
18
  wait({
19
19
  waitId: createWaitId(approvalId, 'decision'),
20
20
  on: { type: 'approval.decided', match: { approvalId } },
21
- tag: { approvalId },
21
+ tag: { approvalId, raceId: approvalId },
22
22
  }),
23
23
  ];
24
+ if (args.timeoutAt !== undefined) {
25
+ if (!Number.isFinite(args.timeoutAt)) {
26
+ throw new Error('Approval timeoutAt must be a finite epoch timestamp');
27
+ }
28
+ effects.push(wait({
29
+ waitId: createWaitId(approvalId, 'timeout'),
30
+ on: { timerAt: args.timeoutAt },
31
+ tag: {
32
+ approvalId,
33
+ raceId: approvalId,
34
+ outcome: 'timeout',
35
+ error: `Approval ${approvalId} timed out`,
36
+ },
37
+ }));
38
+ }
39
+ return effects;
24
40
  }
25
41
  /**
26
42
  * Build the `approval.decided` event that resolves a pending gate.
package/dist/cli/cli.js CHANGED
@@ -3,4 +3,6 @@ import { BunRuntime, BunServices } from '@effect/platform-bun';
3
3
  import { Effect } from 'effect';
4
4
  import { Command } from 'effect/unstable/cli';
5
5
  import { looms, VERSION } from './commands.js';
6
+ // This executable boundary owns the lifetime of the complete application layer.
7
+ // oxlint-disable-next-line effecttsgo/strict-effect-provide
6
8
  looms.pipe(Command.run({ version: VERSION }), Effect.provide(BunServices.layer), BunRuntime.runMain);