@sublang/playbook 0.8.0 → 1.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 +243 -193
- package/package.json +52 -17
- package/reference/sdlc/captain.md +102 -0
- package/reference/sdlc/captain.playbook/captain.fsm.d.ts +227 -0
- package/reference/sdlc/captain.playbook/captain.fsm.js +628 -0
- package/reference/sdlc/captain.playbook/captain.fsm.ts +851 -0
- package/reference/sdlc/captain.playbook/captain.gears.md +60 -0
- package/reference/sdlc/captain.playbook/captain.playbook.d.ts +23 -0
- package/reference/sdlc/captain.playbook/captain.playbook.js +1053 -0
- package/reference/sdlc/captain.playbook/captain.playbook.ts +1144 -0
- package/reference/sdlc/code.playbook/bin/playbook.js +580 -0
- package/reference/sdlc/code.playbook/bin/run.js +893 -0
- package/reference/sdlc/code.playbook/code.fsm.d.ts +11 -4
- package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +2 -2
- package/reference/sdlc/code.playbook/code.fsm.introspect.js +1 -1
- package/reference/sdlc/code.playbook/code.fsm.introspect.ts +6 -6
- package/reference/sdlc/code.playbook/code.fsm.js +334 -102
- package/reference/sdlc/code.playbook/code.fsm.ts +470 -182
- package/reference/sdlc/code.playbook/code.gears.md +11 -10
- package/reference/sdlc/code.playbook/code.playbook.d.ts +18 -9
- package/reference/sdlc/code.playbook/code.playbook.js +1098 -202
- package/reference/sdlc/code.playbook/code.playbook.ts +1440 -258
- package/reference/sdlc/code.playbook/code.registry.d.ts +17 -5
- package/reference/sdlc/code.playbook/code.registry.js +49 -34
- package/reference/sdlc/code.playbook/code.registry.ts +75 -41
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +16 -8
- package/reference/sdlc/code.playbook/playbook-captain.js +1005 -240
- package/reference/sdlc/code.playbook/playbook-captain.ts +1310 -301
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +68 -0
- package/reference/sdlc/discuss.playbook/discuss.fsm.d.ts +396 -0
- package/reference/sdlc/discuss.playbook/discuss.fsm.js +2066 -0
- package/reference/sdlc/discuss.playbook/discuss.fsm.ts +2464 -0
- package/reference/sdlc/discuss.playbook/discuss.gears.md +251 -0
- package/reference/sdlc/discuss.playbook/discuss.playbook.d.ts +113 -0
- package/reference/sdlc/discuss.playbook/discuss.playbook.js +1514 -0
- package/reference/sdlc/discuss.playbook/discuss.playbook.ts +1926 -0
- package/reference/sdlc/discuss.playbook/discuss.registry.d.ts +58 -0
- package/reference/sdlc/discuss.playbook/discuss.registry.js +97 -0
- package/reference/sdlc/discuss.playbook/discuss.registry.ts +153 -0
- package/slc/gears2fsm.md +557 -57
- package/slc/link.md +1097 -80
- package/slc/optimize.md +88 -0
- package/slc/text2gears.md +247 -5
- package/src/runtime.d.ts +145 -3
- package/src/runtime.ts +200 -2
- package/src/xstate-runtime.d.ts +94 -0
- package/src/xstate-runtime.js +1247 -0
- package/src/xstate-runtime.ts +1802 -0
- package/reference/sdlc/code.playbook/bin/playbook-code.js +0 -487
- package/reference/sdlc/code.playbook/code.tmux-play.d.ts +0 -4
- package/reference/sdlc/code.playbook/code.tmux-play.js +0 -11
- package/reference/sdlc/code.playbook/code.tmux-play.ts +0 -29
- package/reference/sdlc/code.playbook/playbook-code.config.template.yaml +0 -72
- package/reference/sdlc/code.playbook/tmux-play.config.yaml +0 -55
- package/reference/sdlc/code.playbook/tmux-play.production.config.yaml +0 -38
package/README.md
CHANGED
|
@@ -7,28 +7,49 @@
|
|
|
7
7
|
[](https://nodejs.org/)
|
|
8
8
|
[](https://github.com/sublang-ai/playbook/actions/workflows/ci.yml)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
_Skills made reliable through state machines and visualization._
|
|
11
11
|
|
|
12
12
|
playbook is a compiler stack and reference implementation for turning a
|
|
13
13
|
natural-language procedure into a runnable, inspectable state-machine
|
|
14
|
-
agent — a
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
agent — a _playbook_ — that orchestrates other AI agents per a spec
|
|
15
|
+
written in plain prose. Instead of a free-form LLM deciding what to do
|
|
16
|
+
next, an explicit finite state machine drives the workflow, every
|
|
17
|
+
Captain-, player-, and nested-playbook-invoking state pinned 1:1 to a
|
|
18
|
+
human-readable spec item and contract-tested.
|
|
19
|
+
|
|
20
|
+
A quick vocabulary, used throughout: the **Boss** is you, the human in
|
|
21
|
+
charge; the **Captain** is the agent pane the Boss talks to;
|
|
22
|
+
**players** are the coding agents a playbook delegates work to; and a
|
|
23
|
+
hidden **judge** classifies free-text Boss input into state-machine
|
|
24
|
+
events, so playbooks need no slash commands of their own. Playbooks run
|
|
25
|
+
inside a *host* built on
|
|
26
|
+
[cligent](https://github.com/sublang-ai/cligent), the sibling SDK that
|
|
27
|
+
drives coding-agent CLIs; cligent's `tmux-play` terminal app is the
|
|
28
|
+
reference host.
|
|
29
|
+
|
|
30
|
+
Three phases take prose to runtime:
|
|
31
|
+
|
|
32
|
+
1. **text → GEARS** ([slc/text2gears.md](slc/text2gears.md)) — GEARS is
|
|
33
|
+
the intermediate representation: normative spec items, one per state
|
|
34
|
+
behavior, partitioned by trigger and prompt content.
|
|
20
35
|
2. **GEARS → FSM** ([slc/gears2fsm.md](slc/gears2fsm.md)) — an XState v5
|
|
21
|
-
finite state machine; each gear maps to one
|
|
22
|
-
with a typed
|
|
36
|
+
finite state machine; each gear maps to one direct-Captain,
|
|
37
|
+
delegated-player, or nested-playbook state with a typed actor
|
|
38
|
+
contract. The compiled FSM can be visualized and simulated with the
|
|
39
|
+
bundled [XState sketch visualizer](views/sketch).
|
|
23
40
|
3. **FSM → runtime** ([slc/link.md](slc/link.md)) — a host-agnostic
|
|
24
41
|
module that drives Boss turns through ports the host wires up
|
|
25
42
|
(cligent's `tmux-play` is one such host).
|
|
26
43
|
|
|
27
|
-
The repository
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
The repository contains end-to-end worked examples. The generic default
|
|
45
|
+
Captain is generated from
|
|
46
|
+
[`reference/sdlc/captain.md`](reference/sdlc/captain.md), CODE — a
|
|
47
|
+
coder / reviewer / committer development loop — from
|
|
48
|
+
[`reference/sdlc/code.md`](reference/sdlc/code.md), and DISCUSS — two
|
|
49
|
+
agents converging on spec items — from
|
|
50
|
+
[`reference/sdlc/discuss.md`](reference/sdlc/discuss.md). Together they
|
|
51
|
+
show direct Captain work, sequential nested playbook calls, and
|
|
52
|
+
parallel players.
|
|
32
53
|
|
|
33
54
|
## Getting started — the reference CODE playbook
|
|
34
55
|
|
|
@@ -40,7 +61,26 @@ the runtime registered behind the built-in Playbook Captain shell for
|
|
|
40
61
|
cligent's `tmux-play` host out of the box.
|
|
41
62
|
The compiled artifacts live under
|
|
42
63
|
[`reference/sdlc/code.playbook/`](reference/sdlc/code.playbook),
|
|
43
|
-
the slc pipeline's
|
|
64
|
+
the [slc](https://github.com/sublang-ai/slc) compiler pipeline's
|
|
65
|
+
`<basename>.<pipeline>/` output directory.
|
|
66
|
+
|
|
67
|
+
> **Release status:** 1.0.0 is the first release of the composed system: the
|
|
68
|
+
> compiled default Captain, CODE and DISCUSS, nested playbook calls, the
|
|
69
|
+
> semver-stable six-port runtime contract (see
|
|
70
|
+
> [docs/embedding.md](docs/embedding.md)), and non-interactive `playbook run`
|
|
71
|
+
> with parked-session resume and per-run agent tuning.
|
|
72
|
+
|
|
73
|
+
### Requirements
|
|
74
|
+
|
|
75
|
+
- Node.js >= 20.6.0.
|
|
76
|
+
- `tmux` and [`glow`](https://github.com/charmbracelet/glow#installation)
|
|
77
|
+
on `PATH` — the `tmux-play` host renders Markdown pane output with
|
|
78
|
+
glow and fails fast without it.
|
|
79
|
+
- Auth for the seeded agents: a signed-in
|
|
80
|
+
[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview)
|
|
81
|
+
(`~/.claude`) or `ANTHROPIC_API_KEY`, and a signed-in
|
|
82
|
+
[Codex CLI](https://github.com/openai/codex) (`~/.codex`) or
|
|
83
|
+
`OPENAI_API_KEY`.
|
|
44
84
|
|
|
45
85
|
### Install (users)
|
|
46
86
|
|
|
@@ -55,232 +95,250 @@ npm install -g @sublang/playbook
|
|
|
55
95
|
Then launch the reference playbook in a `tmux-play` session:
|
|
56
96
|
|
|
57
97
|
```sh
|
|
58
|
-
playbook
|
|
98
|
+
playbook
|
|
59
99
|
```
|
|
60
100
|
|
|
61
|
-
For a one-shot run without a global install,
|
|
62
|
-
through npx:
|
|
101
|
+
For a one-shot run without a global install, invoke the scoped
|
|
102
|
+
package through npx (it runs the package's `playbook` bin):
|
|
63
103
|
|
|
64
104
|
```sh
|
|
65
|
-
npx playbook
|
|
105
|
+
npx @sublang/playbook
|
|
66
106
|
```
|
|
67
107
|
|
|
68
|
-
On first run, `playbook
|
|
69
|
-
`${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook
|
|
70
|
-
from the bundled
|
|
71
|
-
declared adapters before launching.
|
|
72
|
-
not overwrite it.
|
|
108
|
+
On first run, `playbook` creates a commented user config at
|
|
109
|
+
`${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`
|
|
110
|
+
from the bundled starter, prints that path to stderr, then composes a
|
|
111
|
+
`tmux-play` config and checks the declared adapters before launching.
|
|
112
|
+
Later runs reuse that file and do not overwrite it.
|
|
73
113
|
|
|
74
114
|
Known adapter readiness is intentionally light: `claude` is ready when
|
|
75
115
|
local Claude Code auth exists or `ANTHROPIC_API_KEY` is set; `codex` is
|
|
76
116
|
ready when local Codex CLI auth exists or `OPENAI_API_KEY` is set. If a
|
|
77
|
-
known adapter is not ready, `playbook
|
|
78
|
-
|
|
79
|
-
|
|
117
|
+
known adapter is not ready, `playbook` prints its own help text with the
|
|
118
|
+
config path, auth pointers, and agent-swap recipe, then exits without
|
|
119
|
+
launching. You can view the same recovery text at any time:
|
|
80
120
|
|
|
81
121
|
```sh
|
|
82
|
-
playbook
|
|
122
|
+
playbook --help
|
|
83
123
|
```
|
|
84
124
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
bypass permissions.
|
|
125
|
+
`playbook --list` prints the configured playbooks with their slash
|
|
126
|
+
commands and intents. Every seeded agent — the Captain and both roles —
|
|
127
|
+
runs in cligent's protected auto mode (`permissions.mode: auto`), so
|
|
128
|
+
routine in-session approval prompts are suppressed without switching to
|
|
129
|
+
bypass permissions. The seeded Codex Reviewer additionally grants
|
|
130
|
+
`permissions.writablePaths: [.git]` so git metadata writes stay
|
|
131
|
+
available under the Codex sandbox; the Claude agents need no such grant
|
|
132
|
+
under their auto mode.
|
|
133
|
+
|
|
134
|
+
### Run a playbook non-interactively
|
|
135
|
+
|
|
136
|
+
`playbook run <from> [task]` runs one playbook once, without tmux-play
|
|
137
|
+
and without a config entry — point it straight at a registry module:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
playbook run @sublang/playbook/code/registry "add a test for parseArgs" \
|
|
141
|
+
--player coder=claude --player reviewer=codex --cwd ./my-repo
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`[task]` is read from stdin when omitted — pipe long or multi-line
|
|
145
|
+
intents the same way you would to `claude -p` or `codex exec`. Roles
|
|
146
|
+
and the captain default to `claude`; bind them with
|
|
147
|
+
`--player <role>=<agent>` and `--captain <agent>`, where `<agent>` is
|
|
148
|
+
`<adapter>[:<model>][@<effort>]` — say `codex:gpt-5.5@xhigh`, or
|
|
149
|
+
`claude@high` for the default model at high reasoning effort; the
|
|
150
|
+
model keeps every interior colon (`opencode:ollama/llama3:8b@max`),
|
|
151
|
+
and unsupported efforts are rejected up front naming the adapter's
|
|
152
|
+
supported values. Pass a playbook option with
|
|
153
|
+
`--option <key>=<value>`, and add `--json` to print one JSON envelope
|
|
154
|
+
(`outcome`, `sessionId`, and the output or pending questions) instead
|
|
155
|
+
of plain text. It exits `0` on a terminal outcome, `2` on failure, `3`
|
|
156
|
+
when the playbook needs a Boss reply, and `1` on a bad argument or
|
|
157
|
+
module. See [PBCLI-18](specs/user/playbook-cli.md#pbcli-18).
|
|
158
|
+
|
|
159
|
+
When the playbook stops to ask the Boss something, the run is parked,
|
|
160
|
+
not lost: the question prints to stdout, the session is saved under
|
|
161
|
+
`${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions/`, and stderr
|
|
162
|
+
names the exact command that continues it. Answer with `resume`:
|
|
163
|
+
|
|
164
|
+
```sh
|
|
165
|
+
playbook run resume 4f2c…9ab1 "keep the scope small; skip the docs"
|
|
166
|
+
playbook run resume --last # most recently parked session; reply on stdin
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
A resumed run picks the playbook up exactly where it parked — same
|
|
170
|
+
session id, same workflow state, and each agent continues its own
|
|
171
|
+
conversation — then prints the final output and exits `0`, or parks
|
|
172
|
+
again with the next question and exits `3`. The agent lineup, options,
|
|
173
|
+
and working directory are stored with the session, so `resume` takes no
|
|
174
|
+
binding flags. In scripts, capture the session id from the `--json`
|
|
175
|
+
envelope, like Claude Code's `session_id` or `codex exec resume`. See
|
|
176
|
+
[PBCLI-22](specs/user/playbook-cli.md#pbcli-22) and
|
|
177
|
+
[DR-014](specs/decisions/014-durable-one-shot-run-sessions.md).
|
|
90
178
|
|
|
91
179
|
### Configure agents
|
|
92
180
|
|
|
93
181
|
Edit the seeded user config when you want different coding agents:
|
|
94
182
|
|
|
95
183
|
```sh
|
|
96
|
-
$EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook
|
|
184
|
+
$EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
To retune a single launch without editing that file, overlay a
|
|
188
|
+
fragment in the same format with `--with` (repeatable, later files
|
|
189
|
+
win; maps merge recursively, other values replace):
|
|
190
|
+
|
|
191
|
+
```sh
|
|
192
|
+
playbook --with fast-lineup.yaml
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
# fast-lineup.yaml — swap the Coder for one run; nothing is written back.
|
|
197
|
+
profiles:
|
|
198
|
+
codex-fast: { adapter: codex, model: gpt-5.5, reasoningEffort: medium }
|
|
199
|
+
playbooks:
|
|
200
|
+
code:
|
|
201
|
+
players:
|
|
202
|
+
coder: codex-fast
|
|
97
203
|
```
|
|
98
204
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
For example, the seeded overlay runs the Coder on Claude Opus 4.8 1m
|
|
120
|
-
and the Reviewer on GPT-5.5, with the Committer aliased to the Coder:
|
|
205
|
+
See [PBCLI-25](specs/user/playbook-cli.md#pbcli-25) and
|
|
206
|
+
[DR-015](specs/decisions/015-per-run-agent-tuning.md).
|
|
207
|
+
|
|
208
|
+
The config is top-level (no `config:` wrapper): a `profiles` map of
|
|
209
|
+
reusable agent settings, a `captain` agent (it runs both visible
|
|
210
|
+
Captain work and hidden judge calls), optional `layout` /
|
|
211
|
+
`notifications` / `theme`, and a `playbooks` map of enabled playbooks.
|
|
212
|
+
Each `captain` or `players.<role>` value is a profile id or an adapter
|
|
213
|
+
shorthand (`claude`, `codex`); other adapter ids are passed through to
|
|
214
|
+
`tmux-play` with a warning because `playbook` cannot preflight their
|
|
215
|
+
auth. Name profiles by their underlying agent/model (e.g. `claude-opus`,
|
|
216
|
+
`codex-gpt`) so the profile ids read distinctly from the player roles
|
|
217
|
+
that reference them. Within a `playbooks.<id>` block, `from` (the
|
|
218
|
+
registry module), `command` (an optional slash-command override), and
|
|
219
|
+
`players` are launcher-owned; every other key is that playbook's option
|
|
220
|
+
slice. The launcher injects the rest — you do not write host wiring by
|
|
221
|
+
hand.
|
|
222
|
+
|
|
223
|
+
For example, the seeded config runs the Coder on Claude Opus 4.8 1m and
|
|
224
|
+
the Reviewer on GPT-5.5:
|
|
121
225
|
|
|
122
226
|
```yaml
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
coder: # role key must stay `coder` — see PBRT-4
|
|
227
|
+
profiles:
|
|
228
|
+
claude-opus:
|
|
229
|
+
adapter: claude
|
|
230
|
+
model: claude-opus-4-8
|
|
231
|
+
reasoningEffort: high
|
|
232
|
+
permissions:
|
|
233
|
+
mode: auto # protected auto mode for the Claude Captain
|
|
234
|
+
claude-opus-1m:
|
|
132
235
|
adapter: claude
|
|
133
236
|
model: claude-opus-4-8[1m]
|
|
134
237
|
reasoningEffort: xhigh
|
|
135
238
|
permissions:
|
|
136
|
-
mode: auto
|
|
137
|
-
|
|
239
|
+
mode: auto # protected auto mode for the Claude Coder
|
|
240
|
+
codex-gpt:
|
|
138
241
|
adapter: codex
|
|
139
242
|
model: gpt-5.5
|
|
140
243
|
reasoningEffort: xhigh
|
|
141
244
|
permissions:
|
|
142
245
|
mode: auto
|
|
143
246
|
writablePaths:
|
|
144
|
-
- .git
|
|
145
|
-
|
|
247
|
+
- .git # allow git metadata writes under Codex auto mode
|
|
248
|
+
|
|
249
|
+
captain: claude-opus
|
|
250
|
+
|
|
251
|
+
playbooks:
|
|
252
|
+
code:
|
|
253
|
+
from: '@sublang/playbook/code/registry'
|
|
254
|
+
players:
|
|
255
|
+
coder: claude-opus-1m
|
|
256
|
+
reviewer: codex-gpt
|
|
257
|
+
committer: coder # which role commits — `coder` or `reviewer`
|
|
146
258
|
```
|
|
147
259
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
[
|
|
260
|
+
`committer` is CODE's one option: an alias naming which role runs the
|
|
261
|
+
commit turn (fallback semantics:
|
|
262
|
+
[PBRT-8](specs/dev/playbook-runtime.md#pbrt-8)). Each role's per-run
|
|
263
|
+
prompt names its pinned `model`, else its `adapter`
|
|
264
|
+
([PBRT-4](specs/user/playbook-runtime.md#pbrt-4)), so commit trailers
|
|
265
|
+
can credit the concrete model (e.g. `claude-opus-4-8[1m]`) rather than
|
|
266
|
+
the adapter family.
|
|
267
|
+
|
|
268
|
+
If you need a separate config file for a one-off run, pass a raw
|
|
269
|
+
`tmux-play` config explicitly; this bypasses the seed, composition, and
|
|
270
|
+
readiness gate and forwards the arguments to `tmux-play` verbatim
|
|
271
|
+
([PBCLI-1](specs/user/playbook-cli.md#pbcli-1)):
|
|
153
272
|
|
|
154
273
|
```sh
|
|
155
|
-
playbook
|
|
274
|
+
playbook --config ./tmux-play.config.yaml
|
|
156
275
|
```
|
|
157
276
|
|
|
158
277
|
### Install (contributors / from source)
|
|
159
278
|
|
|
160
|
-
|
|
279
|
+
The checked-in lockfile resolves every runtime contract required by the
|
|
280
|
+
source tree:
|
|
161
281
|
|
|
162
282
|
```sh
|
|
163
283
|
git clone https://github.com/sublang-ai/playbook.git
|
|
164
284
|
cd playbook
|
|
165
|
-
pnpm install
|
|
285
|
+
pnpm install --frozen-lockfile
|
|
166
286
|
pnpm build
|
|
167
287
|
pnpm test
|
|
168
288
|
```
|
|
169
289
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
`
|
|
179
|
-
|
|
180
|
-
`package.json` specifier and lockfile together.
|
|
181
|
-
No local link required for any of this. To point pnpm at a local
|
|
182
|
-
`cligent` checkout
|
|
183
|
-
instead, copy
|
|
184
|
-
[`pnpm-workspace.yaml.example`](pnpm-workspace.yaml.example)
|
|
185
|
-
into place; the override is gitignored so it never leaks into a
|
|
186
|
-
production install.
|
|
187
|
-
|
|
188
|
-
Drive a Boss turn against the source tree (uses the developer
|
|
189
|
-
[`tmux-play.config.yaml`](reference/sdlc/code.playbook/tmux-play.config.yaml)
|
|
190
|
-
that imports the compiled Playbook Captain shell via relative path):
|
|
290
|
+
To co-develop Playbook with an unreleased cligent checkout, clone
|
|
291
|
+
cligent beside this repository, build it, and copy
|
|
292
|
+
`pnpm-workspace.yaml.example` to the gitignored
|
|
293
|
+
`pnpm-workspace.yaml`. That optional override links the sibling checkout
|
|
294
|
+
in place of the registry version. Do not commit the local lockfile
|
|
295
|
+
rewrite it produces ([RELEASE-11](specs/dev/release.md#release-11)).
|
|
296
|
+
|
|
297
|
+
Drive a Boss turn against the source tree with the launcher, which
|
|
298
|
+
resolves `tmux-play`, the Playbook Captain shell, and the CODE registry
|
|
299
|
+
from the local package:
|
|
191
300
|
|
|
192
301
|
```sh
|
|
193
|
-
pnpm
|
|
302
|
+
pnpm playbook
|
|
194
303
|
```
|
|
195
304
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
305
|
+
On first run this seeds the generic config at
|
|
306
|
+
`${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`
|
|
307
|
+
(see [Configure agents](#configure-agents)) and launches the composed
|
|
308
|
+
session, so this works whether or not `@sublang/cligent` is installed
|
|
309
|
+
globally.
|
|
199
310
|
|
|
200
311
|
### Running a Boss turn
|
|
201
312
|
|
|
202
313
|
The Boss pane starts at the Playbook Captain shell. Use `/code <task>`
|
|
203
314
|
to explicitly select the CODE playbook, or use ordinary text and let the
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
315
|
+
compiled default Captain ask a material routing question or plan one or more
|
|
316
|
+
enabled playbook calls. It cannot answer the initial intent directly;
|
|
317
|
+
calls run sequentially so Captain can reassess after every child result
|
|
318
|
+
and then return a concrete result or actionable conclusion. Once a turn
|
|
319
|
+
reaches CODE, the CODE judge classifies it into an FSM event (start a coding
|
|
320
|
+
turn, continue or summarize an iteration, interrupt to a named state, or
|
|
321
|
+
nothing) per
|
|
207
322
|
[PBRT-1](specs/user/playbook-runtime.md#pbrt-1).
|
|
208
323
|
When a player surfaces a clarifying question
|
|
209
|
-
the FSM parks
|
|
210
|
-
next turn is normally classified as the reply
|
|
324
|
+
the FSM parks, the pane shows the question, and your
|
|
325
|
+
next turn is normally classified as the reply — or a fresh directive
|
|
211
326
|
abandons it ([PBRT-2](specs/user/playbook-runtime.md#pbrt-2)).
|
|
212
327
|
|
|
213
328
|
The Captain pane shows `/code` start/stop/finished status with `◇` lines
|
|
214
|
-
and streams
|
|
215
|
-
[PBRT-3](specs/user/playbook-runtime.md#pbrt-3), while player
|
|
216
|
-
ride their own panes.
|
|
217
|
-
|
|
218
|
-
Published configs should import the shell adapter from
|
|
219
|
-
`@sublang/playbook/playbook-captain`. Existing explicit configs that
|
|
220
|
-
still import `@sublang/playbook/code/tmux-play` keep resolving through
|
|
221
|
-
a compatibility shim that delegates to the same shell with CODE
|
|
222
|
-
registered.
|
|
329
|
+
and streams CODE progress with captain-speech classification/questions
|
|
330
|
+
per [PBRT-3](specs/user/playbook-runtime.md#pbrt-3), while player
|
|
331
|
+
prompts ride their own panes.
|
|
223
332
|
|
|
224
333
|
### Embedding the runtime in your own host
|
|
225
334
|
|
|
226
|
-
The runtime is host-agnostic
|
|
227
|
-
|
|
228
|
-
[`@sublang/playbook/runtime`](src/runtime.ts)
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
`@sublang/playbook/code/playbook`; `PlaybookRuntimeFactory` is available
|
|
234
|
-
from `@sublang/playbook/runtime`.
|
|
235
|
-
Construct the runtime against your own ports:
|
|
236
|
-
|
|
237
|
-
```ts
|
|
238
|
-
import createPlaybookRuntime from '@sublang/playbook/code/playbook';
|
|
239
|
-
import type { PlaybookPorts } from '@sublang/playbook/runtime';
|
|
240
|
-
|
|
241
|
-
const ports: PlaybookPorts = {
|
|
242
|
-
callPlayer: async (playerId, prompt, signal) => { /* … */ },
|
|
243
|
-
callJudge: async (prompt, signal) => { /* … */ },
|
|
244
|
-
emitStatus: async (message, data) => { /* … */ },
|
|
245
|
-
emitTelemetry: async ({ topic, payload }) => { /* … */ },
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
const runtime = createPlaybookRuntime({
|
|
249
|
-
coderPlayer: 'claude',
|
|
250
|
-
reviewerPlayer: 'codex',
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
await runtime.init(ports);
|
|
254
|
-
await runtime.handleBossInput({
|
|
255
|
-
text: 'Start fixing the bug',
|
|
256
|
-
signal: new AbortController().signal,
|
|
257
|
-
});
|
|
258
|
-
await runtime.dispose();
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
See
|
|
262
|
-
[`code.playbook.test.ts`](reference/sdlc/code.playbook/code.playbook.test.ts)
|
|
263
|
-
for the full range of port shapes (classifier, judge, abort, interrupt,
|
|
264
|
-
status/telemetry) the runtime is contract-tested against.
|
|
265
|
-
|
|
266
|
-
### Reading the published spec contracts
|
|
267
|
-
|
|
268
|
-
The authored compiler-phase specs ship in the package and are exposed
|
|
269
|
-
as a public, semver-stable surface under `@sublang/playbook/slc/*`.
|
|
270
|
-
Resolve and read one with `import.meta.resolve` plus `fs`:
|
|
271
|
-
|
|
272
|
-
```ts
|
|
273
|
-
import { readFile } from 'node:fs/promises';
|
|
274
|
-
import { fileURLToPath } from 'node:url';
|
|
275
|
-
|
|
276
|
-
const url = import.meta.resolve('@sublang/playbook/slc/link.md');
|
|
277
|
-
const link = await readFile(fileURLToPath(url), 'utf8');
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
The three specs are [`slc/text2gears.md`](slc/text2gears.md),
|
|
281
|
-
[`slc/gears2fsm.md`](slc/gears2fsm.md), and [`slc/link.md`](slc/link.md)
|
|
282
|
-
— the FSM-to-runtime contract that `@sublang/playbook/runtime` projects
|
|
283
|
-
into TypeScript.
|
|
335
|
+
The runtime is host-agnostic — the `tmux-play` adapter is one host. The
|
|
336
|
+
port and runtime contracts live in the type-only, semver-stable module
|
|
337
|
+
[`@sublang/playbook/runtime`](src/runtime.ts): a host satisfies the six
|
|
338
|
+
ports once and inherits every playbook. See
|
|
339
|
+
[docs/embedding.md](docs/embedding.md) for the contract surface, a
|
|
340
|
+
complete ports example, session/trace semantics, and how to read the
|
|
341
|
+
published compiler-phase specs from the package.
|
|
284
342
|
|
|
285
343
|
## Workflow
|
|
286
344
|
|
|
@@ -288,33 +346,25 @@ playbook is itself spec-driven: the compiler phases are specs in `slc/`,
|
|
|
288
346
|
and the reference playbook is regenerated from its prose source. The
|
|
289
347
|
loop:
|
|
290
348
|
|
|
291
|
-
1. **Edit source.**
|
|
292
|
-
[`reference/sdlc/code.md`](reference/sdlc/code.md)
|
|
349
|
+
1. **Edit source.** The worked examples include
|
|
350
|
+
[`reference/sdlc/code.md`](reference/sdlc/code.md) and the generic
|
|
351
|
+
[`reference/sdlc/captain.md`](reference/sdlc/captain.md).
|
|
293
352
|
2. **Recompile gears** per [`slc/text2gears.md`](slc/text2gears.md) into
|
|
294
|
-
the
|
|
295
|
-
3. **Recompile FSM** per
|
|
296
|
-
|
|
353
|
+
the source's `<name>.playbook/<name>.gears.md`.
|
|
354
|
+
3. **Recompile FSM and runtime** per
|
|
355
|
+
[`slc/gears2fsm.md`](slc/gears2fsm.md) and
|
|
356
|
+
[`slc/link.md`](slc/link.md) into that playbook artifact directory.
|
|
297
357
|
4. **Sync runtime, tests, and downstream specs** so `pnpm test` stays
|
|
298
358
|
green and the introspect contract holds 1:1 between gear items and
|
|
299
|
-
FSM
|
|
359
|
+
FSM direct-Captain, delegated-player, and nested-playbook states.
|
|
300
360
|
5. **Commit** with co-author trailers per
|
|
301
361
|
[`specs/dev/git.md`](specs/dev/git.md).
|
|
302
362
|
|
|
303
363
|
The behavioral contract between gears and FSM
|
|
304
364
|
([PLAYBOOK-1..6](specs/dev/playbook.md)) and the runtime contract that
|
|
305
|
-
ports satisfy ([PBRT
|
|
306
|
-
in [`specs/dev/`](specs/dev/) and verified by tests under the
|
|
307
|
-
package.
|
|
308
|
-
|
|
309
|
-
## Requirements
|
|
310
|
-
|
|
311
|
-
- Node.js ≥ 20.6.0 (the `playbook-code` shim uses
|
|
312
|
-
`import.meta.resolve`, unflagged since this release)
|
|
313
|
-
- pnpm 9 (for the reference package)
|
|
314
|
-
- A configured `tmux-play` host (for live Boss turns) — requires
|
|
315
|
-
`tmux` and [`glow`](https://github.com/charmbracelet/glow#installation)
|
|
316
|
-
on `PATH`; cligent 0.4+ uses `glow` to render Markdown pane
|
|
317
|
-
output and fails fast without it
|
|
365
|
+
ports satisfy ([the PBRT dev items](specs/dev/playbook-runtime.md)) are
|
|
366
|
+
pinned in [`specs/dev/`](specs/dev/) and verified by tests under the
|
|
367
|
+
reference package.
|
|
318
368
|
|
|
319
369
|
## Contributing
|
|
320
370
|
|