@bastani/atomic 0.6.4 → 0.6.5
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.
- package/.agents/skills/create-spec/SKILL.md +6 -3
- package/.agents/skills/tdd/SKILL.md +107 -0
- package/.agents/skills/tdd/deep-modules.md +33 -0
- package/.agents/skills/tdd/interface-design.md +31 -0
- package/.agents/skills/tdd/mocking.md +59 -0
- package/.agents/skills/tdd/refactoring.md +10 -0
- package/.agents/skills/tdd/tests.md +61 -0
- package/.agents/skills/workflow-creator/SKILL.md +550 -0
- package/.agents/skills/workflow-creator/references/agent-sessions.md +891 -0
- package/.agents/skills/workflow-creator/references/agent-setup-recipe.md +266 -0
- package/.agents/skills/workflow-creator/references/computation-and-validation.md +201 -0
- package/.agents/skills/workflow-creator/references/control-flow.md +470 -0
- package/.agents/skills/workflow-creator/references/failure-modes.md +1014 -0
- package/.agents/skills/workflow-creator/references/getting-started.md +392 -0
- package/.agents/skills/workflow-creator/references/registry-and-validation.md +141 -0
- package/.agents/skills/workflow-creator/references/running-workflows.md +418 -0
- package/.agents/skills/workflow-creator/references/session-config.md +384 -0
- package/.agents/skills/workflow-creator/references/state-and-data-flow.md +356 -0
- package/.agents/skills/workflow-creator/references/user-input.md +234 -0
- package/.agents/skills/workflow-creator/references/workflow-inputs.md +392 -0
- package/.claude/agents/debugger.md +2 -2
- package/.claude/agents/reviewer.md +1 -1
- package/.claude/agents/worker.md +2 -2
- package/.github/agents/debugger.md +1 -1
- package/.github/agents/worker.md +1 -1
- package/.mcp.json +5 -1
- package/.opencode/agents/debugger.md +1 -1
- package/.opencode/agents/worker.md +1 -1
- package/README.md +236 -201
- package/dist/sdk/define-workflow.d.ts +11 -6
- package/dist/sdk/define-workflow.d.ts.map +1 -1
- package/dist/sdk/errors.d.ts +10 -0
- package/dist/sdk/errors.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +21 -9
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/primitives/inputs.d.ts +36 -0
- package/dist/sdk/primitives/inputs.d.ts.map +1 -0
- package/dist/sdk/primitives/metadata.d.ts +40 -0
- package/dist/sdk/primitives/metadata.d.ts.map +1 -0
- package/dist/sdk/primitives/run.d.ts +57 -0
- package/dist/sdk/primitives/run.d.ts.map +1 -0
- package/dist/sdk/primitives/sessions.d.ts +128 -0
- package/dist/sdk/primitives/sessions.d.ts.map +1 -0
- package/dist/sdk/runtime/executor.d.ts +24 -56
- package/dist/sdk/runtime/executor.d.ts.map +1 -1
- package/dist/sdk/runtime/orchestrator-entry.d.ts +26 -0
- package/dist/sdk/runtime/orchestrator-entry.d.ts.map +1 -0
- package/dist/sdk/runtime/tmux.d.ts +20 -0
- package/dist/sdk/runtime/tmux.d.ts.map +1 -1
- package/dist/sdk/types.d.ts +26 -86
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/open-claude-design/claude/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/open-claude-design/copilot/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/open-claude-design/opencode/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts.map +1 -1
- package/dist/sdk/workflows/index.d.ts +20 -12
- package/dist/sdk/workflows/index.d.ts.map +1 -1
- package/dist/services/config/additional-instructions.d.ts +1 -1
- package/dist/services/config/additional-instructions.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/cli.ts +39 -56
- package/src/commands/builtin-registry.ts +37 -0
- package/src/commands/cli/chat/index.ts +1 -3
- package/src/{sdk → commands/cli}/management-commands.ts +15 -55
- package/src/commands/cli/session.ts +1 -1
- package/src/commands/cli/workflow-command.test.ts +250 -16
- package/src/commands/cli/workflow-inputs.test.ts +1 -0
- package/src/commands/cli/workflow-inputs.ts +13 -3
- package/src/commands/cli/workflow-list.test.ts +1 -0
- package/src/commands/cli/workflow-list.ts +0 -0
- package/src/commands/cli/workflow-status.ts +1 -1
- package/src/commands/cli/workflow.ts +191 -11
- package/src/sdk/define-workflow.test.ts +47 -16
- package/src/sdk/define-workflow.ts +24 -6
- package/src/sdk/errors.test.ts +11 -0
- package/src/sdk/errors.ts +13 -0
- package/src/sdk/index.test.ts +92 -0
- package/src/sdk/index.ts +71 -15
- package/src/sdk/primitives/inputs.ts +48 -0
- package/src/sdk/primitives/metadata.ts +63 -0
- package/src/sdk/primitives/run.ts +81 -0
- package/src/sdk/primitives/sessions.test.ts +594 -0
- package/src/sdk/primitives/sessions.ts +328 -0
- package/src/sdk/runtime/executor.ts +36 -115
- package/src/sdk/runtime/orchestrator-entry.ts +110 -0
- package/src/sdk/runtime/tmux.ts +33 -0
- package/src/sdk/types.ts +26 -91
- package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +1 -0
- package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +1 -0
- package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +1 -0
- package/src/sdk/workflows/builtin/open-claude-design/claude/index.ts +1 -0
- package/src/sdk/workflows/builtin/open-claude-design/copilot/index.ts +1 -0
- package/src/sdk/workflows/builtin/open-claude-design/opencode/index.ts +1 -0
- package/src/sdk/workflows/builtin/ralph/claude/index.ts +1 -0
- package/src/sdk/workflows/builtin/ralph/copilot/index.ts +1 -0
- package/src/sdk/workflows/builtin/ralph/opencode/index.ts +1 -0
- package/src/sdk/workflows/index.ts +68 -51
- package/src/services/config/additional-instructions.ts +1 -1
- package/.agents/skills/test-driven-development/SKILL.md +0 -371
- package/.agents/skills/test-driven-development/testing-anti-patterns.md +0 -299
- package/dist/commands/cli/session.d.ts +0 -67
- package/dist/commands/cli/session.d.ts.map +0 -1
- package/dist/commands/cli/workflow-status.d.ts +0 -63
- package/dist/commands/cli/workflow-status.d.ts.map +0 -1
- package/dist/sdk/commander.d.ts +0 -74
- package/dist/sdk/commander.d.ts.map +0 -1
- package/dist/sdk/management-commands.d.ts +0 -42
- package/dist/sdk/management-commands.d.ts.map +0 -1
- package/dist/sdk/workflow-cli.d.ts +0 -103
- package/dist/sdk/workflow-cli.d.ts.map +0 -1
- package/dist/sdk/workflows/builtin-registry.d.ts +0 -113
- package/dist/sdk/workflows/builtin-registry.d.ts.map +0 -1
- package/src/sdk/commander.ts +0 -161
- package/src/sdk/workflow-cli.ts +0 -409
- package/src/sdk/workflows/builtin-registry.ts +0 -23
package/src/sdk/index.ts
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* atomic SDK
|
|
2
|
+
* @bastani/atomic — SDK barrel.
|
|
3
3
|
*
|
|
4
|
-
* Public API
|
|
5
|
-
*
|
|
4
|
+
* Public API for authoring and running workflows. Composition primitives
|
|
5
|
+
* are pure functions; consumers wire them into their own CLI shape (via
|
|
6
|
+
* Commander, citty, yargs, an OpenTUI app, etc.). The SDK itself ships
|
|
7
|
+
* no opinionated CLI wrapper.
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
|
-
// Typed errors
|
|
10
|
+
// ─── Typed errors ───────────────────────────────────────────────────────────
|
|
9
11
|
export {
|
|
10
12
|
MissingDependencyError,
|
|
11
13
|
WorkflowNotCompiledError,
|
|
12
14
|
InvalidWorkflowError,
|
|
15
|
+
SessionNotFoundError,
|
|
13
16
|
} from "./errors.ts";
|
|
14
17
|
|
|
15
|
-
//
|
|
18
|
+
// ─── Authoring ──────────────────────────────────────────────────────────────
|
|
19
|
+
export { defineWorkflow, WorkflowBuilder } from "./define-workflow.ts";
|
|
20
|
+
export { createRegistry } from "./registry.ts";
|
|
21
|
+
export type { Registry } from "./registry.ts";
|
|
22
|
+
|
|
23
|
+
// ─── Shared types ───────────────────────────────────────────────────────────
|
|
16
24
|
export type {
|
|
17
25
|
AgentType,
|
|
18
26
|
Transcript,
|
|
@@ -25,21 +33,69 @@ export type {
|
|
|
25
33
|
WorkflowContext,
|
|
26
34
|
WorkflowOptions,
|
|
27
35
|
WorkflowDefinition,
|
|
36
|
+
WorkflowInput,
|
|
37
|
+
WorkflowInputType,
|
|
28
38
|
StageClientOptions,
|
|
29
39
|
StageSessionOptions,
|
|
30
40
|
ProviderClient,
|
|
31
41
|
ProviderSession,
|
|
32
42
|
} from "./types.ts";
|
|
33
43
|
|
|
34
|
-
//
|
|
35
|
-
export {
|
|
44
|
+
// ─── Metadata accessors ─────────────────────────────────────────────────────
|
|
45
|
+
export {
|
|
46
|
+
getName,
|
|
47
|
+
getDescription,
|
|
48
|
+
getAgent,
|
|
49
|
+
getInputSchema,
|
|
50
|
+
getSource,
|
|
51
|
+
getMinSDKVersion,
|
|
52
|
+
} from "./primitives/metadata.ts";
|
|
36
53
|
|
|
37
|
-
// Registry
|
|
38
|
-
|
|
39
|
-
|
|
54
|
+
// ─── Registry iteration helpers ─────────────────────────────────────────────
|
|
55
|
+
import type { AgentType, Registry, WorkflowDefinition } from "./types.ts";
|
|
56
|
+
|
|
57
|
+
/** Snapshot every workflow registered in `registry`. */
|
|
58
|
+
export function listWorkflows(registry: Registry): readonly WorkflowDefinition[] {
|
|
59
|
+
return registry.list();
|
|
60
|
+
}
|
|
40
61
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
62
|
+
/** Resolve a workflow by `(name, agent)`; returns `undefined` when not found. */
|
|
63
|
+
export function getWorkflow(
|
|
64
|
+
registry: Registry,
|
|
65
|
+
agent: AgentType,
|
|
66
|
+
name: string,
|
|
67
|
+
): WorkflowDefinition | undefined {
|
|
68
|
+
return registry.resolve(name, agent);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ─── Input validation ───────────────────────────────────────────────────────
|
|
72
|
+
export { validateInputs } from "./primitives/inputs.ts";
|
|
73
|
+
export type { ResolvedInputs } from "./primitives/inputs.ts";
|
|
74
|
+
|
|
75
|
+
// ─── Run a workflow ─────────────────────────────────────────────────────────
|
|
76
|
+
export { runWorkflow } from "./primitives/run.ts";
|
|
77
|
+
export type {
|
|
78
|
+
RunWorkflowOptions,
|
|
79
|
+
RunWorkflowResult,
|
|
80
|
+
} from "./primitives/run.ts";
|
|
81
|
+
|
|
82
|
+
// ─── Session management ─────────────────────────────────────────────────────
|
|
83
|
+
export {
|
|
84
|
+
listSessions,
|
|
85
|
+
getSession,
|
|
86
|
+
stopSession,
|
|
87
|
+
attachSession,
|
|
88
|
+
detachSession,
|
|
89
|
+
nextWindow,
|
|
90
|
+
previousWindow,
|
|
91
|
+
gotoOrchestrator,
|
|
92
|
+
getSessionStatus,
|
|
93
|
+
getSessionTranscript,
|
|
94
|
+
} from "./primitives/sessions.ts";
|
|
95
|
+
export type {
|
|
96
|
+
SessionInfo,
|
|
97
|
+
SessionScope,
|
|
98
|
+
StatusSnapshot,
|
|
99
|
+
ListSessionsOptions,
|
|
100
|
+
SessionPrimitiveDeps,
|
|
101
|
+
} from "./primitives/sessions.ts";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation primitive.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `validateAndResolve` from `worker-shared.ts` with a workflow-aware
|
|
5
|
+
* signature so consumers don't need to reach into the SDK internals to
|
|
6
|
+
* coerce, default, and validate raw user-supplied input maps.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { WorkflowInput } from "../types.ts";
|
|
10
|
+
import { validateAndResolve } from "../worker-shared.ts";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Validated, defaults-applied input map. The shape matches
|
|
14
|
+
* `Record<string, string>` because the executor's tmux launcher serialises
|
|
15
|
+
* inputs as JSON strings; integer coercion happens later, inside
|
|
16
|
+
* `runOrchestrator`, against the same schema.
|
|
17
|
+
*/
|
|
18
|
+
export type ResolvedInputs = Record<string, string>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Structural shape `validateInputs` reads off a workflow definition.
|
|
22
|
+
* Typed as a minimal interface (rather than `WorkflowDefinition`) so the
|
|
23
|
+
* primitive accepts narrowly-typed compiled definitions without
|
|
24
|
+
* triggering contravariance failures in the `run` method signature.
|
|
25
|
+
*/
|
|
26
|
+
export interface ValidatableWorkflow {
|
|
27
|
+
readonly inputs: readonly WorkflowInput[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Validate raw user inputs against a workflow's declared schema.
|
|
32
|
+
*
|
|
33
|
+
* - Throws on unknown flags or missing required fields.
|
|
34
|
+
* - Applies declared defaults and the first enum value when no value is given.
|
|
35
|
+
* - Validates enum membership and integer parseability.
|
|
36
|
+
* - For free-form workflows (no declared inputs), passes through every
|
|
37
|
+
* non-empty key as-is — this preserves the legacy
|
|
38
|
+
* `--prompt "<text>"` shape.
|
|
39
|
+
*/
|
|
40
|
+
export function validateInputs(
|
|
41
|
+
workflow: ValidatableWorkflow,
|
|
42
|
+
raw: Record<string, string>,
|
|
43
|
+
): ResolvedInputs {
|
|
44
|
+
if (workflow.inputs.length === 0) {
|
|
45
|
+
return { ...raw };
|
|
46
|
+
}
|
|
47
|
+
return validateAndResolve(raw, workflow.inputs);
|
|
48
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow metadata accessors.
|
|
3
|
+
*
|
|
4
|
+
* Function-style getters keep the public surface forward-compatible —
|
|
5
|
+
* adding optional metadata fields to `WorkflowDefinition` doesn't force
|
|
6
|
+
* every consumer to read directly off the object, so we can add lazy
|
|
7
|
+
* derivation, deprecation warnings, or normalization in one place.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { AgentType, WorkflowInput } from "../types.ts";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Structural shape the metadata accessors read off a workflow
|
|
14
|
+
* definition. Typed as a minimal interface (rather than the full
|
|
15
|
+
* `WorkflowDefinition<A, I>`) so the accessors accept narrowly-typed
|
|
16
|
+
* compiled definitions without triggering contravariance failures on
|
|
17
|
+
* the `run` method signature.
|
|
18
|
+
*/
|
|
19
|
+
export interface MetadataWorkflow {
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly description: string;
|
|
22
|
+
readonly agent: AgentType;
|
|
23
|
+
readonly inputs: readonly WorkflowInput[];
|
|
24
|
+
readonly source: string;
|
|
25
|
+
readonly minSDKVersion: string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Workflow's unique name. */
|
|
29
|
+
export function getName(workflow: MetadataWorkflow): string {
|
|
30
|
+
return workflow.name;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Human-readable description (empty string when none was declared). */
|
|
34
|
+
export function getDescription(workflow: MetadataWorkflow): string {
|
|
35
|
+
return workflow.description;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Agent backend the workflow targets. */
|
|
39
|
+
export function getAgent(workflow: MetadataWorkflow): AgentType {
|
|
40
|
+
return workflow.agent;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Frozen copy of the declared input schema (empty for free-form workflows). */
|
|
44
|
+
export function getInputSchema(
|
|
45
|
+
workflow: MetadataWorkflow,
|
|
46
|
+
): readonly WorkflowInput[] {
|
|
47
|
+
return workflow.inputs;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Absolute path of the workflow's source file (`import.meta.path`). */
|
|
51
|
+
export function getSource(workflow: MetadataWorkflow): string {
|
|
52
|
+
return workflow.source;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Minimum SDK version this workflow declares (or `null` when none was
|
|
57
|
+
* specified). Atomic uses this to gate stale workflows on older installs.
|
|
58
|
+
*/
|
|
59
|
+
export function getMinSDKVersion(
|
|
60
|
+
workflow: MetadataWorkflow,
|
|
61
|
+
): string | null {
|
|
62
|
+
return workflow.minSDKVersion;
|
|
63
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runWorkflow` primitive — the public entry point for spawning a
|
|
3
|
+
* workflow tmux session.
|
|
4
|
+
*
|
|
5
|
+
* Thin wrapper around the runtime executor's `executeWorkflow`. Handles
|
|
6
|
+
* the input-validation step so the executor's contract stays single-
|
|
7
|
+
* responsibility: caller passes raw inputs, primitive validates them
|
|
8
|
+
* against the workflow's schema, executor only sees a clean record.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
executeWorkflow,
|
|
13
|
+
} from "../runtime/executor.ts";
|
|
14
|
+
import type { RegistrableWorkflow, WorkflowDefinition } from "../types.ts";
|
|
15
|
+
import { validateInputs } from "./inputs.ts";
|
|
16
|
+
|
|
17
|
+
/** Options for `runWorkflow()`. */
|
|
18
|
+
export interface RunWorkflowOptions {
|
|
19
|
+
/** Compiled workflow definition (the default export of a workflow module). */
|
|
20
|
+
workflow: RegistrableWorkflow;
|
|
21
|
+
/**
|
|
22
|
+
* Raw input map. The primitive runs the same validation pipeline the
|
|
23
|
+
* atomic CLI uses: required-field check, default fill-in, enum and
|
|
24
|
+
* integer parsing. Pass an empty object for free-form workflows that
|
|
25
|
+
* don't take any user input.
|
|
26
|
+
*/
|
|
27
|
+
inputs?: Record<string, string>;
|
|
28
|
+
/** Project root the workflow runs in. Defaults to `process.cwd()`. */
|
|
29
|
+
cwd?: string;
|
|
30
|
+
/**
|
|
31
|
+
* When true, create the tmux session and return immediately instead
|
|
32
|
+
* of attaching. The orchestrator keeps running in the background on
|
|
33
|
+
* the shared atomic tmux socket and can be reattached later via
|
|
34
|
+
* `attachSession()`.
|
|
35
|
+
*/
|
|
36
|
+
detach?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Result of a successful `runWorkflow()` call. */
|
|
40
|
+
export interface RunWorkflowResult {
|
|
41
|
+
/** Workflow run id (8-char hex; the trailing segment of the tmux session name). */
|
|
42
|
+
id: string;
|
|
43
|
+
/** Tmux session name (`atomic-wf-<agent>-<workflowName>-<id>`). */
|
|
44
|
+
tmuxSessionName: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Run a compiled workflow.
|
|
49
|
+
*
|
|
50
|
+
* Validates inputs, then spawns the orchestrator tmux session via
|
|
51
|
+
* `executeWorkflow`. In foreground mode, the returned promise resolves
|
|
52
|
+
* after the user detaches from the session; in `detach: true` mode the
|
|
53
|
+
* promise resolves as soon as the session is created on the atomic
|
|
54
|
+
* socket.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import workflow from "./hello.ts";
|
|
59
|
+
* import { runWorkflow } from "@bastani/atomic/workflows";
|
|
60
|
+
*
|
|
61
|
+
* await runWorkflow({ workflow, inputs: { greeting: "hi" } });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export async function runWorkflow(
|
|
65
|
+
options: RunWorkflowOptions,
|
|
66
|
+
): Promise<RunWorkflowResult> {
|
|
67
|
+
const { workflow, inputs = {}, cwd, detach } = options;
|
|
68
|
+
const resolved = validateInputs(workflow, inputs);
|
|
69
|
+
return await executeWorkflow({
|
|
70
|
+
// Cast required because RegistrableWorkflow's `run` is `(...args: never[]) => Promise<void>`
|
|
71
|
+
// (a structural shape that bypasses contravariance), while the runtime
|
|
72
|
+
// executor takes the typed WorkflowDefinition. The runtime never
|
|
73
|
+
// calls `run` directly through this path — it spawns a tmux session
|
|
74
|
+
// and the SDK orchestrator entry imports the module fresh.
|
|
75
|
+
definition: workflow as unknown as WorkflowDefinition,
|
|
76
|
+
agent: workflow.agent,
|
|
77
|
+
inputs: resolved,
|
|
78
|
+
projectRoot: cwd,
|
|
79
|
+
detach,
|
|
80
|
+
});
|
|
81
|
+
}
|