@bastani/atomic 0.8.23 → 0.8.24-alpha.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 (70) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +7 -0
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/CHANGELOG.md +7 -0
  5. package/dist/builtin/mcp/package.json +1 -1
  6. package/dist/builtin/subagents/CHANGELOG.md +22 -0
  7. package/dist/builtin/subagents/README.md +16 -0
  8. package/dist/builtin/subagents/agents/code-simplifier.md +2 -3
  9. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -3
  10. package/dist/builtin/subagents/agents/codebase-locator.md +2 -3
  11. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -3
  12. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -3
  13. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -3
  14. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -3
  15. package/dist/builtin/subagents/agents/debugger.md +2 -3
  16. package/dist/builtin/subagents/package.json +1 -1
  17. package/dist/builtin/subagents/skills/subagent/SKILL.md +6 -0
  18. package/dist/builtin/subagents/src/agents/agent-serializer.ts +3 -0
  19. package/dist/builtin/subagents/src/agents/agents.ts +20 -1
  20. package/dist/builtin/subagents/src/runs/background/async-execution.ts +1 -1
  21. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +3 -1
  22. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +7 -7
  23. package/dist/builtin/subagents/src/runs/foreground/execution.ts +5 -1
  24. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +9 -10
  25. package/dist/builtin/subagents/src/shared/types.ts +1 -0
  26. package/dist/builtin/web-access/CHANGELOG.md +7 -0
  27. package/dist/builtin/web-access/package.json +1 -1
  28. package/dist/builtin/workflows/CHANGELOG.md +25 -0
  29. package/dist/builtin/workflows/README.md +38 -41
  30. package/dist/builtin/workflows/builtin/deep-research-codebase.d.ts +35 -0
  31. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +11 -14
  32. package/dist/builtin/workflows/builtin/goal.d.ts +46 -0
  33. package/dist/builtin/workflows/builtin/goal.ts +10 -12
  34. package/dist/builtin/workflows/builtin/index.d.ts +136 -0
  35. package/dist/builtin/workflows/builtin/open-claude-design.d.ts +44 -0
  36. package/dist/builtin/workflows/builtin/open-claude-design.ts +19 -20
  37. package/dist/builtin/workflows/builtin/ralph.d.ts +36 -0
  38. package/dist/builtin/workflows/builtin/ralph.ts +20 -24
  39. package/dist/builtin/workflows/package.json +15 -5
  40. package/dist/builtin/workflows/src/authoring.ts +410 -0
  41. package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +6 -12
  42. package/dist/builtin/workflows/src/extension/workflow-schema.ts +3 -2
  43. package/dist/builtin/workflows/src/index.ts +0 -5
  44. package/dist/builtin/workflows/src/runs/foreground/executor.ts +23 -9
  45. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +33 -5
  46. package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +61 -10
  47. package/dist/builtin/workflows/src/sdk-surface.ts +12 -2
  48. package/dist/builtin/workflows/src/shared/authoring-contract.ts +660 -0
  49. package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +1 -1
  50. package/dist/builtin/workflows/src/shared/types.ts +65 -350
  51. package/dist/builtin/workflows/src/workflows/define-workflow.ts +59 -44
  52. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  53. package/dist/core/atomic-guide-command.js +1 -1
  54. package/dist/core/atomic-guide-command.js.map +1 -1
  55. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  56. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  57. package/dist/modes/interactive/components/chat-message-renderer.js +13 -1
  58. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  59. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  60. package/dist/modes/interactive/interactive-mode.js +1 -1
  61. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  62. package/dist/utils/changelog.d.ts.map +1 -1
  63. package/dist/utils/changelog.js +23 -16
  64. package/dist/utils/changelog.js.map +1 -1
  65. package/docs/extensions.md +2 -2
  66. package/docs/packages.md +8 -4
  67. package/docs/subagents.md +30 -0
  68. package/docs/workflows.md +39 -21
  69. package/package.json +1 -1
  70. package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +0 -335
