atomism 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 (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +210 -0
  3. package/dist/chunk-34O5KJWR.js +81 -0
  4. package/dist/chunk-34O5KJWR.js.map +1 -0
  5. package/dist/chunk-55AP34JO.js +116 -0
  6. package/dist/chunk-55AP34JO.js.map +1 -0
  7. package/dist/chunk-6MDHM2B4.js +17 -0
  8. package/dist/chunk-6MDHM2B4.js.map +1 -0
  9. package/dist/chunk-GU2R4KLP.js +43 -0
  10. package/dist/chunk-GU2R4KLP.js.map +1 -0
  11. package/dist/chunk-H7WC3NXZ.js +39 -0
  12. package/dist/chunk-H7WC3NXZ.js.map +1 -0
  13. package/dist/chunk-P33CQFMY.js +329 -0
  14. package/dist/chunk-P33CQFMY.js.map +1 -0
  15. package/dist/chunk-P6X7T4KA.js +200 -0
  16. package/dist/chunk-P6X7T4KA.js.map +1 -0
  17. package/dist/chunk-PLQJM2KT.js +9 -0
  18. package/dist/chunk-PLQJM2KT.js.map +1 -0
  19. package/dist/chunk-RS2IEGW3.js +10 -0
  20. package/dist/chunk-RS2IEGW3.js.map +1 -0
  21. package/dist/chunk-S6Z5G5DB.js +84 -0
  22. package/dist/chunk-S6Z5G5DB.js.map +1 -0
  23. package/dist/chunk-UVUDQ4XP.js +259 -0
  24. package/dist/chunk-UVUDQ4XP.js.map +1 -0
  25. package/dist/chunk-UWVZQSP4.js +597 -0
  26. package/dist/chunk-UWVZQSP4.js.map +1 -0
  27. package/dist/chunk-YKJO3ZFY.js +308 -0
  28. package/dist/chunk-YKJO3ZFY.js.map +1 -0
  29. package/dist/cli.d.ts +1 -0
  30. package/dist/cli.js +152 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/create-atom-AXPDBYQL.js +153 -0
  33. package/dist/create-atom-AXPDBYQL.js.map +1 -0
  34. package/dist/escalate-BTEJT5NL.js +211 -0
  35. package/dist/escalate-BTEJT5NL.js.map +1 -0
  36. package/dist/extract-RPKCTINT.js +514 -0
  37. package/dist/extract-RPKCTINT.js.map +1 -0
  38. package/dist/graduate-453M7ZRQ.js +222 -0
  39. package/dist/graduate-453M7ZRQ.js.map +1 -0
  40. package/dist/helpers-PJPFPYBQ.js +11 -0
  41. package/dist/helpers-PJPFPYBQ.js.map +1 -0
  42. package/dist/history-OPD7NLZW.js +258 -0
  43. package/dist/history-OPD7NLZW.js.map +1 -0
  44. package/dist/import-generator-4CKRBMTE.js +1864 -0
  45. package/dist/import-generator-4CKRBMTE.js.map +1 -0
  46. package/dist/index.d.ts +230 -0
  47. package/dist/index.js +41 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/init-2FINDMYK.js +741 -0
  50. package/dist/init-2FINDMYK.js.map +1 -0
  51. package/dist/list-NEBVBGG3.js +71 -0
  52. package/dist/list-NEBVBGG3.js.map +1 -0
  53. package/dist/parser-3BILOSOO.js +157 -0
  54. package/dist/parser-3BILOSOO.js.map +1 -0
  55. package/dist/plan-DNVARHWH.js +249 -0
  56. package/dist/plan-DNVARHWH.js.map +1 -0
  57. package/dist/register-XTRMSH7Y.js +91 -0
  58. package/dist/register-XTRMSH7Y.js.map +1 -0
  59. package/dist/revert-J4CRDE2K.js +87 -0
  60. package/dist/revert-J4CRDE2K.js.map +1 -0
  61. package/dist/run-3GI3SBYL.js +188 -0
  62. package/dist/run-3GI3SBYL.js.map +1 -0
  63. package/dist/scan-generators-ST4TBEY7.js +375 -0
  64. package/dist/scan-generators-ST4TBEY7.js.map +1 -0
  65. package/dist/signatures-K5QIL4WG.js +258 -0
  66. package/dist/signatures-K5QIL4WG.js.map +1 -0
  67. package/dist/skills-assign-IHOXX4AI.js +182 -0
  68. package/dist/skills-assign-IHOXX4AI.js.map +1 -0
  69. package/dist/skills-load-JSD5UG2K.js +20 -0
  70. package/dist/skills-load-JSD5UG2K.js.map +1 -0
  71. package/dist/skills-scan-WACJFRJN.js +25 -0
  72. package/dist/skills-scan-WACJFRJN.js.map +1 -0
  73. package/dist/skills-suggest-JFI2NUJI.js +269 -0
  74. package/dist/skills-suggest-JFI2NUJI.js.map +1 -0
  75. package/dist/status-KQVSAZFR.js +111 -0
  76. package/dist/status-KQVSAZFR.js.map +1 -0
  77. package/dist/suggest-IFFJQFIW.js +183 -0
  78. package/dist/suggest-IFFJQFIW.js.map +1 -0
  79. package/dist/test-HP3FG3MO.js +152 -0
  80. package/dist/test-HP3FG3MO.js.map +1 -0
  81. package/dist/test-gen-2ZGPOP35.js +347 -0
  82. package/dist/test-gen-2ZGPOP35.js.map +1 -0
  83. package/dist/trust-4R26DULG.js +248 -0
  84. package/dist/trust-4R26DULG.js.map +1 -0
  85. package/dist/validate-generator-46H2LYYQ.js +410 -0
  86. package/dist/validate-generator-46H2LYYQ.js.map +1 -0
  87. package/dist/workflow-5UVLBS7J.js +655 -0
  88. package/dist/workflow-5UVLBS7J.js.map +1 -0
  89. package/package.json +84 -0
@@ -0,0 +1,655 @@
1
+ import {
2
+ AtomWithArtifacts,
3
+ createArtifactCache,
4
+ createRunState,
5
+ createWorkflowBeads,
6
+ formatDependencyChain,
7
+ getLastFailedRun,
8
+ getResumableAtoms,
9
+ isBeadsAvailable,
10
+ isBeadsInitialized,
11
+ loadRunState,
12
+ resolveDependencies,
13
+ saveRunState,
14
+ updateAtomBead,
15
+ updateAtomState,
16
+ updateWorkflowBead
17
+ } from "./chunk-UWVZQSP4.js";
18
+ import {
19
+ WorkflowDefinition
20
+ } from "./chunk-H7WC3NXZ.js";
21
+ import {
22
+ executeAtom
23
+ } from "./chunk-P33CQFMY.js";
24
+ import "./chunk-P6X7T4KA.js";
25
+ import "./chunk-RS2IEGW3.js";
26
+ import {
27
+ ATOMIC_DIR,
28
+ fileExists
29
+ } from "./chunk-YKJO3ZFY.js";
30
+ import "./chunk-6MDHM2B4.js";
31
+ import {
32
+ fmt
33
+ } from "./chunk-S6Z5G5DB.js";
34
+ import {
35
+ toErrorMessage
36
+ } from "./chunk-PLQJM2KT.js";
37
+
38
+ // src/commands/workflow.ts
39
+ import { join } from "path";
40
+ import { readFile, readdir } from "fs/promises";
41
+ async function executeWorkflowAtoms(atomIds, atoms, runState, accumulator, options, resolvedAtoms) {
42
+ for (const id of atomIds) {
43
+ const atom = atoms.find((a) => (a.alias ?? a.atom) === id);
44
+ const atomState = runState.atoms.find((a) => a.id === id);
45
+ if (!options.json) {
46
+ process.stdout.write(` ${fmt.gray("\u25CB")} ${id}...`);
47
+ }
48
+ if (runState.beadsEnabled && atomState?.beadId) {
49
+ await updateAtomBead(atomState.beadId, "in_progress");
50
+ }
51
+ updateAtomState(runState, id, {
52
+ status: "running",
53
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
54
+ });
55
+ await saveRunState(runState);
56
+ try {
57
+ const resolvedForAtom = resolvedAtoms?.find((r) => r.id === id);
58
+ const atomInput = {};
59
+ if (resolvedForAtom) {
60
+ for (const [fieldName, cachedArtifact] of resolvedForAtom.inputs) {
61
+ atomInput[fieldName] = cachedArtifact.content;
62
+ }
63
+ }
64
+ const atomResult = await executeAtom(
65
+ atom?.atom ?? id,
66
+ atomInput,
67
+ process.cwd()
68
+ );
69
+ if (!atomResult.success) {
70
+ throw new Error(atomResult.error ?? "Atom execution failed");
71
+ }
72
+ accumulator.executed.push(id);
73
+ const producedArtifacts = atom?.produces?.map((p) => p.artifact);
74
+ if (accumulator.artifacts && producedArtifacts && producedArtifacts.length > 0) {
75
+ accumulator.artifacts[id] = producedArtifacts;
76
+ }
77
+ updateAtomState(runState, id, {
78
+ status: "completed",
79
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
80
+ artifacts: producedArtifacts
81
+ });
82
+ await saveRunState(runState);
83
+ if (runState.beadsEnabled && atomState?.beadId) {
84
+ await updateAtomBead(atomState.beadId, "completed");
85
+ }
86
+ if (!options.json) {
87
+ process.stdout.write(`\r ${fmt.green("\u2713")} ${id}
88
+ `);
89
+ }
90
+ } catch (err) {
91
+ const errMsg = toErrorMessage(err);
92
+ accumulator.success = false;
93
+ accumulator.errors.push({
94
+ atom: id,
95
+ error: errMsg
96
+ });
97
+ updateAtomState(runState, id, {
98
+ status: "failed",
99
+ error: errMsg
100
+ });
101
+ runState.status = "failed";
102
+ runState.failedAtom = id;
103
+ runState.error = errMsg;
104
+ await saveRunState(runState);
105
+ if (runState.beadsEnabled && atomState?.beadId) {
106
+ await updateAtomBead(atomState.beadId, "failed", errMsg);
107
+ }
108
+ if (!options.json) {
109
+ process.stdout.write(`\r ${fmt.red("\u2717")} ${id}: ${errMsg}
110
+ `);
111
+ }
112
+ break;
113
+ }
114
+ }
115
+ }
116
+ var WORKFLOWS_DIR = "workflows";
117
+ var WORKFLOW_EXT = ".workflow.json";
118
+ async function loadWorkflow(name) {
119
+ const projectRoot = process.cwd();
120
+ const workflowPath = join(
121
+ projectRoot,
122
+ ATOMIC_DIR,
123
+ WORKFLOWS_DIR,
124
+ `${name}${WORKFLOW_EXT}`
125
+ );
126
+ if (!await fileExists(workflowPath)) {
127
+ throw new Error(
128
+ `Workflow '${name}' not found.
129
+ Expected file: ${workflowPath}`
130
+ );
131
+ }
132
+ const content = await readFile(workflowPath, "utf-8");
133
+ let data;
134
+ try {
135
+ data = JSON.parse(content);
136
+ } catch (err) {
137
+ throw new Error(
138
+ `Workflow '${name}' contains invalid JSON: ${toErrorMessage(err)}`
139
+ );
140
+ }
141
+ const parsed = data;
142
+ const definition = WorkflowDefinition.parse(parsed.definition);
143
+ const atomsData = parsed.atoms ?? parsed.capabilities;
144
+ if (!Array.isArray(atomsData)) {
145
+ throw new Error(`Workflow '${name}' has invalid atoms structure`);
146
+ }
147
+ const atoms = atomsData.map((atom, index) => {
148
+ try {
149
+ return AtomWithArtifacts.parse(atom);
150
+ } catch (err) {
151
+ throw new Error(
152
+ `Workflow '${name}' has invalid atom at index ${index}: ${toErrorMessage(err)}`
153
+ );
154
+ }
155
+ });
156
+ return { definition, atoms };
157
+ }
158
+ function convertToResolverAtoms(workflow, atoms) {
159
+ if (atoms.length > 0) {
160
+ return atoms;
161
+ }
162
+ return workflow.atoms.map((a) => ({
163
+ atom: a.atom,
164
+ dependsOn: a.dependsOn,
165
+ alias: a.alias,
166
+ description: a.description,
167
+ requires: [],
168
+ produces: []
169
+ }));
170
+ }
171
+ function formatWorkflowResult(result) {
172
+ const lines = [];
173
+ if (result.success) {
174
+ lines.push(
175
+ fmt.green("\u2713") + fmt.bold(` Workflow '${result.workflow}' completed`)
176
+ );
177
+ } else {
178
+ lines.push(
179
+ fmt.red("\u2717") + fmt.bold(` Workflow '${result.workflow}' failed`)
180
+ );
181
+ }
182
+ lines.push("");
183
+ lines.push(fmt.gray(`Duration: ${result.duration}ms`));
184
+ lines.push("");
185
+ lines.push(fmt.bold("Execution Summary:"));
186
+ lines.push(` Executed: ${result.executed.length} atoms`);
187
+ lines.push(` Skipped: ${result.skipped.length} atoms (cached)`);
188
+ if (result.executed.length > 0) {
189
+ lines.push("");
190
+ lines.push(fmt.bold("Executed:"));
191
+ for (const atomId of result.executed) {
192
+ lines.push(` ${fmt.green("\u2713")} ${atomId}`);
193
+ }
194
+ }
195
+ if (result.skipped.length > 0) {
196
+ lines.push("");
197
+ lines.push(fmt.bold("Skipped (cached):"));
198
+ for (const atomId of result.skipped) {
199
+ lines.push(` ${fmt.gray("\u25CB")} ${atomId}`);
200
+ }
201
+ }
202
+ if (result.errors.length > 0) {
203
+ lines.push("");
204
+ lines.push(fmt.bold(fmt.red("Errors:")));
205
+ for (const { atom, error } of result.errors) {
206
+ lines.push(` ${fmt.red("\u2717")} ${atom}: ${error}`);
207
+ }
208
+ }
209
+ const artifactCount = Object.values(result.artifacts).flat().length;
210
+ if (artifactCount > 0) {
211
+ lines.push("");
212
+ lines.push(fmt.bold(`Artifacts Produced (${artifactCount}):`));
213
+ for (const [atomId, artifacts] of Object.entries(result.artifacts)) {
214
+ for (const artifact of artifacts) {
215
+ lines.push(` ${fmt.cyan("\u2192")} ${atomId}/${artifact}`);
216
+ }
217
+ }
218
+ }
219
+ return lines.join("\n");
220
+ }
221
+ function formatDryRun(workflow, resolution, atoms) {
222
+ const lines = [];
223
+ lines.push(fmt.bold(`Dry Run: Workflow '${workflow}'`));
224
+ lines.push("");
225
+ lines.push(fmt.bold("Resolving dependencies:"));
226
+ lines.push(` ${formatDependencyChain(resolution.toExecute)}`);
227
+ lines.push("");
228
+ lines.push(fmt.bold("Execution Plan:"));
229
+ let step = 1;
230
+ for (const id of resolution.toExecute) {
231
+ const resolved = resolution.resolved.find((r) => r.id === id);
232
+ const atom = atoms.find(
233
+ (a) => (a.alias ?? a.atom) === id
234
+ );
235
+ const reason = resolved?.reason ?? "Will execute";
236
+ lines.push(` ${step}. ${fmt.cyan(id)}`);
237
+ if (atom?.description) {
238
+ lines.push(` ${fmt.gray(atom.description)}`);
239
+ }
240
+ lines.push(` ${fmt.gray(`Reason: ${reason}`)}`);
241
+ step++;
242
+ }
243
+ if (resolution.skipped.length > 0) {
244
+ lines.push("");
245
+ lines.push(fmt.bold("Will Skip (cached):"));
246
+ for (const id of resolution.skipped) {
247
+ const resolved = resolution.resolved.find((r) => r.id === id);
248
+ lines.push(` ${fmt.gray("\u25CB")} ${id} - ${resolved?.reason ?? "Cached"}`);
249
+ }
250
+ }
251
+ lines.push("");
252
+ lines.push(fmt.bold("Expected Artifacts:"));
253
+ for (const atom of atoms) {
254
+ const id = atom.alias ?? atom.atom;
255
+ if (atom.produces.length > 0 && resolution.toExecute.includes(id)) {
256
+ for (const prod of atom.produces) {
257
+ lines.push(` ${fmt.cyan("\u2192")} ${id}/${prod.artifact}`);
258
+ }
259
+ }
260
+ }
261
+ return lines.join("\n");
262
+ }
263
+ async function workflowRunCommand(name, options) {
264
+ const startTime = Date.now();
265
+ try {
266
+ const { definition, atoms: storedAtoms } = await loadWorkflow(name);
267
+ const atoms = convertToResolverAtoms(
268
+ definition,
269
+ storedAtoms
270
+ );
271
+ const cache = createArtifactCache();
272
+ const forceRebuild = options.forceRebuild ? options.forceRebuild.split(",").map((s) => s.trim()).filter((s) => s.length > 0) : [];
273
+ const resolution = resolveDependencies(atoms, {
274
+ cache,
275
+ forceRebuild,
276
+ forceRebuildAll: options.forceRebuildAll
277
+ });
278
+ if (options.dryRun) {
279
+ if (options.json) {
280
+ const dryRunResult = {
281
+ workflow: name,
282
+ dryRun: true,
283
+ executionOrder: resolution.toExecute,
284
+ skipped: resolution.skipped,
285
+ resolved: resolution.resolved.map((r) => ({
286
+ id: r.id,
287
+ canSkip: r.canSkip,
288
+ reason: r.reason,
289
+ inputs: Array.from(r.inputs.keys())
290
+ }))
291
+ };
292
+ console.log(JSON.stringify(dryRunResult, null, 2));
293
+ } else {
294
+ console.log(formatDryRun(name, resolution, atoms));
295
+ }
296
+ return;
297
+ }
298
+ const beadsEnabled = options.beads !== false && !options.dryRun;
299
+ let beadOptions;
300
+ if (beadsEnabled) {
301
+ if (!await isBeadsAvailable()) {
302
+ if (!options.json) {
303
+ console.log(fmt.yellow("\u26A0"), fmt.gray("Beads CLI not found, skipping tracking"));
304
+ }
305
+ } else if (!await isBeadsInitialized()) {
306
+ if (!options.json) {
307
+ console.log(fmt.yellow("\u26A0"), fmt.gray("Beads not initialized, skipping tracking"));
308
+ }
309
+ } else {
310
+ const beadsResult = await createWorkflowBeads({
311
+ workflow: name,
312
+ description: definition.description,
313
+ atoms: resolution.toExecute
314
+ });
315
+ if (beadsResult.success) {
316
+ beadOptions = {
317
+ enabled: true,
318
+ parentId: beadsResult.parentId,
319
+ atomBeadIds: beadsResult.childIds
320
+ };
321
+ if (!options.json) {
322
+ console.log(fmt.cyan("\u2299"), fmt.gray(`Beads tracking: ${beadsResult.parentId}`));
323
+ }
324
+ } else if (!options.json) {
325
+ console.log(fmt.yellow("\u26A0"), fmt.gray(`Beads error: ${beadsResult.error}`));
326
+ }
327
+ }
328
+ }
329
+ const runState = createRunState(
330
+ name,
331
+ resolution.toExecute,
332
+ resolution.skipped,
333
+ beadOptions
334
+ );
335
+ await saveRunState(runState);
336
+ const result = {
337
+ success: true,
338
+ workflow: name,
339
+ executionOrder: resolution.toExecute,
340
+ skipped: resolution.skipped,
341
+ executed: [],
342
+ artifacts: {},
343
+ errors: [],
344
+ duration: 0
345
+ };
346
+ if (!options.json) {
347
+ console.log(fmt.bold(`Executing Workflow: ${name}`));
348
+ console.log(
349
+ `${fmt.gray("Resolving dependencies:")} ${formatDependencyChain(resolution.toExecute)}`
350
+ );
351
+ console.log("");
352
+ }
353
+ await executeWorkflowAtoms(
354
+ resolution.toExecute,
355
+ atoms,
356
+ runState,
357
+ result,
358
+ { json: options.json },
359
+ resolution.resolved
360
+ );
361
+ if (result.success) {
362
+ runState.status = "completed";
363
+ runState.completedAt = (/* @__PURE__ */ new Date()).toISOString();
364
+ }
365
+ await saveRunState(runState);
366
+ if (runState.beadParentId) {
367
+ await updateWorkflowBead(runState.beadParentId, result.success, runState.failedAtom);
368
+ }
369
+ result.duration = Date.now() - startTime;
370
+ if (options.json) {
371
+ console.log(JSON.stringify(result, null, 2));
372
+ } else {
373
+ console.log("");
374
+ console.log(formatWorkflowResult(result));
375
+ }
376
+ if (!result.success) {
377
+ process.exit(1);
378
+ }
379
+ } catch (err) {
380
+ const duration = Date.now() - startTime;
381
+ if (options.json) {
382
+ console.log(
383
+ JSON.stringify(
384
+ {
385
+ success: false,
386
+ workflow: name,
387
+ error: toErrorMessage(err),
388
+ duration
389
+ },
390
+ null,
391
+ 2
392
+ )
393
+ );
394
+ } else {
395
+ console.error(
396
+ fmt.red("Error:"),
397
+ toErrorMessage(err)
398
+ );
399
+ }
400
+ process.exit(1);
401
+ }
402
+ }
403
+ async function workflowListCommand(options) {
404
+ const projectRoot = process.cwd();
405
+ const workflowsDir = join(projectRoot, ATOMIC_DIR, WORKFLOWS_DIR);
406
+ try {
407
+ if (!await fileExists(workflowsDir)) {
408
+ if (options.json) {
409
+ console.log(JSON.stringify({ workflows: [] }, null, 2));
410
+ } else {
411
+ console.log(fmt.gray("No workflows directory found."));
412
+ console.log(
413
+ fmt.gray(`Create workflows in ${ATOMIC_DIR}/${WORKFLOWS_DIR}/`)
414
+ );
415
+ }
416
+ return;
417
+ }
418
+ const files = await readdir(workflowsDir);
419
+ const workflowFiles = files.filter((f) => f.endsWith(WORKFLOW_EXT));
420
+ if (workflowFiles.length === 0) {
421
+ if (options.json) {
422
+ console.log(JSON.stringify({ workflows: [] }, null, 2));
423
+ } else {
424
+ console.log(fmt.gray("No workflows found."));
425
+ }
426
+ return;
427
+ }
428
+ const workflows = [];
429
+ for (const file of workflowFiles) {
430
+ const name = file.replace(WORKFLOW_EXT, "");
431
+ try {
432
+ const { definition } = await loadWorkflow(name);
433
+ workflows.push({
434
+ name,
435
+ description: definition.description,
436
+ atoms: definition.atoms.length
437
+ });
438
+ } catch (err) {
439
+ if (!options.json) {
440
+ console.error(
441
+ fmt.yellow("Warning:"),
442
+ `Could not load workflow '${name}': ${toErrorMessage(err)}`
443
+ );
444
+ }
445
+ }
446
+ }
447
+ if (options.json) {
448
+ console.log(JSON.stringify({ workflows }, null, 2));
449
+ } else {
450
+ console.log(fmt.bold("Available Workflows:"));
451
+ console.log("");
452
+ for (const wf of workflows) {
453
+ console.log(` ${fmt.cyan(wf.name)}`);
454
+ console.log(` ${wf.description}`);
455
+ console.log(` ${fmt.gray(`${wf.atoms} atoms`)}`);
456
+ console.log("");
457
+ }
458
+ }
459
+ } catch (err) {
460
+ if (options.json) {
461
+ console.log(
462
+ JSON.stringify(
463
+ {
464
+ error: toErrorMessage(err)
465
+ },
466
+ null,
467
+ 2
468
+ )
469
+ );
470
+ } else {
471
+ console.error(
472
+ fmt.red("Error:"),
473
+ toErrorMessage(err)
474
+ );
475
+ }
476
+ process.exit(1);
477
+ }
478
+ }
479
+ async function workflowResumeCommand(name, options) {
480
+ const startTime = Date.now();
481
+ try {
482
+ const { definition, atoms: storedAtoms } = await loadWorkflow(name);
483
+ const atoms = convertToResolverAtoms(
484
+ definition,
485
+ storedAtoms
486
+ );
487
+ let runState = null;
488
+ if (options.run) {
489
+ runState = await loadRunState(options.run);
490
+ if (!runState) {
491
+ throw new Error(`Run '${options.run}' not found`);
492
+ }
493
+ if (runState.workflow !== name) {
494
+ throw new Error(
495
+ `Run '${options.run}' is for workflow '${runState.workflow}', not '${name}'`
496
+ );
497
+ }
498
+ } else {
499
+ runState = await getLastFailedRun(name);
500
+ if (!runState) {
501
+ throw new Error(
502
+ `No failed runs found for workflow '${name}'. Use --run to specify a run ID.`
503
+ );
504
+ }
505
+ }
506
+ const toExecute = getResumableAtoms(runState, options.from);
507
+ if (toExecute.length === 0) {
508
+ if (options.json) {
509
+ console.log(
510
+ JSON.stringify(
511
+ {
512
+ success: true,
513
+ workflow: name,
514
+ runId: runState.runId,
515
+ message: "No atoms need to be executed"
516
+ },
517
+ null,
518
+ 2
519
+ )
520
+ );
521
+ } else {
522
+ console.log(
523
+ fmt.green("\u2713"),
524
+ `Workflow '${name}' has no atoms to resume`
525
+ );
526
+ }
527
+ return;
528
+ }
529
+ const alreadyCompleted = runState.executionOrder.filter(
530
+ (id) => !toExecute.includes(id)
531
+ );
532
+ const beadsDisabled = options.beads === false;
533
+ if (!beadsDisabled && !runState.beadsEnabled) {
534
+ if (await isBeadsAvailable() && await isBeadsInitialized()) {
535
+ const beadsResult = await createWorkflowBeads({
536
+ workflow: name,
537
+ description: definition.description,
538
+ atoms: toExecute
539
+ });
540
+ if (beadsResult.success) {
541
+ runState.beadsEnabled = true;
542
+ runState.beadParentId = beadsResult.parentId;
543
+ for (const id of toExecute) {
544
+ const beadId = beadsResult.childIds.get(id);
545
+ if (beadId) {
546
+ updateAtomState(runState, id, { beadId });
547
+ }
548
+ }
549
+ if (!options.json) {
550
+ console.log(fmt.cyan("\u2299"), fmt.gray(`Beads tracking: ${beadsResult.parentId}`));
551
+ }
552
+ }
553
+ }
554
+ } else if (!beadsDisabled && runState.beadsEnabled) {
555
+ if (!options.json && runState.beadParentId) {
556
+ console.log(fmt.cyan("\u2299"), fmt.gray(`Beads tracking: ${runState.beadParentId} (resumed)`));
557
+ }
558
+ }
559
+ const result = {
560
+ success: true,
561
+ workflow: name,
562
+ runId: runState.runId,
563
+ resumedFrom: toExecute[0],
564
+ executed: [],
565
+ skipped: alreadyCompleted,
566
+ errors: [],
567
+ duration: 0
568
+ };
569
+ if (!options.json) {
570
+ console.log(fmt.bold(`Resuming Workflow: ${name}`));
571
+ console.log(`${fmt.gray("Run ID:")} ${runState.runId}`);
572
+ console.log(
573
+ `${fmt.gray("Skipping completed:")} ${alreadyCompleted.length > 0 ? alreadyCompleted.join(", ") : "none"}`
574
+ );
575
+ console.log(`${fmt.gray("Resuming from:")} ${toExecute[0]}`);
576
+ console.log("");
577
+ }
578
+ runState.status = "running";
579
+ await saveRunState(runState);
580
+ await executeWorkflowAtoms(
581
+ toExecute,
582
+ atoms,
583
+ runState,
584
+ result,
585
+ { json: options.json }
586
+ );
587
+ if (result.success) {
588
+ runState.status = "completed";
589
+ runState.completedAt = (/* @__PURE__ */ new Date()).toISOString();
590
+ }
591
+ await saveRunState(runState);
592
+ if (runState.beadsEnabled && runState.beadParentId) {
593
+ await updateWorkflowBead(runState.beadParentId, result.success, runState.failedAtom);
594
+ }
595
+ result.duration = Date.now() - startTime;
596
+ if (options.json) {
597
+ console.log(JSON.stringify(result, null, 2));
598
+ } else {
599
+ console.log("");
600
+ if (result.success) {
601
+ console.log(
602
+ fmt.green("\u2713") + fmt.bold(` Workflow '${name}' resumed successfully`)
603
+ );
604
+ } else {
605
+ console.log(
606
+ fmt.red("\u2717") + fmt.bold(` Workflow '${name}' resume failed`)
607
+ );
608
+ }
609
+ console.log("");
610
+ console.log(fmt.gray(`Duration: ${result.duration}ms`));
611
+ console.log(
612
+ fmt.gray(`Skipped: ${result.skipped.length} (already completed)`)
613
+ );
614
+ console.log(fmt.gray(`Executed: ${result.executed.length}`));
615
+ if (result.errors.length > 0) {
616
+ console.log("");
617
+ console.log(fmt.bold(fmt.red("Errors:")));
618
+ for (const { atom, error } of result.errors) {
619
+ console.log(` ${fmt.red("\u2717")} ${atom}: ${error}`);
620
+ }
621
+ }
622
+ }
623
+ if (!result.success) {
624
+ process.exit(1);
625
+ }
626
+ } catch (err) {
627
+ const duration = Date.now() - startTime;
628
+ if (options.json) {
629
+ console.log(
630
+ JSON.stringify(
631
+ {
632
+ success: false,
633
+ workflow: name,
634
+ error: toErrorMessage(err),
635
+ duration
636
+ },
637
+ null,
638
+ 2
639
+ )
640
+ );
641
+ } else {
642
+ console.error(
643
+ fmt.red("Error:"),
644
+ toErrorMessage(err)
645
+ );
646
+ }
647
+ process.exit(1);
648
+ }
649
+ }
650
+ export {
651
+ workflowListCommand,
652
+ workflowResumeCommand,
653
+ workflowRunCommand
654
+ };
655
+ //# sourceMappingURL=workflow-5UVLBS7J.js.map