@swirls/looms 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/CHANGELOG.md +9 -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 +55 -32
  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/definitions-store.d.ts +2 -3
  13. package/dist/agent/definitions-store.js +2 -4
  14. package/dist/agent/definitions.d.ts +46 -20
  15. package/dist/agent/definitions.js +36 -8
  16. package/dist/agent/effects.d.ts +359 -2
  17. package/dist/agent/effects.js +60 -34
  18. package/dist/agent/events.d.ts +175 -19
  19. package/dist/agent/events.js +45 -10
  20. package/dist/agent/index.d.ts +1 -0
  21. package/dist/agent/index.js +1 -0
  22. package/dist/agent/llm.d.ts +11 -2
  23. package/dist/agent/llm.js +13 -3
  24. package/dist/agent/module.d.ts +812 -78
  25. package/dist/agent/module.js +16 -4
  26. package/dist/agent/scope.d.ts +174 -18
  27. package/dist/agent/signals.d.ts +24 -1
  28. package/dist/agent/signals.js +77 -0
  29. package/dist/agent/threads.d.ts +3 -33
  30. package/dist/agent/threads.js +20 -25
  31. package/dist/agent/tool-schema.js +0 -1
  32. package/dist/agent/types.d.ts +49 -4
  33. package/dist/agent/types.js +5 -5
  34. package/dist/ai-vercel/index.d.ts +1 -0
  35. package/dist/ai-vercel/index.js +1 -0
  36. package/dist/ai-vercel/messages.js +22 -7
  37. package/dist/ai-vercel/vercel-evaluator.d.ts +23 -0
  38. package/dist/ai-vercel/vercel-evaluator.js +68 -0
  39. package/dist/ai-vercel/vercel-llm.js +64 -44
  40. package/dist/approval/effects.d.ts +89 -0
  41. package/dist/approval/module.d.ts +179 -29
  42. package/dist/approval/projections.d.ts +0 -14
  43. package/dist/approval/projections.js +20 -3
  44. package/dist/approval/signals.d.ts +2 -0
  45. package/dist/approval/signals.js +18 -2
  46. package/dist/cli/cli.js +2 -0
  47. package/dist/cli/commands.js +12 -16
  48. package/dist/client/client.d.ts +1195 -18
  49. package/dist/client/client.js +118 -120
  50. package/dist/client/index.d.ts +1 -1
  51. package/dist/client/index.js +1 -1
  52. package/dist/client/sse.d.ts +13 -0
  53. package/dist/client/sse.js +38 -44
  54. package/dist/cloudflare/alarm-scheduler.d.ts +12 -2
  55. package/dist/cloudflare/alarm-scheduler.js +34 -7
  56. package/dist/cloudflare/durable-object.d.ts +10 -2
  57. package/dist/cloudflare/durable-object.js +59 -28
  58. package/dist/cloudflare/event-store.d.ts +7 -2
  59. package/dist/cloudflare/event-store.js +8 -7
  60. package/dist/cloudflare/index.d.ts +2 -2
  61. package/dist/cloudflare/index.js +2 -2
  62. package/dist/cloudflare/router.js +13 -14
  63. package/dist/core/catalog.d.ts +3 -3
  64. package/dist/core/catalog.js +2 -5
  65. package/dist/core/coalesce.js +5 -3
  66. package/dist/core/compose.d.ts +2 -1
  67. package/dist/core/compose.js +18 -2
  68. package/dist/core/definition-store.d.ts +11 -0
  69. package/dist/core/definition-store.js +6 -0
  70. package/dist/core/effects.d.ts +127 -15
  71. package/dist/core/effects.js +89 -17
  72. package/dist/core/envelope.d.ts +27 -7
  73. package/dist/core/envelope.js +20 -6
  74. package/dist/core/event-codec.d.ts +4 -2
  75. package/dist/core/event-codec.js +10 -5
  76. package/dist/core/event-index.js +1 -3
  77. package/dist/core/fold.d.ts +3 -0
  78. package/dist/core/fold.js +171 -24
  79. package/dist/core/ids.d.ts +5 -0
  80. package/dist/core/ids.js +35 -2
  81. package/dist/core/index.d.ts +5 -1
  82. package/dist/core/index.js +5 -1
  83. package/dist/core/kind.d.ts +22 -0
  84. package/dist/core/kind.js +17 -0
  85. package/dist/core/limits.d.ts +34 -0
  86. package/dist/core/limits.js +46 -0
  87. package/dist/core/match.d.ts +1 -0
  88. package/dist/core/match.js +10 -1
  89. package/dist/core/module-scope.d.ts +22 -20
  90. package/dist/core/module-scope.js +38 -28
  91. package/dist/core/module.d.ts +16 -5
  92. package/dist/core/module.js +4 -0
  93. package/dist/core/projection.d.ts +13 -13
  94. package/dist/core/projection.js +9 -5
  95. package/dist/core/protocol.d.ts +68 -11
  96. package/dist/core/protocol.js +82 -11
  97. package/dist/core/replay.d.ts +312 -3
  98. package/dist/core/replay.js +11 -1
  99. package/dist/core/schema.d.ts +8 -19
  100. package/dist/core/schema.js +25 -80
  101. package/dist/core/serialize.js +2 -4
  102. package/dist/core/snapshot-store.d.ts +2 -1
  103. package/dist/core/snapshot-store.js +8 -2
  104. package/dist/core/snapshots.d.ts +5 -1
  105. package/dist/core/snapshots.js +10 -15
  106. package/dist/core/sqlite-store.js +56 -11
  107. package/dist/core/state.d.ts +142 -4
  108. package/dist/core/state.js +78 -0
  109. package/dist/core/store.d.ts +38 -3
  110. package/dist/core/store.js +77 -22
  111. package/dist/core/thread.d.ts +10 -9
  112. package/dist/core/types.d.ts +5 -8
  113. package/dist/core/types.js +28 -24
  114. package/dist/core/validate-event.js +14 -4
  115. package/dist/core/worker-callback.d.ts +17 -0
  116. package/dist/core/worker-callback.js +1 -0
  117. package/dist/debugger/components/event-stream.js +9 -10
  118. package/dist/debugger/events/protocol-summarize.js +26 -0
  119. package/dist/debugger/lib/event-meta.js +1 -2
  120. package/dist/evaluator/definitions-store.d.ts +11 -0
  121. package/dist/evaluator/definitions-store.js +8 -0
  122. package/dist/evaluator/definitions.d.ts +18 -0
  123. package/dist/evaluator/definitions.js +4 -0
  124. package/dist/evaluator/effects.d.ts +226 -0
  125. package/dist/evaluator/effects.js +132 -0
  126. package/dist/evaluator/evaluator.d.ts +24 -0
  127. package/dist/evaluator/evaluator.js +67 -0
  128. package/dist/evaluator/events.d.ts +59 -0
  129. package/dist/evaluator/events.js +21 -0
  130. package/dist/evaluator/index.d.ts +11 -0
  131. package/dist/evaluator/index.js +11 -0
  132. package/dist/evaluator/module.d.ts +606 -0
  133. package/dist/evaluator/module.js +25 -0
  134. package/dist/evaluator/projections.d.ts +50 -0
  135. package/dist/evaluator/projections.js +20 -0
  136. package/dist/evaluator/scope.d.ts +59 -0
  137. package/dist/evaluator/scope.js +7 -0
  138. package/dist/evaluator/signals.d.ts +3 -0
  139. package/dist/evaluator/signals.js +17 -0
  140. package/dist/evaluator/threads.d.ts +62 -0
  141. package/dist/evaluator/threads.js +117 -0
  142. package/dist/evaluator/types.d.ts +125 -0
  143. package/dist/evaluator/types.js +51 -0
  144. package/dist/projectors/delivery.d.ts +83 -0
  145. package/dist/projectors/delivery.js +182 -0
  146. package/dist/projectors/index-model.d.ts +1 -1
  147. package/dist/projectors/index-model.js +4 -6
  148. package/dist/projectors/index.d.ts +2 -0
  149. package/dist/projectors/index.js +2 -0
  150. package/dist/projectors/memory.d.ts +1 -1
  151. package/dist/projectors/memory.js +10 -8
  152. package/dist/projectors/postgres.js +44 -58
  153. package/dist/projectors/projector.d.ts +17 -0
  154. package/dist/projectors/projector.js +26 -1
  155. package/dist/projectors/sqlite-delivery.d.ts +4 -0
  156. package/dist/projectors/sqlite-delivery.js +147 -0
  157. package/dist/projectors/sqlite.js +23 -23
  158. package/dist/projectors/with-projectors.d.ts +7 -2
  159. package/dist/projectors/with-projectors.js +27 -28
  160. package/dist/react/notify.js +11 -8
  161. package/dist/react/react.d.ts +2 -3
  162. package/dist/react/react.js +14 -30
  163. package/dist/react/sse.d.ts +1 -1
  164. package/dist/react/sse.js +1 -1
  165. package/dist/react/store.d.ts +2 -2
  166. package/dist/react/store.js +109 -119
  167. package/dist/runtime/cancellation.d.ts +16 -0
  168. package/dist/runtime/cancellation.js +129 -0
  169. package/dist/runtime/deadline-transition-planner.d.ts +31 -0
  170. package/dist/runtime/deadline-transition-planner.js +139 -0
  171. package/dist/runtime/dispatch-effect.d.ts +3 -2
  172. package/dist/runtime/dispatch-effect.js +7 -13
  173. package/dist/runtime/errors.d.ts +51 -0
  174. package/dist/runtime/errors.js +39 -0
  175. package/dist/runtime/{runtime-helpers.d.ts → helpers.d.ts} +24 -4
  176. package/dist/runtime/{runtime-helpers.js → helpers.js} +56 -19
  177. package/dist/runtime/index.d.ts +3 -3
  178. package/dist/runtime/index.js +3 -3
  179. package/dist/runtime/ingress.d.ts +15 -0
  180. package/dist/runtime/ingress.js +42 -0
  181. package/dist/runtime/local-effect-executor.d.ts +21 -0
  182. package/dist/runtime/local-effect-executor.js +137 -0
  183. package/dist/runtime/looms.d.ts +22 -4
  184. package/dist/runtime/looms.js +54 -36
  185. package/dist/runtime/observer.d.ts +45 -0
  186. package/dist/runtime/observer.js +11 -0
  187. package/dist/runtime/repository.d.ts +55 -0
  188. package/dist/runtime/repository.js +278 -0
  189. package/dist/runtime/retry-policy.d.ts +16 -0
  190. package/dist/runtime/retry-policy.js +29 -0
  191. package/dist/runtime/run-execution-context.d.ts +30 -0
  192. package/dist/runtime/run-execution-context.js +56 -0
  193. package/dist/runtime/run-start.d.ts +4 -0
  194. package/dist/runtime/run-start.js +44 -0
  195. package/dist/runtime/runtime.d.ts +6 -87
  196. package/dist/runtime/runtime.js +233 -470
  197. package/dist/runtime/server/auth.d.ts +40 -0
  198. package/dist/runtime/server/auth.js +40 -0
  199. package/dist/runtime/server/fetch-handler.d.ts +14 -0
  200. package/dist/runtime/server/fetch-handler.js +51 -0
  201. package/dist/runtime/server/http.d.ts +37 -0
  202. package/dist/runtime/server/http.js +62 -0
  203. package/dist/runtime/server/route-table.d.ts +55 -0
  204. package/dist/runtime/server/route-table.js +74 -0
  205. package/dist/runtime/server/routes/effects.d.ts +3 -0
  206. package/dist/runtime/server/routes/effects.js +59 -0
  207. package/dist/runtime/server/routes/operations.d.ts +3 -0
  208. package/dist/runtime/server/routes/operations.js +14 -0
  209. package/dist/runtime/server/routes/runs.d.ts +3 -0
  210. package/dist/runtime/server/routes/runs.js +192 -0
  211. package/dist/runtime/server.d.ts +2 -8
  212. package/dist/runtime/server.js +4 -211
  213. package/dist/runtime/sse.d.ts +2 -1
  214. package/dist/runtime/sse.js +24 -17
  215. package/dist/runtime/types.d.ts +115 -0
  216. package/dist/runtime/types.js +1 -0
  217. package/dist/runtime/wake-engine.d.ts +20 -0
  218. package/dist/runtime/wake-engine.js +311 -0
  219. package/dist/runtime/wake-scheduler.d.ts +3 -4
  220. package/dist/runtime/wake-scheduler.js +25 -31
  221. package/dist/runtime/worker-callbacks.d.ts +16 -0
  222. package/dist/runtime/worker-callbacks.js +167 -0
  223. package/dist/runtime/worker-effect-dispatch.d.ts +36 -0
  224. package/dist/runtime/worker-effect-dispatch.js +126 -0
  225. package/dist/s2/config.d.ts +1 -1
  226. package/dist/s2/config.js +1 -1
  227. package/dist/s2/lite.js +70 -82
  228. package/dist/s2/pagination.d.ts +15 -0
  229. package/dist/s2/pagination.js +36 -0
  230. package/dist/s2/projector.js +6 -5
  231. package/dist/s2/snapshot-store.js +148 -163
  232. package/dist/s2/store.d.ts +3 -21
  233. package/dist/s2/store.js +71 -165
  234. package/dist/testing/index.d.ts +15 -0
  235. package/dist/testing/index.js +53 -16
  236. package/dist/workflow/definitions-store.d.ts +2 -3
  237. package/dist/workflow/definitions-store.js +2 -2
  238. package/dist/workflow/definitions.d.ts +78 -22
  239. package/dist/workflow/definitions.js +80 -14
  240. package/dist/workflow/effects.d.ts +453 -107
  241. package/dist/workflow/effects.js +214 -115
  242. package/dist/workflow/events.d.ts +149 -5
  243. package/dist/workflow/events.js +27 -5
  244. package/dist/workflow/graph.d.ts +56 -0
  245. package/dist/workflow/graph.js +207 -0
  246. package/dist/workflow/index.d.ts +1 -0
  247. package/dist/workflow/index.js +1 -0
  248. package/dist/workflow/module.d.ts +1047 -266
  249. package/dist/workflow/projections.d.ts +14 -12
  250. package/dist/workflow/projections.js +30 -8
  251. package/dist/workflow/scope.d.ts +146 -4
  252. package/dist/workflow/threads.d.ts +383 -155
  253. package/dist/workflow/threads.js +308 -110
  254. package/package.json +7 -2
  255. package/dist/runtime/events-api.d.ts +0 -4
  256. package/dist/runtime/events-api.js +0 -84
