@bastani/atomic 0.8.1 → 0.8.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.
- package/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/config.ts +3 -4
- package/dist/builtin/intercom/index.ts +6 -6
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/agent-dir.ts +11 -2
- package/dist/builtin/mcp/cli.js +12 -6
- package/dist/builtin/mcp/config.ts +31 -22
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/agents/agents.ts +63 -23
- package/dist/builtin/subagents/src/agents/skills.ts +21 -21
- package/dist/builtin/subagents/src/extension/index.ts +9 -8
- package/dist/builtin/subagents/src/runs/shared/run-history.ts +13 -10
- package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +3 -3
- package/dist/builtin/subagents/src/shared/artifacts.ts +18 -17
- package/dist/builtin/subagents/src/shared/types.ts +4 -4
- package/dist/builtin/web-access/config-paths.ts +11 -0
- package/dist/builtin/web-access/exa.ts +3 -2
- package/dist/builtin/web-access/gemini-api.ts +2 -1
- package/dist/builtin/web-access/gemini-search.ts +2 -1
- package/dist/builtin/web-access/gemini-web-config.ts +2 -1
- package/dist/builtin/web-access/github-extract.ts +2 -1
- package/dist/builtin/web-access/index.ts +11 -8
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/web-access/perplexity.ts +2 -1
- package/dist/builtin/web-access/video-extract.ts +2 -1
- package/dist/builtin/web-access/youtube-extract.ts +2 -1
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +4 -0
- package/dist/builtin/workflows/builtin/open-claude-design.ts +39 -22
- package/dist/builtin/workflows/builtin/ralph.ts +7 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/workflow/SKILL.md +28 -20
- package/dist/builtin/workflows/skills/workflow/references/design-checklist.md +8 -4
- package/dist/builtin/workflows/skills/workflow/references/running-workflows.md +52 -23
- package/dist/builtin/workflows/skills/workflow/references/sdk-authoring.md +41 -12
- package/dist/builtin/workflows/src/extension/config-loader.ts +13 -14
- package/dist/builtin/workflows/src/extension/discovery.ts +4 -6
- package/dist/builtin/workflows/src/extension/index.ts +675 -524
- package/dist/builtin/workflows/src/extension/runtime.ts +40 -16
- package/dist/builtin/workflows/src/extension/wiring.ts +3 -0
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +43 -33
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +34 -10
- package/dist/builtin/workflows/src/shared/types.ts +1 -5
- package/dist/builtin/workflows/src/tui/graph-view.ts +245 -75
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +23 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +259 -149
- package/dist/builtin/workflows/src/tui/status-helpers.ts +3 -3
- package/dist/builtin/workflows/src/tui/store-widget-installer.ts +99 -10
- package/dist/builtin/workflows/src/tui/switcher.ts +4 -5
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +29 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -8
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +59 -4
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +3 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +31 -8
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +9 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +11 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +3 -2
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +25 -8
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-manager.d.ts +3 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +97 -58
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +37 -36
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +5 -4
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +29 -8
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +2 -2
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +2 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +8 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/todos.d.ts.map +1 -1
- package/dist/core/tools/todos.js +3 -3
- package/dist/core/tools/todos.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +6 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/atomic-banner.d.ts +4 -0
- package/dist/modes/interactive/components/atomic-banner.d.ts.map +1 -0
- package/dist/modes/interactive/components/atomic-banner.js +34 -0
- package/dist/modes/interactive/components/atomic-banner.js.map +1 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +99 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-message-renderer.js +450 -0
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -0
- package/dist/modes/interactive/components/chat-transcript.d.ts +69 -0
- package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-transcript.js +183 -0
- package/dist/modes/interactive/components/chat-transcript.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +16 -4
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +110 -137
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +2 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +9 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +192 -137
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/catppuccin-mocha.json +5 -5
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +11 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +2 -2
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +2 -2
- package/dist/utils/version-check.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workflow
|
|
3
|
-
description: Create, run, inspect, and improve pi/atomic workflows. Use whenever the user wants
|
|
3
|
+
description: Create, run, inspect, and improve pi/atomic workflows. Use whenever the user wants reusable multi-stage automation, a DAG or staged agent pipeline, workflow definitions with defineWorkflow, ctx.task/ctx.parallel/ctx.chain/ctx.stage/ctx.ui orchestration, workflow tool calls, /workflow list/inputs/connect/attach/pause/resume/status help, custom workflow discovery, model fallback chains, or context-engineered multi-session processes.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Workflow Skill
|
|
7
7
|
|
|
8
|
-
You help users create and operate pi/atomic workflows. A workflow is a reusable TypeScript definition that orchestrates named stages, parallel branches, handoffs, artifacts,
|
|
8
|
+
You help users create and operate pi/atomic workflows. A workflow is a reusable TypeScript definition that orchestrates named stages, parallel branches, handoffs, artifacts, human-in-the-loop prompts, live graph/status UI, attachable stage chats, model fallback chains, and resumable background runs through pi's workflow extension.
|
|
9
9
|
|
|
10
10
|
This skill is for people using workflows. Default to helping users author workflow definitions and run them through pi. Only discuss package implementation details if the user explicitly asks to modify the `@bastani/workflows` package itself.
|
|
11
11
|
|
|
12
12
|
Use this skill for two user journeys:
|
|
13
13
|
|
|
14
|
-
1. **Run or
|
|
14
|
+
1. **Run, inspect, attach to, pause, or resume an existing workflow** — use the workflow tool or `/workflow` surface. Load `references/running-workflows.md`.
|
|
15
15
|
2. **Create or edit a workflow definition** — design the information flow, then author a `defineWorkflow(...).run(...).compile()` TypeScript file. Load `references/sdk-authoring.md` and `references/design-checklist.md`.
|
|
16
16
|
|
|
17
17
|
## Reference Files
|
|
@@ -20,8 +20,8 @@ Load references on demand. Keep this file lean; put details in references.
|
|
|
20
20
|
|
|
21
21
|
| File | Load when |
|
|
22
22
|
| --- | --- |
|
|
23
|
-
| `references/sdk-authoring.md` | Creating/editing workflow definition files, inputs, `ctx.task`, `ctx.parallel`, `ctx.chain`, `ctx.stage`, or programmatic runner usage. |
|
|
24
|
-
| `references/running-workflows.md` | Running, monitoring, interrupting, resuming, or inspecting workflows. |
|
|
23
|
+
| `references/sdk-authoring.md` | Creating/editing workflow definition files, inputs, `ctx.task`, `ctx.parallel`, `ctx.chain`, `ctx.stage`, `ctx.ui`, model fallbacks, registries, or programmatic runner usage. |
|
|
24
|
+
| `references/running-workflows.md` | Running, monitoring, connecting/attaching, pausing, interrupting, resuming, or inspecting workflows. |
|
|
25
25
|
| `references/design-checklist.md` | Before implementing or shipping any non-trivial workflow. |
|
|
26
26
|
| `references/context-engineering.md` | Any multi-stage or multi-agent workflow; routes to copied context-engineering references. |
|
|
27
27
|
| `references/context-engineering/context-fundamentals.md` | Prompt/context basics, token budgeting, prompt placement, progressive disclosure. |
|
|
@@ -42,9 +42,9 @@ Load references on demand. Keep this file lean; put details in references.
|
|
|
42
42
|
|
|
43
43
|
Classify the user's ask before acting:
|
|
44
44
|
|
|
45
|
-
- **Run**: "run workflow X", "kick off ralph", "is it done?", "resume", "interrupt", "status", "what inputs does it need?" → load `references/running-workflows.md`; list/inspect first if needed; execute rather than merely printing commands when tools allow.
|
|
46
|
-
- **Author**: "create a workflow", "turn this process into a workflow", "add a stage", "make a reusable workflow", "defineWorkflow", "ctx.parallel", "workflow schema" → load `references/sdk-authoring.md`; design before coding.
|
|
47
|
-
- **Design/architecture**: "make this workflow robust", "multi-agent pipeline", "context handoff", "review/fix loop" → load `references/design-checklist.md` and `references/context-engineering.md` before writing code.
|
|
45
|
+
- **Run**: "run workflow X", "kick off ralph", "is it done?", "resume", "interrupt", "pause", "attach", "status", "what inputs does it need?" → load `references/running-workflows.md`; list/inspect first if needed; execute rather than merely printing commands when tools allow.
|
|
46
|
+
- **Author**: "create a workflow", "turn this process into a workflow", "add a stage", "make a reusable workflow", "defineWorkflow", "ctx.parallel", "ctx.ui", "workflow schema" → load `references/sdk-authoring.md`; design before coding.
|
|
47
|
+
- **Design/architecture**: "make this workflow robust", "multi-agent pipeline", "context handoff", "review/fix loop", "fallback models", "human approval gate" → load `references/design-checklist.md` and `references/context-engineering.md` before writing code.
|
|
48
48
|
|
|
49
49
|
## Running Existing Workflows
|
|
50
50
|
|
|
@@ -52,8 +52,9 @@ Inspect before running unfamiliar named workflows:
|
|
|
52
52
|
|
|
53
53
|
```ts
|
|
54
54
|
workflow({ action: "list" })
|
|
55
|
+
workflow({ action: "get", workflow: "deep-research-codebase" })
|
|
55
56
|
workflow({ action: "inputs", workflow: "deep-research-codebase" })
|
|
56
|
-
workflow({ workflow: "deep-research-codebase", inputs: { prompt: "map workflow runtime" } })
|
|
57
|
+
workflow({ action: "run", workflow: "deep-research-codebase", inputs: { prompt: "map workflow runtime" } })
|
|
57
58
|
```
|
|
58
59
|
|
|
59
60
|
Slash equivalents:
|
|
@@ -61,13 +62,18 @@ Slash equivalents:
|
|
|
61
62
|
```text
|
|
62
63
|
/workflow list
|
|
63
64
|
/workflow inputs deep-research-codebase
|
|
65
|
+
/workflow deep-research-codebase --help
|
|
64
66
|
/workflow deep-research-codebase prompt="map src" max_partitions=2
|
|
67
|
+
/workflow connect <run-id>
|
|
68
|
+
/workflow attach <run-id> <stage-id-or-name>
|
|
69
|
+
/workflow pause <run-id> [stage-id-or-name]
|
|
65
70
|
/workflow status --all
|
|
66
71
|
/workflow status <run-id>
|
|
67
|
-
/workflow
|
|
72
|
+
/workflow interrupt <run-id|--all>
|
|
73
|
+
/workflow resume <run-id> [stage-id-or-name] [message]
|
|
68
74
|
```
|
|
69
75
|
|
|
70
|
-
Named workflow dispatch is background-oriented: expect a run id
|
|
76
|
+
Named workflow dispatch is always background-oriented: expect a run id, then monitor status/attention states. Press F2 or run `/workflow connect <run-id>` to open the live graph viewer. HIL prompts from `ctx.ui.input/confirm/select/editor` appear in that workflow UI, not as modal chat dialogs.
|
|
71
77
|
|
|
72
78
|
## Direct Workflow-Native Orchestration
|
|
73
79
|
|
|
@@ -129,8 +135,9 @@ Task options mirror pi session options plus workflow-owned fields such as `outpu
|
|
|
129
135
|
|
|
130
136
|
For user-authored workflows, place definitions where pi discovers them:
|
|
131
137
|
|
|
132
|
-
- Project-local: `.atomic/workflows/*.ts` inside the current project.
|
|
133
|
-
- User-global: `~/.atomic/agent/workflows/*.ts` for workflows available across projects.
|
|
138
|
+
- Project-local: `.atomic/workflows/*.{ts,js,mjs,cjs}` inside the current project. Legacy `.pi/workflows/` is also checked for compatibility.
|
|
139
|
+
- User-global: `~/.atomic/agent/workflows/*.{ts,js,mjs,cjs}` for workflows available across projects. Legacy `~/.pi/agent/workflows/` is also checked.
|
|
140
|
+
- Configured directories: `.atomic/extensions/workflow/config.json` or `~/.atomic/agent/extensions/workflow/config.json` may add named `workflows.<name>.path` entries; legacy `.pi/...` config paths are also considered.
|
|
134
141
|
- Package workflows: a pi package can expose bundled workflow directories through `package.json` under `pi.builtin`.
|
|
135
142
|
|
|
136
143
|
If an existing project has workflow examples, inspect those first for import style and naming conventions. In a normal consumer project, import from the package:
|
|
@@ -169,7 +176,7 @@ export default defineWorkflow("explain-file")
|
|
|
169
176
|
.input("path", { type: "text", required: true, description: "File path to explain." })
|
|
170
177
|
.run(async (ctx) => {
|
|
171
178
|
const explanation = await ctx.task("explain", {
|
|
172
|
-
|
|
179
|
+
prompt: `Read ${String(ctx.inputs.path)} and explain purpose, risks, and key symbols.`,
|
|
173
180
|
context: "fresh",
|
|
174
181
|
});
|
|
175
182
|
|
|
@@ -186,7 +193,7 @@ Builder rules:
|
|
|
186
193
|
- `.run(async (ctx) => ({ ... }))` defines the workflow body.
|
|
187
194
|
- `.compile()` returns the workflow definition for discovery.
|
|
188
195
|
|
|
189
|
-
Input types: `text`, `string`, `number`, `boolean`, `select`. All support `description` and `required`; defaults are type-specific; `select` requires `choices`.
|
|
196
|
+
Input types: `text`, `string`, `number`, `boolean`, `select`. All support `description` and `required`; defaults are type-specific; `select` requires `choices`. Runtime validation rejects unknown keys, missing required values, type mismatches, and select values outside `choices`.
|
|
190
197
|
|
|
191
198
|
### 4. Pick the right primitive
|
|
192
199
|
|
|
@@ -196,7 +203,7 @@ Input types: `text`, `string`, `number`, `boolean`, `select`. All support `descr
|
|
|
196
203
|
| Independent branches | `ctx.parallel(steps, { task? })` |
|
|
197
204
|
| Dependent stages | `ctx.chain(steps, { task? })` |
|
|
198
205
|
| Low-level session controls | `ctx.stage(name, options)` then `stage.prompt/complete` |
|
|
199
|
-
| User interaction during run | `ctx.ui`
|
|
206
|
+
| User interaction during run | `ctx.ui.input/confirm/select/editor` |
|
|
200
207
|
| Pure computation / file I/O / parsing | Plain TypeScript in `.run()` or helpers |
|
|
201
208
|
|
|
202
209
|
Use `previous` plus `{previous}` for context handoff. If no placeholder is present, the runtime appends context. Chain defaults: first missing task uses `{task}`, later missing tasks use `{previous}`, and missing tasks inside chain-parallel groups use `{previous}`.
|
|
@@ -220,8 +227,9 @@ Prefer concise structured returns and durable artifacts over dumping full transc
|
|
|
220
227
|
|
|
221
228
|
Use these supported workflow surfaces:
|
|
222
229
|
|
|
223
|
-
- `/workflow <name> key=value ...` for interactive pi use.
|
|
224
|
-
-
|
|
230
|
+
- `/workflow <name> key=value ...` for interactive pi use; omit required args to open the input picker when the TUI is available.
|
|
231
|
+
- `/workflow connect|attach|pause|interrupt|resume|status|inputs` for live control and inspection.
|
|
232
|
+
- The `workflow` tool for LLM-initiated orchestration and direct one-off task/parallel/chain runs.
|
|
225
233
|
- `runWorkflow(definition)` for explicit library/script usage.
|
|
226
234
|
|
|
227
235
|
Programmatic runner example:
|
|
@@ -245,10 +253,10 @@ await runWorkflow(definition, options);
|
|
|
245
253
|
|
|
246
254
|
## Safety and Compatibility Rules
|
|
247
255
|
|
|
248
|
-
- Do not fabricate workflow names or inputs; list/inspect first
|
|
256
|
+
- Do not fabricate workflow names or inputs; list/inspect first with `list`, `get`, or `inputs`.
|
|
249
257
|
- Do not use legacy workflow tool fields such as `agent`, `stage`, or run-control `name`.
|
|
250
258
|
- Do not expect workflow-tool `create`, `update`, or `delete`; reusable definitions are code-authored.
|
|
251
|
-
- Use `/workflow` slash commands for named runs,
|
|
259
|
+
- Use `/workflow` slash commands for named runs, input picker/help, graph attach, pause/resume, status, and diagnostics.
|
|
252
260
|
- Prefer `ctx.task`, `ctx.parallel`, and `ctx.chain`; drop to `ctx.stage` only for lower-level controls.
|
|
253
261
|
- Keep stage names user-readable because they appear in workflow status/UI.
|
|
254
262
|
- Put deterministic code outside standalone stages.
|
|
@@ -13,7 +13,8 @@ Use this before implementing or shipping a non-trivial workflow.
|
|
|
13
13
|
|
|
14
14
|
- Declare every user-provided value as an input.
|
|
15
15
|
- Pick the narrowest schema type: `text`, `string`, `number`, `boolean`, or `select`.
|
|
16
|
-
- Add useful descriptions
|
|
16
|
+
- Add useful descriptions because `/workflow inputs`, `--help`, and the input picker show them.
|
|
17
|
+
- Set defaults only when safe; remember runtime validation rejects unknown keys, missing required values, wrong types, and invalid `select` choices.
|
|
17
18
|
- Validate risky input combinations before starting expensive stages.
|
|
18
19
|
|
|
19
20
|
## 3. Stage decomposition
|
|
@@ -26,7 +27,7 @@ For each planned stage, write:
|
|
|
26
27
|
- input context required
|
|
27
28
|
- output artifact/result shape
|
|
28
29
|
- model/thinking/tool/MCP needs
|
|
29
|
-
- failure mode and retry/fallback behavior
|
|
30
|
+
- failure mode and retry/fallback behavior, including whether `fallbackModels` is appropriate
|
|
30
31
|
|
|
31
32
|
Avoid stages that only do filesystem, parsing, git, or formatting work.
|
|
32
33
|
|
|
@@ -58,7 +59,8 @@ Load `context-engineering.md` and relevant detailed references. At minimum consi
|
|
|
58
59
|
|
|
59
60
|
- Use `ctx.chain` for dependent steps.
|
|
60
61
|
- Use `ctx.parallel` for independent branches.
|
|
61
|
-
- Use `
|
|
62
|
+
- Use `ctx.ui.input/confirm/select/editor` for real human decisions or missing information during a run.
|
|
63
|
+
- Use direct-mode `concurrency` limits when available; for authored `ctx.parallel(...)`, keep fan-outs intentionally bounded because the high-level primitive currently runs its steps together.
|
|
62
64
|
- Use `failFast` deliberately where available.
|
|
63
65
|
- Use loops only with clear bounds and termination criteria.
|
|
64
66
|
- Use `fallbackModels` for critical expensive stages when model availability is uncertain.
|
|
@@ -68,7 +70,8 @@ Load `context-engineering.md` and relevant detailed references. At minimum consi
|
|
|
68
70
|
- Name stages so they make sense in workflow UI/status.
|
|
69
71
|
- Return a compact structured output at the end.
|
|
70
72
|
- Save important artifacts with stable paths.
|
|
71
|
-
- Surface HIL/attention states promptly.
|
|
73
|
+
- Surface HIL/attention states promptly and tell users to open F2 or `/workflow connect <run-id>` when input is needed.
|
|
74
|
+
- Make attachable stage names clear enough for `/workflow attach <run-id> <stage>`.
|
|
72
75
|
- Include enough progress and output for resumed/inspected runs.
|
|
73
76
|
|
|
74
77
|
## 8. Final sanity pass
|
|
@@ -77,3 +80,4 @@ Load `context-engineering.md` and relevant detailed references. At minimum consi
|
|
|
77
80
|
- Confirm every required input is declared and described.
|
|
78
81
|
- Confirm every stage name is user-readable in `/workflow status` and the graph UI.
|
|
79
82
|
- Confirm the workflow uses a supported surface: `/workflow`, the `workflow` tool, or explicit `runWorkflow(...)` objects.
|
|
83
|
+
- Confirm any required live controls are represented accurately: `connect`/`attach`/`pause` are slash/TUI controls; tool controls cover status/interrupt/resume.
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
# Running and Inspecting Pi Workflows
|
|
2
2
|
|
|
3
|
-
Use this when the user asks to run, start, kick off, monitor,
|
|
3
|
+
Use this when the user asks to run, start, kick off, monitor, connect to, attach to, pause, interrupt, resume, or inspect a workflow.
|
|
4
4
|
|
|
5
5
|
## Discover first
|
|
6
6
|
|
|
7
|
-
For named workflows, do not guess
|
|
7
|
+
For named workflows, do not guess names or schemas:
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
workflow({ action: "list" })
|
|
11
|
+
workflow({ action: "get", workflow: "<name>" })
|
|
11
12
|
workflow({ action: "inputs", workflow: "<name>" })
|
|
12
13
|
```
|
|
13
14
|
|
|
14
15
|
If required inputs are missing and cannot be inferred, ask the user with `ask_user_question` or a concise free-form question.
|
|
15
16
|
|
|
16
|
-
## Run
|
|
17
|
+
## Run named workflows
|
|
17
18
|
|
|
18
19
|
```ts
|
|
19
|
-
workflow({
|
|
20
|
+
workflow({
|
|
21
|
+
action: "run",
|
|
22
|
+
workflow: "deep-research-codebase",
|
|
23
|
+
inputs: { prompt: "map workflow dispatch" },
|
|
24
|
+
})
|
|
20
25
|
```
|
|
21
26
|
|
|
22
27
|
Slash equivalent:
|
|
@@ -25,62 +30,84 @@ Slash equivalent:
|
|
|
25
30
|
/workflow deep-research-codebase prompt="map workflow dispatch"
|
|
26
31
|
```
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
Input overrides are bare `key=value` tokens. Values are JSON-parsed when possible, so `count=3`, `flag=true`, and `prompt="multi word value"` preserve useful types. A whole input object can also be passed as one JSON token.
|
|
34
|
+
|
|
35
|
+
Named workflow dispatch is always background-oriented: expect a run id and then monitor status. Press F2 or use `/workflow connect <run-id>` to attach to the graph viewer. If the TUI is available and required inputs are missing, `/workflow <name>` opens an input picker unless the user passes `--no-picker`.
|
|
36
|
+
|
|
37
|
+
## Slash command surface
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
/workflow list
|
|
41
|
+
/workflow inputs <name>
|
|
42
|
+
/workflow <name> --help
|
|
43
|
+
/workflow <name> [key=value ...]
|
|
44
|
+
/workflow connect [run-id]
|
|
45
|
+
/workflow attach [run-id] [stage-id-or-name]
|
|
46
|
+
/workflow pause [run-id] [stage-id-or-name]
|
|
47
|
+
/workflow status [run-id]
|
|
48
|
+
/workflow status --all
|
|
49
|
+
/workflow interrupt <run-id|--all>
|
|
50
|
+
/workflow resume <run-id> [stage-id-or-name] [message]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Use `connect` for the orchestrator graph. Use `attach` when the user wants to open a chat pane for a specific stage. Use `pause`/`resume` for live paused work; `resume` on a non-paused run reopens the saved snapshot/overlay.
|
|
54
|
+
|
|
55
|
+
Human-in-the-loop prompts from `ctx.ui.input`, `ctx.ui.confirm`, `ctx.ui.select`, and `ctx.ui.editor` surface in the workflow UI/graph viewer, not as ordinary chat modals.
|
|
29
56
|
|
|
30
57
|
## Direct runs
|
|
31
58
|
|
|
32
|
-
Use direct workflow-native orchestration for one-off tracked work
|
|
59
|
+
Use direct workflow-native orchestration for one-off tracked work that does not need a reusable workflow file.
|
|
60
|
+
|
|
61
|
+
Single tracked task:
|
|
33
62
|
|
|
34
63
|
```ts
|
|
35
64
|
workflow({
|
|
36
65
|
task: { name: "review", task: "Review this patch for API risks." },
|
|
37
66
|
async: true,
|
|
38
|
-
intercom: { delivery: "result" }
|
|
67
|
+
intercom: { delivery: "result" },
|
|
39
68
|
})
|
|
40
69
|
```
|
|
41
70
|
|
|
42
|
-
Parallel:
|
|
71
|
+
Parallel fan-out:
|
|
43
72
|
|
|
44
73
|
```ts
|
|
45
74
|
workflow({
|
|
46
75
|
tasks: [
|
|
47
76
|
{ name: "docs", task: "Review documentation gaps" },
|
|
48
|
-
{ name: "risks", task: "Review operational risks" }
|
|
77
|
+
{ name: "risks", task: "Review operational risks" },
|
|
49
78
|
],
|
|
50
79
|
concurrency: 2,
|
|
51
|
-
outputMode: "file-only"
|
|
80
|
+
outputMode: "file-only",
|
|
81
|
+
async: true,
|
|
52
82
|
})
|
|
53
83
|
```
|
|
54
84
|
|
|
55
|
-
|
|
85
|
+
Dependent chain:
|
|
56
86
|
|
|
57
87
|
```ts
|
|
58
88
|
workflow({
|
|
59
89
|
task: "Design the workflow SDK migration",
|
|
60
90
|
chain: [
|
|
61
91
|
{ name: "research", task: "Research {task}" },
|
|
62
|
-
{ name: "plan", task: "Plan from {previous}" }
|
|
63
|
-
]
|
|
92
|
+
{ name: "plan", task: "Plan from {previous}" },
|
|
93
|
+
],
|
|
94
|
+
async: true,
|
|
64
95
|
})
|
|
65
96
|
```
|
|
66
97
|
|
|
67
|
-
|
|
98
|
+
Direct mode supports top-level/default options and per-task options such as `context`, `model`, `fallbackModels`, `thinkingLevel`, `mcp`, `output`, `reads`, `progress`, `worktree`, `maxOutput`, `artifacts`, `sessionDir`, and `cwd`. For large fan-outs, prefer `outputMode: "file-only"`.
|
|
99
|
+
|
|
100
|
+
## Monitor/control with the workflow tool
|
|
68
101
|
|
|
69
102
|
```ts
|
|
70
103
|
workflow({ action: "status" })
|
|
71
104
|
workflow({ action: "status", runId: "<id>" })
|
|
72
105
|
workflow({ action: "interrupt", runId: "<id>" })
|
|
106
|
+
workflow({ action: "interrupt", runId: "--all" })
|
|
73
107
|
workflow({ action: "resume", runId: "<id>" })
|
|
74
108
|
```
|
|
75
109
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
```text
|
|
79
|
-
/workflow status --all
|
|
80
|
-
/workflow status <id>
|
|
81
|
-
/workflow interrupt <id>
|
|
82
|
-
/workflow resume <id>
|
|
83
|
-
```
|
|
110
|
+
The LLM-callable tool exposes status/interrupt/resume controls. Use slash commands for graph connect, stage attach, and pause because those are interactive TUI surfaces.
|
|
84
111
|
|
|
85
112
|
When a run needs user input or attention, surface that to the user instead of polling silently.
|
|
86
113
|
|
|
@@ -92,7 +119,7 @@ For async direct runs, request result delivery when available:
|
|
|
92
119
|
workflow({
|
|
93
120
|
tasks: [{ name: "reviewer", task: "Review the patch" }],
|
|
94
121
|
async: true,
|
|
95
|
-
intercom: { delivery: "result" }
|
|
122
|
+
intercom: { delivery: "result" },
|
|
96
123
|
})
|
|
97
124
|
```
|
|
98
125
|
|
|
@@ -101,7 +128,9 @@ Treat intercom payloads as user-visible workflow output.
|
|
|
101
128
|
## Common mistakes
|
|
102
129
|
|
|
103
130
|
- Do not fabricate workflow names; list first.
|
|
131
|
+
- Do not guess input keys; inspect with `inputs` or `get` first.
|
|
104
132
|
- Do not call `create`, `update`, or `delete` on the workflow tool; definitions are code-authored.
|
|
105
133
|
- Do not use legacy tool fields like `agent`, `stage`, or run-control `name`.
|
|
134
|
+
- Do not expect named workflow runs to block the chat turn; they are background tasks.
|
|
106
135
|
- Prefer `outputMode: "file-only"` for large fan-outs.
|
|
107
136
|
- Use status/resume controls for run lifecycle; inspect workflow output and artifacts for behavior.
|
|
@@ -4,10 +4,11 @@ Use this when creating or editing user-facing workflow definition files for `@ba
|
|
|
4
4
|
|
|
5
5
|
## Where workflow files live
|
|
6
6
|
|
|
7
|
-
Pi discovers workflows from these user-facing locations:
|
|
7
|
+
Pi/Atomic discovers workflows from these user-facing locations:
|
|
8
8
|
|
|
9
|
-
- Project-local: `.atomic/workflows/*.ts` inside a project.
|
|
10
|
-
- User-global: `~/.atomic/agent/workflows/*.ts` for workflows shared across projects.
|
|
9
|
+
- Project-local: `.atomic/workflows/*.{ts,js,mjs,cjs}` inside a project. Legacy `.pi/workflows/` is also checked for compatibility.
|
|
10
|
+
- User-global: `~/.atomic/agent/workflows/*.{ts,js,mjs,cjs}` for workflows shared across projects. Legacy `~/.pi/agent/workflows/` is also checked.
|
|
11
|
+
- Configured directories: `.atomic/extensions/workflow/config.json` or `~/.atomic/agent/extensions/workflow/config.json` can add `workflows.<name>.path` entries; legacy `.pi/...` config paths are also considered.
|
|
11
12
|
- Package-provided: a pi package can expose bundled workflow directories through `package.json` under `pi.builtin`.
|
|
12
13
|
|
|
13
14
|
In a normal consumer project, import from the package:
|
|
@@ -31,18 +32,20 @@ export default defineWorkflow("my-workflow")
|
|
|
31
32
|
description: "Task or question for the workflow.",
|
|
32
33
|
})
|
|
33
34
|
.run(async (ctx) => {
|
|
35
|
+
const prompt = String(ctx.inputs.prompt);
|
|
36
|
+
|
|
34
37
|
const scout = await ctx.task("scout", {
|
|
35
|
-
|
|
38
|
+
prompt: `Map the relevant context for: ${prompt}`,
|
|
36
39
|
context: "fresh",
|
|
37
40
|
});
|
|
38
41
|
|
|
39
42
|
const reviews = await ctx.parallel([
|
|
40
|
-
{ name: "quality",
|
|
41
|
-
{ name: "runtime",
|
|
43
|
+
{ name: "quality", prompt: "Inspect quality risks using this context: {previous}", previous: scout },
|
|
44
|
+
{ name: "runtime", prompt: "Inspect runtime concerns using this context: {previous}", previous: scout },
|
|
42
45
|
]);
|
|
43
46
|
|
|
44
47
|
const final = await ctx.task("synthesis", {
|
|
45
|
-
|
|
48
|
+
prompt: "Synthesize findings and recommend next steps.",
|
|
46
49
|
previous: reviews,
|
|
47
50
|
});
|
|
48
51
|
|
|
@@ -51,6 +54,8 @@ export default defineWorkflow("my-workflow")
|
|
|
51
54
|
.compile();
|
|
52
55
|
```
|
|
53
56
|
|
|
57
|
+
`prompt` and `task` are aliases for task text. Prefer `prompt` inside authored workflow files because it mirrors the lower-level `stage.prompt(...)`; `task` remains useful in direct tool calls and chain examples.
|
|
58
|
+
|
|
54
59
|
## Builder facts
|
|
55
60
|
|
|
56
61
|
- `defineWorkflow(name)` requires a non-empty string name.
|
|
@@ -69,7 +74,7 @@ Supported input schema types are:
|
|
|
69
74
|
- `boolean`: optional `default: boolean`
|
|
70
75
|
- `select`: required `choices: string[]`, optional `default: string`
|
|
71
76
|
|
|
72
|
-
All schemas support `description` and `required`. Prefer explicit descriptions because `/workflow inputs <name
|
|
77
|
+
All schemas support `description` and `required`. Prefer explicit descriptions because `/workflow inputs <name>`, `/workflow <name> --help`, and the input picker show them to the user. Runtime validation rejects unknown keys, missing required values, type mismatches, and select values outside `choices`; it does not coerce strings like `"3"` to numbers.
|
|
73
78
|
|
|
74
79
|
## Run context
|
|
75
80
|
|
|
@@ -78,9 +83,9 @@ All schemas support `description` and `required`. Prefer explicit descriptions b
|
|
|
78
83
|
Prefer high-level primitives:
|
|
79
84
|
|
|
80
85
|
- `ctx.task(name, options)` — one tracked stage + prompt, returns `WorkflowTaskResult`.
|
|
81
|
-
- `ctx.parallel(steps, options?)` — run independent task steps
|
|
86
|
+
- `ctx.parallel(steps, options?)` — run independent task steps together; keep authored fan-outs intentionally bounded.
|
|
82
87
|
- `ctx.chain(steps, options?)` — run dependent task steps sequentially.
|
|
83
|
-
- `ctx.ui` —
|
|
88
|
+
- `ctx.ui` — human-in-the-loop primitives when a run needs user input.
|
|
84
89
|
|
|
85
90
|
Use `ctx.stage(name, options?)` only when you need lower-level session control. `StageContext` supports:
|
|
86
91
|
|
|
@@ -91,6 +96,17 @@ Use `ctx.stage(name, options?)` only when you need lower-level session control.
|
|
|
91
96
|
- state access: `agent`, `model`, `thinkingLevel`, `messages`, `isStreaming`
|
|
92
97
|
- tree navigation, compaction, and abort
|
|
93
98
|
|
|
99
|
+
## Human-in-the-loop UI
|
|
100
|
+
|
|
101
|
+
`ctx.ui` supports:
|
|
102
|
+
|
|
103
|
+
- `input(prompt): Promise<string>`
|
|
104
|
+
- `confirm(message): Promise<boolean>`
|
|
105
|
+
- `select(message, options): Promise<T>`
|
|
106
|
+
- `editor(initial?): Promise<string>`
|
|
107
|
+
|
|
108
|
+
These suspend the workflow until the user responds. In interactive pi/Atomic, prompts appear in the workflow graph/input UI opened by F2 or `/workflow connect <run-id>`, not as modal chat dialogs. Always make the surrounding stage/output clear enough that the user knows what decision they are making.
|
|
109
|
+
|
|
94
110
|
## Task/session options
|
|
95
111
|
|
|
96
112
|
Common task/stage options include:
|
|
@@ -102,6 +118,8 @@ Common task/stage options include:
|
|
|
102
118
|
- `output`, `outputMode`, `reads`, `progress`, `worktree`, `maxOutput`, `artifacts`, `sessionDir`, `cwd`
|
|
103
119
|
- `mcp: { allow?: string[], deny?: string[] }`
|
|
104
120
|
|
|
121
|
+
`fallbackModels` retries transient provider/model failures with the primary `model` first, then each fallback, then the current pi-selected model when available. It is for rate limits, quota/auth/provider outages, unavailable models, network timeouts, and 5xx errors — not workflow-code errors, tool failures, validation failures, or cancellations. Use provider-qualified IDs when bare IDs would be ambiguous.
|
|
122
|
+
|
|
105
123
|
Chain defaults:
|
|
106
124
|
|
|
107
125
|
- first missing task uses `{task}` from chain options/root direct task
|
|
@@ -112,12 +130,23 @@ Chain defaults:
|
|
|
112
130
|
|
|
113
131
|
A stage should correspond to an LLM/session interaction. Put pure deterministic work directly in `.run()` or helper functions, not in a standalone stage. Examples: parsing, filesystem writes, JSON validation, git queries, and formatting. Pair deterministic parsing/validation with a nearby LLM call when it is part of that stage's output handling.
|
|
114
132
|
|
|
115
|
-
##
|
|
133
|
+
## Registries and programmatic execution
|
|
134
|
+
|
|
135
|
+
Use `createRegistry()` when code needs to group definitions explicitly:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { createRegistry, defineWorkflow } from "@bastani/workflows";
|
|
139
|
+
|
|
140
|
+
const alpha = defineWorkflow("alpha").run(async () => ({})).compile();
|
|
141
|
+
const registry = createRegistry().register(alpha);
|
|
142
|
+
registry.names();
|
|
143
|
+
registry.get("alpha");
|
|
144
|
+
```
|
|
116
145
|
|
|
117
146
|
`@bastani/workflows` is a pi package/extension. Pi loads the extension from the package manifest; the extension registers the `workflow` tool, `/workflow` command, renderers, widgets, and lifecycle hooks. Use these user-facing surfaces:
|
|
118
147
|
|
|
119
148
|
- `/workflow <name> key=value ...` inside pi.
|
|
120
|
-
- The `workflow` tool for LLM-driven orchestration.
|
|
149
|
+
- The `workflow` tool for LLM-driven orchestration and direct one-off runs.
|
|
121
150
|
- `runWorkflow(definition)` for explicit library/script usage.
|
|
122
151
|
|
|
123
152
|
Programmatic runner example:
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { join, isAbsolute } from "node:path";
|
|
20
20
|
import { homedir } from "node:os";
|
|
21
|
-
import { CONFIG_DIR_NAME } from "@bastani/atomic";
|
|
21
|
+
import { CONFIG_DIR_NAME, CONFIG_DIR_NAMES, getProjectConfigPaths } from "@bastani/atomic";
|
|
22
22
|
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
24
|
// Public types
|
|
@@ -439,37 +439,36 @@ export async function loadWorkflowConfig(
|
|
|
439
439
|
|
|
440
440
|
const diagnostics: ConfigDiagnostic[] = [];
|
|
441
441
|
|
|
442
|
-
// Global config
|
|
443
|
-
const
|
|
442
|
+
// Global config paths (primary Atomic first, then legacy pi)
|
|
443
|
+
const globalCandidates = CONFIG_DIR_NAMES.map((name) => join(home, name, "agent", "extensions", "workflow", "config.json"));
|
|
444
444
|
|
|
445
|
-
// Project-local config
|
|
446
|
-
const projectCandidates: string[] =
|
|
447
|
-
join(projectRoot, CONFIG_DIR_NAME, "extensions", "workflow", "config.json"),
|
|
448
|
-
];
|
|
445
|
+
// Project-local config paths (primary Atomic first, then legacy pi)
|
|
446
|
+
const projectCandidates: string[] = getProjectConfigPaths(projectRoot, "extensions", "workflow", "config.json");
|
|
449
447
|
|
|
450
|
-
// Load global config
|
|
448
|
+
// Load global config (primary overrides legacy)
|
|
451
449
|
let globalConfig: WorkflowExtensionConfig | null = null;
|
|
452
|
-
{
|
|
450
|
+
for (let i = globalCandidates.length - 1; i >= 0; i--) {
|
|
451
|
+
const globalPath = globalCandidates[i]!;
|
|
453
452
|
const outcome = await loadConfigFile(globalPath);
|
|
454
453
|
if (outcome.kind === "error") {
|
|
455
454
|
diagnostics.push(outcome.diagnostic);
|
|
456
455
|
} else if (outcome.kind === "ok") {
|
|
457
|
-
globalConfig = outcome.parsed;
|
|
456
|
+
globalConfig = globalConfig ? mergeConfigs(globalConfig, outcome.parsed) : outcome.parsed;
|
|
458
457
|
}
|
|
459
458
|
// "missing" → silently skip
|
|
460
459
|
}
|
|
461
460
|
|
|
462
|
-
// Load
|
|
461
|
+
// Load project-local configs (primary overrides legacy)
|
|
463
462
|
let projectConfig: WorkflowExtensionConfig | null = null;
|
|
464
|
-
for (
|
|
463
|
+
for (let i = projectCandidates.length - 1; i >= 0; i--) {
|
|
464
|
+
const candidatePath = projectCandidates[i]!;
|
|
465
465
|
const outcome = await loadConfigFile(candidatePath);
|
|
466
466
|
if (outcome.kind === "missing") continue;
|
|
467
467
|
if (outcome.kind === "error") {
|
|
468
468
|
diagnostics.push(outcome.diagnostic);
|
|
469
469
|
} else {
|
|
470
|
-
projectConfig = outcome.parsed;
|
|
470
|
+
projectConfig = projectConfig ? mergeConfigs(projectConfig, outcome.parsed) : outcome.parsed;
|
|
471
471
|
}
|
|
472
|
-
break; // Only first existing candidate
|
|
473
472
|
}
|
|
474
473
|
|
|
475
474
|
// Merge: start from global, apply project override
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
import { readdir, stat } from "node:fs/promises";
|
|
23
23
|
import { join, resolve, extname, isAbsolute } from "node:path";
|
|
24
|
-
import {
|
|
24
|
+
import { CONFIG_DIR_NAMES, getProjectConfigPaths } from "@bastani/atomic";
|
|
25
25
|
import type { WorkflowDefinition } from "../shared/types.js";
|
|
26
26
|
import { createRegistry } from "../workflows/registry.js";
|
|
27
27
|
import type { WorkflowRegistry } from "../workflows/registry.js";
|
|
@@ -408,8 +408,7 @@ export async function discoverWorkflows(
|
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
// 2. project-local
|
|
411
|
-
{
|
|
412
|
-
const dir = join(cwd, CONFIG_DIR_NAME, "workflows");
|
|
411
|
+
for (const dir of getProjectConfigPaths(cwd, "workflows").reverse()) {
|
|
413
412
|
const candidates = await loadFromDir(dir, "project-local", diagnostics);
|
|
414
413
|
registry = applyBatch(candidates, registry, sources, diagnostics);
|
|
415
414
|
}
|
|
@@ -424,9 +423,8 @@ export async function discoverWorkflows(
|
|
|
424
423
|
}
|
|
425
424
|
}
|
|
426
425
|
|
|
427
|
-
// 4. user-global — canonical Atomic path
|
|
428
|
-
{
|
|
429
|
-
const dir = join(homeDir, CONFIG_DIR_NAME, "agent", "workflows");
|
|
426
|
+
// 4. user-global — canonical Atomic path plus legacy pi path
|
|
427
|
+
for (const dir of CONFIG_DIR_NAMES.map((name) => join(homeDir, name, "agent", "workflows")).reverse()) {
|
|
430
428
|
const candidates = await loadFromDir(dir, "user-global", diagnostics);
|
|
431
429
|
registry = applyBatch(candidates, registry, sources, diagnostics);
|
|
432
430
|
}
|