@relayflows/core 0.0.1 → 1.0.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 (182) hide show
  1. package/dist/agent-handle.d.ts +27 -0
  2. package/dist/agent-handle.d.ts.map +1 -0
  3. package/dist/agent-handle.js +32 -0
  4. package/dist/agent-handle.js.map +1 -0
  5. package/dist/api-executor.d.ts +16 -0
  6. package/dist/api-executor.d.ts.map +1 -0
  7. package/dist/api-executor.js +94 -0
  8. package/dist/api-executor.js.map +1 -0
  9. package/dist/barrier.d.ts +72 -0
  10. package/dist/barrier.d.ts.map +1 -0
  11. package/dist/barrier.js +162 -0
  12. package/dist/barrier.js.map +1 -0
  13. package/dist/budget-tracker.d.ts +75 -0
  14. package/dist/budget-tracker.d.ts.map +1 -0
  15. package/dist/budget-tracker.js +184 -0
  16. package/dist/budget-tracker.js.map +1 -0
  17. package/dist/builder.d.ts +229 -0
  18. package/dist/builder.d.ts.map +1 -0
  19. package/dist/builder.js +430 -0
  20. package/dist/builder.js.map +1 -0
  21. package/dist/builtin-templates/bug-fix.yaml +139 -0
  22. package/dist/builtin-templates/code-review.yaml +137 -0
  23. package/dist/builtin-templates/competitive.yaml +107 -0
  24. package/dist/builtin-templates/documentation.yaml +128 -0
  25. package/dist/builtin-templates/feature-dev.yaml +146 -0
  26. package/dist/builtin-templates/refactor.yaml +145 -0
  27. package/dist/builtin-templates/review-loop.yaml +227 -0
  28. package/dist/builtin-templates/security-audit.yaml +139 -0
  29. package/dist/channel-messenger.d.ts +28 -0
  30. package/dist/channel-messenger.d.ts.map +1 -0
  31. package/dist/channel-messenger.js +275 -0
  32. package/dist/channel-messenger.js.map +1 -0
  33. package/dist/cli-registry.d.ts +77 -0
  34. package/dist/cli-registry.d.ts.map +1 -0
  35. package/dist/cli-registry.js +268 -0
  36. package/dist/cli-registry.js.map +1 -0
  37. package/dist/cli-session-collector.d.ts +39 -0
  38. package/dist/cli-session-collector.d.ts.map +1 -0
  39. package/dist/cli-session-collector.js +23 -0
  40. package/dist/cli-session-collector.js.map +1 -0
  41. package/dist/cli.d.ts +11 -0
  42. package/dist/cli.d.ts.map +1 -0
  43. package/dist/cli.js +395 -0
  44. package/dist/cli.js.map +1 -0
  45. package/dist/cloud-runner.d.ts +15 -0
  46. package/dist/cloud-runner.d.ts.map +1 -0
  47. package/dist/cloud-runner.js +41 -0
  48. package/dist/cloud-runner.js.map +1 -0
  49. package/dist/cloud-schedules.d.ts +3 -0
  50. package/dist/cloud-schedules.d.ts.map +1 -0
  51. package/dist/cloud-schedules.js +2 -0
  52. package/dist/cloud-schedules.js.map +1 -0
  53. package/dist/collectors/claude.d.ts +6 -0
  54. package/dist/collectors/claude.d.ts.map +1 -0
  55. package/dist/collectors/claude.js +330 -0
  56. package/dist/collectors/claude.js.map +1 -0
  57. package/dist/collectors/codex.d.ts +18 -0
  58. package/dist/collectors/codex.d.ts.map +1 -0
  59. package/dist/collectors/codex.js +265 -0
  60. package/dist/collectors/codex.js.map +1 -0
  61. package/dist/collectors/opencode.d.ts +6 -0
  62. package/dist/collectors/opencode.d.ts.map +1 -0
  63. package/dist/collectors/opencode.js +204 -0
  64. package/dist/collectors/opencode.js.map +1 -0
  65. package/dist/coordinator.d.ts +73 -0
  66. package/dist/coordinator.d.ts.map +1 -0
  67. package/dist/coordinator.js +647 -0
  68. package/dist/coordinator.js.map +1 -0
  69. package/dist/custom-steps.d.ts +73 -0
  70. package/dist/custom-steps.d.ts.map +1 -0
  71. package/dist/custom-steps.js +321 -0
  72. package/dist/custom-steps.js.map +1 -0
  73. package/dist/default-logger.d.ts +9 -0
  74. package/dist/default-logger.d.ts.map +1 -0
  75. package/dist/default-logger.js +104 -0
  76. package/dist/default-logger.js.map +1 -0
  77. package/dist/dry-run-format.d.ts +6 -0
  78. package/dist/dry-run-format.d.ts.map +1 -0
  79. package/dist/dry-run-format.js +79 -0
  80. package/dist/dry-run-format.js.map +1 -0
  81. package/dist/file-db.d.ts +85 -0
  82. package/dist/file-db.d.ts.map +1 -0
  83. package/dist/file-db.js +215 -0
  84. package/dist/file-db.js.map +1 -0
  85. package/dist/index.d.ts +37 -1
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +34 -3
  88. package/dist/index.js.map +1 -0
  89. package/dist/integrations/browser.d.ts +99 -0
  90. package/dist/integrations/browser.d.ts.map +1 -0
  91. package/dist/integrations/browser.js +419 -0
  92. package/dist/integrations/browser.js.map +1 -0
  93. package/dist/integrations/github.d.ts +79 -0
  94. package/dist/integrations/github.d.ts.map +1 -0
  95. package/dist/integrations/github.js +459 -0
  96. package/dist/integrations/github.js.map +1 -0
  97. package/dist/integrations/slack.d.ts +80 -0
  98. package/dist/integrations/slack.d.ts.map +1 -0
  99. package/dist/integrations/slack.js +355 -0
  100. package/dist/integrations/slack.js.map +1 -0
  101. package/dist/listr-renderer.d.ts +26 -0
  102. package/dist/listr-renderer.d.ts.map +1 -0
  103. package/dist/listr-renderer.js +230 -0
  104. package/dist/listr-renderer.js.map +1 -0
  105. package/dist/memory-db.d.ts +17 -0
  106. package/dist/memory-db.d.ts.map +1 -0
  107. package/dist/memory-db.js +33 -0
  108. package/dist/memory-db.js.map +1 -0
  109. package/dist/process-backend-executor.d.ts +18 -0
  110. package/dist/process-backend-executor.d.ts.map +1 -0
  111. package/dist/process-backend-executor.js +74 -0
  112. package/dist/process-backend-executor.js.map +1 -0
  113. package/dist/process-spawner.d.ts +35 -0
  114. package/dist/process-spawner.d.ts.map +1 -0
  115. package/dist/process-spawner.js +173 -0
  116. package/dist/process-spawner.js.map +1 -0
  117. package/dist/provisioner.d.ts +64 -0
  118. package/dist/provisioner.d.ts.map +1 -0
  119. package/dist/provisioner.js +269 -0
  120. package/dist/provisioner.js.map +1 -0
  121. package/dist/proxy-env.d.ts +52 -0
  122. package/dist/proxy-env.d.ts.map +1 -0
  123. package/dist/proxy-env.js +92 -0
  124. package/dist/proxy-env.js.map +1 -0
  125. package/dist/run-script.d.ts +82 -0
  126. package/dist/run-script.d.ts.map +1 -0
  127. package/dist/run-script.js +527 -0
  128. package/dist/run-script.js.map +1 -0
  129. package/dist/run-summary-table.d.ts +5 -0
  130. package/dist/run-summary-table.d.ts.map +1 -0
  131. package/dist/run-summary-table.js +132 -0
  132. package/dist/run-summary-table.js.map +1 -0
  133. package/dist/run.d.ts +45 -0
  134. package/dist/run.d.ts.map +1 -0
  135. package/dist/run.js +37 -0
  136. package/dist/run.js.map +1 -0
  137. package/dist/runner.d.ts +528 -0
  138. package/dist/runner.d.ts.map +1 -0
  139. package/dist/runner.js +6269 -0
  140. package/dist/runner.js.map +1 -0
  141. package/dist/schema.d.ts +275 -0
  142. package/dist/schema.d.ts.map +1 -0
  143. package/dist/schema.js +27 -0
  144. package/dist/schema.js.map +1 -0
  145. package/dist/schema.json +940 -0
  146. package/dist/sibling-links.d.ts +100 -0
  147. package/dist/sibling-links.d.ts.map +1 -0
  148. package/dist/sibling-links.js +205 -0
  149. package/dist/sibling-links.js.map +1 -0
  150. package/dist/state.d.ts +77 -0
  151. package/dist/state.d.ts.map +1 -0
  152. package/dist/state.js +140 -0
  153. package/dist/state.js.map +1 -0
  154. package/dist/step-executor.d.ts +95 -0
  155. package/dist/step-executor.d.ts.map +1 -0
  156. package/dist/step-executor.js +393 -0
  157. package/dist/step-executor.js.map +1 -0
  158. package/dist/template-resolver.d.ts +33 -0
  159. package/dist/template-resolver.d.ts.map +1 -0
  160. package/dist/template-resolver.js +144 -0
  161. package/dist/template-resolver.js.map +1 -0
  162. package/dist/templates.d.ts +47 -0
  163. package/dist/templates.d.ts.map +1 -0
  164. package/dist/templates.js +405 -0
  165. package/dist/templates.js.map +1 -0
  166. package/dist/trajectory.d.ts +87 -0
  167. package/dist/trajectory.d.ts.map +1 -0
  168. package/dist/trajectory.js +412 -0
  169. package/dist/trajectory.js.map +1 -0
  170. package/dist/types.d.ts +471 -0
  171. package/dist/types.d.ts.map +1 -0
  172. package/dist/types.js +37 -0
  173. package/dist/types.js.map +1 -0
  174. package/dist/validator.d.ts +11 -0
  175. package/dist/validator.d.ts.map +1 -0
  176. package/dist/validator.js +186 -0
  177. package/dist/validator.js.map +1 -0
  178. package/dist/verification.d.ts +53 -0
  179. package/dist/verification.d.ts.map +1 -0
  180. package/dist/verification.js +238 -0
  181. package/dist/verification.js.map +1 -0
  182. package/package.json +12 -8