@@ -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);
@@ -1,9 +1,10 @@
1
- import { Config, Console, Effect, FileSystem, Layer, Option, Path, Queue, Stdio, Stream, Terminal, } from 'effect';
1
+ import { Config, Console, Effect, FileSystem, Layer, Option, Path, Queue, Schema, Stdio, Stream, Terminal, } from 'effect';
2
2
  import { Argument, CliError, Command, Flag } from 'effect/unstable/cli';
3
3
  import { ChildProcessSpawner } from 'effect/unstable/process';
4
4
  import { steer as steerEvent } from '@swirls/looms/agent';
5
5
  import { decision } from '@swirls/looms/approval';
6
6
  import { createLoomsClient } from '@swirls/looms/client';
7
+ import { stringifyJson, stringifyJsonPretty } from '@swirls/looms/core';
7
8
  import { createLooms } from '@swirls/looms/runtime';
8
9
  const VERSION = '0.0.1';
9
10
  const urlFlag = Flag.string('url').pipe(Flag.withDescription('Looms host base URL (env LOOMS_URL)'), Flag.withFallbackConfig(Config.string('LOOMS_URL')), Flag.withDefault('http://127.0.0.1:8787'), Flag.map((url) => url.replace(/\/$/, '')));
@@ -11,13 +12,7 @@ function parseJsonArg(raw) {
11
12
  if (Option.isNone(raw) || raw.value === '') {
12
13
  return null;
13
14
  }
14
- try {
15
- // SAFETY: CLI JSON args decode to JsonValue; parse failures fall back to the raw string
16
- return JSON.parse(raw.value);
17
- }
18
- catch {
19
- return raw.value;
20
- }
15
+ return Option.getOrElse(Schema.decodeOption(Schema.fromJsonString(Schema.Json))(raw.value), () => raw.value);
21
16
  }
