@sublang/playbook 4.0.0 → 6.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 +69 -122
- package/docs/assets/playbook-venn.svg +13 -0
- package/docs/cli.md +43 -26
- package/docs/configuration.md +63 -18
- package/docs/embedding.md +24 -16
- package/package.json +43 -22
- package/reference/sdlc/captain.md +70 -83
- package/reference/sdlc/captain.playbook/captain.fsm.d.ts +127 -142
- package/reference/sdlc/captain.playbook/captain.fsm.js +349 -470
- package/reference/sdlc/captain.playbook/captain.fsm.ts +535 -598
- package/reference/sdlc/captain.playbook/captain.gears.md +37 -41
- package/reference/sdlc/captain.playbook/captain.playbook.d.ts +90 -15
- package/reference/sdlc/captain.playbook/captain.playbook.js +466 -976
- package/reference/sdlc/captain.playbook/captain.playbook.ts +698 -1001
- package/reference/sdlc/code.md +55 -97
- package/reference/sdlc/code.playbook/code.fsm.d.ts +229 -94
- package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +26 -44
- package/reference/sdlc/code.playbook/code.fsm.introspect.js +61 -66
- package/reference/sdlc/code.playbook/code.fsm.introspect.ts +100 -149
- package/reference/sdlc/code.playbook/code.fsm.js +587 -1347
- package/reference/sdlc/code.playbook/code.fsm.ts +809 -1650
- package/reference/sdlc/code.playbook/code.gears.md +51 -263
- package/reference/sdlc/code.playbook/code.playbook.d.ts +8 -47
- package/reference/sdlc/code.playbook/code.playbook.js +69 -639
- package/reference/sdlc/code.playbook/code.playbook.ts +90 -850
- package/reference/sdlc/code.playbook/code.registry.d.ts +9 -25
- package/reference/sdlc/code.playbook/code.registry.js +20 -78
- package/reference/sdlc/code.playbook/code.registry.ts +58 -122
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +2 -0
- package/reference/sdlc/code.playbook/playbook-captain.js +1877 -251
- package/reference/sdlc/code.playbook/playbook-captain.ts +2385 -352
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +33 -22
- package/reference/sdlc/decide.md +54 -0
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +261 -0
- package/reference/sdlc/decide.playbook/decide.fsm.js +894 -0
- package/reference/sdlc/decide.playbook/decide.fsm.ts +1152 -0
- package/reference/sdlc/decide.playbook/decide.gears.md +88 -0
- package/reference/sdlc/decide.playbook/decide.playbook.d.ts +67 -0
- package/reference/sdlc/{discuss.playbook/discuss.playbook.js → decide.playbook/decide.playbook.js} +511 -370
- package/reference/sdlc/{discuss.playbook/discuss.playbook.ts → decide.playbook/decide.playbook.ts} +616 -451
- package/reference/sdlc/decide.playbook/decide.registry.d.ts +41 -0
- package/reference/sdlc/decide.playbook/decide.registry.js +60 -0
- package/reference/sdlc/decide.playbook/decide.registry.ts +125 -0
- package/reference/sdlc/review.md +81 -0
- package/reference/sdlc/review.playbook/review.fsm.d.ts +183 -0
- package/reference/sdlc/review.playbook/review.fsm.js +524 -0
- package/reference/sdlc/review.playbook/review.fsm.ts +652 -0
- package/reference/sdlc/review.playbook/review.gears.md +112 -0
- package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -0
- package/reference/sdlc/review.playbook/review.playbook.js +112 -0
- package/reference/sdlc/review.playbook/review.playbook.ts +201 -0
- package/reference/sdlc/review.playbook/review.registry.d.ts +43 -0
- package/reference/sdlc/review.playbook/review.registry.js +73 -0
- package/reference/sdlc/review.playbook/review.registry.ts +138 -0
- package/slc/gears2fsm.md +67 -6
- package/slc/link.md +339 -25
- package/slc/text2gears.md +22 -2
- package/src/runtime.d.ts +36 -1
- package/src/runtime.ts +59 -0
- package/src/xstate-playbook-runtime.d.ts +96 -7
- package/src/xstate-playbook-runtime.js +1018 -49
- package/src/xstate-playbook-runtime.ts +1283 -59
- package/src/xstate-runtime.js +25 -0
- package/src/xstate-runtime.ts +51 -0
- package/reference/sdlc/discuss.md +0 -93
- package/reference/sdlc/discuss.playbook/discuss.fsm.d.ts +0 -396
- package/reference/sdlc/discuss.playbook/discuss.fsm.js +0 -2067
- package/reference/sdlc/discuss.playbook/discuss.fsm.ts +0 -2465
- package/reference/sdlc/discuss.playbook/discuss.gears.md +0 -258
- package/reference/sdlc/discuss.playbook/discuss.playbook.d.ts +0 -113
- package/reference/sdlc/discuss.playbook/discuss.registry.d.ts +0 -58
- package/reference/sdlc/discuss.playbook/discuss.registry.js +0 -97
- package/reference/sdlc/discuss.playbook/discuss.registry.ts +0 -153
package/README.md
CHANGED
|
@@ -1,143 +1,101 @@
|
|
|
1
1
|
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
2
2
|
<!-- SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai> -->
|
|
3
3
|
|
|
4
|
-
#
|
|
4
|
+
# Playbook: Reliability Is All You Need
|
|
5
5
|
|
|
6
6
|
[](https://www.npmjs.com/package/@sublang/playbook)
|
|
7
7
|
[](https://nodejs.org/)
|
|
8
8
|
[](https://github.com/sublang-ai/playbook/actions/workflows/ci.yml)
|
|
9
9
|
|
|
10
|
-
_Skills made reliable through state machines and
|
|
10
|
+
_Skills made reliable through state machines and diverse LLMs._
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
AI agents per a spec written in plain prose. Instead of a free-form LLM
|
|
15
|
-
deciding what to do next, an explicit finite state machine drives the
|
|
16
|
-
workflow, every agent-invoking state pinned 1:1 to a human-readable spec
|
|
17
|
-
item and contract-tested.
|
|
12
|
+
Natural-language skills are flexible and easy to use, but less predictable than scripted workflows, especially on long-horizon jobs.
|
|
13
|
+
And even the best LLMs make mistakes, partly because plain-language descriptions rarely eliminate vagueness or guarantee completeness.
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
SubLang Playbook addresses both:
|
|
16
|
+
|
|
17
|
+
- The companion [SLC compiler](https://github.com/sublang-ai/slc) turns plain-language procedures, such as a `SKILL.md`, into playbooks with deterministic state-machine control flow.
|
|
18
|
+
- A playbook can assign different agents or LLMs to its steps and have them review and challenge one another, helping catch mistakes before delivery.
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
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
|
+
|
|
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.
|
|
26
25
|
|
|
27
26
|
## Quick start
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
or `ANTHROPIC_API_KEY`, and signed-in
|
|
34
|
-
[Codex CLI](https://github.com/openai/codex) or `OPENAI_API_KEY`.
|
|
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
|
+
CODE and DECIDE call REVIEW as a nested playbook.
|
|
30
|
+
|
|
31
|
+
The interactive starter config uses Claude as both Captain and Coder, and Codex as Reviewer.
|
|
35
32
|
|
|
36
33
|
```sh
|
|
37
|
-
npm install -g @sublang/playbook
|
|
34
|
+
npm install -g @sublang/playbook
|
|
35
|
+
npm install -g @anthropic-ai/claude-agent-sdk @openai/codex-sdk
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Custom configurations need the SDKs required by their providers; see [Configuring agents](docs/configuration.md).
|
|
39
|
+
If an SDK is missing or older than cligent supports, Playbook prints the pinned install command before launching anything; see [Installing agent SDKs](docs/cli.md#installing-agent-sdks) for upgrades, `npx`, and other adapters.
|
|
40
|
+
|
|
41
|
+
Prerequisites:
|
|
42
|
+
|
|
43
|
+
- Node.js >= 20.6.0
|
|
44
|
+
- `tmux` and [`glow`](https://github.com/charmbracelet/glow#installation) on `PATH`
|
|
45
|
+
- Authenticated [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) or `ANTHROPIC_API_KEY`
|
|
46
|
+
- Authenticated [Codex CLI](https://github.com/openai/codex) or `OPENAI_API_KEY`
|
|
47
|
+
|
|
48
|
+
CODE works in the current directory and can edit and commit autonomously, so use a clean branch or worktree.
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
cd /path/to/your/project
|
|
38
52
|
playbook
|
|
39
53
|
```
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
[DR-027](specs/decisions/027-runtime-compatibility-from-cligent.md)).
|
|
52
|
-
|
|
53
|
-
Upgrading from 3.1.0 or earlier? Use the same full line — npm removes
|
|
54
|
-
the SDK copies those releases bundled when it upgrades the package, so
|
|
55
|
-
upgrading `@sublang/playbook` alone leaves no agent SDK installed.
|
|
56
|
-
Running via `npx` instead? Name each SDK as a sibling package of the
|
|
57
|
-
same invocation (`npx -y -p @sublang/playbook -p <sdk> playbook`) — no
|
|
58
|
-
install command reaches npx's ephemeral tree; see
|
|
59
|
-
[docs/cli.md](docs/cli.md).
|
|
60
|
-
|
|
61
|
-
The first launch seeds a commented config at
|
|
62
|
-
`${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`,
|
|
63
|
-
composes a `tmux-play` config, checks the declared adapters, and opens
|
|
64
|
-
the session. Then type a task, or `/code <task>` to select the CODE
|
|
65
|
-
playbook directly.
|
|
66
|
-
|
|
67
|
-
Every agent carries its own settings, so retuning one player never
|
|
68
|
-
changes another:
|
|
69
|
-
|
|
70
|
-
```yaml
|
|
71
|
-
playbooks:
|
|
72
|
-
code:
|
|
73
|
-
from: '@sublang/playbook/code/registry'
|
|
74
|
-
players:
|
|
75
|
-
coder: { adapter: claude, model: 'claude-opus-4-8[1m]', effort: xhigh }
|
|
76
|
-
reviewer: { adapter: codex, model: gpt-5.5, effort: xhigh }
|
|
55
|
+
Type a task, enter `/code <task>` for implementation, or enter
|
|
56
|
+
`/decide <question>` for an independently proposed and reviewed decision.
|
|
57
|
+
|
|
58
|
+
On first launch, Playbook writes its config to `${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`.
|
|
59
|
+
|
|
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:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
playbook run @sublang/playbook/review/registry "review the latest commit" --player reviewer=codex --json
|
|
77
65
|
```
|
|
78
66
|
|
|
79
|
-
|
|
80
|
-
|
|
67
|
+
CODE and DECIDE require interactive `playbook` because the one-shot host does not drive nested calls.
|
|
68
|
+
|
|
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.
|
|
70
|
+
|
|
71
|
+
## Create your own playbook
|
|
72
|
+
|
|
73
|
+
The separate [SLC compiler](https://github.com/sublang-ai/slc) requires Node.js >= 23.6 and compiles a plain-language `.md` or `.txt` procedure:
|
|
81
74
|
|
|
82
75
|
```sh
|
|
83
|
-
|
|
76
|
+
npm install -g @sublang/slc
|
|
77
|
+
slc playbook my-workflow.md
|
|
78
|
+
playbook run ./my-workflow.ts "<your task>"
|
|
84
79
|
```
|
|
85
80
|
|
|
86
|
-
-
|
|
87
|
-
exit codes, and resuming a parked `run`.
|
|
88
|
-
- **[docs/configuration.md](docs/configuration.md)** — the config file,
|
|
89
|
-
per-launch `--with` overlays, and choosing the Captain agent.
|
|
90
|
-
- **[docs/embedding.md](docs/embedding.md)** — the six-port runtime
|
|
91
|
-
contract for hosts other than `tmux-play`.
|
|
92
|
-
|
|
93
|
-
> **Current release:** 4.0.0. The composed system — the compiled default
|
|
94
|
-
> Captain, CODE and DISCUSS, nested playbook calls, script actors and the
|
|
95
|
-
> GEARS optimize pass, the semver-stable six-port runtime contract, and
|
|
96
|
-
> non-interactive `playbook run` with parked-session resume — landed in
|
|
97
|
-
> 1.0.0. Since then, `playbook run` gained defaults in the user config,
|
|
98
|
-
> 3.0.0 replaced the top-level `profiles` map with inline agent settings
|
|
99
|
-
> (existing configs migrate themselves on the next launch), 3.1.0
|
|
100
|
-
> added the linked-artifact/engine compatibility check, and 4.0.0 made
|
|
101
|
-
> the agent SDKs optional — an install carries only the vendors you name
|
|
102
|
-
> — with which versions work now owned and published by cligent. See the
|
|
103
|
-
> [CHANGELOG](CHANGELOG.md).
|
|
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.
|
|
104
82
|
|
|
105
83
|
## How it compiles
|
|
106
84
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
1. **text → GEARS** ([slc/text2gears.md](slc/text2gears.md)) —
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
can be visualized and simulated with the bundled
|
|
116
|
-
[XState sketch visualizer](views/sketch).
|
|
117
|
-
3. **FSM → runtime** ([slc/link.md](slc/link.md)) — a host-agnostic
|
|
118
|
-
module that drives Boss turns through ports the host wires up.
|
|
119
|
-
|
|
120
|
-
Between the first two, [slc/optimize.md](slc/optimize.md) may rewrite a
|
|
121
|
-
deterministic mechanical gear — canonically git repository setup — into a
|
|
122
|
-
*script item* the runtime executes directly, with no agent call.
|
|
123
|
-
Unoptimized compiles are byte-identical, so the pass is opt-in.
|
|
124
|
-
|
|
125
|
-
The repository carries end-to-end worked examples: the generic default
|
|
126
|
-
Captain from [`reference/sdlc/captain.md`](reference/sdlc/captain.md),
|
|
127
|
-
CODE — a coder / reviewer / committer loop — from
|
|
128
|
-
[`reference/sdlc/code.md`](reference/sdlc/code.md), and DISCUSS — two
|
|
129
|
-
agents converging on spec items — from
|
|
130
|
-
[`reference/sdlc/discuss.md`](reference/sdlc/discuss.md). Together they
|
|
131
|
-
show direct Captain work, sequential nested playbook calls, and parallel
|
|
132
|
-
players. Compiled artifacts live beside each source in
|
|
133
|
-
`<basename>.playbook/`, the [slc](https://github.com/sublang-ai/slc)
|
|
134
|
-
pipeline's output directory.
|
|
85
|
+
SLC's `playbook` pipeline has three phases:
|
|
86
|
+
|
|
87
|
+
1. **text → GEARS** ([slc/text2gears.md](slc/text2gears.md)) — makes each behavior explicit with its trigger, actor, prompt, and outcomes.
|
|
88
|
+
2. **GEARS → FSM** ([slc/gears2fsm.md](slc/gears2fsm.md)) — maps each item to an XState state that invokes the Captain, a player, another playbook, or a local script.
|
|
89
|
+
3. **FSM → runtime** ([slc/link.md](slc/link.md)) — links the machine to a host-independent interface for user input, agent calls, status, and telemetry.
|
|
90
|
+
|
|
91
|
+
The default [optimization pass](slc/optimize.md) replaces eligible mechanical steps with local shell scripts; `--no-optimize` skips it.
|
|
92
|
+
Inspect the complete [Captain](reference/sdlc/captain.md), [CODE](reference/sdlc/code.md), [REVIEW](reference/sdlc/review.md), and [DECIDE](reference/sdlc/decide.md) examples.
|
|
135
93
|
|
|
136
94
|
## Contributing
|
|
137
95
|
|
|
138
96
|
We welcome contributions of all kinds.
|
|
139
97
|
|
|
140
|
-
- 🌟 Star our repo if you find
|
|
98
|
+
- 🌟 Star our repo if you find Playbook useful.
|
|
141
99
|
- [Open an issue](https://github.com/sublang-ai/playbook/issues) for bugs or feature requests.
|
|
142
100
|
- [Open a PR](https://github.com/sublang-ai/playbook/pulls) for fixes or improvements.
|
|
143
101
|
- Discuss on [Discord](https://discord.gg/XxTPjNqy9g) for support or new ideas.
|
|
@@ -153,20 +111,9 @@ pnpm test
|
|
|
153
111
|
pnpm playbook # drive a Boss turn against the source tree
|
|
154
112
|
```
|
|
155
113
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
produces ([RELEASE-11](specs/dev/release.md#release-11)).
|
|
160
|
-
|
|
161
|
-
playbook is itself spec-driven: the compiler phases are specs in
|
|
162
|
-
[`slc/`](slc), and the reference playbooks are regenerated from their
|
|
163
|
-
prose sources. Edit a source, recompile gears then FSM and runtime into
|
|
164
|
-
its artifact directory, sync tests and downstream specs until
|
|
165
|
-
`pnpm test` is green, and commit with co-author trailers per
|
|
166
|
-
[`specs/dev/git.md`](specs/dev/git.md). The gears↔FSM contract
|
|
167
|
-
([the PLAYBOOK dev items](specs/dev/playbook.md)) and the runtime
|
|
168
|
-
contract ([the PBRT dev items](specs/dev/playbook-runtime.md)) are
|
|
169
|
-
pinned in [`specs/dev/`](specs/dev) and verified by the test suite.
|
|
114
|
+
Playbook is itself spec-driven: the compiler phases are specs in [`slc/`](slc), and the reference playbooks are regenerated from their prose sources.
|
|
115
|
+
Edit a source, regenerate its GEARS, FSM, and runtime artifacts, sync the tests and downstream specs until `pnpm test` passes, and commit with co-author trailers per [`specs/packages/git.md`](specs/packages/git.md).
|
|
116
|
+
The gears↔FSM contract ([the playbook package](specs/packages/playbook.md)) and runtime contract ([the playbook-runtime package](specs/packages/playbook-runtime.md)) are pinned in [`specs/packages/`](specs/packages) and verified by the test suite.
|
|
170
117
|
|
|
171
118
|
## License
|
|
172
119
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
+
<!-- SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai> -->
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 415 124" width="415" height="124" role="img" aria-labelledby="venn-title" font-family="-apple-system,'Segoe UI',Helvetica,Arial,sans-serif">
|
|
4
|
+
<title id="venn-title">Skills are flexible, workflows are deterministic; Playbook sits in the intersection and is both.</title>
|
|
5
|
+
<ellipse cx="136" cy="62" rx="126" ry="56" fill="#e5484d" fill-opacity="0.06" stroke="#e5484d" stroke-width="2.2"/>
|
|
6
|
+
<ellipse cx="279" cy="62" rx="126" ry="56" fill="#4285d6" fill-opacity="0.06" stroke="#4285d6" stroke-width="2.2"/>
|
|
7
|
+
<path d="M 207.5 15.9 A 126 56 0 0 1 207.5 108.1 A 126 56 0 0 1 207.5 15.9 Z" fill="#b06bff" fill-opacity="0.08"/>
|
|
8
|
+
<text x="91" y="42.7" text-anchor="middle" font-size="12" font-weight="600" letter-spacing="1" fill="#e5484d">FLEXIBLE</text>
|
|
9
|
+
<text x="91" y="71.7" text-anchor="middle" font-size="16" font-weight="600" fill="#e5484d">Skill</text>
|
|
10
|
+
<text x="324" y="42.7" text-anchor="middle" font-size="12" font-weight="600" letter-spacing="1" fill="#4285d6">DETERMINISTIC</text>
|
|
11
|
+
<text x="324" y="71.7" text-anchor="middle" font-size="16" font-weight="600" fill="#4285d6">Workflow</text>
|
|
12
|
+
<text x="207.5" y="71.7" text-anchor="middle" font-size="16" font-weight="700" fill="#b06bff">Playbook</text>
|
|
13
|
+
</svg>
|
package/docs/cli.md
CHANGED
|
@@ -50,7 +50,7 @@ runtime is reported as not installed; a stale one with its installed
|
|
|
50
50
|
and required versions, never as absent. Either way the remedy printed
|
|
51
51
|
is cligent's pinned install, `npm install -g <package>@<version>`, so
|
|
52
52
|
following it cannot install a version the gate refuses again
|
|
53
|
-
([
|
|
53
|
+
([[playbook-cli-40](../specs/packages/playbook-cli.md#playbook-cli-40)]).
|
|
54
54
|
|
|
55
55
|
## Interactive
|
|
56
56
|
|
|
@@ -81,39 +81,56 @@ The command resolves its config (seeding it on first run), composes a
|
|
|
81
81
|
`tmux-play` config, checks adapter readiness, and launches. It exits
|
|
82
82
|
with tmux-play's status, re-raises a terminating signal on itself, and
|
|
83
83
|
exits `127` when it cannot launch at all
|
|
84
|
-
([
|
|
85
|
-
[
|
|
84
|
+
([[playbook-cli-1](../specs/packages/playbook-cli.md#playbook-cli-1)],
|
|
85
|
+
[[playbook-cli-2](../specs/packages/playbook-cli.md#playbook-cli-2)]).
|
|
86
86
|
|
|
87
87
|
### Running a Boss turn
|
|
88
88
|
|
|
89
|
-
The Boss pane starts at the Playbook Captain shell
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
a
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
89
|
+
The Boss pane starts at the Playbook Captain shell, where the session
|
|
90
|
+
Captain runs for the whole session and sees every turn. Use `/code`,
|
|
91
|
+
`/review`, or `/decide` followed by a task to select one of the bundled
|
|
92
|
+
playbooks explicitly. A registered command resolves deterministically,
|
|
93
|
+
with no model call parsing it: at idle it starts that playbook, at its
|
|
94
|
+
own leaf it delivers the rest of the line, an enabled command absent
|
|
95
|
+
from the active path switches to it, and a bare command answers with
|
|
96
|
+
status or a clarification instead of restarting anything. Type ordinary
|
|
97
|
+
text and the session Captain decides the turn instead: it chats back,
|
|
98
|
+
starts or switches a playbook, hands the text to the working playbook,
|
|
99
|
+
dismisses it, or applies one recovery action the running playbook
|
|
100
|
+
currently offers. It never does the specialized work itself, and a
|
|
101
|
+
conversational turn — including a progress or status question — leaves
|
|
102
|
+
the engagement, its parked state, and any pending player question
|
|
103
|
+
untouched
|
|
104
|
+
([[playbook-captain-1](../specs/packages/playbook-captain.md#playbook-captain-1)],
|
|
105
|
+
[[playbook-captain-2](../specs/packages/playbook-captain.md#playbook-captain-2)]).
|
|
106
|
+
|
|
107
|
+
The current CODE, REVIEW, and DECIDE workflows take their deterministic
|
|
108
|
+
initial event from the selecting Boss turn. CODE and DECIDE then call
|
|
109
|
+
REVIEW as a nested playbook: an exact same-name child role continues the
|
|
110
|
+
ancestor's player pane and backend conversation, while any additional
|
|
111
|
+
role uses REVIEW's configured fallback. When a player surfaces a
|
|
112
|
+
clarifying question the FSM parks, the pane shows the question, and a
|
|
113
|
+
judge classifies your next turn as its reply or a fresh directive that
|
|
114
|
+
abandons it
|
|
115
|
+
([[playbook-runtime-2](../specs/packages/playbook-runtime.md#playbook-runtime-2)]).
|
|
104
116
|
|
|
105
117
|
The Captain pane shows start/stop/finished status with `◇` lines and
|
|
106
118
|
streams progress with captain-speech classification and questions
|
|
107
|
-
([
|
|
108
|
-
prompts ride their own panes.
|
|
119
|
+
([[playbook-runtime-3](../specs/packages/playbook-runtime.md#playbook-runtime-3)]), while player
|
|
120
|
+
prompts ride their own panes. A turn that actually did something ends
|
|
121
|
+
with one Captain reply summarizing what changed, composed only from that
|
|
122
|
+
turn's reported outcome; a turn that changed nothing ends with an
|
|
123
|
+
ordinary reply and no saved-counts line
|
|
124
|
+
([[playbook-captain-19](../specs/packages/playbook-captain.md#playbook-captain-19)]).
|
|
109
125
|
|
|
110
126
|
## Non-interactive
|
|
111
127
|
|
|
112
128
|
`playbook run <from> [task]` runs one playbook once, without tmux-play
|
|
113
|
-
and without
|
|
129
|
+
and without an interactive config entry. For example, run REVIEW
|
|
130
|
+
directly against the latest commit:
|
|
114
131
|
|
|
115
132
|
```sh
|
|
116
|
-
playbook run @sublang/playbook/
|
|
133
|
+
playbook run @sublang/playbook/review/registry "review the latest commit" \
|
|
117
134
|
--player coder=claude --player reviewer=codex --cwd ./my-repo
|
|
118
135
|
```
|
|
119
136
|
|
|
@@ -124,7 +141,7 @@ intents the same way you would to `claude -p` or `codex exec`.
|
|
|
124
141
|
| --- | --- |
|
|
125
142
|
| `--player <role>=<agent>` | bind a required role |
|
|
126
143
|
| `--captain <agent>` | set the captain/judge agent |
|
|
127
|
-
| `--option <key>=<value>` | a playbook option (
|
|
144
|
+
| `--option <key>=<value>` | a registry-defined playbook option (none in the current bundled workflows) |
|
|
128
145
|
| `--cwd <dir>` | the agents' working directory |
|
|
129
146
|
| `--json` | one envelope: `outcome`, `sessionId`, output or questions |
|
|
130
147
|
| `--no-provision` | never create engine links beside a filesystem `<from>` |
|
|
@@ -138,7 +155,7 @@ config supplies [run defaults](configuration.md#defaults-for-playbook-run).
|
|
|
138
155
|
|
|
139
156
|
Exit codes: `0` terminal, `1` bad argument or module, `2` failure, `3`
|
|
140
157
|
the playbook needs a Boss reply
|
|
141
|
-
([
|
|
158
|
+
([[playbook-cli-18](../specs/packages/playbook-cli.md#playbook-cli-18)]).
|
|
142
159
|
|
|
143
160
|
### Engine provisioning
|
|
144
161
|
|
|
@@ -150,7 +167,7 @@ install with no project-local packages —
|
|
|
150
167
|
`node_modules/xstate` and `node_modules/@sublang/playbook` beside the
|
|
151
168
|
module as symlinks to the running host's own packages and prints one
|
|
152
169
|
line naming what it linked
|
|
153
|
-
([
|
|
170
|
+
([[playbook-cli-36](../specs/packages/playbook-cli.md#playbook-cli-36)],
|
|
154
171
|
[DR-024](../specs/decisions/024-runtime-engine-provisioning.md)).
|
|
155
172
|
A directory where the imports already resolve is never touched — a
|
|
156
173
|
project-local install always wins — and `--no-provision` disables the
|
|
@@ -179,5 +196,5 @@ lineup, options, and working directory are stored with the session, so
|
|
|
179
196
|
`resume` takes no binding flags. In scripts, capture the session id from
|
|
180
197
|
the `--json` envelope, like Claude Code's `session_id` or
|
|
181
198
|
`codex exec resume`
|
|
182
|
-
([
|
|
199
|
+
([[playbook-cli-22](../specs/packages/playbook-cli.md#playbook-cli-22)],
|
|
183
200
|
[DR-014](../specs/decisions/014-durable-one-shot-run-sessions.md)).
|
package/docs/configuration.md
CHANGED
|
@@ -15,7 +15,8 @@ $EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml"
|
|
|
15
15
|
## Anatomy
|
|
16
16
|
|
|
17
17
|
The config is top-level (no `config:` wrapper): a `captain` agent (it
|
|
18
|
-
runs
|
|
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
20
|
`layout` / `notifications` / `theme`, and a `playbooks` map of enabled
|
|
20
21
|
playbooks.
|
|
21
22
|
|
|
@@ -32,8 +33,8 @@ Within a `playbooks.<id>` block, `from` (the registry module), `command`
|
|
|
32
33
|
every other key is that playbook's option slice. The launcher injects
|
|
33
34
|
the rest — you do not write host wiring by hand.
|
|
34
35
|
|
|
35
|
-
The seeded config runs
|
|
36
|
-
on GPT-5.5:
|
|
36
|
+
The seeded config runs each Coder on Claude Opus 4.8 1m and each
|
|
37
|
+
Reviewer on GPT-5.5:
|
|
37
38
|
|
|
38
39
|
```yaml
|
|
39
40
|
captain:
|
|
@@ -53,6 +54,16 @@ playbooks:
|
|
|
53
54
|
effort: xhigh
|
|
54
55
|
permissions:
|
|
55
56
|
mode: auto # protected auto mode for the Claude Coder
|
|
57
|
+
|
|
58
|
+
review:
|
|
59
|
+
from: '@sublang/playbook/review/registry'
|
|
60
|
+
players:
|
|
61
|
+
coder:
|
|
62
|
+
adapter: claude
|
|
63
|
+
model: claude-opus-4-8[1m]
|
|
64
|
+
effort: xhigh
|
|
65
|
+
permissions:
|
|
66
|
+
mode: auto
|
|
56
67
|
reviewer:
|
|
57
68
|
adapter: codex
|
|
58
69
|
model: gpt-5.5
|
|
@@ -61,24 +72,57 @@ playbooks:
|
|
|
61
72
|
mode: auto
|
|
62
73
|
writablePaths:
|
|
63
74
|
- .git # allow git metadata writes under Codex auto mode
|
|
64
|
-
|
|
75
|
+
|
|
76
|
+
decide:
|
|
77
|
+
from: '@sublang/playbook/decide/registry'
|
|
78
|
+
players:
|
|
79
|
+
coder:
|
|
80
|
+
adapter: claude
|
|
81
|
+
model: claude-opus-4-8[1m]
|
|
82
|
+
effort: xhigh
|
|
83
|
+
permissions:
|
|
84
|
+
mode: auto
|
|
85
|
+
reviewer:
|
|
86
|
+
adapter: codex
|
|
87
|
+
model: gpt-5.5
|
|
88
|
+
effort: xhigh
|
|
89
|
+
permissions:
|
|
90
|
+
mode: auto
|
|
91
|
+
writablePaths:
|
|
92
|
+
- .git
|
|
65
93
|
```
|
|
66
94
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
[
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
95
|
+
The current bundled workflows accept no workflow-specific options.
|
|
96
|
+
Each role's per-run prompt names its pinned `model`, else its `adapter`
|
|
97
|
+
([[playbook-runtime-4](../specs/packages/playbook-runtime.md#playbook-runtime-4)]),
|
|
98
|
+
so commit trailers credit the concrete model rather than the adapter
|
|
99
|
+
family.
|
|
100
|
+
|
|
101
|
+
## Nested roles and sessions
|
|
102
|
+
|
|
103
|
+
The launcher creates a namespaced fallback player for every configured
|
|
104
|
+
playbook role, but a nested call maps an exact same-name role to the
|
|
105
|
+
nearest ancestor's effective player and backend conversation. CODE's
|
|
106
|
+
nested REVIEW therefore continues CODE's `coder` and uses REVIEW's
|
|
107
|
+
configured `reviewer`; DECIDE's nested REVIEW continues both of
|
|
108
|
+
DECIDE's roles. A standalone REVIEW starts with REVIEW's own configured
|
|
109
|
+
players, and every new root engagement starts fresh
|
|
110
|
+
([DR-030](../specs/decisions/030-shared-mapped-player-continuity.md)).
|
|
111
|
+
|
|
112
|
+
The separate fallback entries are still required because tmux creates
|
|
113
|
+
its roster at launch time. The host changes which existing panes are
|
|
114
|
+
visible as the active nested leaf changes; it does not create a new
|
|
115
|
+
host player or backend agent session for a mapped role.
|
|
73
116
|
|
|
74
117
|
## Choosing the Captain agent
|
|
75
118
|
|
|
76
|
-
|
|
77
|
-
|
|
119
|
+
Every session-Captain call and adjudication call is hidden and runs
|
|
120
|
+
tool-free, which is what keeps the Captain deciding and reporting
|
|
121
|
+
instead of doing the work itself. Claude enforces
|
|
78
122
|
that at the provider level. The Codex adapter cannot — it rejects any
|
|
79
123
|
tool list — so a `captain:` on `codex` falls back to a prompt-level
|
|
80
124
|
restriction
|
|
81
|
-
([DR-013
|
|
125
|
+
([DR-013](../specs/decisions/013-routing-only-captain-control.md) A1).
|
|
82
126
|
Codex remains a good choice for *players*, where full tools are wanted.
|
|
83
127
|
|
|
84
128
|
Adapter readiness is intentionally light: `claude` is ready with local
|
|
@@ -107,8 +151,8 @@ playbooks:
|
|
|
107
151
|
effort: medium
|
|
108
152
|
permissions:
|
|
109
153
|
mode: auto
|
|
110
|
-
#
|
|
111
|
-
#
|
|
154
|
+
# CODE's Coder commits, so Codex needs the `.git` grant to write
|
|
155
|
+
# repository metadata.
|
|
112
156
|
writablePaths:
|
|
113
157
|
- .git
|
|
114
158
|
```
|
|
@@ -120,7 +164,7 @@ role switched to `codex` needs its own `writablePaths` grant, because
|
|
|
120
164
|
the base Claude block had no reason to carry one.
|
|
121
165
|
|
|
122
166
|
The global file is never modified, and `--with` is not forwarded to
|
|
123
|
-
`tmux-play` ([
|
|
167
|
+
`tmux-play` ([[playbook-cli-25](../specs/packages/playbook-cli.md#playbook-cli-25)]).
|
|
124
168
|
|
|
125
169
|
## Defaults for `playbook run`
|
|
126
170
|
|
|
@@ -129,7 +173,7 @@ lineup so you stop retyping flags — `run.captain`, `run.players.<role>`,
|
|
|
129
173
|
and a `run.player` catch-all for any other required role, each an
|
|
130
174
|
`<adapter>[:<model>][@<effort>]` string. Flags win per role, and
|
|
131
175
|
`resume` always keeps the lineup stored with the parked session
|
|
132
|
-
([
|
|
176
|
+
([[playbook-cli-28](../specs/packages/playbook-cli.md#playbook-cli-28)],
|
|
133
177
|
[DR-017](../specs/decisions/017-run-defaults-config.md)).
|
|
134
178
|
|
|
135
179
|
```yaml
|
|
@@ -137,6 +181,7 @@ run:
|
|
|
137
181
|
captain: claude:claude-opus-4-8@high
|
|
138
182
|
players:
|
|
139
183
|
coder: claude:claude-opus-4-8[1m]@xhigh
|
|
184
|
+
reviewer: codex:gpt-5.5@xhigh
|
|
140
185
|
```
|
|
141
186
|
|
|
142
187
|
## Migrating from `profiles`
|
|
@@ -151,7 +196,7 @@ do by hand.
|
|
|
151
196
|
|
|
152
197
|
For a one-off, pass a raw `tmux-play` config explicitly. This bypasses
|
|
153
198
|
the seed, composition, and readiness gate, forwarding arguments to
|
|
154
|
-
`tmux-play` verbatim ([
|
|
199
|
+
`tmux-play` verbatim ([[playbook-cli-1](../specs/packages/playbook-cli.md#playbook-cli-1)]):
|
|
155
200
|
|
|
156
201
|
```sh
|
|
157
202
|
playbook --config ./tmux-play.config.yaml
|
package/docs/embedding.md
CHANGED
|
@@ -8,7 +8,7 @@ one host, and [spex](https://github.com/sublang-ai/spex) (the desktop
|
|
|
8
8
|
app) is another. This guide shows how to wire a playbook runtime into
|
|
9
9
|
your own host.
|
|
10
10
|
|
|
11
|
-
> **Release note:** this guide targets the semver-stable
|
|
11
|
+
> **Release note:** this guide targets the current semver-stable six-port
|
|
12
12
|
> contract; see the [CHANGELOG](../CHANGELOG.md) for migration details.
|
|
13
13
|
|
|
14
14
|
## The runtime contract
|
|
@@ -17,11 +17,11 @@ The port and runtime contracts live in the type-only module
|
|
|
17
17
|
[`@sublang/playbook/runtime`](../src/runtime.ts) — a public,
|
|
18
18
|
semver-stable surface (`PlayerResult`, `PlaybookPorts`,
|
|
19
19
|
`PlaybookRuntime`, `PlaybookSession`, `PlayerCallOptions`,
|
|
20
|
-
`
|
|
21
|
-
`PlaybookRuntimeFactory`) that imports no CODE
|
|
22
|
-
satisfies it once and inherits every playbook.
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
`PlayerSessionStore`, `CaptainCallOptions`, `CaptainResult`,
|
|
21
|
+
`PlaybookTraceEvent`, and `PlaybookRuntimeFactory`) that imports no CODE
|
|
22
|
+
or FSM types, so a host satisfies it once and inherits every playbook.
|
|
23
|
+
The generated CODE, REVIEW, and DECIDE modules re-export their shared
|
|
24
|
+
runtime contract types from their public `playbook` subpaths;
|
|
25
25
|
`PlaybookRuntimeFactory` is available from `@sublang/playbook/runtime`.
|
|
26
26
|
|
|
27
27
|
Generated linked runtimes reuse the XState integration engine exposed
|
|
@@ -32,7 +32,7 @@ nested-playbook bridge.
|
|
|
32
32
|
## Constructing a runtime against your own ports
|
|
33
33
|
|
|
34
34
|
```ts
|
|
35
|
-
import createPlaybookRuntime from '@sublang/playbook/
|
|
35
|
+
import createPlaybookRuntime from '@sublang/playbook/review/playbook';
|
|
36
36
|
import type {
|
|
37
37
|
CaptainCallOptions,
|
|
38
38
|
CaptainResult,
|
|
@@ -104,20 +104,20 @@ const ports: PlaybookPorts = {
|
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
const runtime = createPlaybookRuntime({
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
coderLlm: 'claude-opus-4-8[1m]',
|
|
108
|
+
reviewerLlm: 'gpt-5.5',
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
const playbookSessionId = randomUUID();
|
|
112
112
|
await runtime.init({
|
|
113
113
|
sessionId: playbookSessionId,
|
|
114
|
-
playbookId: '
|
|
114
|
+
playbookId: 'review',
|
|
115
115
|
rootSessionId: playbookSessionId,
|
|
116
116
|
depth: 0,
|
|
117
117
|
ports,
|
|
118
118
|
});
|
|
119
119
|
await runtime.handleBossInput({
|
|
120
|
-
text: '
|
|
120
|
+
text: 'Review the latest commit against the requested intent',
|
|
121
121
|
signal: new AbortController().signal,
|
|
122
122
|
});
|
|
123
123
|
await runtime.dispose();
|
|
@@ -129,11 +129,19 @@ Every init-to-dispose lifecycle is one playbook session. Its
|
|
|
129
129
|
`playbook.trace` telemetry carries that immutable ID plus a contiguous
|
|
130
130
|
sequence across exact Boss input, judge/player calls, FSM transitions,
|
|
131
131
|
visible Captain work, nested playbook calls, status, settlement, and
|
|
132
|
-
disposal.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
disposal. Without `PlaybookSession.playerSessions`, a standalone runtime
|
|
133
|
+
starts each player fresh and privately retains the latest opaque
|
|
134
|
+
`resumeToken` its adapter returned.
|
|
135
|
+
|
|
136
|
+
A composing host can instead supply a frame-local `PlayerSessionStore`
|
|
137
|
+
view over one root-owned continuation map. The host maps each local role
|
|
138
|
+
to its effective binding, so a nested exact same-name role selects and
|
|
139
|
+
updates the ancestor conversation while an unmatched child role gets
|
|
140
|
+
its own binding. Child return or disposal does not clear the root's
|
|
141
|
+
token, and a new root engagement starts fresh. Trace data and tokens
|
|
142
|
+
never enter Boss-visible status text. Because trace observers do receive
|
|
143
|
+
opaque resume tokens, persisted traces should be protected as sensitive
|
|
144
|
+
data.
|
|
137
145
|
|
|
138
146
|
See
|
|
139
147
|
[`code.playbook.test.ts`](../reference/sdlc/code.playbook/code.playbook.test.ts)
|