@@ -1,335 +0,0 @@
1
- /**
2
- * Programmatic workflow runner.
3
- *
4
- * This helper executes named workflows and direct workflow task definitions
5
- * from an explicit object that mirrors the workflow tool surface.
6
- */
7
-
8
- import { homedir } from "node:os";
9
- import { run, runChain, runParallel, runTask, type RunOpts as ExecutorRunOptions } from "../foreground/executor.js";
10
- import { buildRuntimeAdapters, type RuntimeAdapterBuildOptions, type RuntimeWiringSurface } from "../../extension/wiring.js";
11
- import { discoverWorkflows } from "../../extension/discovery.js";
12
- import { createStore } from "../../shared/store.js";
13
- import { renderInputsSchema } from "../../shared/render-inputs-schema.js";
14
- import { deriveInputFields } from "../../shared/schema-introspection.js";
15
- import { validateInputs, type ValidationError } from "./validate-inputs.js";
16
- import type { CreateAgentSessionOptions } from "@bastani/atomic";
17
- import type { StageSessionRuntime } from "../foreground/stage-runner.js";
18
- import type {
19
- StageOptions,
20
- WorkflowChainStep,
21
- WorkflowDetails,
22
- WorkflowDetailsStatus,
23
- WorkflowDirectOptions,
24
- WorkflowDirectTaskItem,
25
- WorkflowInputSchema,
26
- WorkflowInputValues,
27
- WorkflowMaxOutput,
28
- WorkflowOutputMode,
29
- } from "../../shared/types.js";
30
-
31
- export interface WorkflowDefinition extends StageOptions {
32
- mode?: "workflow" | "named" | "single" | "parallel" | "chain";
33
- workflow?: string;
34
- inputs?: WorkflowInputValues;
35
- /** Direct single-task mode, or root task text for direct chain/parallel execution. */
36
- task?: WorkflowDirectTaskItem | string;
37
- /** Direct top-level parallel mode. */
38
- tasks?: readonly WorkflowDirectTaskItem[];
39
- /** Direct sequential/parallel chain mode. */
40
- chain?: readonly WorkflowChainStep[];
41
- chainName?: string;
42
- concurrency?: number;
43
- failFast?: boolean;
44
- /** Chain-only shared artifact directory for relative reads, outputs, and worktree diffs. */
45
- chainDir?: string;
46
- reads?: readonly string[] | false;
47
- output?: string | false;
48
- outputMode?: WorkflowOutputMode;
49
- worktree?: boolean;
50
- gitWorktreeDir?: string;
51
- baseBranch?: string;
52
- maxOutput?: WorkflowMaxOutput;
53
- artifacts?: boolean;
54
- }
55
-
56
- export type WorkflowRunOptions = Omit<ExecutorRunOptions, "adapters" | "store">;
57
-
58
- export interface WorkflowOptions {
59
- cwd?: string;
60
- homeDir?: string;
61
- pi?: RuntimeWiringSurface;
62
- adapterOptions?: RuntimeAdapterBuildOptions;
63
- runOptions?: WorkflowRunOptions;
64
- /** Use a deterministic in-memory agent session when no adapter is supplied. */
65
- stubAgent?: boolean;
66
- }
67
-
68
- function runOptionsWithAdapters(
69
- options: WorkflowOptions,
70
- definition?: WorkflowDefinition,
71
- ): ExecutorRunOptions {
72
- const adapterOptions = options.stubAgent === true
73
- ? {
74
- ...options.adapterOptions,
75
- createAgentSession: options.adapterOptions?.createAgentSession ?? createStubAgentSession,
76
- }
77
- : options.adapterOptions;
78
-
79
- const argConcurrency =
80
- typeof definition?.concurrency === "number" && Number.isFinite(definition.concurrency)
81
- ? Math.max(1, Math.floor(definition.concurrency))
82
- : undefined;
83
- const config = argConcurrency === undefined
84
- ? options.runOptions?.config
85
- : {
86
- maxDepth: options.runOptions?.config?.maxDepth ?? 4,
87
- defaultConcurrency: argConcurrency,
88
- persistRuns: options.runOptions?.config?.persistRuns ?? true,
89
- statusFile: options.runOptions?.config?.statusFile ?? false,
90
- ...(options.runOptions?.config?.statusFilePath !== undefined
91
- ? { statusFilePath: options.runOptions.config.statusFilePath }
92
- : {}),
93
- resumeInFlight: options.runOptions?.config?.resumeInFlight ?? ("ask" as const),
94
- };
95
-
96
- return {
97
- ...options.runOptions,
98
- cwd: options.cwd ?? options.runOptions?.cwd,
99
- ...(config !== undefined ? { config } : {}),
100
- adapters: buildRuntimeAdapters(options.pi ?? {}, adapterOptions),
101
- store: createStore(),
102
- };
103
- }
104
-
105
- async function createStubAgentSession(
106
- _options?: CreateAgentSessionOptions,
107
- ): Promise<{ session: StageSessionRuntime }> {
108
- let lastAssistantText: string | undefined;
109
- const session: StageSessionRuntime = {
110
- async prompt(text: string): Promise<string> {
111
- lastAssistantText = `stub:workflow:${text}`;
112
- return lastAssistantText;
113
- },
114
- async steer(_text: string): Promise<void> {},
115
- async followUp(_text: string): Promise<void> {},
116
- subscribe(): () => void {
117
- return () => {};
118
- },
119
- sessionFile: undefined,
120
- sessionId: `workflow-stub-${crypto.randomUUID()}`,
121
- async setModel(_model): Promise<void> {},
122
- setThinkingLevel(_level): void {},
123
- async cycleModel() {
124
- return undefined;
125
- },
126
- cycleThinkingLevel() {
127
- return undefined;
128
- },
129
- agent: Object.create(null) as StageSessionRuntime["agent"],
130
- model: undefined,
131
- thinkingLevel: "off",
132
- messages: [] as StageSessionRuntime["messages"],
133
- isStreaming: false as StageSessionRuntime["isStreaming"],
134
- async navigateTree(): ReturnType<StageSessionRuntime["navigateTree"]> {
135
- return { cancelled: true };
136
- },
137
- async compact(): ReturnType<StageSessionRuntime["compact"]> {
138
- return { summary: "", firstKeptEntryId: "", tokensBefore: 0 };
139
- },
140
- abortCompaction(): void {},
141
- async abort(): Promise<void> {},
142
- dispose(): void {},
143
- getLastAssistantText(): string | undefined {
144
- return lastAssistantText;
145
- },
146
- };
147
- return { session };
148
- }
149
-
150
- function withoutUndefinedProperties<T extends object>(value: T): Partial<T> {
151
- return Object.fromEntries(
152
- Object.entries(value).filter(([, field]) => field !== undefined),
153
- ) as Partial<T>;
154
- }
155
-
156
- function directOptions(definition: WorkflowDefinition): WorkflowDirectOptions {
157
- const {
158
- mode: _mode,
159
- workflow: _workflow,
160
- inputs: _inputs,
161
- task,
162
- tasks: _tasks,
163
- chain: _chain,
164
- chainName,
165
- concurrency,
166
- failFast,
167
- chainDir,
168
- reads,
169
- output,
170
- outputMode,
171
- worktree,
172
- gitWorktreeDir,
173
- baseBranch,
174
- maxOutput,
175
- artifacts,
176
- ...stageOptions
177
- } = definition;
178
-
179
- return {
180
- ...withoutUndefinedProperties(stageOptions),
181
- ...(typeof task === "string" ? { task } : {}),
182
- ...(typeof chainName === "string" ? { chainName } : {}),
183
- ...(typeof concurrency === "number" ? { concurrency } : {}),
184
- ...(typeof failFast === "boolean" ? { failFast } : {}),
185
- ...(typeof chainDir === "string" ? { chainDir } : {}),
186
- ...(reads !== undefined ? { reads } : {}),
187
- ...(output !== undefined ? { output } : {}),
188
- ...(outputMode !== undefined ? { outputMode } : {}),
189
- ...(typeof worktree === "boolean" ? { worktree } : {}),
190
- ...(typeof gitWorktreeDir === "string" ? { gitWorktreeDir } : {}),
191
- ...(typeof baseBranch === "string" ? { baseBranch } : {}),
192
- ...(maxOutput !== undefined ? { maxOutput } : {}),
193
- ...(typeof artifacts === "boolean" ? { artifacts } : {}),
194
- };
195
- }
196
-
197
- function hasDirectExecutionMode(definition: WorkflowDefinition): boolean {
198
- return (
199
- definition.mode === "single" ||
200
- definition.mode === "parallel" ||
201
- definition.mode === "chain" ||
202
- (definition.task !== undefined && typeof definition.task === "object") ||
203
- Array.isArray(definition.tasks) ||
204
- Array.isArray(definition.chain)
205
- );
206
- }
207
-
208
- async function runNamedWorkflow(
209
- definition: WorkflowDefinition,
210
- options: WorkflowOptions,
211
- runOptions: ExecutorRunOptions,
212
- ): Promise<WorkflowDetails> {
213
- const workflowName = definition.workflow;
214
- if (typeof workflowName !== "string" || workflowName.length === 0) {
215
- throw new Error('Workflow definition must include "workflow" for named workflow execution.');
216
- }
217
- const discovery = await discoverWorkflows({
218
- cwd: options.cwd ?? process.cwd(),
219
- homeDir: options.homeDir ?? homedir(),
220
- });
221
- const workflow = discovery.registry.get(workflowName);
222
- if (workflow === undefined) {
223
- const available = discovery.registry.names();
224
- throw new Error(`Workflow not found: "${workflowName}". Available: ${available.length > 0 ? available.join(", ") : "(none)"}`);
225
- }
226
- // Apply schema defaults before validating so an input declared with both
227
- // `required: true` and a `default` is not rejected as "missing" when omitted,
228
- // mirroring the resolve-then-validate order every other dispatch path uses.
229
- // validateInputs (rather than resolveInputs) still surfaces the full set of
230
- // input problems through formatWorkflowValidationFailure; run() re-resolves
231
- // internally, which is idempotent on already-defaulted inputs.
232
- const inputs = withResolvedDefaults(workflow.inputs, definition.inputs ?? {});
233
- const errors = validateInputs(workflow.inputs, inputs);
234
- if (errors.length > 0) {
235
- throw new Error(formatWorkflowValidationFailure(workflow.name, workflow.inputs, errors));
236
- }
237
- const result = await run(workflow, inputs, {
238
- ...runOptions,
239
- registry: discovery.registry,
240
- });
241
- return {
242
- action: "run",
243
- mode: "named",
244
- runId: result.runId,
245
- status: toWorkflowDetailsStatus(result.status),
246
- output: result.result,
247
- error: result.error,
248
- progress: {
249
- completed: result.stages.filter((stage) => stage.status === "completed").length,
250
- total: result.stages.length,
251
- },
252
- };
253
- }
254
-
255
- function withResolvedDefaults(
256
- schema: Readonly<Record<string, WorkflowInputSchema>>,
257
- provided: WorkflowInputValues,
258
- ): WorkflowInputValues {
259
- const resolved: Record<string, WorkflowInputValues[string]> = {};
260
- for (const [key, value] of Object.entries(provided)) {
261
- if (value !== undefined) resolved[key] = value;
262
- }
263
- for (const [key, def] of Object.entries(schema)) {
264
- const declaredDefault = (def as { default?: unknown }).default;
265
- if (resolved[key] === undefined && declaredDefault !== undefined) {
266
- resolved[key] = declaredDefault as WorkflowInputValues[string];
267
- }
268
- }
269
- return resolved;
270
- }
271
-
272
- function formatWorkflowValidationFailure(
273
- workflowName: string,
274
- schema: Readonly<Record<string, WorkflowInputSchema>>,
275
- errors: ValidationError[],
276
- ): string {
277
- const entries = deriveInputFields(schema);
278
- const lines = errors.map((error) => ` - ${error.key}: ${error.reason}`);
279
- return `Invalid inputs for "${workflowName}":\n${lines.join("\n")}\n\n${renderInputsSchema(workflowName, entries)}`;
280
- }
281
-
282
- function toWorkflowDetailsStatus(status: string): WorkflowDetailsStatus {
283
- switch (status) {
284
- case "completed":
285
- case "failed":
286
- case "killed":
287
- return status;
288
- case "running":
289
- case "pending":
290
- return "running";
291
- default:
292
- return "failed";
293
- }
294
- }
295
-
296
- async function runDirectWorkflow(
297
- definition: WorkflowDefinition,
298
- runOptions: ExecutorRunOptions,
299
- ): Promise<WorkflowDetails> {
300
- const options = directOptions(definition);
301
-
302
- if (Array.isArray(definition.chain) || definition.mode === "chain") {
303
- if (!Array.isArray(definition.chain)) {
304
- throw new Error('Direct chain workflow definitions must include "chain".');
305
- }
306
- return runChain(definition.chain, options, runOptions);
307
- }
308
-
309
- if (Array.isArray(definition.tasks) || definition.mode === "parallel") {
310
- if (!Array.isArray(definition.tasks)) {
311
- throw new Error('Direct parallel workflow definitions must include "tasks".');
312
- }
313
- return runParallel(definition.tasks, options, runOptions);
314
- }
315
-
316
- if (typeof definition.task === "object") {
317
- return runTask(definition.task, options, runOptions);
318
- }
319
-
320
- if (typeof definition.task === "string" && definition.mode === "single") {
321
- return runTask({ name: "task", task: definition.task }, options, runOptions);
322
- }
323
-
324
- throw new Error('Direct workflow definitions must include "task", "tasks", or "chain".');
325
- }
326
-
327
- export async function runWorkflow(
328
- definition: WorkflowDefinition,
329
- options: WorkflowOptions = {},
330
- ): Promise<WorkflowDetails> {
331
- const runOptions = runOptionsWithAdapters(options, definition);
332
- return hasDirectExecutionMode(definition)
333
- ? runDirectWorkflow(definition, runOptions)
334
- : runNamedWorkflow(definition, options, runOptions);
335
- }