@sublang/playbook 6.0.0 → 7.0.0

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/README.md CHANGED
@@ -21,14 +21,14 @@ SubLang Playbook addresses both:
21
21
 
22
22
  Vocabulary: the **Boss** is you; the **Captain** is the coordinating agent you talk to; **players** are the agents a playbook delegates work to.
23
23
 
24
- Run `playbook` for an interactive tmux UI powered by [cligent](https://github.com/sublang-ai/cligent), or `playbook run` for one-shot scripts and CI.
24
+ Run `playbook` for an interactive tmux UI powered by [cligent](https://github.com/sublang-ai/cligent), or `playbook run` for the same Captain session without tmux in scripts and CI.
25
25
 
26
26
  ## Quick start
27
27
 
28
28
  Out of the box, Playbook includes **CODE** for implementation, **REVIEW** for commit-based review and fixes, and **DECIDE** for independently proposed and reviewed specification decisions.
29
29
  CODE and DECIDE call REVIEW as a nested playbook.
30
30
 
31
- The interactive starter config uses Claude as both Captain and Coder, and Codex as Reviewer.
31
+ The shared starter config uses Claude as both Captain and Coder, and Codex as Reviewer.
32
32
 
33
33
  ```sh
34
34
  npm install -g @sublang/playbook
@@ -41,10 +41,11 @@ If an SDK is missing or older than cligent supports, Playbook prints the pinned
41
41
  Prerequisites:
42
42
 
43
43
  - Node.js >= 20.6.0
44
- - `tmux` and [`glow`](https://github.com/charmbracelet/glow#installation) on `PATH`
45
44
  - Authenticated [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) or `ANTHROPIC_API_KEY`
46
45
  - Authenticated [Codex CLI](https://github.com/openai/codex) or `OPENAI_API_KEY`
47
46
 
47
+ Interactive `playbook` additionally needs `tmux` and [`glow`](https://github.com/charmbracelet/glow#installation) on `PATH`; headless `playbook run` does not.
48
+
48
49
  CODE works in the current directory and can edit and commit autonomously, so use a clean branch or worktree.
49
50
 
50
51
  ```sh
@@ -57,16 +58,17 @@ Type a task, enter `/code <task>` for implementation, or enter
57
58
 
58
59
  On first launch, Playbook writes its config to `${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`.
59
60
 
60
- One-shot runs use separate defaults instead of the interactive lineup.
61
- Without configured `run` defaults, the Captain and every player use Claude; run standalone REVIEW with a Codex Reviewer using:
61
+ The same config, compiled Captain, enabled playbooks, players, and nested calls power headless turns.
62
+ Run REVIEW explicitly, or pipe a longer request to Captain:
62
63
 
63
64
  ```sh
64
- playbook run @sublang/playbook/review/registry "review the latest commit" --player reviewer=codex --json
65
+ playbook run "/review review the latest commit"
66
+ printf '%s\n' 'Implement the approved specification, then review it.' | playbook run
65
67
  ```
66
68
 
67
- CODE and DECIDE require interactive `playbook` because the one-shot host does not drive nested calls.
69
+ `playbook run` prints the one Boss-visible Captain reply to stdout and operational status to stderr; CODE and DECIDE can complete their nested REVIEW calls there too.
68
70
 
69
- See [Using the CLI](docs/cli.md) for flags and session resume, [Configuring agents](docs/configuration.md) for lineups, [Embedding](docs/embedding.md) for custom hosts, and the [changelog](CHANGELOG.md) for releases.
71
+ See [Using the CLI](docs/cli.md) for flags and durable continuation, [Configuring agents](docs/configuration.md) for the shared lineup, [Embedding](docs/embedding.md) for custom hosts, and the [changelog](CHANGELOG.md) for releases.
70
72
 
71
73
  ## Create your own playbook
72
74
 
@@ -75,10 +77,12 @@ The separate [SLC compiler](https://github.com/sublang-ai/slc) requires Node.js
75
77
  ```sh
76
78
  npm install -g @sublang/slc
77
79
  slc playbook my-workflow.md
78
- playbook run ./my-workflow.ts "<your task>"
80
+ # After enabling /absolute/path/to/my-workflow.ts in the shared config:
81
+ playbook run "/my-workflow <your task>"
79
82
  ```
80
83
 
81
- SLC writes `my-workflow.ts` beside the source, and the inspectable intermediates and tests under `my-workflow.playbook/`; see the [SLC documentation](https://github.com/sublang-ai/slc#quick-start) for setup and phase commands.
84
+ SLC writes `my-workflow.ts`, a registry entry ready for Playbook, beside the source, and the inspectable intermediates and tests under `my-workflow.playbook/`.
85
+ Enable that entry and bind each role it declares under `playbooks.my-workflow` in the shared config, then invoke `/my-workflow`; see [External playbooks](docs/configuration.md#external-playbooks) and the [SLC documentation](https://github.com/sublang-ai/slc#quick-start).
82
86
 
83
87
  ## How it compiles
84
88
 
package/docs/cli.md CHANGED
@@ -3,9 +3,10 @@
3
3
 
4
4
  # Using the CLI
5
5
 
6
- `playbook` has two surfaces: an interactive tmux-play session, and a
7
- one-shot non-interactive `run`. Agent settings for both come from the
8
- [config](configuration.md).
6
+ `playbook` has two presentations of one configured Captain session: an
7
+ interactive tmux-play UI and a headless `playbook run` turn for scripts and
8
+ CI. Both use the same compiled Captain, enabled catalog, players, nested
9
+ stack, and [config](configuration.md); only presentation differs.
9
10
 
10
11
  ## Installing agent SDKs
11
12
 
@@ -123,78 +124,122 @@ turn's reported outcome; a turn that changed nothing ends with an
123
124
  ordinary reply and no saved-counts line
124
125
  ([[playbook-captain-19](../specs/packages/playbook-captain.md#playbook-captain-19)]).
125
126
 
126
- ## Non-interactive
127
+ ## Headless
127
128
 
128
- `playbook run <from> [task]` runs one playbook once, without tmux-play
129
- and without an interactive config entry. For example, run REVIEW
130
- directly against the latest commit:
129
+ `playbook run [input]` submits one exact Boss turn to the same Captain that
130
+ the interactive pane hosts, without constructing tmux. The shared config
131
+ selects the Captain, enabled playbooks, players, options, provisioning, and
132
+ readiness; a slash command selects a playbook through Captain, and ordinary
133
+ text remains a conversational Captain turn.
131
134
 
132
135
  ```sh
133
- playbook run @sublang/playbook/review/registry "review the latest commit" \
134
- --player coder=claude --player reviewer=codex --cwd ./my-repo
136
+ cd ./my-repo
137
+ playbook run "/review review the latest commit"
138
+ playbook run "/code implement the approved specification"
139
+ printf '%s\n' 'Summarize the current work and propose the next step.' | playbook run
135
140
  ```
136
141
 
137
- `[task]` is read from stdin when omitted pipe long or multi-line
138
- intents the same way you would to `claude -p` or `codex exec`.
142
+ When `[input]` is absent, stdin is read to EOF as verbatim UTF-8 text.
143
+ Use `--` before one flag-shaped input. Plain stdout is exactly the one
144
+ Boss-visible Captain reply plus a line feed; status and diagnostics use
145
+ stderr, and `--verbose` adds only telemetry topic names to stderr.
146
+ `--json` instead prints exactly `{"sessionId":"…","reply":"…"}`.
139
147
 
140
148
  | Flag | Meaning |
141
149
  | --- | --- |
142
- | `--player <role>=<agent>` | bind a required role |
143
- | `--captain <agent>` | set the captain/judge agent |
144
- | `--option <key>=<value>` | a registry-defined playbook option (none in the current bundled workflows) |
145
- | `--cwd <dir>` | the agents' working directory |
146
- | `--json` | one envelope: `outcome`, `sessionId`, output or questions |
147
- | `--no-provision` | never create engine links beside a filesystem `<from>` |
148
-
149
- `<agent>` is `<adapter>[:<model>][@<effort>]` `codex:gpt-5.5@xhigh`,
150
- or `claude@high` for the default model at high reasoning effort. The
151
- model keeps every interior colon (`opencode:ollama/llama3:8b@max`), and
152
- an unsupported effort is rejected up front naming the adapter's
153
- supported values. Roles and the captain default to `claude` unless the
154
- config supplies [run defaults](configuration.md#defaults-for-playbook-run).
155
-
156
- Exit codes: `0` terminal, `1` bad argument or module, `2` failure, `3`
157
- the playbook needs a Boss reply
150
+ | `--with <path>` | overlay the shared config for a new session; repeatable |
151
+ | `--no-provision` | do not create missing engine links for configured filesystem registries |
152
+ | `--json` | print exactly one `sessionId` / `reply` object |
153
+ | `--verbose` | add Captain telemetry topic names to stderr |
154
+ | `--continue` | continue the latest durable Captain session |
155
+ | `--session <id>` | continue one durable Captain session explicitly |
156
+ | `--retry-uncertain` | with `--session`, retry its exact recorded uncertain input |
157
+ | `--discard-uncertain` | with `--session`, abandon its uncertain attempt |
158
+ | `--` | end options before one literal input or reply |
159
+ | `-h`, `--help` | print the complete grammar without reading stdin or config |
160
+
161
+ Exit `0` means the Captain turn and its durable hand-off were presented,
162
+ even when the selected action reported rejection or failure through the
163
+ Captain reply. Argument, config, catalog, readiness, or pre-turn setup errors
164
+ exit `1`; a started-turn, persistence, lease-release, or presentation failure
165
+ exits `2` with stdout empty. SIGINT, SIGTERM, and SIGHUP preserve the
166
+ uncertain boundary, withhold stdout, and are re-raised after lease retirement
158
167
  ([[playbook-cli-18](../specs/packages/playbook-cli.md#playbook-cli-18)]).
159
168
 
160
- ### Engine provisioning
169
+ The former positional `<from>`, `resume`, `--player`, `--captain`,
170
+ `--option`, `--cwd`, `--last`, run-only `--config`, and top-level `run:`
171
+ config are removed. Enable a registry under `playbooks`, tune its inline
172
+ agents and options there or in a fresh `--with` overlay, invoke its effective
173
+ `/command`, and run from the working directory you want agents to use.
161
174
 
162
- A compiled playbook module imports `xstate` and
163
- `@sublang/playbook/xstate-runtime` from its own directory. When a
164
- filesystem `<from>` cannot resolve them typically under a global
165
- install with no project-local packages —
166
- `playbook run` provisions them automatically before loading: it creates
167
- `node_modules/xstate` and `node_modules/@sublang/playbook` beside the
168
- module as symlinks to the running host's own packages and prints one
169
- line naming what it linked
175
+ ### Piping a Spex update prompt
176
+
177
+ `spex scaffold --update` refreshes its scaffold before printing guidance and
178
+ a fenced reconciliation prompt. Force Spex's non-interactive agent-file
179
+ selection, capture its successful output, extract the first fenced prompt,
180
+ and pass only that prompt to Captain:
181
+
182
+ ```sh
183
+ update_output="$(spex scaffold --update </dev/null)" &&
184
+ printf '%s\n' "$update_output" |
185
+ awk '/^```$/{if (++n==2) exit; next} n==1' |
186
+ playbook run
187
+ ```
188
+
189
+ The capture prevents a failed Spex command from launching Playbook. Without
190
+ `--lang`, the first fenced block is the sole structure reconciliation or
191
+ legacy-migration prompt; a language switch adds a second translation prompt.
192
+
193
+ ### External playbooks and engine provisioning
194
+
195
+ Enable an external registry in the shared config and invoke its effective
196
+ slash command; a path-shaped `playbooks.<id>.from` is resolved relative to
197
+ the primary config file. Before either front end imports a configured
198
+ filesystem registry, the shared launcher checks whether that module can
199
+ resolve `xstate` and `@sublang/playbook/xstate-runtime`. When needed, it
200
+ creates engine symlinks beside the module and prints one provisioning line
170
201
  ([[playbook-cli-36](../specs/packages/playbook-cli.md#playbook-cli-36)],
171
202
  [DR-024](../specs/decisions/024-runtime-engine-provisioning.md)).
172
- A directory where the imports already resolve is never touched — a
173
- project-local install always wins — and `--no-provision` disables the
174
- mechanism entirely.
175
203
 
176
- If the module's directory is a git repository, add `node_modules/` to
177
- its `.gitignore` so the provisioned links never land in commits made by
178
- player agents working there.
204
+ A directory where both imports already resolve is untouched, and
205
+ `--no-provision` disables new links for either fresh front end. If the
206
+ module's directory is a git repository, add `node_modules/` to its
207
+ `.gitignore` so provisioned links never enter player commits.
179
208
 
180
- ### Resuming a parked run
209
+ ### Continuing a Captain session
181
210
 
182
- When the playbook stops to ask something, the run is parked, not lost:
183
- the question prints to stdout, the session is saved under
184
- `${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions/`, and stderr
185
- names the command that continues it.
211
+ Every successfully presented headless turn is stored under
212
+ `${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions/` before stdout.
213
+ Continue the newest logical session, or select the id returned by `--json`:
186
214
 
187
215
  ```sh
188
- playbook run resume 4f2c…9ab1 "keep the scope small; skip the docs"
189
- playbook run resume --last # most recently parked session; reply on stdin
216
+ playbook run --continue "keep the scope small; skip the docs"
217
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1
190
218
  ```
191
219
 
192
- A resumed run picks up exactly where it parked same session id, same
193
- workflow state, and each agent continues its own conversation — then
194
- prints the final output and exits `0`, or parks again and exits `3`. The
195
- lineup, options, and working directory are stored with the session, so
196
- `resume` takes no binding flags. In scripts, capture the session id from
197
- the `--json` envelope, like Claude Code's `session_id` or
198
- `codex exec resume`
220
+ A missing reply is read verbatim from stdin. Continuation restores the exact
221
+ compiled Captain conversation, engagement stack, nested child boundary,
222
+ mapped-player conversations, normalized execution config, and absolute
223
+ working directory. It does not reread current config, does not repeat a
224
+ settled or pending child start, and rejects `--with` because an existing
225
+ session's lineup is frozen
199
226
  ([[playbook-cli-22](../specs/packages/playbook-cli.md#playbook-cli-22)],
200
- [DR-014](../specs/decisions/014-durable-one-shot-run-sessions.md)).
227
+ [DR-031](../specs/decisions/031-shared-captain-session-front-ends.md)).
228
+
229
+ ### Recovering an uncertain turn
230
+
231
+ Before model work, the runner takes one exclusive session lease and writes an
232
+ uncertain marker. If the process is interrupted after effects may
233
+ have begun but before settlement is durable, ordinary continuation refuses
234
+ to guess. Choose explicitly:
235
+
236
+ ```sh
237
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --retry-uncertain
238
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --discard-uncertain
239
+ ```
240
+
241
+ Retry reads no input and reuses the byte-exact recorded turn; it may duplicate
242
+ external effects. Discard reads no input and runs no model: it restores the
243
+ exact prior settled boundary, or deletes a never-settled fresh session, while
244
+ abandoning the attempted work. Session files written by the removed direct
245
+ v6 runner are not shared-Captain sessions and cannot be continued.
@@ -3,7 +3,7 @@
3
3
 
4
4
  # Configuring agents
5
5
 
6
- `playbook` reads one config at
6
+ `playbook` and every fresh `playbook run` read one config at
7
7
  `${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`. The
8
8
  first launch seeds it from the bundled starter and prints the path;
9
9
  later launches reuse it untouched.
@@ -16,9 +16,10 @@ $EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml"
16
16
 
17
17
  The config is top-level (no `config:` wrapper): a `captain` agent (it
18
18
  runs the session Captain's hidden control calls, the hidden judge calls,
19
- and the replies you see in the Captain pane), optional
19
+ and the replies you see in the Captain pane or on headless stdout), optional
20
20
  `layout` / `notifications` / `theme`, and a `playbooks` map of enabled
21
- playbooks.
21
+ playbooks. Those three presentation fields apply only to interactive tmux;
22
+ headless runs ignore them.
22
23
 
23
24
  Each `captain` or `players.<role>` value is either an adapter shorthand
24
25
  (`claude`, `codex`) or a block carrying that agent's own `adapter`,
@@ -138,6 +139,7 @@ recursively, other values replace):
138
139
 
139
140
  ```sh
140
141
  playbook --with fast-lineup.yaml
142
+ playbook run --with fast-lineup.yaml "/code implement the approved change"
141
143
  ```
142
144
 
143
145
  ```yaml
@@ -165,25 +167,64 @@ the base Claude block had no reason to carry one.
165
167
 
166
168
  The global file is never modified, and `--with` is not forwarded to
167
169
  `tmux-play` ([[playbook-cli-25](../specs/packages/playbook-cli.md#playbook-cli-25)]).
170
+ Overlays apply only when creating a fresh session. A continued headless
171
+ session restores its frozen config and working directory and rejects `--with`.
168
172
 
169
- ## Defaults for `playbook run`
173
+ ## Shared headless configuration
170
174
 
171
- An optional top-level `run` block supplies the non-interactive host's
172
- lineup so you stop retyping flags `run.captain`, `run.players.<role>`,
173
- and a `run.player` catch-all for any other required role, each an
174
- `<adapter>[:<model>][@<effort>]` string. Flags win per role, and
175
- `resume` always keeps the lineup stored with the parked session
176
- ([[playbook-cli-28](../specs/packages/playbook-cli.md#playbook-cli-28)],
177
- [DR-017](../specs/decisions/017-run-defaults-config.md)).
175
+ Fresh interactive and headless sessions use the same top-level `captain`
176
+ and `playbooks` blocks. A headless session retains the normalized lineup,
177
+ catalog, options, and absolute working directory with every durable turn;
178
+ continuation does not reread the current file. Presentation-only fields are
179
+ inert headlessly.
180
+
181
+ ## External playbooks
182
+
183
+ `slc playbook my-workflow.md` emits `my-workflow.ts` beside its artifact
184
+ directory. That file already default-exports the registry manifest Playbook
185
+ requires: `id`, `command`, `intent`, `requiredRoleIds`, `validateOptions`,
186
+ and `createRuntime`. Enable it under `playbooks`, bind every role listed in
187
+ its `requiredRoleIds`, and invoke its effective slash command through Captain:
178
188
 
179
189
  ```yaml
180
- run:
181
- captain: claude:claude-opus-4-8@high
182
- players:
183
- coder: claude:claude-opus-4-8[1m]@xhigh
184
- reviewer: codex:gpt-5.5@xhigh
190
+ playbooks:
191
+ my-workflow:
192
+ from: /absolute/path/to/my-workflow.ts
193
+ players:
194
+ worker: claude
185
195
  ```
186
196
 
197
+ ```sh
198
+ playbook run "/my-workflow perform the task"
199
+ ```
200
+
201
+ A relative path-shaped `from` is resolved relative to the primary config
202
+ file, not the invocation directory; an absolute path is clearest for an SLC
203
+ entry emitted in a project working tree.
204
+ Before either front end imports a filesystem registry, the shared launcher
205
+ checks and, unless `--no-provision` is set, provisions its runtime engine
206
+ links as described in [Using the CLI](cli.md#external-playbooks-and-engine-provisioning).
207
+
208
+ ## Migrating direct runs from 6.x
209
+
210
+ The top-level `run:` block is deliberately rejected rather than silently
211
+ ignored or rewritten, because doing otherwise could change the agents after
212
+ an upgrade. Re-express `run.captain`, `run.players`, and former `--player`
213
+ bindings as the inline agent blocks above; the old `run.player` catch-all has
214
+ no shared equivalent, so configure every required role explicitly at
215
+ `playbooks.<id>.players.<role>`. Use a fresh `--with` fragment for temporary
216
+ lineup changes. Move former `--option` values into their `playbooks.<id>`
217
+ block, run from the desired directory instead of passing `--cwd`, enable a
218
+ former positional `<from>` as a configured registry, and quote or pipe one
219
+ `/command task` Boss message. Replace `resume` and `--last` with `--continue`
220
+ or `--session`.
221
+
222
+ The JSON response is now exactly `{ "sessionId": "…", "reply": "…" }`.
223
+ Released direct-run session records are not complete Captain sessions and
224
+ cannot be continued by the new host ([[playbook-cli-19](../specs/packages/playbook-cli.md#playbook-cli-19)],
225
+ [[playbook-cli-22](../specs/packages/playbook-cli.md#playbook-cli-22)],
226
+ [[playbook-cli-28](../specs/packages/playbook-cli.md#playbook-cli-28)]).
227
+
187
228
  ## Migrating from `profiles`
188
229
 
189
230
  Configs written before 3.0.0 carried a top-level `profiles` map. The
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sublang/playbook",
3
- "version": "6.0.0",
3
+ "version": "7.0.0",
4
4
  "type": "module",
5
5
  "description": "Composable XState v5 playbook runtime with compiled Captain, CODE, REVIEW, and DECIDE workflows driven by GEARS specs.",
6
6
  "license": "Apache-2.0",
@@ -67,7 +67,9 @@
67
67
  "reference/sdlc/code.playbook/code.gears.md",
68
68
  "reference/sdlc/code.playbook/playbook.config.template.yaml",
69
69
  "reference/sdlc/code.playbook/bin/playbook.js",
70
+ "reference/sdlc/code.playbook/bin/launch-config.js",
70
71
  "reference/sdlc/code.playbook/bin/run.js",
72
+ "reference/sdlc/code.playbook/bin/session-store.js",
71
73
  "reference/sdlc/code.playbook/bin/provision.js",
72
74
  "reference/sdlc/code.playbook/bin/adapter-sdk.js",
73
75
  "reference/sdlc/review.playbook/review.gears.md",