22
17
  function clientFor(url) {
23
18
  return createLoomsClient({ baseUrl: url });
@@ -47,21 +42,21 @@ const start = Command.make('start', {
47
42
  }, Effect.fn('start')(function* ({ kind, name, json }) {
48
43
  const { url } = yield* loomsBase;
49
44
  const result = yield* tryClient(() => clientFor(url).startRun({ kind, definitionName: name, input: parseJsonArg(json) }));
50
- yield* Console.log(JSON.stringify(result, null, 2));
45
+ yield* Console.log(stringifyJsonPretty(result));
51
46
  })).pipe(Command.withDescription('Start a run from a registered definition: looms start agent echo \'{"text":"hi"}\''), Command.withShortDescription('Start a run'));
52
47
  const events = Command.make('events', {
53
48
  runId: Argument.string('runId').pipe(Argument.withDescription('Run id')),
54
49
  }, Effect.fn('events')(function* ({ runId }) {
55
50
  const { url } = yield* loomsBase;
56
51
  const result = yield* tryClient(() => clientFor(url).getEvents(runId));
57
- yield* Console.log(JSON.stringify(result, null, 2));
52
+ yield* Console.log(stringifyJsonPretty(result));
58
53
  })).pipe(Command.withDescription('List events for a run'), Command.withShortDescription('List run events'));
59
54
  const state = Command.make('state', {
60
55
  runId: Argument.string('runId').pipe(Argument.withDescription('Run id')),
61
56
  }, Effect.fn('state')(function* ({ runId }) {
62
57
  const { url } = yield* loomsBase;
63
58
  const result = yield* tryClient(() => clientFor(url).getRun(runId));
64
- yield* Console.log(JSON.stringify(result, null, 2));
59
+ yield* Console.log(stringifyJsonPretty(result));
65
60
  })).pipe(Command.withDescription('Show run state'), Command.withShortDescription('Show run state'));
66
61
  const approve = Command.make('approve', {
67
62
  runId: Argument.string('runId').pipe(Argument.withDescription('Run id')),
@@ -78,7 +73,8 @@ const approve = Command.make('approve', {
78
73
  const outcome = accept ? 'approve' : 'reject';
79
74
  const { url } = yield* loomsBase;
80
75
  const result = yield* tryClient(() => clientFor(url).signal(runId, [decision(approvalId, outcome)]));
81
- yield* Console.log(JSON.stringify(result, null, 2));
76
+ yield* Console.log(stringifyJsonPretty(result));
77
+ return undefined;
82
78
  })).pipe(Command.withDescription('Approve or reject a pending approval'), Command.withShortDescription('Decide an approval'));
83
79
  const replay = Command.make('replay', {
84
80
  runId: Argument.string('runId').pipe(Argument.withDescription('Run id')),
@@ -86,7 +82,7 @@ const replay = Command.make('replay', {
86
82
  }, Effect.fn('replay')(function* ({ runId, seq }) {
87
83
  const { url } = yield* loomsBase;
88
84
  const result = yield* tryClient(() => clientFor(url).replayTo(runId, seq));
89
- yield* Console.log(JSON.stringify(result, null, 2));
85
+ yield* Console.log(stringifyJsonPretty(result));
90
86
  })).pipe(Command.withDescription('Replay a run to a sequence'), Command.withShortDescription('Replay to seq'));
91
87
  const signal = Command.make('signal', {
92
88
  runId: Argument.string('runId').pipe(Argument.withDescription('Run id')),
@@ -95,7 +91,7 @@ const signal = Command.make('signal', {
95
91
  }, Effect.fn('signal')(function* ({ runId, type, json }) {
96
92
  const { url } = yield* loomsBase;
97
93
  const result = yield* tryClient(() => clientFor(url).signal(runId, [{ type, payload: parseJsonArg(json) }]));
98
- yield* Console.log(JSON.stringify(result, null, 2));
94
+ yield* Console.log(stringifyJsonPretty(result));
99
95
  })).pipe(Command.withDescription('Append an external event and wake the run'), Command.withShortDescription('Signal a run'));
100
96
  const steer = Command.make('steer', {
101
97
  runId: Argument.string('runId').pipe(Argument.withDescription('Run id')),
@@ -104,7 +100,7 @@ const steer = Command.make('steer', {
104
100
  }, Effect.fn('steer')(function* ({ runId, message, interrupt }) {
105
101
  const { url } = yield* loomsBase;
106
102
  const result = yield* tryClient(() => clientFor(url).signal(runId, [steerEvent(message.join(' '), { interrupt })]));
107
- yield* Console.log(JSON.stringify(result, null, 2));
103
+ yield* Console.log(stringifyJsonPretty(result));
108
104
  })).pipe(Command.withDescription('Send a steering message to a running agent'), Command.withShortDescription('Steer an agent'));
109
105
  const tail = Command.make('tail', {
110
106
  runId: Argument.string('runId').pipe(Argument.withDescription('Run id')),
@@ -115,7 +111,7 @@ const tail = Command.make('tail', {
115
111
  yield* Effect.scoped(Effect.gen(function* () {
116
112
  const queue = yield* Queue.unbounded();
117
113
  yield* Effect.acquireRelease(Effect.sync(() => client.subscribeEvents(runId, (event) => {
118
- Queue.offerUnsafe(queue, JSON.stringify(event));
114
+ Queue.offerUnsafe(queue, stringifyJson(event));
119
115
  })), (stop) => Effect.sync(() => stop()));
120
116
  yield* Stream.fromQueue(queue).pipe(Stream.runForEach((line) => Console.log(line)));
121
117
  }));