@@ -0,0 +1,430 @@
1
+ import path from 'node:path';
2
+ import { stringify as stringifyYaml } from 'yaml';
3
+ import { JsonFileWorkflowDb } from './file-db.js';
4
+ import { WorkflowRunner } from './runner.js';
5
+ import { formatDryRunReport } from './dry-run-format.js';
6
+ import { createDefaultEventLogger } from './default-logger.js';
7
+ import { runInCloud } from './cloud-runner.js';
8
+ // ── WorkflowBuilder ─────────────────────────────────────────────────────────
9
+ /**
10
+ * Fluent builder for constructing workflow configurations programmatically.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { workflow } from "@relayflows/core";
15
+ *
16
+ * const result = await workflow("my-workflow")
17
+ * .pattern("dag")
18
+ * .agent("worker", { cli: "claude", role: "Backend engineer" })
19
+ * .step("build", { agent: "worker", task: "Build the project" })
20
+ * .step("test", { agent: "worker", task: "Run tests", dependsOn: ["build"] })
21
+ * .run();
22
+ * ```
23
+ */
24
+ export class WorkflowBuilder {
25
+ _name;
26
+ _description;
27
+ _pattern = 'dag';
28
+ _maxConcurrency;
29
+ _timeoutMs;
30
+ _channel;
31
+ _idleNudge;
32
+ _paths;
33
+ _agents = [];
34
+ _steps = [];
35
+ _errorHandling;
36
+ _coordination;
37
+ _state;
38
+ _trajectories;
39
+ _startFrom;
40
+ _previousRunId;
41
+ constructor(name) {
42
+ this._name = name;
43
+ }
44
+ /** Set workflow description. */
45
+ description(desc) {
46
+ this._description = desc;
47
+ return this;
48
+ }
49
+ /** Set swarm pattern (default: "dag"). */
50
+ pattern(p) {
51
+ this._pattern = p;
52
+ return this;
53
+ }
54
+ /** Set maximum concurrent agents. */
55
+ maxConcurrency(n) {
56
+ this._maxConcurrency = n;
57
+ return this;
58
+ }
59
+ /** Set global timeout in milliseconds. */
60
+ timeout(ms) {
61
+ this._timeoutMs = ms;
62
+ return this;
63
+ }
64
+ /** Set the relay channel for agent communication. */
65
+ channel(ch) {
66
+ const CHANNEL_RE = /^[a-z0-9][a-z0-9-]*$/;
67
+ if (!CHANNEL_RE.test(ch)) {
68
+ throw new Error(`Invalid channel name "${ch}". Channel names must be lowercase alphanumeric and hyphens, starting with a letter or number. ` +
69
+ `Fix: use .toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '')`);
70
+ }
71
+ this._channel = ch;
72
+ return this;
73
+ }
74
+ /** Configure idle agent detection and nudging for interactive agents. */
75
+ idleNudge(config) {
76
+ this._idleNudge = config;
77
+ return this;
78
+ }
79
+ /** Set workflow coordination settings (barriers, voting threshold, consensus strategy). */
80
+ coordination(config) {
81
+ this._coordination = config;
82
+ return this;
83
+ }
84
+ /** Configure shared workflow state backend settings. */
85
+ state(config) {
86
+ this._state = config;
87
+ return this;
88
+ }
89
+ /** Configure trajectory recording, or pass `false` to disable it. */
90
+ trajectories(config) {
91
+ this._trajectories = config;
92
+ return this;
93
+ }
94
+ /** Start execution from a specific step, skipping all predecessor steps. */
95
+ startFrom(stepName) {
96
+ this._startFrom = stepName;
97
+ return this;
98
+ }
99
+ /** Set the previous run ID whose cached step outputs should be used with startFrom. */
100
+ previousRunId(id) {
101
+ this._previousRunId = id;
102
+ return this;
103
+ }
104
+ /**
105
+ * Declare named paths to additional directories the workflow needs.
106
+ *
107
+ * For multi-repo cloud workflows (relay#774, cloud#302), each entry is
108
+ * tarballed by the CLI at submit time and mounted at
109
+ * `/home/daytona/workspace/{name}/` in the sandbox. Locally, the runner
110
+ * resolves `path` relative to the workflow file's parent directory and
111
+ * agents reference each entry by its declared `name`.
112
+ *
113
+ * Calling this is a no-op for the runtime — the runner doesn't need
114
+ * `paths` to execute steps. The CLI and the cloud bootstrap consume
115
+ * it. Declaring via the builder keeps single-source-of-truth for tools
116
+ * that walk the built config (e.g. dashboards, dry-run reports).
117
+ */
118
+ paths(paths) {
119
+ if (!Array.isArray(paths)) {
120
+ throw new Error('.paths() expects an array of PathDefinition objects');
121
+ }
122
+ const seen = new Set();
123
+ for (const p of paths) {
124
+ if (!p || typeof p.name !== 'string' || typeof p.path !== 'string') {
125
+ throw new Error('.paths() entries must each have string `name` and `path` fields');
126
+ }
127
+ if (seen.has(p.name)) {
128
+ throw new Error(`.paths() got duplicate entry name "${p.name}"`);
129
+ }
130
+ seen.add(p.name);
131
+ }
132
+ this._paths = paths.map((p) => ({ ...p }));
133
+ return this;
134
+ }
135
+ /** Add an agent definition. */
136
+ agent(name, options) {
137
+ const def = {
138
+ name,
139
+ cli: options.cli,
140
+ };
141
+ if (options.role !== undefined)
142
+ def.role = options.role;
143
+ if (options.task !== undefined)
144
+ def.task = options.task;
145
+ if (options.channels !== undefined)
146
+ def.channels = options.channels;
147
+ if (options.preset !== undefined)
148
+ def.preset = options.preset;
149
+ if (options.interactive !== undefined)
150
+ def.interactive = options.interactive;
151
+ if (options.skills !== undefined)
152
+ def.skills = options.skills;
153
+ if (options.model !== undefined ||
154
+ options.maxTokens !== undefined ||
155
+ options.timeoutMs !== undefined ||
156
+ options.retries !== undefined ||
157
+ options.idleThresholdSecs !== undefined) {
158
+ def.constraints = {};
159
+ if (options.model !== undefined)
160
+ def.constraints.model = options.model;
161
+ if (options.maxTokens !== undefined)
162
+ def.constraints.maxTokens = options.maxTokens;
163
+ if (options.timeoutMs !== undefined)
164
+ def.constraints.timeoutMs = options.timeoutMs;
165
+ if (options.retries !== undefined)
166
+ def.constraints.retries = options.retries;
167
+ if (options.idleThresholdSecs !== undefined)
168
+ def.constraints.idleThresholdSecs = options.idleThresholdSecs;
169
+ }
170
+ this._agents.push(def);
171
+ return this;
172
+ }
173
+ /** Add a workflow step (agent or deterministic). */
174
+ step(name, options) {
175
+ const step = { name };
176
+ if ('type' in options && options.type === 'deterministic') {
177
+ if (!options.command) {
178
+ throw new Error('deterministic steps must have a command');
179
+ }
180
+ if ('agent' in options || 'task' in options) {
181
+ throw new Error('deterministic steps must not have agent or task');
182
+ }
183
+ step.type = 'deterministic';
184
+ step.command = options.command;
185
+ if (options.cwd !== undefined)
186
+ step.cwd = options.cwd;
187
+ if (options.captureOutput !== undefined)
188
+ step.captureOutput = options.captureOutput;
189
+ if (options.failOnError !== undefined)
190
+ step.failOnError = options.failOnError;
191
+ if (options.dependsOn !== undefined)
192
+ step.dependsOn = options.dependsOn;
193
+ if (options.verification !== undefined)
194
+ step.verification = options.verification;
195
+ if (options.timeoutMs !== undefined)
196
+ step.timeoutMs = options.timeoutMs;
197
+ }
198
+ else if ('type' in options && options.type === 'worktree') {
199
+ if ('agent' in options || 'task' in options) {
200
+ throw new Error('worktree steps must not have agent or task');
201
+ }
202
+ step.type = 'worktree';
203
+ step.branch = options.branch;
204
+ if (options.baseBranch !== undefined)
205
+ step.baseBranch = options.baseBranch;
206
+ if (options.path !== undefined)
207
+ step.path = options.path;
208
+ if (options.createBranch !== undefined)
209
+ step.createBranch = options.createBranch;
210
+ if (options.dependsOn !== undefined)
211
+ step.dependsOn = options.dependsOn;
212
+ if (options.timeoutMs !== undefined)
213
+ step.timeoutMs = options.timeoutMs;
214
+ }
215
+ else {
216
+ // Agent step
217
+ const agentOpts = options;
218
+ if (!agentOpts.agent || !agentOpts.task) {
219
+ throw new Error('Agent steps must have both agent and task');
220
+ }
221
+ step.agent = agentOpts.agent;
222
+ step.task = agentOpts.task;
223
+ if (agentOpts.cwd !== undefined)
224
+ step.cwd = agentOpts.cwd;
225
+ if (agentOpts.dependsOn !== undefined)
226
+ step.dependsOn = agentOpts.dependsOn;
227
+ if (agentOpts.verification !== undefined)
228
+ step.verification = agentOpts.verification;
229
+ if (agentOpts.timeoutMs !== undefined)
230
+ step.timeoutMs = agentOpts.timeoutMs;
231
+ if (agentOpts.retries !== undefined)
232
+ step.retries = agentOpts.retries;
233
+ }
234
+ this._steps.push(step);
235
+ return this;
236
+ }
237
+ /** Set error handling strategy. */
238
+ onError(strategy, options) {
239
+ this._errorHandling = { strategy };
240
+ if (options?.maxRetries !== undefined)
241
+ this._errorHandling.maxRetries = options.maxRetries;
242
+ if (options?.retryDelayMs !== undefined)
243
+ this._errorHandling.retryDelayMs = options.retryDelayMs;
244
+ if (options?.notifyChannel !== undefined)
245
+ this._errorHandling.notifyChannel = options.notifyChannel;
246
+ if (options?.repairAgent !== undefined)
247
+ this._errorHandling.repairAgent = options.repairAgent;
248
+ if (options?.repairRetries !== undefined)
249
+ this._errorHandling.repairRetries = options.repairRetries;
250
+ return this;
251
+ }
252
+ /**
253
+ * Opt into the product reliability contract: repairable workflow failures get
254
+ * routed through an agent and retried before the workflow is allowed to fail.
255
+ */
256
+ repairable(options = {}) {
257
+ return this.onError('retry', {
258
+ maxRetries: options.maxRetries ?? options.repairRetries ?? 2,
259
+ retryDelayMs: options.retryDelayMs ?? 1000,
260
+ notifyChannel: options.notifyChannel,
261
+ repairAgent: options.repairAgent,
262
+ repairRetries: options.repairRetries ?? options.maxRetries ?? 2,
263
+ });
264
+ }
265
+ /** Alias for `.repairable()` for workflow authors who think in product terms. */
266
+ reliable(options = {}) {
267
+ return this.repairable(options);
268
+ }
269
+ validateBuilderState() {
270
+ const hasAgentSteps = this._steps.some((s) => s.type !== 'deterministic' && s.type !== 'worktree');
271
+ if (hasAgentSteps && this._agents.length === 0) {
272
+ throw new Error('Workflow must have at least one agent when using agent steps');
273
+ }
274
+ if (this._steps.length === 0) {
275
+ throw new Error('Workflow must have at least one step');
276
+ }
277
+ const agentNames = new Set(this._agents.map((agent) => agent.name));
278
+ for (const step of this._steps) {
279
+ const diagnosticAgent = step.verification?.diagnosticAgent;
280
+ if (!diagnosticAgent)
281
+ continue;
282
+ if (!agentNames.has(diagnosticAgent)) {
283
+ throw new Error(`Step "${step.name}" references unknown diagnosticAgent "${diagnosticAgent}"`);
284
+ }
285
+ if (step.retries === undefined || step.retries === 0) {
286
+ console.warn(`Step "${step.name}": diagnosticAgent configured but no retries — diagnostic will never run`);
287
+ }
288
+ }
289
+ }
290
+ /** Build and return the RelayYamlConfig object. */
291
+ toConfig() {
292
+ this.validateBuilderState();
293
+ const wfDef = {
294
+ name: `${this._name}-workflow`,
295
+ steps: [...this._steps],
296
+ };
297
+ const config = {
298
+ version: '1.0',
299
+ name: this._name,
300
+ swarm: {
301
+ pattern: this._pattern,
302
+ },
303
+ agents: [...this._agents],
304
+ workflows: [wfDef],
305
+ };
306
+ if (this._description !== undefined)
307
+ config.description = this._description;
308
+ if (this._paths !== undefined && this._paths.length > 0) {
309
+ config.paths = this._paths.map((p) => ({ ...p }));
310
+ }
311
+ if (this._maxConcurrency !== undefined)
312
+ config.swarm.maxConcurrency = this._maxConcurrency;
313
+ if (this._timeoutMs !== undefined)
314
+ config.swarm.timeoutMs = this._timeoutMs;
315
+ if (this._channel !== undefined)
316
+ config.swarm.channel = this._channel;
317
+ if (this._idleNudge !== undefined)
318
+ config.swarm.idleNudge = this._idleNudge;
319
+ config.errorHandling = this._errorHandling ?? {
320
+ strategy: 'retry',
321
+ maxRetries: 2,
322
+ retryDelayMs: 1000,
323
+ repairRetries: 2,
324
+ };
325
+ if (this._coordination !== undefined)
326
+ config.coordination = this._coordination;
327
+ if (this._state !== undefined)
328
+ config.state = this._state;
329
+ if (this._trajectories !== undefined)
330
+ config.trajectories = this._trajectories;
331
+ return config;
332
+ }
333
+ /** Serialize the config to a YAML string. */
334
+ toYaml() {
335
+ return stringifyYaml(this.toConfig());
336
+ }
337
+ async run(options = {}) {
338
+ const config = this.toConfig();
339
+ const runnerCwd = options.cwd ?? process.cwd();
340
+ const dbPath = path.join(runnerCwd, '.agent-relay', 'workflow-runs.jsonl');
341
+ const db = new JsonFileWorkflowDb(dbPath);
342
+ const runner = new WorkflowRunner({
343
+ cwd: options.cwd,
344
+ relay: options.relay,
345
+ executor: options.executor,
346
+ envSecrets: options.envSecrets,
347
+ db,
348
+ });
349
+ // Auto-detect DRY_RUN env var so existing scripts get dry-run for free
350
+ const isDryRun = options.dryRun ?? !!process.env.DRY_RUN;
351
+ if (isDryRun) {
352
+ const report = runner.dryRun(config, options.workflow, options.vars);
353
+ console.log(formatDryRunReport(report));
354
+ return report;
355
+ }
356
+ // Cloud execution path — submit to remote API and poll for completion
357
+ if (options.cloud) {
358
+ const cloudApiUrl = options.cloudApiUrl ?? process.env.CLOUD_API_URL;
359
+ const cloudApiToken = options.cloudApiToken ?? process.env.CLOUD_API_TOKEN;
360
+ if (!cloudApiUrl)
361
+ throw new Error('cloud: true requires cloudApiUrl or CLOUD_API_URL env var');
362
+ if (!cloudApiToken)
363
+ throw new Error('cloud: true requires cloudApiToken or CLOUD_API_TOKEN env var');
364
+ return runInCloud(config, {
365
+ cloudApiUrl,
366
+ cloudApiToken,
367
+ envSecrets: options.envSecrets,
368
+ pollIntervalMs: options.cloudPollIntervalMs,
369
+ timeoutMs: this._timeoutMs,
370
+ onStatusChange: options.onCloudStatusChange,
371
+ });
372
+ }
373
+ // Wire up default console logger unless explicitly disabled
374
+ // renderer: "listr" owns the terminal — skip console logger to avoid garbled output
375
+ // renderer: false implies no output at all
376
+ const logLevel = options.renderer === 'listr' || options.renderer === false ? false : (options.logLevel ?? 'normal');
377
+ if (logLevel !== false) {
378
+ runner.on(createDefaultEventLogger(logLevel));
379
+ }
380
+ // Wire up user-provided event handler (additive — does not replace the default logger)
381
+ if (options.onEvent) {
382
+ runner.on(options.onEvent);
383
+ }
384
+ // Auto-detect RESUME_RUN_ID env var for resuming failed runs
385
+ const resumeRunId = process.env.RESUME_RUN_ID;
386
+ const startFrom = this._startFrom ?? options.startFrom ?? process.env.START_FROM;
387
+ const previousRunId = this._previousRunId ?? options.previousRunId ?? process.env.PREVIOUS_RUN_ID;
388
+ const executeOptions = startFrom
389
+ ? { startFrom, previousRunId }
390
+ : undefined;
391
+ // If listr renderer requested, wire it up and run concurrently
392
+ // Must be set up BEFORE the resume check so resume runs also get event output
393
+ if (options.renderer === 'listr') {
394
+ const { createWorkflowRenderer } = await import('./listr-renderer.js');
395
+ const renderer = createWorkflowRenderer();
396
+ runner.on(renderer.onEvent);
397
+ const runPromise = resumeRunId
398
+ ? runner.resume(resumeRunId, options.vars, config)
399
+ : runner.execute(config, options.workflow, options.vars, executeOptions);
400
+ try {
401
+ const [result] = await Promise.all([runPromise, renderer.start()]);
402
+ return result;
403
+ }
404
+ finally {
405
+ renderer.unmount();
406
+ }
407
+ }
408
+ if (resumeRunId) {
409
+ return runner.resume(resumeRunId, options.vars, config);
410
+ }
411
+ return runner.execute(config, options.workflow, options.vars, executeOptions);
412
+ }
413
+ }
414
+ // ── Entry point ─────────────────────────────────────────────────────────────
415
+ /**
416
+ * Create a new workflow builder.
417
+ *
418
+ * @example
419
+ * ```typescript
420
+ * const result = await workflow("my-task")
421
+ * .pattern("fan-out")
422
+ * .agent("worker", { cli: "claude" })
423
+ * .step("do-work", { agent: "worker", task: "Build the feature" })
424
+ * .run();
425
+ * ```
426
+ */
427
+ export function workflow(name) {
428
+ return new WorkflowBuilder(name);
429
+ }
430
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ version: '1.0'
2
+ name: bug-fix
3
+ description: 'Blueprint-style bug investigation and remediation with validation gates.'
4
+ swarm:
5
+ pattern: hub-spoke
6
+ maxConcurrency: 2
7
+ timeoutMs: 2700000
8
+ channel: swarm-bug-fix
9
+ idleNudge:
10
+ nudgeAfterMs: 120000
11
+ escalateAfterMs: 120000
12
+ maxNudges: 1
13
+ agents:
14
+ - name: lead
15
+ cli: claude
16
+ role: 'Coordinates debugging and release decisions'
17
+ permissions: { access: full }
18
+ - name: investigator
19
+ cli: codex
20
+ role: 'Reproduces and scopes the defect'
21
+ permissions: { access: readonly }
22
+ interactive: false
23
+ - name: fixer
24
+ cli: codex
25
+ role: 'Implements and tests the fix'
26
+ permissions: { access: readwrite }
27
+ interactive: false
28
+ - name: verifier
29
+ cli: claude
30
+ role: 'Validates risk, regressions, and completion'
31
+ permissions: { access: readonly }
32
+ workflows:
33
+ - name: bug-remediation
34
+ description: 'Investigate root cause, patch safely, and verify no regressions.'
35
+ onError: retry
36
+ preflight:
37
+ - command: git status --porcelain
38
+ failIf: non-empty
39
+ description: 'Ensure working directory is clean'
40
+ - command: npm test 2>/dev/null || echo "baseline"
41
+ description: 'Capture baseline test state'
42
+ steps:
43
+ # Agent: Investigate root cause
44
+ - name: investigate
45
+ type: agent
46
+ agent: investigator
47
+ task: |
48
+ Reproduce the issue, identify root cause, and provide a fix strategy:
49
+ {{task}}
50
+ verification:
51
+ type: output_contains
52
+ value: ROOT_CAUSE_IDENTIFIED
53
+
54
+ # Deterministic: Create fix branch
55
+ - name: create-branch
56
+ type: deterministic
57
+ dependsOn: [investigate]
58
+ command: git checkout -b fix/{{branch-name}}
59
+
60
+ # Agent: Implement the fix
61
+ - name: patch
62
+ type: agent
63
+ agent: fixer
64
+ dependsOn: [create-branch]
65
+ task: |
66
+ Implement the fix based on the investigation report:
67
+ {{steps.investigate.output}}
68
+ retries: 2
69
+ verification:
70
+ type: output_contains
71
+ value: PATCH_APPLIED
72
+
73
+ # Deterministic: Run tests
74
+ - name: test
75
+ type: deterministic
76
+ dependsOn: [patch]
77
+ command: npm test
78
+
79
+ # Agent: Fix test failures if any (with iteration limit)
80
+ - name: fix-if-broken
81
+ type: agent
82
+ agent: fixer
83
+ dependsOn: [test]
84
+ task: |
85
+ Review test results. If tests failed, fix them. If all passed, output TESTS_PASSED.
86
+ Test output: {{steps.test.output}}
87
+ maxIterations: 2
88
+ verification:
89
+ type: output_contains
90
+ value: TESTS_PASSED
91
+
92
+ # Deterministic: Commit
93
+ - name: commit
94
+ type: deterministic
95
+ dependsOn: [fix-if-broken]
96
+ command: 'git add -A && git commit -m "fix: {{steps.investigate.output | first-line}}"'
97
+
98
+ # Agent: Verify no regressions
99
+ - name: regression-check
100
+ type: agent
101
+ agent: verifier
102
+ dependsOn: [commit]
103
+ task: |
104
+ Validate the patch for correctness and regression risk:
105
+ {{steps.patch.output}}
106
+ verification:
107
+ type: output_contains
108
+ value: VERIFICATION_COMPLETE
109
+
110
+ # Deterministic: Push to remote
111
+ - name: push
112
+ type: deterministic
113
+ dependsOn: [regression-check]
114
+ command: git push origin fix/{{branch-name}}
115
+
116
+ # Agent: Closeout
117
+ - name: closeout
118
+ type: agent
119
+ agent: lead
120
+ dependsOn: [push]
121
+ task: |
122
+ Prepare final incident summary, residual risk, and deployment notes.
123
+ verification:
124
+ type: output_contains
125
+ value: DONE
126
+ coordination:
127
+ barriers:
128
+ - name: fix-ready
129
+ waitFor: [investigate, patch, regression-check]
130
+ timeoutMs: 600000
131
+ state:
132
+ backend: memory
133
+ ttlMs: 43200000
134
+ namespace: bug-fix
135
+ errorHandling:
136
+ strategy: retry
137
+ maxRetries: 3
138
+ retryDelayMs: 3000
139
+ notifyChannel: swarm-bug-fix