@bastani/atomic 0.8.24-alpha.1 → 0.8.24-alpha.2

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.
@@ -0,0 +1,523 @@
1
+ /**
2
+ * Dependency-light workflow authoring contract shared by the runtime type graph
3
+ * and the standalone package typing surface.
4
+ *
5
+ * This module intentionally imports only TypeBox types. Do not import
6
+ * @bastani/atomic, executor internals, stores, or runtime graph modules here.
7
+ */
8
+ import type { Static, TOptional, TSchema } from "typebox";
9
+ export type { Static, TSchema };
10
+ export type WorkflowSerializablePrimitive = string | number | boolean | null;
11
+ export type WorkflowSerializableValue = WorkflowSerializablePrimitive | readonly WorkflowSerializableValue[] | WorkflowSerializableObject;
12
+ export interface WorkflowSerializableObject {
13
+ /**
14
+ * Optional properties use `undefined` at the type level for ergonomic
15
+ * intellisense, but workflow runtime validation rejects actual `undefined`
16
+ * values in returned/input objects. Omit optional keys instead.
17
+ */
18
+ readonly [key: string]: WorkflowSerializableValue | undefined;
19
+ }
20
+ export type WorkflowInputValues = WorkflowSerializableObject;
21
+ export type WorkflowOutputValues = WorkflowSerializableObject;
22
+ export type WorkflowRunOutput = WorkflowOutputValues;
23
+ export type WorkflowInputSchemaMap = Readonly<Record<string, TSchema>>;
24
+ export type WorkflowOutputSchemaMap = Readonly<Record<string, TSchema>>;
25
+ export type WorkflowInputSchema = TSchema;
26
+ export type WorkflowOutputSchema = TSchema;
27
+ export type WorkflowOutputMode = "inline" | "file-only";
28
+ export type WorkflowContextMode = "fresh" | "fork";
29
+ export type WorkflowThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
30
+ export type WorkflowExecutionMode = "interactive" | "non_interactive";
31
+ export type RunStatus = "pending" | "running" | "paused" | "completed" | "failed" | "killed";
32
+ export type WorkflowDetailsMode = "named" | "single" | "parallel" | "chain" | "inspection" | "control";
33
+ export type WorkflowDetailsStatus = "accepted" | "running" | "completed" | "failed" | "killed" | "noop";
34
+ export type WorkflowAction = "list" | "get" | "inputs" | "run" | "status" | "interrupt" | "resume";
35
+ export interface WorkflowModelFallbackFields {
36
+ /** Ordered model IDs to try after `model` fails; entries may use `:off|minimal|low|medium|high|xhigh` reasoning suffixes. */
37
+ readonly fallbackModels?: readonly string[];
38
+ /** Optional deprecated compatibility helper aligned to `fallbackModels`; ignored for entries with a reasoning suffix. */
39
+ readonly fallbackThinkingLevels?: readonly string[];
40
+ }
41
+ export type WorkflowModelValue = string | object;
42
+ export interface WorkflowModelUsage extends WorkflowSerializableObject {
43
+ readonly input?: number;
44
+ readonly output?: number;
45
+ readonly cacheRead?: number;
46
+ readonly cacheWrite?: number;
47
+ readonly cost?: number;
48
+ readonly turns?: number;
49
+ }
50
+ export interface WorkflowModelAttempt extends WorkflowSerializableObject {
51
+ readonly model: string;
52
+ readonly success: boolean;
53
+ readonly reasoningLevel?: WorkflowThinkingLevel;
54
+ readonly error?: string;
55
+ readonly usage?: WorkflowModelUsage;
56
+ }
57
+ export interface WorkflowModelInfo {
58
+ readonly provider: string;
59
+ readonly id: string;
60
+ readonly fullId: string;
61
+ readonly model?: WorkflowModelValue;
62
+ }
63
+ export interface WorkflowModelCatalogPort {
64
+ listModels(): Promise<readonly WorkflowModelInfo[]>;
65
+ readonly currentModel?: WorkflowModelValue;
66
+ readonly preferredProvider?: string;
67
+ recordWarning?: (warning: string) => void;
68
+ }
69
+ export interface WorkflowMaxOutput {
70
+ readonly bytes?: number;
71
+ readonly lines?: number;
72
+ }
73
+ export interface StageMcpOptions {
74
+ readonly allow?: readonly string[];
75
+ readonly deny?: readonly string[];
76
+ }
77
+ export interface WorkflowAgentToolResult<TDetails = unknown> {
78
+ readonly content: unknown;
79
+ readonly details?: TDetails;
80
+ }
81
+ export interface WorkflowCustomToolDefinition<TParams extends TSchema = TSchema, TDetails = unknown> {
82
+ readonly name: string;
83
+ readonly label: string;
84
+ readonly description: string;
85
+ readonly promptSnippet?: string;
86
+ readonly promptGuidelines?: readonly string[];
87
+ readonly parameters: TParams;
88
+ readonly renderShell?: "default" | "self";
89
+ readonly prepareArguments?: (args: unknown) => Static<TParams>;
90
+ readonly executionMode?: "sequential" | "parallel";
91
+ execute(toolCallId: string, params: Static<TParams>, signal: AbortSignal | undefined, onUpdate: ((update: WorkflowAgentToolResult<TDetails>) => void) | undefined, ctx: object): Promise<WorkflowAgentToolResult<TDetails>>;
92
+ }
93
+ export interface WorkflowScopedModel {
94
+ readonly model: WorkflowModelValue;
95
+ /** @deprecated Prefer suffixing model/fallbackModels entries with `:level`; removal is deferred. */
96
+ readonly thinkingLevel?: WorkflowThinkingLevel;
97
+ }
98
+ export interface WorkflowFastModeSettings extends WorkflowSerializableObject {
99
+ readonly enabled?: boolean;
100
+ readonly model?: string;
101
+ }
102
+ export interface WorkflowFastModeSettingsManager {
103
+ getCodexFastModeSettings(): WorkflowFastModeSettings;
104
+ }
105
+ export interface StageOptions extends WorkflowModelFallbackFields {
106
+ readonly model?: WorkflowModelValue;
107
+ readonly mcp?: StageMcpOptions;
108
+ readonly tools?: readonly string[];
109
+ readonly noTools?: "all" | "builtin";
110
+ readonly excludedTools?: readonly string[];
111
+ readonly customTools?: readonly WorkflowCustomToolDefinition[];
112
+ readonly cwd?: string;
113
+ readonly agentDir?: string;
114
+ readonly scopedModels?: readonly WorkflowScopedModel[];
115
+ readonly sessionManager?: never;
116
+ readonly settingsManager?: never;
117
+ readonly context?: WorkflowContextMode;
118
+ readonly forkFromSessionFile?: string;
119
+ readonly gitWorktreeDir?: string;
120
+ readonly baseBranch?: string;
121
+ readonly sessionDir?: string;
122
+ /** @deprecated Prefer suffixing model/fallbackModels entries with `:level`; removal is deferred. */
123
+ readonly thinkingLevel?: WorkflowThinkingLevel;
124
+ }
125
+ export interface CompleteStageOpts extends WorkflowModelFallbackFields {
126
+ readonly model?: WorkflowModelValue;
127
+ readonly maxTokens?: number;
128
+ }
129
+ export interface StageOutputOptions {
130
+ readonly output?: string | false;
131
+ readonly outputMode?: WorkflowOutputMode;
132
+ readonly context?: WorkflowContextMode;
133
+ readonly cwd?: string;
134
+ readonly maxOutput?: WorkflowMaxOutput;
135
+ readonly artifacts?: boolean;
136
+ readonly sessionDir?: string;
137
+ }
138
+ export type WorkflowInputSource = "interactive" | "rpc" | "extension";
139
+ export type WorkflowStreamingBehavior = "steer" | "followUp";
140
+ export type WorkflowImageContent = object;
141
+ export interface PromptOptions {
142
+ readonly expandPromptTemplates?: boolean;
143
+ readonly images?: readonly WorkflowImageContent[];
144
+ readonly streamingBehavior?: WorkflowStreamingBehavior;
145
+ readonly source?: WorkflowInputSource;
146
+ readonly preflightResult?: (success: boolean) => void;
147
+ }
148
+ export type StagePromptOptions = PromptOptions & StageOutputOptions;
149
+ export interface WorkflowExecutionPolicy {
150
+ readonly mode: WorkflowExecutionMode;
151
+ readonly allowHumanInput: boolean;
152
+ readonly awaitTerminalRun: boolean;
153
+ readonly allowInputPicker: boolean;
154
+ }
155
+ export interface WorkflowMcpPort {
156
+ setScope(stageId: string, allow: readonly string[] | null, deny: readonly string[] | null): void;
157
+ clearScope(stageId: string): void;
158
+ }
159
+ export interface WorkflowPersistencePort {
160
+ appendEntry(type: string, payload: Record<string, unknown>): string | undefined;
161
+ setLabel?(entryId: string, label: string): void;
162
+ appendCustomMessageEntry?(content: string, meta?: Record<string, unknown>): string | undefined;
163
+ }
164
+ export interface StageSessionRuntime {
165
+ prompt(text: string, options?: PromptOptions): Promise<string | void>;
166
+ steer(text: string): Promise<void>;
167
+ followUp(text: string): Promise<void>;
168
+ subscribe(listener: (event: never) => void): () => void;
169
+ readonly sessionFile: string | undefined;
170
+ readonly sessionId: string;
171
+ setModel(model: WorkflowSerializableValue): Promise<void>;
172
+ setThinkingLevel(level: WorkflowThinkingLevel): void;
173
+ cycleModel(): WorkflowSerializableValue;
174
+ cycleThinkingLevel(): WorkflowThinkingLevel | undefined;
175
+ readonly agent: WorkflowSerializableValue;
176
+ readonly model: WorkflowSerializableValue;
177
+ readonly thinkingLevel: WorkflowThinkingLevel | undefined;
178
+ readonly messages: readonly WorkflowSerializableValue[];
179
+ readonly isStreaming: boolean;
180
+ readonly pendingMessageCount?: number;
181
+ readonly settingsManager?: WorkflowFastModeSettingsManager;
182
+ navigateTree(targetId: string, options?: {
183
+ readonly summarize?: boolean;
184
+ readonly customInstructions?: string;
185
+ readonly replaceInstructions?: boolean;
186
+ readonly label?: string;
187
+ }): Promise<{
188
+ readonly editorText?: string;
189
+ readonly cancelled: boolean;
190
+ }>;
191
+ compact(customInstructions?: string): Promise<object>;
192
+ abortCompaction(): void;
193
+ abort(): Promise<void>;
194
+ dispose(): void | Promise<void>;
195
+ getLastAssistantText?: () => string | undefined;
196
+ }
197
+ export type StageSessionCreateOptions = StageOptions;
198
+ export interface StageSessionCreateResult {
199
+ readonly session: StageSessionRuntime;
200
+ readonly settingsManager?: WorkflowFastModeSettingsManager;
201
+ }
202
+ export interface StageExecutionMeta {
203
+ readonly runId: string;
204
+ readonly stageId: string;
205
+ readonly stageName: string;
206
+ readonly stageOptions?: StageOptions;
207
+ readonly signal?: AbortSignal;
208
+ readonly executionMode?: WorkflowExecutionMode;
209
+ }
210
+ export interface AgentSessionAdapter {
211
+ create(options: StageSessionCreateOptions, meta?: StageExecutionMeta): Promise<StageSessionRuntime | StageSessionCreateResult>;
212
+ }
213
+ export interface PromptAdapter {
214
+ prompt(text: string, meta?: StageExecutionMeta): Promise<string>;
215
+ }
216
+ export interface CompleteAdapter {
217
+ complete(text: string, opts?: CompleteStageOpts, meta?: StageExecutionMeta): Promise<string>;
218
+ }
219
+ export interface StageAdapters {
220
+ readonly agentSession?: AgentSessionAdapter;
221
+ readonly prompt?: PromptAdapter;
222
+ readonly complete?: CompleteAdapter;
223
+ }
224
+ export interface StageContext {
225
+ readonly name: string;
226
+ prompt(text: string, options?: StagePromptOptions): Promise<string>;
227
+ complete(text: string, options?: CompleteStageOpts): Promise<string>;
228
+ steer(text: string): Promise<void>;
229
+ followUp(text: string): Promise<void>;
230
+ subscribe(listener: (event: never) => void): () => void;
231
+ readonly sessionFile: string | undefined;
232
+ readonly sessionId: string;
233
+ setModel(model: WorkflowModelValue): Promise<void>;
234
+ setThinkingLevel(level: WorkflowThinkingLevel): void;
235
+ cycleModel(): Promise<object | undefined>;
236
+ cycleThinkingLevel(): WorkflowThinkingLevel | undefined;
237
+ readonly agent: object;
238
+ readonly model: WorkflowModelValue | undefined;
239
+ readonly thinkingLevel: WorkflowThinkingLevel | undefined;
240
+ readonly messages: readonly object[];
241
+ readonly isStreaming: boolean;
242
+ navigateTree(targetId: string, options?: {
243
+ readonly summarize?: boolean;
244
+ readonly customInstructions?: string;
245
+ readonly replaceInstructions?: boolean;
246
+ readonly label?: string;
247
+ }): Promise<{
248
+ readonly editorText?: string;
249
+ readonly cancelled: boolean;
250
+ }>;
251
+ compact(customInstructions?: string): Promise<object>;
252
+ abortCompaction(): void;
253
+ abort(): Promise<void>;
254
+ }
255
+ export interface WorkflowArtifact extends WorkflowSerializableObject {
256
+ readonly kind: "output" | "session" | "diff" | "patch";
257
+ readonly path: string;
258
+ readonly taskName?: string;
259
+ readonly branch?: string;
260
+ readonly diffStat?: string;
261
+ readonly filesChanged?: number;
262
+ readonly insertions?: number;
263
+ readonly deletions?: number;
264
+ }
265
+ export interface WorkflowTaskContext extends WorkflowSerializableObject {
266
+ readonly name?: string;
267
+ readonly text: string;
268
+ }
269
+ export type WorkflowTaskContextInput = string | WorkflowTaskContext | WorkflowTaskResult;
270
+ export interface WorkflowTaskResult extends WorkflowTaskContext {
271
+ readonly stageName: string;
272
+ readonly sessionId?: string;
273
+ readonly sessionFile?: string;
274
+ readonly artifacts?: readonly WorkflowArtifact[];
275
+ readonly model?: string;
276
+ readonly fastMode?: boolean;
277
+ readonly attemptedModels?: readonly string[];
278
+ readonly modelAttempts?: readonly WorkflowModelAttempt[];
279
+ readonly warnings?: readonly string[];
280
+ }
281
+ export interface WorkflowTaskSessionFields {
282
+ readonly prompt?: string;
283
+ readonly task?: string;
284
+ readonly output?: string | false;
285
+ readonly outputMode?: WorkflowOutputMode;
286
+ readonly reads?: readonly string[] | false;
287
+ readonly worktree?: boolean;
288
+ readonly gitWorktreeDir?: string;
289
+ readonly baseBranch?: string;
290
+ readonly maxOutput?: WorkflowMaxOutput;
291
+ readonly artifacts?: boolean;
292
+ }
293
+ export interface WorkflowTaskOptions extends StageOptions, WorkflowTaskSessionFields {
294
+ readonly previous?: WorkflowTaskContextInput | readonly WorkflowTaskContextInput[];
295
+ }
296
+ export interface WorkflowTaskStep extends WorkflowTaskOptions {
297
+ readonly name: string;
298
+ }
299
+ export interface WorkflowSharedTaskDefaults extends StageOptions, WorkflowTaskSessionFields {
300
+ }
301
+ export interface WorkflowChainOptions extends WorkflowSharedTaskDefaults {
302
+ readonly chainDir?: string;
303
+ }
304
+ export interface WorkflowParallelOptions extends WorkflowSharedTaskDefaults {
305
+ readonly concurrency?: number;
306
+ readonly failFast?: boolean;
307
+ }
308
+ export interface WorkflowDirectTaskItem extends WorkflowTaskOptions {
309
+ readonly name: string;
310
+ readonly count?: number;
311
+ }
312
+ export interface WorkflowParallelChainStep {
313
+ readonly parallel: readonly WorkflowDirectTaskItem[];
314
+ readonly concurrency?: number;
315
+ readonly failFast?: boolean;
316
+ readonly worktree?: boolean;
317
+ readonly gitWorktreeDir?: string;
318
+ readonly baseBranch?: string;
319
+ }
320
+ export type WorkflowChainStep = WorkflowDirectTaskItem | WorkflowParallelChainStep;
321
+ export type WorkflowTaskSessionOptions = StageOptions & WorkflowTaskSessionFields;
322
+ export interface WorkflowDirectOptions extends StageOptions, WorkflowTaskSessionFields {
323
+ readonly chainName?: string;
324
+ readonly concurrency?: number;
325
+ readonly failFast?: boolean;
326
+ readonly chainDir?: string;
327
+ }
328
+ export interface WorkflowRunChildOptions<TInputs extends WorkflowInputValues = WorkflowInputValues> {
329
+ readonly inputs?: TInputs;
330
+ readonly stageName?: string;
331
+ }
332
+ export interface WorkflowChildResult<TOutputs extends WorkflowOutputValues = WorkflowOutputValues> extends WorkflowSerializableObject {
333
+ readonly workflow: string;
334
+ readonly runId: string;
335
+ readonly status: "completed";
336
+ readonly outputs: TOutputs;
337
+ }
338
+ export interface WorkflowUIContext {
339
+ input(prompt: string): Promise<string>;
340
+ confirm(message: string): Promise<boolean>;
341
+ select<T extends string>(message: string, options: readonly T[]): Promise<T>;
342
+ editor(initial?: string): Promise<string>;
343
+ }
344
+ export type WorkflowUIAdapter = WorkflowUIContext;
345
+ export interface WorkflowRunContext<TInputs extends WorkflowInputValues = WorkflowInputValues, TDefinitionBrand extends object = {}> {
346
+ readonly inputs: Readonly<TInputs>;
347
+ readonly cwd?: string;
348
+ stage(name: string, options?: StageOptions): StageContext;
349
+ task(name: string, options: WorkflowTaskOptions): Promise<WorkflowTaskResult>;
350
+ chain(steps: readonly WorkflowTaskStep[], options?: WorkflowChainOptions): Promise<WorkflowTaskResult[]>;
351
+ parallel(steps: readonly WorkflowTaskStep[], options?: WorkflowParallelOptions): Promise<WorkflowTaskResult[]>;
352
+ workflow<TChildInputs extends WorkflowInputValues, TChildOutputs extends WorkflowOutputValues>(definition: WorkflowDefinition<TChildInputs, TChildOutputs> & TDefinitionBrand, options?: WorkflowRunChildOptions<TChildInputs>): Promise<WorkflowChildResult<TChildOutputs>>;
353
+ readonly ui: WorkflowUIContext;
354
+ }
355
+ export type WorkflowRunFn<TInputs extends WorkflowInputValues = WorkflowInputValues, TOutputs extends WorkflowOutputValues = WorkflowOutputValues, TDefinitionBrand extends object = {}> = (ctx: WorkflowRunContext<TInputs, TDefinitionBrand>) => Promise<TOutputs> | TOutputs;
356
+ export interface WorkflowRuntimeConfig {
357
+ readonly maxDepth: number;
358
+ readonly defaultConcurrency: number;
359
+ readonly persistRuns: boolean;
360
+ readonly statusFile: boolean;
361
+ readonly statusFilePath?: string;
362
+ readonly resumeInFlight: "ask" | "auto" | "never";
363
+ }
364
+ export interface WorkflowWorktreeInputBinding {
365
+ readonly gitWorktreeDir: string;
366
+ readonly baseBranch?: string;
367
+ }
368
+ export interface WorkflowInputBindings {
369
+ readonly worktree?: WorkflowWorktreeInputBinding;
370
+ }
371
+ export interface WorkflowDefinition<TInputs extends WorkflowInputValues = WorkflowInputValues, TOutputs extends WorkflowOutputValues = WorkflowOutputValues, TRunInputs extends WorkflowInputValues = TInputs, TDefinitionBrand extends object = {}> {
372
+ readonly __piWorkflow: true;
373
+ readonly __runInputs?: TRunInputs;
374
+ readonly name: string;
375
+ readonly normalizedName: string;
376
+ readonly description: string;
377
+ readonly inputs: WorkflowInputSchemaMap;
378
+ readonly outputs?: WorkflowOutputSchemaMap;
379
+ readonly inputBindings?: WorkflowInputBindings;
380
+ run(ctx: WorkflowRunContext<TInputs, TDefinitionBrand>): Promise<TOutputs> | TOutputs;
381
+ }
382
+ type DeclaredResolvedEntry<K extends string, S extends TSchema> = S extends TOptional<TSchema> ? {
383
+ readonly [P in K]?: Static<S>;
384
+ } : {
385
+ readonly [P in K]: Static<S>;
386
+ };
387
+ type DeclaredProvidedEntry<K extends string, S extends TSchema> = S extends TOptional<TSchema> | {
388
+ readonly default: WorkflowSerializableValue;
389
+ } ? {
390
+ readonly [P in K]?: Static<S>;
391
+ } : {
392
+ readonly [P in K]: Static<S>;
393
+ };
394
+ type Simplify<T> = {
395
+ [K in keyof T]: T[K];
396
+ } & {};
397
+ export type NoExtraOutputs<TDeclared extends WorkflowOutputValues, TActual extends TDeclared> = TActual & Record<Exclude<keyof TActual, keyof TDeclared>, never>;
398
+ export interface WorkflowBuilder<TInputs extends WorkflowInputValues = {}, TOutputs extends WorkflowOutputValues = {}, TRunInputs extends WorkflowInputValues = TInputs, TDefinitionBrand extends object = {}, TCompiledDefinition extends WorkflowDefinition<TInputs, TOutputs, TRunInputs, TDefinitionBrand> = WorkflowDefinition<TInputs, TOutputs, TRunInputs, TDefinitionBrand>> {
399
+ description(text: string): WorkflowBuilder<TInputs, TOutputs, TRunInputs, TDefinitionBrand, TCompiledDefinition>;
400
+ input<K extends string, S extends TSchema>(key: K, schema: S): WorkflowBuilder<Simplify<TInputs & DeclaredResolvedEntry<K, S>>, TOutputs, Simplify<TRunInputs & DeclaredProvidedEntry<K, S>>, TDefinitionBrand, WorkflowDefinition<Simplify<TInputs & DeclaredResolvedEntry<K, S>>, TOutputs, Simplify<TRunInputs & DeclaredProvidedEntry<K, S>>, TDefinitionBrand> & TDefinitionBrand>;
401
+ output<K extends string, S extends TSchema>(key: K, schema: S): WorkflowBuilder<TInputs, Simplify<TOutputs & (DeclaredResolvedEntry<K, S> & WorkflowOutputValues)>, TRunInputs, TDefinitionBrand, WorkflowDefinition<TInputs, Simplify<TOutputs & (DeclaredResolvedEntry<K, S> & WorkflowOutputValues)>, TRunInputs, TDefinitionBrand> & TDefinitionBrand>;
402
+ worktreeFromInputs(binding: WorkflowWorktreeInputBinding): WorkflowBuilder<TInputs, TOutputs, TRunInputs, TDefinitionBrand, TCompiledDefinition>;
403
+ run<TActualOutputs extends TOutputs>(fn: (ctx: WorkflowRunContext<TInputs, TDefinitionBrand>) => Promise<NoExtraOutputs<TOutputs, TActualOutputs>> | NoExtraOutputs<TOutputs, TActualOutputs>): CompletedWorkflowBuilder<TInputs, TOutputs, TRunInputs, TDefinitionBrand, TCompiledDefinition>;
404
+ }
405
+ export interface CompletedWorkflowBuilder<TInputs extends WorkflowInputValues = {}, TOutputs extends WorkflowOutputValues = {}, TRunInputs extends WorkflowInputValues = TInputs, TDefinitionBrand extends object = {}, TCompiledDefinition extends WorkflowDefinition<TInputs, TOutputs, TRunInputs, TDefinitionBrand> = WorkflowDefinition<TInputs, TOutputs, TRunInputs, TDefinitionBrand>> extends WorkflowBuilder<TInputs, TOutputs, TRunInputs, TDefinitionBrand, TCompiledDefinition> {
406
+ description(text: string): CompletedWorkflowBuilder<TInputs, TOutputs, TRunInputs, TDefinitionBrand, TCompiledDefinition>;
407
+ input<K extends string, S extends TSchema>(key: K, schema: S): CompletedWorkflowBuilder<Simplify<TInputs & DeclaredResolvedEntry<K, S>>, TOutputs, Simplify<TRunInputs & DeclaredProvidedEntry<K, S>>, TDefinitionBrand, WorkflowDefinition<Simplify<TInputs & DeclaredResolvedEntry<K, S>>, TOutputs, Simplify<TRunInputs & DeclaredProvidedEntry<K, S>>, TDefinitionBrand> & TDefinitionBrand>;
408
+ output<K extends string, S extends TSchema>(key: K, schema: S): CompletedWorkflowBuilder<TInputs, Simplify<TOutputs & (DeclaredResolvedEntry<K, S> & WorkflowOutputValues)>, TRunInputs, TDefinitionBrand, WorkflowDefinition<TInputs, Simplify<TOutputs & (DeclaredResolvedEntry<K, S> & WorkflowOutputValues)>, TRunInputs, TDefinitionBrand> & TDefinitionBrand>;
409
+ worktreeFromInputs(binding: WorkflowWorktreeInputBinding): CompletedWorkflowBuilder<TInputs, TOutputs, TRunInputs, TDefinitionBrand, TCompiledDefinition>;
410
+ compile(): TCompiledDefinition;
411
+ }
412
+ export interface WorkflowOverlayAdapter extends WorkflowSerializableObject {
413
+ }
414
+ export interface RunSnapshot extends WorkflowSerializableObject {
415
+ }
416
+ export interface ActiveRunEntry {
417
+ readonly controller: AbortController;
418
+ readonly children: readonly AbortController[];
419
+ }
420
+ export interface CancellationRegistry {
421
+ register(runId: string, controller: AbortController): void;
422
+ registerChild(runId: string, controller: AbortController): void;
423
+ abort(runId: string, reason?: unknown): boolean;
424
+ abortAll(reason?: unknown): number;
425
+ unregister(runId: string): void;
426
+ isAborted(runId: string): boolean;
427
+ }
428
+ export interface RunContinuationOpts {
429
+ readonly source: RunSnapshot;
430
+ readonly resumeFromStageId: string;
431
+ }
432
+ export interface WorkflowParentRunLink {
433
+ readonly runId: string;
434
+ readonly stageId: string;
435
+ readonly rootRunId: string;
436
+ }
437
+ export interface RunOpts {
438
+ readonly adapters?: StageAdapters;
439
+ readonly cwd?: string;
440
+ readonly ui?: WorkflowUIAdapter;
441
+ readonly executionMode?: WorkflowExecutionMode;
442
+ readonly usePromptNodesForUi?: boolean;
443
+ readonly confirmStageReadiness?: (request: {
444
+ readonly runId: string;
445
+ readonly stageId: string;
446
+ readonly stageName: string;
447
+ readonly signal: AbortSignal;
448
+ }) => Promise<boolean>;
449
+ readonly store?: object;
450
+ readonly persistence?: WorkflowPersistencePort;
451
+ readonly mcp?: WorkflowMcpPort;
452
+ readonly cancellation?: CancellationRegistry;
453
+ readonly overlay?: WorkflowOverlayAdapter;
454
+ readonly signal?: AbortSignal;
455
+ readonly deferWorkflowStart?: boolean;
456
+ readonly config?: WorkflowRuntimeConfig;
457
+ readonly models?: WorkflowModelCatalogPort;
458
+ readonly registry?: object;
459
+ readonly depth?: number;
460
+ readonly stageControlRegistry?: object;
461
+ readonly runId?: string;
462
+ readonly continuation?: RunContinuationOpts;
463
+ readonly parentRun?: WorkflowParentRunLink;
464
+ readonly onRunStart?: (snapshot: RunSnapshot) => void;
465
+ readonly onStageStart?: (runId: string, snapshot: StageSnapshot) => void;
466
+ readonly onStageEnd?: (runId: string, snapshot: StageSnapshot) => void;
467
+ readonly onRunEnd?: (runId: string, status: RunStatus, result?: WorkflowOutputValues, error?: string) => void;
468
+ }
469
+ export interface WorkflowProgressSummary extends WorkflowSerializableObject {
470
+ readonly completed?: number;
471
+ readonly total?: number;
472
+ }
473
+ export interface WorkflowControlEvent extends WorkflowSerializableObject {
474
+ readonly type?: "notify" | "needs_attention" | "interrupted" | "resumed";
475
+ readonly message?: string;
476
+ }
477
+ export interface WorkflowIntercomSummary extends WorkflowSerializableObject {
478
+ readonly enabled?: boolean;
479
+ readonly delivery?: "off" | "notify" | "result" | "control-and-result";
480
+ readonly parentSession?: string;
481
+ }
482
+ export interface WorkflowDetails extends WorkflowSerializableObject {
483
+ readonly mode: WorkflowDetailsMode;
484
+ readonly action?: WorkflowAction;
485
+ readonly runId?: string;
486
+ readonly status: WorkflowDetailsStatus;
487
+ readonly context?: WorkflowContextMode;
488
+ readonly results?: readonly WorkflowTaskResult[];
489
+ readonly output?: WorkflowOutputValues;
490
+ readonly progress?: WorkflowProgressSummary;
491
+ readonly artifacts?: readonly WorkflowArtifact[];
492
+ readonly controlEvents?: readonly WorkflowControlEvent[];
493
+ readonly intercom?: WorkflowIntercomSummary;
494
+ readonly warnings?: readonly string[];
495
+ readonly error?: string;
496
+ }
497
+ export type StageStatus = RunStatus | "skipped" | "awaiting_input" | "blocked";
498
+ export interface StageSnapshot extends WorkflowSerializableObject {
499
+ readonly id: string;
500
+ readonly name: string;
501
+ readonly status: StageStatus;
502
+ readonly result?: WorkflowSerializableValue;
503
+ readonly error?: string;
504
+ }
505
+ export interface RunResult<TOutputs extends WorkflowOutputValues = WorkflowOutputValues> extends WorkflowSerializableObject {
506
+ readonly runId: string;
507
+ readonly status: RunStatus;
508
+ readonly result?: TOutputs;
509
+ readonly error?: string;
510
+ readonly stages: readonly StageSnapshot[];
511
+ }
512
+ export type ResolvedInputs<TInputs extends WorkflowInputValues = WorkflowInputValues> = Readonly<TInputs> & WorkflowSerializableObject;
513
+ export interface GitWorktreeSetupOptions extends WorkflowSerializableObject {
514
+ readonly gitWorktreeDir: string;
515
+ readonly baseBranch?: string;
516
+ readonly cwd: string;
517
+ }
518
+ export interface GitWorktreeSetupResult extends WorkflowSerializableObject {
519
+ readonly worktreeRoot: string;
520
+ readonly cwd: string;
521
+ readonly repositoryRoot: string;
522
+ readonly created: boolean;
523
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference path="./builtin/workflows/ambient.d.ts" />
1
2
  export { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, CONFIG_DIR_NAMES, LEGACY_CONFIG_DIR_NAME, LEGACY_ENV_PREFIX, getAgentConfigPaths, getAgentDir, getAgentDirs, getLegacyAgentDir, getProjectConfigDirs, getProjectConfigPaths, getEnvNames, getEnvValue, ENV_CODEX_FAST_MODE, WORKFLOW_STAGE_SUBAGENT_GUARD_ENV, isBunBinary, getUserConfigDirs, getUserConfigPaths, hasEnvValue, PACKAGE_NAME, setEnvValue, VERSION, } from "./config.ts";
2
3
  export { type BashResult, executeBashWithOperations } from "./core/bash-executor.ts";
3
4
  export { AgentSession, type AgentSessionConfig, type AgentSessionEvent, type AgentSessionEventListener, type ModelCycleResult, type ParsedSkillBlock, type PromptOptions, parseSkillBlock, type SessionStats, } from "./core/agent-session.ts";
package/docs/packages.md CHANGED
@@ -166,7 +166,7 @@ If no app manifest (`atomic`, or legacy `pi`) is present, Atomic auto-discovers
166
166
  - `skills/` recursively finds `SKILL.md` folders and loads top-level `.md` files as skills
167
167
  - `prompts/` loads `.md` files
168
168
  - `themes/` loads `.json` files
169
- - `workflows/` loads workflow SDK files (`.ts`, `.js`, `.mjs`, `.cjs`); `workflow/` is also accepted as a singular alias. Workflow files should `import { defineWorkflow, Type } from "@bastani/workflows"` and export `defineWorkflow(...).compile()` output. TypeScript package authors do not need a local `.d.ts` or `declare module` shim for the SDK import.
169
+ - `workflows/` loads workflow SDK files (`.ts`, `.js`, `.mjs`, `.cjs`); `workflow/` is also accepted as a singular alias. Workflow files should `import { defineWorkflow, Type } from "@bastani/workflows"` and export `defineWorkflow(...).compile()` output. TypeScript package authors do not need a hand-authored `.d.ts`, a `declare module` shim, or a `tsconfig` `paths` alias for the SDK import — the SDK types ship with `@bastani/atomic`. A package that also imports `@bastani/atomic` picks them up automatically; a pure workflow-only package adds one opt-in line (`compilerOptions.types: ["@bastani/atomic/workflows/ambient"]` or a `/// <reference types="@bastani/atomic/workflows/ambient" />` directive). See the workflow SDK typing guidance under Programmatic Usage in the workflows guide.
170
170
 
171
171
  When a package manifest exists, declared resource arrays normally define what loads. Workflows are the exception: if `atomic.workflows` / legacy `pi.workflows` is omitted, Atomic still checks conventional `workflows/` and `workflow/` directories.
172
172
 
@@ -176,7 +176,7 @@ Third-party runtime dependencies belong in `dependencies` in `package.json`. Dep
176
176
 
177
177
  Atomic bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@earendil-works/pi-ai`, `@earendil-works/pi-agent-core`, `@bastani/atomic`, `@earendil-works/pi-tui`, `typebox`.
178
178
 
179
- Workflow packages should author workflow files with `import { defineWorkflow, Type } from "@bastani/workflows"` and export definitions produced by `defineWorkflow(...).compile()`. Do not use the removed `runWorkflow` object-form API, and do not hand-roll objects with `__piWorkflow: true`; discovery accepts only compiled definitions.
179
+ Workflow packages should author workflow files with `import { defineWorkflow, Type } from "@bastani/workflows"` and export definitions produced by `defineWorkflow(...).compile()`. Do not use the removed `runWorkflow` object-form API, and do not hand-roll objects with `__piWorkflow: true`; discovery accepts only compiled definitions. `@bastani/workflows` is not a separate npm package: its types resolve through `@bastani/atomic`, so list `@bastani/atomic` and `typebox` in `peerDependencies` (the workflow SDK's emitted types reference `typebox`). A pure workflow-only package also adds the one-line ambient opt-in noted above; a package that imports `@bastani/atomic` elsewhere picks the types up automatically.
180
180
 
181
181
  Other Atomic packages must be bundled in your tarball. Add them to `dependencies` and `bundledDependencies`, then reference their resources through `node_modules/` paths. Atomic loads packages with separate module roots, so separate installs do not collide or share modules.
182
182
 
package/docs/workflows.md CHANGED
@@ -845,7 +845,7 @@ Author workflows to create at least one tracked stage by calling `ctx.task()`, `
845
845
 
846
846
  ### Inputs
847
847
 
848
- Inputs are declared with TypeBox `Type.*` schemas passed to `.input(key, schema)`. `Type` is re-exported from `@bastani/workflows` (along with the `Static` and `TSchema` type helpers), so you can author and type schemas without adding a separate `typebox` dependency. Common input schemas map to picker kinds and accepted runtime values:
848
+ Inputs are declared with TypeBox `Type.*` schemas passed to `.input(key, schema)`. `Type` is re-exported from `@bastani/workflows` (along with the `Static` and `TSchema` type helpers), so you do not import from `typebox` directly in workflow files. Workflow packages still declare `typebox` as a peer dependency so the SDK's shipped types resolve under `tsc` — see [Programmatic Usage](#programmatic-usage). Common input schemas map to picker kinds and accepted runtime values:
849
849
 
850
850
  | TypeBox schema | Picker kind | Accepted runtime value |
851
851
  |---|---|---|
@@ -1241,7 +1241,7 @@ This applies everywhere a stage accepts a model: direct `ctx.task`/`ctx.chain`/`
1241
1241
  - the `workflow` tool for agent-initiated orchestration and direct one-off runs
1242
1242
  Workflow definition files must export definitions produced by `defineWorkflow(...).compile()`. The former imperative object-form runner is not part of the public SDK, and authored workflow files cannot import `runWorkflow` from `@bastani/workflows`.
1243
1243
 
1244
- Standalone TypeScript workflow packages can import the typed SDK directly, with no hand-authored `.d.ts` or `declare module` shim:
1244
+ Standalone TypeScript workflow packages type-check the SDK import with no hand-authored `.d.ts`, no `declare module` shim, and no `tsconfig` `paths` alias. The SDK types ship with `@bastani/atomic`, so a workflow package depends only on `@bastani/atomic` (plus a `typebox` peer):
1245
1245
 
1246
1246
  ```ts
1247
1247
  import { defineWorkflow, Type } from "@bastani/workflows";
@@ -1255,6 +1255,29 @@ export default defineWorkflow("map-workflow-sdk")
1255
1255
  .compile();
1256
1256
  ```
1257
1257
 
1258
+ How those types resolve depends on what else the package imports:
1259
+
1260
+ - A package that imports `@bastani/atomic` anywhere (for example, an extension shipped in the same package) picks the workflow SDK types up automatically. `@bastani/atomic`'s root declarations reference the ambient bridge, so no extra configuration is needed.
1261
+ - A pure workflow-only package — one that imports nothing but `@bastani/workflows` — adds a single opt-in so TypeScript loads the ambient bridge. Set it once for the project in `tsconfig.json`:
1262
+
1263
+ ```jsonc
1264
+ {
1265
+ "compilerOptions": {
1266
+ "module": "NodeNext",
1267
+ "moduleResolution": "NodeNext",
1268
+ "types": ["@bastani/atomic/workflows/ambient"]
1269
+ }
1270
+ }
1271
+ ```
1272
+
1273
+ or add a single reference directive at the top of one workflow file:
1274
+
1275
+ ```ts
1276
+ /// <reference types="@bastani/atomic/workflows/ambient" />
1277
+ ```
1278
+
1279
+ Either form makes `import { defineWorkflow, Type } from "@bastani/workflows"` and the `@bastani/workflows/builtin/*` composition imports resolve under `tsc` (`moduleResolution: NodeNext`) with no hand-authored `.d.ts`, no `declare module` shim, and no `paths` alias. `@bastani/workflows` is not a separate npm package — its types ship with `@bastani/atomic` — so list both `@bastani/atomic` and `typebox` (the SDK's emitted types reference TypeBox) in `peerDependencies`. Runtime discovery and loading via `atomic.workflows` are unchanged: Atomic's loader still supplies the SDK when workflow files execute.
1280
+
1258
1281
  The `workflow` tool still supports direct one-off `task`, `tasks`, and `chain` modes. Direct chains support `chainName` for status/artifact grouping and `chainDir` as a shared directory for relative reads, outputs, and worktree diffs.
1259
1282
 
1260
1283
  Use `createRegistry()` when code needs to group definitions explicitly:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/atomic",
3
- "version": "0.8.24-alpha.1",
3
+ "version": "0.8.24-alpha.2",
4
4
  "description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "atomicConfig": {
@@ -26,6 +26,24 @@
26
26
  "./hooks": {
27
27
  "types": "./dist/core/hooks/index.d.ts",
28
28
  "import": "./dist/core/hooks/index.js"
29
+ },
30
+ "./workflows": {
31
+ "types": "./dist/builtin/workflows/src/authoring.d.ts",
32
+ "import": "./dist/builtin/workflows/src/index.ts",
33
+ "default": "./dist/builtin/workflows/src/index.ts"
34
+ },
35
+ "./workflows/ambient": {
36
+ "types": "./dist/builtin/workflows/ambient.d.ts"
37
+ },
38
+ "./workflows/builtin": {
39
+ "types": "./dist/builtin/workflows/builtin/index.d.ts",
40
+ "import": "./dist/builtin/workflows/builtin/index.ts",
41
+ "default": "./dist/builtin/workflows/builtin/index.ts"
42
+ },
43
+ "./workflows/builtin/*": {
44
+ "types": "./dist/builtin/workflows/builtin/*.d.ts",
45
+ "import": "./dist/builtin/workflows/builtin/*.ts",
46
+ "default": "./dist/builtin/workflows/builtin/*.ts"
29
47
  }
30
48
  },
31
49
  "files": [
@@ -44,6 +62,7 @@
44
62
  "copy-builtin-packages": "bun run scripts/copy-builtin-packages.ts",
45
63
  "copy-builtin-workflows": "bun run copy-builtin-packages",
46
64
  "docs:check": "bun run scripts/validate-docs-links.ts",
65
+ "verify:workflow-types": "bun run scripts/verify-workflow-sdk-types.ts",
47
66
  "test": "vitest --run",
48
67
  "prepublishOnly": "bun run clean && bun run build"
49
68
  },