@hraness/wordcell 0.20.0-bootstrap.1

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 (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +749 -0
  3. package/dist/agent-context.js +35 -0
  4. package/dist/agent-guide-audit.js +18 -0
  5. package/dist/attachments.js +19 -0
  6. package/dist/authoring.js +33 -0
  7. package/dist/benchmark.js +19 -0
  8. package/dist/capture.js +49 -0
  9. package/dist/cli.js +57 -0
  10. package/dist/clip/acquire.js +57 -0
  11. package/dist/clip/args.js +21 -0
  12. package/dist/clip/bounded-byte-buffer.js +9 -0
  13. package/dist/clip/browser-profiles.js +17 -0
  14. package/dist/clip/bundle-reader.js +11 -0
  15. package/dist/clip/cli.js +27 -0
  16. package/dist/clip/cookies.js +21 -0
  17. package/dist/clip/defuddle-worker.js +84 -0
  18. package/dist/clip/doctor.js +32 -0
  19. package/dist/clip/jobs.js +784 -0
  20. package/dist/clip/network-proxy.js +9 -0
  21. package/dist/clip/network.js +28 -0
  22. package/dist/clip/persist.js +30 -0
  23. package/dist/clip/refresh.js +11 -0
  24. package/dist/clip/terminal.js +11 -0
  25. package/dist/evaluation-builder.js +12238 -0
  26. package/dist/evaluation-kb.js +26 -0
  27. package/dist/evaluation.js +35 -0
  28. package/dist/git.js +39 -0
  29. package/dist/graph.js +41 -0
  30. package/dist/index-054mb7d3.js +1974 -0
  31. package/dist/index-06c9ctr6.js +738 -0
  32. package/dist/index-180zbkkt.js +2480 -0
  33. package/dist/index-1gwbassd.js +743 -0
  34. package/dist/index-1xxnjn0d.js +171 -0
  35. package/dist/index-23z4zxgg.js +119 -0
  36. package/dist/index-2gv8y733.js +432 -0
  37. package/dist/index-3ehtt59c.js +199 -0
  38. package/dist/index-3rm7cz6h.js +373 -0
  39. package/dist/index-48pz4jpc.js +392 -0
  40. package/dist/index-4j3tt0c3.js +234 -0
  41. package/dist/index-5n05se68.js +307 -0
  42. package/dist/index-5vwpzb5a.js +764 -0
  43. package/dist/index-6jcz0m1c.js +712 -0
  44. package/dist/index-6sw24nvv.js +1189 -0
  45. package/dist/index-8a08v6x8.js +56 -0
  46. package/dist/index-adx6khj5.js +488 -0
  47. package/dist/index-b88v3vtm.js +805 -0
  48. package/dist/index-bcknqxrq.js +1943 -0
  49. package/dist/index-bs0yf4pp.js +711 -0
  50. package/dist/index-by0pbant.js +827 -0
  51. package/dist/index-d13v9ckt.js +150 -0
  52. package/dist/index-dfag79p7.js +370 -0
  53. package/dist/index-e4fagfjz.js +44 -0
  54. package/dist/index-e5fbsywq.js +658 -0
  55. package/dist/index-ekpwvbra.js +1070 -0
  56. package/dist/index-f984hw45.js +927 -0
  57. package/dist/index-gh719d91.js +63 -0
  58. package/dist/index-h170byqw.js +371 -0
  59. package/dist/index-hgve9rh2.js +2046 -0
  60. package/dist/index-hya40gb2.js +474 -0
  61. package/dist/index-j4zgmzjr.js +152 -0
  62. package/dist/index-m7et4rz4.js +966 -0
  63. package/dist/index-mxxxytys.js +1254 -0
  64. package/dist/index-n05s3wsb.js +2728 -0
  65. package/dist/index-nd6nynv2.js +1162 -0
  66. package/dist/index-npg9z1a4.js +431 -0
  67. package/dist/index-pj501bh1.js +140 -0
  68. package/dist/index-rdd5f7jj.js +70 -0
  69. package/dist/index-sy0zety7.js +3630 -0
  70. package/dist/index-tkpxp48t.js +1166 -0
  71. package/dist/index-w2zc0vwa.js +571 -0
  72. package/dist/index-why54q5p.js +462 -0
  73. package/dist/index-x3fthpsc.js +585 -0
  74. package/dist/index-x6m57nfc.js +1041 -0
  75. package/dist/index.js +784 -0
  76. package/dist/kb-alias.js +55 -0
  77. package/dist/navigation.js +13 -0
  78. package/dist/pdf.js +85 -0
  79. package/dist/percolate.js +44 -0
  80. package/dist/portfolio.js +77 -0
  81. package/dist/query.js +29 -0
  82. package/dist/repository-memory.js +60 -0
  83. package/dist/sdk.js +36 -0
  84. package/dist/search-rules.js +34 -0
  85. package/dist/search.js +22 -0
  86. package/dist/semantic.js +39 -0
  87. package/dist/source-inbox.js +17 -0
  88. package/dist/untrusted-content.js +32 -0
  89. package/dist/url-intelligence.js +74 -0
  90. package/dist/workflow.js +23 -0
  91. package/dist/workflows/decision-context.js +20 -0
  92. package/dist/workflows/explain-change.js +8 -0
  93. package/dist/workflows/index.js +28 -0
  94. package/dist/workflows/plan-radar.js +10 -0
  95. package/package.json +421 -0
  96. package/skills/wordcell/AGENTS.md +22 -0
  97. package/skills/wordcell/SKILL.md +91 -0
  98. package/skills/wordcell/agents/openai.yaml +4 -0
  99. package/skills/wordcell/references/companion-skills.md +96 -0
  100. package/skills/wordcell/references/customize.md +123 -0
  101. package/skills/wordcell/references/pdf-review.md +51 -0
  102. package/skills/wordcell/references/percolate.md +176 -0
  103. package/skills/wordcell/references/plan-structure.md +105 -0
  104. package/skills/wordcell/references/plan.md +115 -0
  105. package/skills/wordcell/references/query.md +252 -0
  106. package/skills/wordcell/references/refresh.md +133 -0
  107. package/skills/wordcell/references/save-pdf.md +125 -0
  108. package/skills/wordcell/references/save-url.md +178 -0
  109. package/skills/wordcell/references/url-authentication.md +75 -0
  110. package/skills/wordcell/references/url-platforms.md +25 -0
  111. package/skills/wordcell/templates/companion-skill.template.md +57 -0
  112. package/src/agent-context.ts +1241 -0
  113. package/src/agent-guide-audit.ts +750 -0
  114. package/src/attachments.ts +723 -0
  115. package/src/authoring-model.ts +798 -0
  116. package/src/authoring-platform.ts +549 -0
  117. package/src/authoring-program.ts +278 -0
  118. package/src/authoring-runtime.ts +54 -0
  119. package/src/authoring.ts +75 -0
  120. package/src/benchmark.ts +362 -0
  121. package/src/capture.ts +68 -0
  122. package/src/cli-program.ts +3662 -0
  123. package/src/cli.ts +6 -0
  124. package/src/clip/acquire.ts +1273 -0
  125. package/src/clip/archive-today.ts +402 -0
  126. package/src/clip/args.ts +423 -0
  127. package/src/clip/assets.ts +262 -0
  128. package/src/clip/bounded-byte-buffer.ts +75 -0
  129. package/src/clip/browser-profiles.ts +372 -0
  130. package/src/clip/bundle-reader.ts +608 -0
  131. package/src/clip/capture.ts +1054 -0
  132. package/src/clip/cli.ts +181 -0
  133. package/src/clip/cookies.ts +512 -0
  134. package/src/clip/doctor.ts +1110 -0
  135. package/src/clip/extract.ts +868 -0
  136. package/src/clip/jobs.ts +959 -0
  137. package/src/clip/lib.ts +861 -0
  138. package/src/clip/media.ts +1474 -0
  139. package/src/clip/metadata-search-tool/Cargo.lock +2498 -0
  140. package/src/clip/metadata-search-tool/Cargo.toml +18 -0
  141. package/src/clip/metadata-search-tool/runner.ts +685 -0
  142. package/src/clip/metadata-search-tool/src/main.rs +389 -0
  143. package/src/clip/metadata-search.ts +687 -0
  144. package/src/clip/network-proxy.ts +627 -0
  145. package/src/clip/network.ts +950 -0
  146. package/src/clip/package-root.ts +54 -0
  147. package/src/clip/persist.ts +1472 -0
  148. package/src/clip/platforms.ts +1824 -0
  149. package/src/clip/refresh.ts +197 -0
  150. package/src/clip/structured.ts +432 -0
  151. package/src/clip/terminal.ts +197 -0
  152. package/src/clip/url-intelligence.ts +581 -0
  153. package/src/clip/url-metadata-backfill.ts +616 -0
  154. package/src/clip/url-metadata-cli.ts +251 -0
  155. package/src/clip/url-metadata.ts +1397 -0
  156. package/src/evaluation-analysis-v2.ts +1440 -0
  157. package/src/evaluation-builder.ts +2539 -0
  158. package/src/evaluation-corpus-authoring.ts +2052 -0
  159. package/src/evaluation-evidence.ts +1147 -0
  160. package/src/evaluation-execution-v2.ts +426 -0
  161. package/src/evaluation-implementation.ts +131 -0
  162. package/src/evaluation-kb-closure.ts +1430 -0
  163. package/src/evaluation-kb-runner-v2.ts +735 -0
  164. package/src/evaluation-kb-v2.ts +2567 -0
  165. package/src/evaluation-kb.ts +1018 -0
  166. package/src/evaluation-measurement-v2.ts +1462 -0
  167. package/src/evaluation-packing-v2.ts +452 -0
  168. package/src/evaluation-redaction.ts +28 -0
  169. package/src/evaluation-v2.ts +3857 -0
  170. package/src/evaluation.ts +1220 -0
  171. package/src/git.ts +1276 -0
  172. package/src/graph.ts +1494 -0
  173. package/src/index.ts +21 -0
  174. package/src/init.ts +123 -0
  175. package/src/kb-alias.ts +14 -0
  176. package/src/navigation.ts +277 -0
  177. package/src/note-lock.ts +529 -0
  178. package/src/oh-adoption.ts +444 -0
  179. package/src/pdf/args.ts +202 -0
  180. package/src/pdf/capture.ts +298 -0
  181. package/src/pdf/cli.ts +159 -0
  182. package/src/pdf/extract.ts +303 -0
  183. package/src/pdf/layout.ts +618 -0
  184. package/src/pdf/markdown.ts +154 -0
  185. package/src/pdf/model.ts +234 -0
  186. package/src/pdf/ocr.ts +190 -0
  187. package/src/pdf/persist.ts +314 -0
  188. package/src/pdf/source.ts +135 -0
  189. package/src/pdf/tools.ts +146 -0
  190. package/src/pdf.ts +92 -0
  191. package/src/percolate.ts +1948 -0
  192. package/src/portfolio-audit.ts +574 -0
  193. package/src/portfolio-identity.ts +162 -0
  194. package/src/portfolio-registry.ts +473 -0
  195. package/src/portfolio.ts +765 -0
  196. package/src/query.ts +646 -0
  197. package/src/repository-memory.ts +1150 -0
  198. package/src/sdk.ts +1452 -0
  199. package/src/search-rules.ts +712 -0
  200. package/src/search.ts +710 -0
  201. package/src/semantic-runtime.ts +1139 -0
  202. package/src/semantic.ts +2480 -0
  203. package/src/source-inbox.ts +232 -0
  204. package/src/untrusted-content.ts +401 -0
  205. package/src/url-intelligence.ts +104 -0
  206. package/src/vault.ts +636 -0
  207. package/src/workflow-model.ts +444 -0
  208. package/src/workflow-platform.ts +74 -0
  209. package/src/workflow-program.ts +183 -0
  210. package/src/workflow-runtime.ts +51 -0
  211. package/src/workflow.ts +23 -0
  212. package/src/workflows/decision-context.ts +81 -0
  213. package/src/workflows/explain-change.ts +73 -0
  214. package/src/workflows/index.ts +3 -0
  215. package/src/workflows/plan-radar.ts +101 -0
@@ -0,0 +1,63 @@
1
+ // @bun
2
+ // src/clip/bounded-byte-buffer.ts
3
+ class BoundedByteBuffer {
4
+ #maxBytes;
5
+ #storage = new Uint8Array;
6
+ #length = 0;
7
+ constructor(maxBytes) {
8
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {
9
+ throw new RangeError("byte buffer limit must be a non-negative safe integer");
10
+ }
11
+ this.#maxBytes = maxBytes;
12
+ }
13
+ get byteLength() {
14
+ return this.#length;
15
+ }
16
+ append(chunk) {
17
+ if (chunk.byteLength > this.#maxBytes - this.#length)
18
+ return false;
19
+ if (chunk.byteLength === 0)
20
+ return true;
21
+ const required = this.#length + chunk.byteLength;
22
+ if (required > this.#storage.byteLength)
23
+ this.#grow(required);
24
+ this.#storage.set(chunk, this.#length);
25
+ this.#length = required;
26
+ return true;
27
+ }
28
+ toUint8Array() {
29
+ if (this.#length === this.#storage.byteLength)
30
+ return this.#storage;
31
+ return this.#storage.slice(0, this.#length);
32
+ }
33
+ #grow(required) {
34
+ let capacity = this.#storage.byteLength;
35
+ if (capacity === 0)
36
+ capacity = Math.min(this.#maxBytes, Math.max(1024, required));
37
+ while (capacity < required) {
38
+ capacity = capacity <= Math.floor(this.#maxBytes / 2) ? capacity * 2 : this.#maxBytes;
39
+ }
40
+ const grown = new Uint8Array(capacity);
41
+ grown.set(this.#storage.subarray(0, this.#length));
42
+ this.#storage = grown;
43
+ }
44
+ }
45
+ async function readBoundedByteStream(stream, maxBytes, overflowLabel = "stream") {
46
+ const bytes = new BoundedByteBuffer(maxBytes);
47
+ const reader = stream.getReader();
48
+ try {
49
+ for (;; ) {
50
+ const result = await reader.read();
51
+ if (result.done)
52
+ break;
53
+ if (!bytes.append(result.value)) {
54
+ throw new Error(`${overflowLabel} exceeded ${maxBytes} bytes`);
55
+ }
56
+ }
57
+ } finally {
58
+ reader.releaseLock();
59
+ }
60
+ return bytes.toUint8Array();
61
+ }
62
+
63
+ export { BoundedByteBuffer, readBoundedByteStream };
@@ -0,0 +1,371 @@
1
+ // @bun
2
+ // src/workflow-model.ts
3
+ var MAX_WORKFLOW_NODES = 64;
4
+ var MAX_WORKFLOW_CONCURRENCY = 8;
5
+ var MAX_GIT_WORKFLOW_CONCURRENCY = 4;
6
+ var DEFAULT_WORKFLOW_OUTPUT_BYTES = 16 * 1024 * 1024;
7
+ var MAX_WORKFLOW_OUTPUT_BYTES = 64 * 1024 * 1024;
8
+ var workflowIdPattern = /^[a-z][a-z0-9-]{0,63}$/u;
9
+
10
+ class WorkflowRunError extends Error {
11
+ kind;
12
+ node;
13
+ constructor(kind, message, options = {}) {
14
+ super(message, options);
15
+ this.name = "WorkflowRunError";
16
+ this.kind = kind;
17
+ if (options.node !== undefined)
18
+ this.node = options.node;
19
+ }
20
+ }
21
+ function isRecord(value) {
22
+ return typeof value === "object" && value !== null && !Array.isArray(value);
23
+ }
24
+ function needsFor(node) {
25
+ return node.needs ?? [];
26
+ }
27
+ function validateWorkflowId(id, label) {
28
+ if (!workflowIdPattern.test(id)) {
29
+ throw new Error(`${label} must start with a lowercase letter and contain at most 64 lowercase letters, digits, or hyphens.`);
30
+ }
31
+ }
32
+ function validateWorkflow(definition) {
33
+ validateWorkflowId(definition.id, "Workflow id");
34
+ if (definition.nodes.length < 1 || definition.nodes.length > MAX_WORKFLOW_NODES) {
35
+ throw new RangeError(`A workflow must contain from 1 through ${MAX_WORKFLOW_NODES} nodes.`);
36
+ }
37
+ const nodesById = new Map;
38
+ for (const node of definition.nodes) {
39
+ validateWorkflowId(node.id, "Workflow node id");
40
+ if (nodesById.has(node.id)) {
41
+ throw new Error(`Workflow node id ${JSON.stringify(node.id)} is duplicated.`);
42
+ }
43
+ if (typeof node.run !== "function") {
44
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} must define run().`);
45
+ }
46
+ const needs = needsFor(node);
47
+ if (new Set(needs).size !== needs.length) {
48
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} repeats a dependency.`);
49
+ }
50
+ nodesById.set(node.id, node);
51
+ }
52
+ if (!nodesById.has(definition.output)) {
53
+ throw new Error(`Workflow output node ${JSON.stringify(definition.output)} does not exist.`);
54
+ }
55
+ for (const node of definition.nodes) {
56
+ for (const dependency of needsFor(node)) {
57
+ if (!nodesById.has(dependency)) {
58
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} depends on unknown node ${JSON.stringify(dependency)}.`);
59
+ }
60
+ if (dependency === node.id) {
61
+ throw new Error(`Workflow node ${JSON.stringify(node.id)} cannot depend on itself.`);
62
+ }
63
+ }
64
+ }
65
+ const remaining = new Set(nodesById.keys());
66
+ const completed = new Set;
67
+ while (remaining.size > 0) {
68
+ const ready = definition.nodes.filter((node) => remaining.has(node.id) && needsFor(node).every((dependency) => completed.has(dependency)));
69
+ if (ready.length === 0) {
70
+ throw new Error(`Workflow contains a dependency cycle among: ${[...remaining].join(", ")}.`);
71
+ }
72
+ for (const node of ready) {
73
+ remaining.delete(node.id);
74
+ completed.add(node.id);
75
+ }
76
+ }
77
+ }
78
+ function createWorkflowBuilder(id, nodes) {
79
+ const builder = {
80
+ node: (node) => createWorkflowBuilder(id, [...nodes, node]),
81
+ output: (output) => defineWorkflow({
82
+ id,
83
+ nodes,
84
+ output
85
+ })
86
+ };
87
+ return builder;
88
+ }
89
+ function defineWorkflow(specification) {
90
+ if (typeof specification === "string") {
91
+ return createWorkflowBuilder(specification, []);
92
+ }
93
+ const definition = {
94
+ kind: "hraness-kb-workflow",
95
+ version: 1,
96
+ ...specification
97
+ };
98
+ validateWorkflow(definition);
99
+ return definition;
100
+ }
101
+ function workflowFromUnknown(value) {
102
+ if (!isRecord(value))
103
+ throw new Error("Workflow export must be an object.");
104
+ if (value.kind !== "hraness-kb-workflow" || value.version !== 1) {
105
+ throw new Error("Workflow export has an unsupported kind or version.");
106
+ }
107
+ if (typeof value.id !== "string" || typeof value.output !== "string" || !Array.isArray(value.nodes)) {
108
+ throw new Error("Workflow export has malformed id, output, or nodes.");
109
+ }
110
+ const nodes = value.nodes.map((item, index) => {
111
+ if (!isRecord(item) || typeof item.id !== "string") {
112
+ throw new Error(`Workflow export node ${index} is malformed.`);
113
+ }
114
+ const run = item.run;
115
+ if (typeof run !== "function") {
116
+ throw new Error(`Workflow export node ${index} is malformed.`);
117
+ }
118
+ const needs = item.needs;
119
+ if (needs !== undefined && (!Array.isArray(needs) || needs.some((entry) => typeof entry !== "string"))) {
120
+ throw new Error(`Workflow export node ${index}.needs must be an array of strings.`);
121
+ }
122
+ const resource = item.resource;
123
+ if (resource !== undefined && resource !== "default" && resource !== "git" && resource !== "qmd") {
124
+ throw new Error(`Workflow export node ${index}.resource is invalid.`);
125
+ }
126
+ return {
127
+ id: item.id,
128
+ ...needs === undefined ? {} : { needs },
129
+ ...resource === undefined ? {} : { resource },
130
+ run: (context) => {
131
+ const returned = Reflect.apply(run, undefined, [context]);
132
+ return returned;
133
+ }
134
+ };
135
+ });
136
+ const definition = {
137
+ kind: "hraness-kb-workflow",
138
+ version: 1,
139
+ id: value.id,
140
+ nodes,
141
+ output: value.output
142
+ };
143
+ validateWorkflow(definition);
144
+ return definition;
145
+ }
146
+ function checkedConcurrency(value) {
147
+ const concurrency = value ?? 4;
148
+ if (!Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > MAX_WORKFLOW_CONCURRENCY) {
149
+ throw new RangeError(`Workflow concurrency must be an integer from 1 through ${MAX_WORKFLOW_CONCURRENCY}.`);
150
+ }
151
+ return concurrency;
152
+ }
153
+ function resourceLimits(concurrency, configured) {
154
+ const limits = {
155
+ default: concurrency,
156
+ git: Math.min(MAX_GIT_WORKFLOW_CONCURRENCY, concurrency),
157
+ qmd: 1
158
+ };
159
+ for (const resource of ["default", "git", "qmd"]) {
160
+ const value = configured?.[resource];
161
+ if (value === undefined)
162
+ continue;
163
+ if (resource === "qmd" && value !== 1) {
164
+ throw new RangeError("Workflow qmd concurrency is fixed at 1.");
165
+ }
166
+ if (!Number.isSafeInteger(value) || value < 1 || value > MAX_WORKFLOW_CONCURRENCY) {
167
+ throw new RangeError(`Workflow ${resource} concurrency must be an integer from 1 through ${MAX_WORKFLOW_CONCURRENCY}.`);
168
+ }
169
+ limits[resource] = resource === "git" ? Math.min(value, concurrency, MAX_GIT_WORKFLOW_CONCURRENCY) : Math.min(value, concurrency);
170
+ }
171
+ return limits;
172
+ }
173
+ function checkedOutputBytes(value) {
174
+ const maximum = value ?? DEFAULT_WORKFLOW_OUTPUT_BYTES;
175
+ if (!Number.isSafeInteger(maximum) || maximum < 1 || maximum > MAX_WORKFLOW_OUTPUT_BYTES) {
176
+ throw new RangeError(`Workflow output byte limit must be an integer from 1 through ${MAX_WORKFLOW_OUTPUT_BYTES}.`);
177
+ }
178
+ return maximum;
179
+ }
180
+ // src/workflow-runtime.ts
181
+ import { Cause, Effect as Effect3, Exit, Option } from "effect";
182
+
183
+ // src/workflow-program.ts
184
+ import { Effect as Effect2, Fiber } from "effect";
185
+
186
+ // src/workflow-platform.ts
187
+ import { serialize } from "v8";
188
+ import { Effect } from "effect";
189
+ function admitCallback(id, run) {
190
+ const completion = Promise.resolve().then(run).then((value) => ({ ok: true, id, value })).catch((error) => ({ ok: false, id, error }));
191
+ return { completion };
192
+ }
193
+ function awaitCallback(callback) {
194
+ return Effect.promise(() => callback.completion);
195
+ }
196
+ function nextCallback(callbacks) {
197
+ return Effect.promise(() => Promise.race(Array.from(callbacks, ({ completion }) => completion)));
198
+ }
199
+ function structuredOutputBytes(value, node) {
200
+ return Effect.try({
201
+ try: () => serialize(value).byteLength,
202
+ catch: (error) => new WorkflowRunError("node-failed", `Workflow node ${JSON.stringify(node)} returned a result that cannot be structurally serialized.`, { node, cause: error })
203
+ });
204
+ }
205
+
206
+ class WorkflowListenerRemovalFailure {
207
+ reason;
208
+ constructor(reason) {
209
+ this.reason = reason;
210
+ }
211
+ }
212
+ function workflowCancellation(signal) {
213
+ return Effect.acquireRelease(Effect.sync(() => {
214
+ const controller = new AbortController;
215
+ let abortedByCaller = false;
216
+ const abort = () => {
217
+ abortedByCaller = true;
218
+ controller.abort(signal?.reason);
219
+ };
220
+ signal?.addEventListener("abort", abort, { once: true });
221
+ return { controller, abort, get abortedByCaller() {
222
+ return abortedByCaller;
223
+ } };
224
+ }), ({ abort }) => Effect.sync(() => {
225
+ try {
226
+ signal?.removeEventListener("abort", abort);
227
+ } catch (error) {
228
+ throw new WorkflowListenerRemovalFailure(error);
229
+ }
230
+ }));
231
+ }
232
+
233
+ // src/workflow-program.ts
234
+ function abortedError() {
235
+ return new WorkflowRunError("aborted", "Workflow execution was aborted.");
236
+ }
237
+ function executeWorkflow(definition, options, policy) {
238
+ return Effect2.gen(function* () {
239
+ const cancellation = yield* workflowCancellation(options.signal);
240
+ const { controller } = cancellation;
241
+ const pending = new Set(definition.nodes.map(({ id }) => id));
242
+ const completed = new Set;
243
+ const values = new Map;
244
+ const active = new Map;
245
+ let failure;
246
+ let outputBytes = 0;
247
+ const completedValue = (id) => {
248
+ if (!values.has(id)) {
249
+ throw new Error(`Workflow result ${JSON.stringify(id)} is unavailable after its dependency completed.`);
250
+ }
251
+ return values.get(id);
252
+ };
253
+ const contextFor = (node) => {
254
+ const needs = needsFor(node);
255
+ const allowedResults = new Set(needs);
256
+ const dependencyResults = new Map(needs.map((id) => [id, completedValue(id)]));
257
+ const context = {
258
+ input: options.input,
259
+ kb: options.kb,
260
+ signal: controller.signal,
261
+ results: dependencyResults,
262
+ result: (id) => {
263
+ if (!allowedResults.has(id)) {
264
+ throw new Error(`Workflow result ${JSON.stringify(id)} is not a declared dependency of ${JSON.stringify(node.id)}.`);
265
+ }
266
+ return dependencyResults.get(id);
267
+ }
268
+ };
269
+ return context;
270
+ };
271
+ while (completed.size < definition.nodes.length && failure === undefined) {
272
+ if (controller.signal.aborted) {
273
+ failure = abortedError();
274
+ break;
275
+ }
276
+ for (const node of definition.nodes) {
277
+ if (!pending.has(node.id) || active.size >= policy.concurrency)
278
+ continue;
279
+ if (!needsFor(node).every((dependency) => completed.has(dependency)))
280
+ continue;
281
+ const resource = node.resource ?? "default";
282
+ const occupied = Array.from(active.values()).filter((task3) => task3.resource === resource).length;
283
+ if (occupied >= policy.limits[resource])
284
+ continue;
285
+ const context = contextFor(node);
286
+ const task2 = yield* Effect2.uninterruptible(Effect2.gen(function* () {
287
+ const callback = yield* Effect2.sync(() => admitCallback(node.id, () => node.run(context)));
288
+ const fiber = yield* Effect2.forkScoped(Effect2.uninterruptible(awaitCallback(callback)));
289
+ return { callback, fiber, resource };
290
+ }));
291
+ pending.delete(node.id);
292
+ active.set(node.id, task2);
293
+ }
294
+ if (active.size === 0) {
295
+ return yield* Effect2.die(new Error("Workflow scheduler made no progress after validation."));
296
+ }
297
+ const outcome = yield* nextCallback(Array.from(active.values(), ({ callback }) => callback));
298
+ const task = active.get(outcome.id);
299
+ if (task !== undefined)
300
+ yield* Fiber.await(task.fiber).pipe(Effect2.asVoid);
301
+ active.delete(outcome.id);
302
+ if (outcome.ok) {
303
+ const measured = yield* Effect2.either(structuredOutputBytes(outcome.value, outcome.id));
304
+ if (measured._tag === "Left") {
305
+ failure = measured.left;
306
+ } else if (measured.right > policy.outputLimit - outputBytes) {
307
+ failure = new WorkflowRunError("output-limit", `Workflow results exceed the ${policy.outputLimit}-byte output limit at node ${JSON.stringify(outcome.id)}.`, { node: outcome.id });
308
+ } else {
309
+ outputBytes += measured.right;
310
+ values.set(outcome.id, outcome.value);
311
+ completed.add(outcome.id);
312
+ }
313
+ if (failure !== undefined)
314
+ controller.abort(failure);
315
+ } else {
316
+ controller.abort(outcome.error);
317
+ failure = cancellation.abortedByCaller ? abortedError() : new WorkflowRunError("node-failed", `Workflow node ${JSON.stringify(outcome.id)} failed.`, { node: outcome.id, cause: outcome.error });
318
+ }
319
+ }
320
+ yield* Effect2.forEach(active.values(), ({ fiber }) => Fiber.await(fiber).pipe(Effect2.asVoid), { discard: true });
321
+ if (failure !== undefined)
322
+ return yield* Effect2.fail(failure);
323
+ let finalOutputBytes = 0;
324
+ for (const node of definition.nodes) {
325
+ const resultBytes = yield* structuredOutputBytes(values.get(node.id), node.id);
326
+ if (resultBytes > policy.outputLimit - finalOutputBytes) {
327
+ return yield* Effect2.fail(new WorkflowRunError("output-limit", `Workflow results exceed the ${policy.outputLimit}-byte output limit at node ${JSON.stringify(node.id)}.`, { node: node.id }));
328
+ }
329
+ finalOutputBytes += resultBytes;
330
+ }
331
+ const orderedValues = new Map(definition.nodes.map((node) => [node.id, completedValue(node.id)]));
332
+ return {
333
+ workflow: definition.id,
334
+ outputNode: definition.output,
335
+ output: values.get(definition.output),
336
+ outputBytes: finalOutputBytes,
337
+ trace: definition.nodes.map((node) => ({
338
+ id: node.id,
339
+ needs: needsFor(node),
340
+ resource: node.resource ?? "default",
341
+ status: "completed"
342
+ })),
343
+ results: orderedValues
344
+ };
345
+ });
346
+ }
347
+
348
+ // src/workflow-runtime.ts
349
+ async function runWorkflow(definition, options) {
350
+ validateWorkflow(definition);
351
+ const concurrency = checkedConcurrency(options.concurrency);
352
+ const limits = resourceLimits(concurrency, options.resourceConcurrency);
353
+ const outputLimit = checkedOutputBytes(options.maxOutputBytes);
354
+ if (options.signal?.aborted === true) {
355
+ throw new WorkflowRunError("aborted", "Workflow execution was aborted.");
356
+ }
357
+ const exit = await Effect3.runPromiseExit(Effect3.scoped(executeWorkflow(definition, options, { concurrency, limits, outputLimit })));
358
+ if (Exit.isSuccess(exit))
359
+ return exit.value;
360
+ const cleanup = Array.from(Cause.defects(exit.cause)).find((defect2) => defect2 instanceof WorkflowListenerRemovalFailure);
361
+ if (cleanup !== undefined)
362
+ throw cleanup.reason;
363
+ const failure = Cause.failureOption(exit.cause);
364
+ if (Option.isSome(failure))
365
+ throw failure.value;
366
+ const defect = Cause.dieOption(exit.cause);
367
+ if (Option.isSome(defect))
368
+ throw defect.value;
369
+ throw new Error("Workflow owner was interrupted without a caller cancellation outcome.");
370
+ }
371
+ export { MAX_WORKFLOW_NODES, MAX_WORKFLOW_CONCURRENCY, MAX_GIT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_OUTPUT_BYTES, MAX_WORKFLOW_OUTPUT_BYTES, WorkflowRunError, defineWorkflow, workflowFromUnknown, runWorkflow };