@quintinshaw/pi-dynamic-workflows 1.9.0 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +89 -66
  2. package/package.json +16 -3
package/README.md CHANGED
@@ -1,12 +1,35 @@
1
1
  # pi-dynamic-workflows
2
2
 
3
- > Claude-Code-style dynamic workflows for [Pi](https://github.com/earendil-works/pi).
3
+ [![npm](https://img.shields.io/npm/v/@quintinshaw/pi-dynamic-workflows?color=cb3837&logo=npm)](https://www.npmjs.com/package/@quintinshaw/pi-dynamic-workflows)
4
+ [![license](https://img.shields.io/badge/license-MIT-blue)](#license)
5
+ [![for Pi](https://img.shields.io/badge/for-Pi-7c3aed)](https://github.com/earendil-works/pi)
6
+ [![tests](https://img.shields.io/badge/tests-43%20passing-success)](#development)
4
7
 
5
- A Pi extension that adds a `workflow` tool. Instead of one assistant doing everything sequentially, the model writes a small JavaScript script that fans out the work across many isolated subagents, then synthesizes the results.
8
+ > **Claude-Code-style dynamic workflows for [Pi](https://github.com/earendil-works/pi).** One assistant turn fans out into dozens of isolated subagents, cross-checks itself, and hands you a synthesized result.
6
9
 
7
- Great for codebase audits, multi-perspective review, large refactors, and fan-out research. Inspired by Anthropic's [dynamic workflows in Claude Code](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code).
10
+ Instead of one model grinding through a task step by step, Pi writes a small JavaScript **orchestration script** that spawns many subagents in parallel, holds the intermediate results in script variables (not the chat context), and returns only the answer. You get the structure of a pipeline with the flexibility of plain code.
8
11
 
9
- Fork of [Michaelliv/pi-dynamic-workflows](https://github.com/Michaelliv/pi-dynamic-workflows), updated for `@earendil-works/*` packages with a subagent settings-inheritance fix.
12
+ Perfect for **codebase-wide audits, multi-perspective review, large refactors, and cross-checked research** anything where one context window isn't enough.
13
+
14
+ Inspired by Anthropic's [dynamic workflows in Claude Code](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code).
15
+
16
+ ---
17
+
18
+ ## ✨ Highlights
19
+
20
+ - 🚀 **Fan-out orchestration** — `agent()`, `parallel()`, `pipeline()`, `phase()` in a sandboxed script. Up to 16 concurrent / 1000 total subagents.
21
+ - 🧭 **Interactive `/workflows` TUI** — drill through runs → phases → agents → agent detail with the keyboard, just like Claude Code. Pause, stop, and save runs without leaving the view.
22
+ - 📊 **Real token & cost accounting** — read straight from each subagent's session (input / output / cost), not estimated. Your `budget` gates on the real total.
23
+ - 🧠 **Real per-agent / per-phase model routing** — send the cheap work to a small model and the hard synthesis to a big one, resolved against your authenticated models.
24
+ - ⏯️ **Resume** — interrupted runs replay completed agents from a journal (no re-run, no tokens) and only run what's left or what you changed.
25
+ - 🌲 **Git worktree isolation** — `isolation: "worktree"` gives an agent its own branch so parallel agents can edit the same files without clobbering each other.
26
+ - 🔭 **Bundled `/deep-research`** — fans out **real** web searches, fetches sources, keeps only multi-source-supported claims, and writes a cited report. Plus `/adversarial-review` for skeptic-vetted findings.
27
+ - 🧩 **Saved & nested workflows** — turn any run into a `/<name>` slash command; compose saved workflows from inside other scripts.
28
+ - 🪟 **Background + live task panel** — run workflows in the background, watch a "Workflows running" panel under your input, and get the result delivered back into the chat when it finishes.
29
+
30
+ > **This is a heavily extended fork.** The [upstream project](https://github.com/Michaelliv/pi-dynamic-workflows) shipped the core script runtime; here, every advertised capability is actually **implemented, real-tested against the Pi SDK, and shipped** — see the [comparison](#whats-different-from-upstream) below.
31
+
32
+ ---
10
33
 
11
34
  ## Install
12
35
 
@@ -14,7 +37,7 @@ Fork of [Michaelliv/pi-dynamic-workflows](https://github.com/Michaelliv/pi-dynam
14
37
  pi install @quintinshaw/pi-dynamic-workflows
15
38
  ```
16
39
 
17
- Then `/reload` in Pi. The extension registers a `workflow` tool and activates it on session start.
40
+ Then `/reload` in Pi. The extension registers the `workflow` tool and the `/workflows`, `/deep-research`, and `/adversarial-review` commands.
18
41
 
19
42
  <details>
20
43
  <summary>From source (for development)</summary>
@@ -25,55 +48,68 @@ pi install /path/to/pi-dynamic-workflows
25
48
  ```
26
49
  </details>
27
50
 
28
- ## Usage
51
+ ## 30-second demo
29
52
 
30
- Ask Pi for a workflow in plain language:
53
+ Just ask for a workflow in plain language:
31
54
 
32
55
  ```text
33
- Run a workflow to inspect this repository and summarize the main modules.
56
+ Run a workflow to audit every route under src/routes/ for missing auth checks.
34
57
  ```
35
58
 
36
- The model writes a workflow script and calls the `workflow` tool. Live progress streams inline:
59
+ Pi writes the script and streams compact progress inline:
37
60
 
38
61
  ```text
39
- ◆ Workflow: inspect_project (3/3 done · 12,480 tokens)
62
+ ◆ Workflow: auth_audit (5/5 done · 48,210 tokens · $0.0131)
40
63
  ✓ Scan 1/1
41
- #1 ✓ repo inventory
42
- Analyze 2/2
43
- #2 ✓ source modules
44
- #3 ✓ final summary
64
+ #1 ✓ enumerate routes
65
+ Review 3/3
66
+ #2 ✓ routes/users.ts
67
+ #3 ✓ routes/admin.ts
68
+ #4 ✓ routes/billing.ts
69
+ ✓ Verify 1/1
70
+ #5 ✓ adversarial recheck
45
71
  ```
46
72
 
47
- Press `Esc` to cancel a running run; active subagents are aborted and surfaced as skipped.
73
+ Press `Esc` to cancel; active subagents are aborted and surfaced as skipped.
48
74
 
49
- ### Background runs & `/workflows`
75
+ ## What's different from upstream
50
76
 
51
- Ask for a background workflow (the model passes `background: true`) and it runs without blocking your session. Manage it with the `/workflows` command:
77
+ This fork turns the original's roadmap into working, tested features:
52
78
 
53
- ```text
54
- /workflows # open the interactive navigator (plain list in print mode)
55
- /workflows list # force the plain-text list
56
- /workflows status <id> # watch a running run live (status bar), prints result when done
57
- /workflows stop <id> # abort a running run
58
- /workflows pause <id> # pause a running run
59
- /workflows resume <id> # resume an interrupted run (replays cached results)
60
- /workflows rm <id> # remove a run from the list
61
- ```
79
+ | Capability | Upstream | This fork |
80
+ | --- | :---: | :---: |
81
+ | Core `agent`/`parallel`/`pipeline` runtime | ✅ | ✅ |
82
+ | Structured (JSON-Schema) subagent output | | |
83
+ | **Token & cost accounting** | estimate | ✅ real, from the SDK session |
84
+ | **Per-agent / per-phase model routing** | prose-only* | ✅ actually switches models |
85
+ | **`/workflows` command + interactive TUI** | | full keyboard navigator |
86
+ | **Resume an interrupted run** | — | ✅ journaled, replays the prefix |
87
+ | **Git worktree isolation** | — | ✅ real worktrees, auto-cleanup |
88
+ | **`/deep-research` with real web access** | — | ✅ live search + cross-checking |
89
+ | **Saved workflows as `/<name>`** | — | ✅ |
90
+ | **Nested `workflow()`** | — | ✅ shares the global caps |
91
+ | **Background runs + live task panel + result delivery** | — | ✅ |
92
+ | Test suite | minimal | ✅ 43 tests + real Pi end-to-end |
62
93
 
63
- ### Bundled workflows
94
+ <sub>*Upstream injected the requested model as a text line in the prompt; it never changed the subagent's actual model.</sub>
95
+
96
+ ## Commands
64
97
 
65
98
  ```text
66
- /deep-research <question> # web-researched, source-cross-checked report
67
- /adversarial-review <task> # findings cross-checked by skeptical reviewers
68
- ```
99
+ /workflows # open the interactive navigator (plain list in print mode)
100
+ /workflows status <id> # watch a running run live; prints the result when it finishes
101
+ /workflows save <name> # save the latest run's script as a reusable /<name> command
102
+ /workflows pause|resume|stop|rm <id>
69
103
 
70
- `/deep-research` fans out web searches across several angles, fetches the top sources with real `web_search` / `web_fetch` tools, keeps only claims supported by multiple sources, and writes a cited report.
104
+ /deep-research <question> # web-researched, source-cross-checked report
105
+ /adversarial-review <task> # findings cross-checked by skeptical reviewers
106
+ ```
71
107
 
72
- Save any run as a reusable command: `/workflows save <name>` writes the most recent run's script to `.pi/workflows/saved/<name>.json`, and it immediately becomes `/<name>` (arguments parsed as `key=value` + positionals into `args`).
108
+ In the **interactive navigator**: `↑/↓` (or `j/k`) select · `enter`/`→` open · `esc`/`←` back · `j/k` scroll detail · `p` pause/resume · `x` stop · `s` save · `q` quit.
73
109
 
74
- ## Workflow script shape
110
+ ## Writing a workflow
75
111
 
76
- A workflow is plain JavaScript. The first statement must export literal metadata:
112
+ A workflow is plain JavaScript whose first statement exports literal metadata:
77
113
 
78
114
  ```js
79
115
  export const meta = {
@@ -102,7 +138,7 @@ return { inventory, summary }
102
138
  | `workflow(name, args)` | Run a saved workflow inline and return its result (one level deep; shares the global caps). |
103
139
  | `log(message)` | Append a workflow-level log line. |
104
140
  | `args` | Optional JSON value passed via the tool's `args` parameter. |
105
- | `budget` | `{ total, spent(), remaining() }` token-budget tracker. |
141
+ | `budget` | `{ total, spent(), remaining() }` token-budget tracker (real tokens). |
106
142
  | `cwd`, `process.cwd()` | Working directory for subagents. |
107
143
 
108
144
  ### Agent options
@@ -111,16 +147,16 @@ return { inventory, summary }
111
147
  | --- | --- | --- |
112
148
  | `label` | string | Human-readable label for progress display |
113
149
  | `phase` | string | Override the current phase for this agent |
114
- | `schema` | object | JSON Schema for structured output |
150
+ | `schema` | object | JSON Schema the subagent returns a validated object |
115
151
  | `model` | string | Run this agent on a specific model — `provider/modelId` or a bare `modelId` |
116
152
  | `isolation` | `"worktree"` | Run this agent in its own throwaway git worktree (parallel edits without conflict) |
117
153
  | `timeoutMs` | number | Override the default 5-minute agent timeout |
118
154
 
119
- Models can also be set per phase via `meta.phases[].model`. Precedence is `opts.model` > phase model > session default; an unknown model logs a warning and falls back to the default.
155
+ Models can also be set per phase via `meta.phases[].model`. Precedence: `opts.model` > phase model > session default; an unknown model logs a warning and falls back.
120
156
 
121
157
  ### Structured output
122
158
 
123
- Pass a JSON Schema via `opts.schema` and the subagent returns a validated object:
159
+ Pass a JSON Schema and the subagent returns a validated object instead of prose:
124
160
 
125
161
  ```js
126
162
  const finding = await agent('Find security-sensitive files.', {
@@ -136,51 +172,38 @@ const finding = await agent('Find security-sensitive files.', {
136
172
  })
137
173
  ```
138
174
 
139
- Backed by a Pi `structured_output` tool with `terminate: true`, so the subagent ends on that call.
175
+ Backed by a Pi `structured_output` tool with `terminate: true`, so the subagent ends on that call — no wasted follow-up turn.
140
176
 
141
- ### Determinism rules
177
+ ### Determinism
142
178
 
143
- Scripts run inside a Node `vm` sandbox. Intentionally unavailable: `Date.now()`, `new Date()`, `Math.random()`, `require`/`import`/`fs`/network, and (inside `meta`) spreads, computed keys, template interpolation, and function calls. This keeps `meta` parseable and runs reproducible.
144
-
145
- ## What works today
146
-
147
- - **Core runtime** — `agent` / `parallel` / `pipeline` / `phase` / `log` / `budget` in a sandboxed script
148
- - **Structured output** — JSON-Schema-validated subagent results
149
- - **Real token & cost accounting** — read from each subagent's SDK session (input / output / total / cost), with a character estimate only as fallback when a provider reports no usage; `budget` gates on the real total
150
- - **Real per-agent / per-phase model routing** — `opts.model` and `meta.phases[].model` actually select the model (resolved against your authed model registry), with graceful fallback
151
- - **`/workflows` interactive navigator** — `/workflows` opens a focused TUI you drill through with the keyboard (runs → phases → agents → agent detail): `↑/↓` (or `j/k`) select, `enter`/`→` open, `esc`/`←` back, `j/k` scroll detail, `p` pause/resume, `x` stop, `s` save, `q` quit. In print/RPC mode it falls back to plain text
152
- - **Live task panel + background delivery** — while a `background: true` run is going, a "Workflows running" panel sits below the input (focus it and press `enter` to open the navigator); when the run finishes, its result is delivered back into the conversation so your paused task continues
153
- - **Bundled `/deep-research` & `/adversarial-review`** — `/deep-research` runs real web searches (via built-in `web_search` / `web_fetch` tools), extracts claims, cross-checks them across sources, and reports only what survived; `/adversarial-review` investigates a task then has independent skeptics try to refute each finding, keeping only those that clear an agreement threshold
154
- - **Saved workflows as `/<name>`** — save a run's script with `/workflows save <name>` and it becomes a reusable slash command; arguments are parsed (`key=value` and positionals) and passed through as `args`
155
- - **Nested `workflow()`** — call `await workflow('saved-name', args)` inside a script to run a saved workflow inline; nesting is one level deep and shares the parent's concurrency limiter, agent counter, and token budget so the global caps hold
156
- - **Resume** — each agent result is journaled by a deterministic call index; resuming replays the unchanged prefix from cache (no re-run, no tokens) and runs only new or edited calls live
157
- - **Worktree isolation** — `isolation: "worktree"` runs an agent in its own git worktree on a throwaway branch, so parallel agents can edit the same files without conflict; the worktree is torn down after (results are not auto-merged), and it falls back to a logged no-op outside a git repo
158
- - **Safety limits** — 1000-agent cap (`maxAgents`), per-agent timeout (`agentTimeoutMs`), recoverable-vs-fatal error classification
159
- - **Live progress + token/cost display**, `Esc` to abort
160
- - **Log persistence** to `.pi/workflows/runs/`
179
+ Scripts run inside a Node `vm` sandbox. Intentionally unavailable: `Date.now()`, `new Date()`, `Math.random()`, `require`/`import`/`fs`/network, and (inside `meta`) spreads, computed keys, template interpolation, and function calls. This keeps `meta` parseable and runs **reproducible** — which is what makes resume reliable.
161
180
 
162
181
  ## How it works
163
182
 
164
183
  ```text
165
184
  user prompt
166
- → Pi model writes a workflow script
167
- → workflow tool parses + runs it in a vm sandbox
168
- → script calls agent() / parallel() / pipeline()
185
+ → Pi writes a workflow script
186
+ the workflow tool parses + runs it in a vm sandbox
187
+ the script calls agent() / parallel() / pipeline()
169
188
  → each agent() spawns a fresh in-memory Pi subagent session
170
- → snapshots stream back as compact progress
171
- → final structured result returns to the parent assistant
189
+ results are journaled; snapshots stream back as compact progress
190
+ the final structured result returns to the parent assistant
172
191
  ```
173
192
 
174
- Subagents run in fresh in-memory Pi sessions with the standard coding tools (read, bash, edit, write, grep, find, ls), so they work exactly like a normal Pi turn.
193
+ Subagents run in fresh in-memory Pi sessions with the standard coding tools (read, bash, edit, write, grep, find, ls), so they work exactly like a normal Pi turn — and inherit your provider/model settings.
175
194
 
176
195
  ## Development
177
196
 
178
197
  ```bash
179
198
  npm install
180
- npm test # biome check + tsc + unit tests
199
+ npm test # biome check + tsc + 43 unit tests
181
200
  ```
182
201
 
183
- Parser unit tests live in `tests/workflow-parser.test.ts`.
202
+ Tests live in `tests/`. Each feature is also verified end-to-end against a real Pi subagent session before release.
203
+
204
+ ## Credits
205
+
206
+ Fork of [Michaelliv/pi-dynamic-workflows](https://github.com/Michaelliv/pi-dynamic-workflows), rebuilt on `@earendil-works/*` packages with the advertised feature set implemented and a subagent settings-inheritance fix. Inspired by [Claude Code dynamic workflows](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code).
184
207
 
185
208
  ## License
186
209
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@quintinshaw/pi-dynamic-workflows",
3
- "version": "1.9.0",
4
- "description": "Claude-Code-style dynamic workflow orchestration for Pi.",
3
+ "version": "1.9.1",
4
+ "description": "Claude-Code-style dynamic workflows for Pi — fan a task out across 100s of subagents with real model routing, token/cost accounting, resume, git-worktree isolation, an interactive /workflows TUI, and a real /deep-research.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -33,8 +33,21 @@
33
33
  "keywords": [
34
34
  "pi-package",
35
35
  "pi",
36
+ "pi-coding-agent",
36
37
  "workflow",
37
- "agents"
38
+ "workflows",
39
+ "dynamic-workflows",
40
+ "orchestration",
41
+ "subagents",
42
+ "multi-agent",
43
+ "agents",
44
+ "ai-agents",
45
+ "parallel",
46
+ "fan-out",
47
+ "claude-code",
48
+ "deep-research",
49
+ "code-review",
50
+ "llm"
38
51
  ],
39
52
  "pi": {
40
53
  "extensions": [