@thedevlabs-io/labd 0.3.1 → 0.6.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/AGENTS.md +89 -30
- package/README.md +96 -81
- package/dist/labd.js +2608 -435
- package/dist/labd.js.map +4 -4
- package/package.json +1 -3
package/AGENTS.md
CHANGED
|
@@ -35,7 +35,7 @@ executes tools.
|
|
|
35
35
|
|
|
36
36
|
```
|
|
37
37
|
packages/core/ the agent loop, tools, permission checks, sessions, checkpoints
|
|
38
|
-
packages/tui/ terminal rendering - differential redraw, markdown, cards
|
|
38
|
+
packages/tui/ terminal rendering - the full screen, differential redraw, markdown, cards
|
|
39
39
|
packages/cli/ the binary: config, auth, extensions, and the four run modes
|
|
40
40
|
vendor/labd/ submodule - the labd repo, for @labd/protocol
|
|
41
41
|
test/ vitest; `e2e.test.ts` runs the built binary against a fake server
|
|
@@ -176,52 +176,111 @@ Do not "simplify" this into a list. The list version cannot do any of the three.
|
|
|
176
176
|
|
|
177
177
|
## Terminal rules
|
|
178
178
|
|
|
179
|
+
Two kinds of program live in this repo, and the rules differ by which one you are in.
|
|
180
|
+
|
|
181
|
+
**The interactive session owns the screen.** `labd` on its own runs
|
|
182
|
+
`modes/screen.ts`: the alternate screen buffer, a scrollable transcript, a
|
|
183
|
+
multi-line composer, popups for `/` and `@`, dialogs for lists, approvals inline.
|
|
184
|
+
This replaced the "print into the scrollback, keep one live box at the bottom"
|
|
185
|
+
model in 0.4.0. That model was principled - the terminal owned the transcript, so
|
|
186
|
+
search and copy came free - and learners did not want it: they wanted an app, not
|
|
187
|
+
a log. `--plain` still runs the old loop for one release and is deprecated. Rules
|
|
188
|
+
for the screen:
|
|
189
|
+
|
|
190
|
+
- **Full-screen only when stdin AND stdout are TTYs.** Anything else falls
|
|
191
|
+
through to the printing modes below; a learner must never type blind.
|
|
192
|
+
- **Give the terminal back, whatever happens.** `Screen.leave` runs from the
|
|
193
|
+
normal exit, the `finally`, the signal handlers and the process `exit` hook, in
|
|
194
|
+
the reverse order of `enter`, and is idempotent. Raw mode or the alternate
|
|
195
|
+
screen left on looks like a broken machine.
|
|
196
|
+
- **Frames are whole and drawn differentially with absolute positions.** No
|
|
197
|
+
relative cursor moves: there is no scrollback to keep in step with.
|
|
198
|
+
- **Pure logic is separate from I/O.** `keys`, `layout`, `transcript`, `editor`,
|
|
199
|
+
`popup`, `dialog` know nothing about a stream and are tested without one.
|
|
200
|
+
`Screen` owns the terminal; `modes/screen.ts` is the state machine between them.
|
|
201
|
+
- **The mouse is taken by default, for wheel scrolling, and `--no-mouse` gives
|
|
202
|
+
it back** - native text selection needs the terminal to have it.
|
|
203
|
+
|
|
204
|
+
**The non-interactive modes own nothing and print.** `labd -p`, `--json`,
|
|
205
|
+
`--mode rpc`, and anything with a piped stdout use `Renderer` and plain writes:
|
|
206
|
+
|
|
179
207
|
- **Never assume a TTY.** Piped, redirected, or in CI, colour is off and the live
|
|
180
208
|
region is a no-op. Escape codes in a log file are worse than plain text.
|
|
181
209
|
- **The scrollback is not ours.** Finished output is printed and belongs to the
|
|
182
|
-
terminal; only the status line is a live region.
|
|
183
|
-
selection, and copy-paste working.
|
|
210
|
+
terminal; only the status line is a live region.
|
|
184
211
|
- **stdout is the answer. Everything else is stderr.** A pipeline must receive
|
|
185
|
-
only what labd meant as the answer.
|
|
212
|
+
only what labd meant as the answer. The interactive session keeps this for
|
|
213
|
+
what it prints on the way out - the "session saved" line goes to stderr.
|
|
214
|
+
|
|
215
|
+
**Everywhere:**
|
|
216
|
+
|
|
186
217
|
- **Escape sequences are written as `\u001b` escapes**, never as literal bytes, so
|
|
187
218
|
source files stay greppable ASCII.
|
|
219
|
+
- **Zero runtime dependencies.** No ink, no blessed, no opentui: the TUI is the
|
|
220
|
+
repo's own `Screen` and differential drawing, so the bundle stays one file and
|
|
221
|
+
still works as a Node single-executable.
|
|
188
222
|
|
|
189
223
|
## Distribution
|
|
190
224
|
|
|
191
|
-
|
|
225
|
+
**The GitHub organisation is private, and public docs must not link to it.**
|
|
226
|
+
Learners cannot reach `github.com/thedevlabs-io/*`, raw.githubusercontent.com,
|
|
227
|
+
or GitHub Release assets. The public channels are npm (`@thedevlabs-io/labd`, bin
|
|
228
|
+
`labd`) and the VS Code Marketplace (`thedevlabs-io.labd`); README.md and every
|
|
229
|
+
user-facing string point at those and nowhere else. This file is for
|
|
230
|
+
contributors with access, so it may name the repositories.
|
|
231
|
+
|
|
232
|
+
Two bundles, one source, one channel:
|
|
192
233
|
|
|
193
234
|
- **`dist/labd.js`** - ESM, zero runtime dependencies, what npm's `bin` points at.
|
|
194
|
-
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
macOS needs the signing dance in `build-binaries.mjs`, and it is not optional -
|
|
203
|
-
injecting invalidates the signature, and macOS kills an invalidly-signed binary
|
|
204
|
-
rather than running it. The build also RUNS the binary before calling it done,
|
|
205
|
-
because every one of those steps fails by producing something that does not start
|
|
206
|
-
rather than by erroring.
|
|
235
|
+
`npm install -g @thedevlabs-io/labd` is the install; `npm update -g` the upgrade.
|
|
236
|
+
- **`dist/labd.cjs`** - the same code as CommonJS. Kept because Node's
|
|
237
|
+
single-executable support runs its entry as CJS and refuses an ESM one, so a
|
|
238
|
+
standalone build stays possible without a code change. This is why `bin/labd.ts`
|
|
239
|
+
must never use top-level await; CI runs the CJS bundle to prove it loads.
|
|
240
|
+
|
|
241
|
+
Standalone binaries, the install scripts and the GitHub Release step were removed
|
|
242
|
+
in 0.4.0: they were only reachable through GitHub, which learners cannot see.
|
|
207
243
|
|
|
208
244
|
`npm install -g git+ssh://...` cannot work: `dist/` is not committed and npm does
|
|
209
245
|
not fetch submodules for a git dependency. `scripts/prepare.mjs` says so rather
|
|
210
246
|
than letting the install appear to succeed with no binary - which is what it did
|
|
211
247
|
before, reporting "added 1 package" and installing nothing.
|
|
212
248
|
|
|
213
|
-
##
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
approval
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
`
|
|
249
|
+
## Helpers - inside the permission model, not beside it
|
|
250
|
+
|
|
251
|
+
This section used to be "Sub-agents - deliberately outside", and its argument was
|
|
252
|
+
right about the design it rejected: a `spawn_agent` tool whose children ran in the
|
|
253
|
+
parent's mode would turn one approval into N unattended writes, and children with a
|
|
254
|
+
mode of their own would hand the model the one setting it must not touch. The
|
|
255
|
+
helpers labd has now avoid both, because **there is no approval to spawn and no
|
|
256
|
+
mode for a helper to have**:
|
|
257
|
+
|
|
258
|
+
- Spawning changes nothing, so it asks nothing. What a helper then DOES is checked
|
|
259
|
+
call by call: every write and command goes through `executeCall`
|
|
260
|
+
(`packages/core/src/calls.ts`) - the same code the turn's own calls go through -
|
|
261
|
+
and `needsApproval` against the learner's mode. So `auto` still asks about every
|
|
262
|
+
command a helper wants to run, and `ask` about every write.
|
|
263
|
+
- Its cards join the turn's line: one at a time, marked "from a helper", and once
|
|
264
|
+
the turn is stopped nothing still waiting is asked.
|
|
265
|
+
- **Unattended means declined, for helpers too.** `labd -p` has no one to ask, so a
|
|
266
|
+
helper's write is refused and the run exits 2. `e2e.test.ts` proves it.
|
|
267
|
+
- One level: a helper is offered every tool but `spawn_agent` and refuses it if
|
|
268
|
+
called. At most `MAX_SUBAGENTS` at once; the rest are refused with a reason.
|
|
269
|
+
- It shares the turn's ToolContext, so its writes are in the turn's checkpoint
|
|
270
|
+
and `/undo` puts them back with the rest.
|
|
271
|
+
- It writes nothing to the session but the parent's call and its report, and is
|
|
272
|
+
never handed to memory on its own.
|
|
273
|
+
- The helper's brief, the report bound and when to use one are the protocol's
|
|
274
|
+
(`subAgentBrief`, `SUBAGENT_REPORT_CHARS`, the prompt's "Helpers" section), not
|
|
275
|
+
this repo's.
|
|
276
|
+
|
|
277
|
+
`test/helpers.test.ts` pins these against the real tools and checkpoint store.
|
|
278
|
+
|
|
279
|
+
**Orchestration across processes is still outside, and still the right tool for
|
|
280
|
+
it.** `--mode rpc` makes every labd process a driveable agent, where each child's
|
|
281
|
+
mode is set by the person who wrote the script and each child asks that script for
|
|
282
|
+
approval. `examples/orchestrate.mjs` is the reference; `test/rpc-e2e.test.ts` runs
|
|
283
|
+
two children at once. An RPC host is told which helper is asking on `labd/approve`.
|
|
225
284
|
|
|
226
285
|
## Branches - promotion is by pull request, always
|
|
227
286
|
|
package/README.md
CHANGED
|
@@ -3,80 +3,49 @@
|
|
|
3
3
|
labd in your terminal — the Dev Labs assistant, in the project you're standing in.
|
|
4
4
|
|
|
5
5
|
```
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
[o_o] labd · labd-cli develop · session 3f9a12c0 auto
|
|
7
|
+
─────────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
> why is session.test.ts failing?
|
|
9
|
+
|
|
10
|
+
● Read test/session.test.ts
|
|
11
|
+
? Run a command
|
|
12
|
+
to see which of the eleven cases fails
|
|
13
|
+
|
|
14
|
+
npx vitest run test/session.test.ts
|
|
15
|
+
|
|
16
|
+
On auto, commands still ask - a command can do anything your shell can, and
|
|
17
|
+
put back isn't one of them.
|
|
18
|
+
y to allow · n or esc to decline
|
|
19
|
+
╭───────────────────────────────────────────────────────────────────────────────╮
|
|
20
|
+
│ > ask labd something - / for commands - @ to tag a file │
|
|
21
|
+
╰───────────────────────────────────────────────────────────────────────────────╯
|
|
22
|
+
y allow · n decline · ctrl+c stop context 12% · credits 82%
|
|
20
23
|
```
|
|
21
24
|
|
|
22
|
-
This is the same assistant as the
|
|
23
|
-
and the one docked in the learning portal
|
|
24
|
-
|
|
25
|
+
This is the same assistant as the labd VS Code extension (Marketplace:
|
|
26
|
+
`thedevlabs-io.labd`) and the one docked in the learning portal at
|
|
27
|
+
[learn.thedevlabs.io](https://learn.thedevlabs.io) — same server, same prompt,
|
|
28
|
+
same memory, same permission model. Ask something in your editor, follow up in
|
|
29
|
+
your terminal.
|
|
25
30
|
|
|
26
31
|
## Install
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
curl -fsSL https://raw.githubusercontent.com/thedevlabs-io/labd-cli/production/install.sh | sh
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**Windows** — same, in PowerShell:
|
|
35
|
-
|
|
36
|
-
```powershell
|
|
37
|
-
irm https://raw.githubusercontent.com/thedevlabs-io/labd-cli/production/install.ps1 | iex
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
**With npm**, if you already have Node 22+:
|
|
33
|
+
You need Node 22 or newer. Then:
|
|
41
34
|
|
|
42
35
|
```bash
|
|
43
36
|
npm install -g @thedevlabs-io/labd
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Then connect:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
37
|
labd login # approve a short code in your browser
|
|
50
38
|
```
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
<summary>Other ways, and what each is for</summary>
|
|
54
|
-
|
|
55
|
-
| how | when |
|
|
56
|
-
|---|---|
|
|
57
|
-
| `install.sh` / `install.ps1` | a machine with nothing on it. Downloads a ~40 MB archive containing a single executable with the Node runtime inside it. |
|
|
58
|
-
| `npm install -g @thedevlabs-io/labd` | you have Node. Smaller download, and `npm update -g @thedevlabs-io/labd` upgrades it. |
|
|
59
|
-
| `npm pack` → share the `.tgz` | an air-gapped machine, or pinning an exact build. `npm install -g thedevlabs-io-labd-0.3.1.tgz`. |
|
|
60
|
-
| copy `dist/labd.js` | you built from source. It has **zero runtime dependencies**, so that one file plus Node 22+ is a working install anywhere. |
|
|
61
|
-
| clone + `npm link` | working on labd itself. |
|
|
62
|
-
|
|
63
|
-
`npm install -g git+ssh://…` does **not** work, and says so rather than half-installing: `dist/` is not committed, and npm does not fetch the git submodule that the build needs.
|
|
64
|
-
|
|
65
|
-
While this repository is private, the install scripts need a credential to read release assets. They use the GitHub CLI when it is signed in, or `GH_TOKEN` if you set one, and explain that rather than failing with a 404.
|
|
66
|
-
|
|
67
|
-
**Building from source:**
|
|
40
|
+
To upgrade:
|
|
68
41
|
|
|
69
42
|
```bash
|
|
70
|
-
|
|
71
|
-
cd labd-cli
|
|
72
|
-
git submodule update --init # the protocol lives in the labd repo
|
|
73
|
-
npm install
|
|
74
|
-
npm run build # dist/labd.js (and dist/labd.cjs, for binaries)
|
|
75
|
-
npm link # puts `labd` on your PATH
|
|
76
|
-
npm run build:binary # optional: a standalone executable for this platform
|
|
43
|
+
npm update -g @thedevlabs-io/labd
|
|
77
44
|
```
|
|
78
45
|
|
|
79
|
-
|
|
46
|
+
The package is one bundled file with zero runtime dependencies, so that is the
|
|
47
|
+
whole install. There are no standalone binaries and no `curl | sh` installer: npm
|
|
48
|
+
is the one public channel.
|
|
80
49
|
|
|
81
50
|
## Using it
|
|
82
51
|
|
|
@@ -101,14 +70,53 @@ labd -c # pick up the most recent session here
|
|
|
101
70
|
| `-e`, `--extension <path>` | load an extension file (repeatable; `/reload` keeps it) |
|
|
102
71
|
| `--no-extensions` | load none, now and on `/reload` |
|
|
103
72
|
| `--no-color` / `--color` | force colour off or on |
|
|
73
|
+
| `--no-mouse` | leave the mouse to the terminal, for native text selection |
|
|
74
|
+
| `--plain` | the older print-style session (deprecated; removed in 0.5) |
|
|
104
75
|
| `-v`, `--version` | |
|
|
105
76
|
|
|
106
77
|
Subcommands: `login`, `logout` (revokes the token server-side too), `sessions`
|
|
107
78
|
(earlier sessions here), `trust` (let this project load its own extensions and
|
|
108
79
|
name its own server).
|
|
109
80
|
|
|
110
|
-
Inside a session
|
|
111
|
-
|
|
81
|
+
### Inside a session
|
|
82
|
+
|
|
83
|
+
`labd` on its own opens a full-screen session: a header, a scrollable transcript,
|
|
84
|
+
a box to type in at the bottom, and a footer with the keys that apply right now
|
|
85
|
+
and how full the conversation is. The transcript follows the answer as it
|
|
86
|
+
streams; scroll up and it stops following and tells you how many lines have
|
|
87
|
+
arrived since (`End`, or scrolling back to the bottom, follows again).
|
|
88
|
+
|
|
89
|
+
| key | |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `enter` | send |
|
|
92
|
+
| `shift+enter`, `ctrl+j`, or a line ending in `\` | new line in the box (it grows to 8 rows) |
|
|
93
|
+
| `/` | a list of commands appears above the box; `↑↓` moves, `tab`/`enter` accepts, `esc` closes |
|
|
94
|
+
| `@` | the same, for files in the project — `@src/index.ts` tags the file into the question |
|
|
95
|
+
| `tab` | complete the command or path being typed |
|
|
96
|
+
| `shift+tab` | next mode: `ask`, `auto`, `agent` - the same as `/mode`, and it says what the new mode does |
|
|
97
|
+
| `pgup` / `pgdn`, mouse wheel | scroll the transcript |
|
|
98
|
+
| `home` / `end` | top / bottom of the transcript (with an empty box; otherwise they move within the line) |
|
|
99
|
+
| `↑` / `↓` | earlier questions, when the caret is on the first / last line |
|
|
100
|
+
| `esc` | close a list or dialog; otherwise jump back to the bottom |
|
|
101
|
+
| `y` / `n` | answer an approval card. Nothing else answers it, and `enter` never does |
|
|
102
|
+
| `ctrl+c` | stop the answer; else clear the box; else press it again within 2 s to quit |
|
|
103
|
+
| `ctrl+d` | quit |
|
|
104
|
+
| `ctrl+n`, `ctrl+o` | new session, earlier sessions |
|
|
105
|
+
| `ctrl+l` | redraw |
|
|
106
|
+
|
|
107
|
+
`/help`, `/sessions` and `/tree` open a dialog you can type into to narrow the
|
|
108
|
+
list; `enter` picks — a session to resume, or a point in this session to continue
|
|
109
|
+
from. Approvals are never dialogs: the card is drawn inline in the transcript
|
|
110
|
+
with its context, and `y` is the only key that allows it.
|
|
111
|
+
|
|
112
|
+
Two flags for the screen. `--no-mouse` leaves the mouse to the terminal (the
|
|
113
|
+
session takes it for wheel scrolling, and native text selection needs it
|
|
114
|
+
released); `mouse: false` in a settings file does the same. `--plain` runs the
|
|
115
|
+
older print-style session, where answers land in the terminal's scrollback and
|
|
116
|
+
only the box is redrawn — kept for one release for terminals that cannot cope
|
|
117
|
+
with the alternate screen, and deprecated. `sidebar: true`, or `/sidebar`, adds
|
|
118
|
+
a panel with the project, branch, mode and recent steps when there are 120 or
|
|
119
|
+
more columns.
|
|
112
120
|
|
|
113
121
|
| command | |
|
|
114
122
|
|---|---|
|
|
@@ -118,7 +126,9 @@ and `/commands`, ctrl-c stops an answer without leaving.
|
|
|
118
126
|
| `/redo` | reapply what `/undo` put back |
|
|
119
127
|
| `/tree` | every point in this session; branch from any of them |
|
|
120
128
|
| `/resume <id>` | continue from a point in `/tree` |
|
|
121
|
-
| `/sessions`, `/session` | earlier sessions here; where this one is stored |
|
|
129
|
+
| `/sessions`, `/session` | earlier sessions here (a dialog; `enter` resumes); where this one is stored |
|
|
130
|
+
| `/new` | start a fresh session; the current one stays saved |
|
|
131
|
+
| `/sidebar`, `/clear` | show or hide the side panel; clear the screen |
|
|
122
132
|
| `/usage` | what's left of this month's allowance |
|
|
123
133
|
| `/trust` | let this project load its own extensions |
|
|
124
134
|
| `/reload` | reload extensions and the file list |
|
|
@@ -173,20 +183,33 @@ Two more rules worth knowing before you point this at a repository you didn't wr
|
|
|
173
183
|
| `.labd/extensions/` | per-project extensions, loaded once trusted |
|
|
174
184
|
|
|
175
185
|
`settings.json` keys, global or per project: `timeout` as `commandTimeoutSeconds`
|
|
176
|
-
(5–600), `effort` (`low`/`medium`/`high`), `checkpoints` (`true` by default),
|
|
177
|
-
`
|
|
178
|
-
`
|
|
186
|
+
(5–600), `effort` (`low`/`medium`/`high`), `checkpoints` (`true` by default),
|
|
187
|
+
`mouse` (`true`; the full-screen session takes the mouse for scrolling), `sidebar`
|
|
188
|
+
(`false`), and `serverUrl` — honoured from a project file only once that project
|
|
189
|
+
is trusted. `mode` is read from the global file only.
|
|
179
190
|
|
|
180
191
|
`LABD_HOME`, `LABD_SERVER_URL`, and `LABD_TOKEN` override the corresponding thing;
|
|
181
192
|
the last is how you run labd in CI without pairing. `NO_COLOR` turns colour off,
|
|
182
193
|
`FORCE_COLOR` turns it on (`FORCE_COLOR=0` off) and wins over everything else, and
|
|
183
194
|
`LABD_NO_MOTION` skips the opening animation.
|
|
184
195
|
|
|
185
|
-
##
|
|
196
|
+
## Helpers and orchestration
|
|
186
197
|
|
|
187
|
-
labd
|
|
188
|
-
|
|
189
|
-
|
|
198
|
+
**Helpers.** labd can hand a self-contained piece of a job to a helper - another
|
|
199
|
+
labd with the same tools, working from a brief labd writes, whose report comes
|
|
200
|
+
back into the answer. Several can run at once, up to three. A helper is not a way
|
|
201
|
+
around your settings:
|
|
202
|
+
|
|
203
|
+
- a helper has no mode of its own. Its writes and commands ask you exactly when
|
|
204
|
+
labd's would, one card at a time, marked **from a helper**;
|
|
205
|
+
- under `labd -p` nothing can be approved, so a helper's changes are declined and
|
|
206
|
+
the run exits 2;
|
|
207
|
+
- what a helper changed is part of the answer, so `/undo` puts it back too;
|
|
208
|
+
- a helper cannot start helpers of its own.
|
|
209
|
+
|
|
210
|
+
**Orchestration.** `--mode rpc` makes every labd process a driveable agent on
|
|
211
|
+
stdin/stdout, so an orchestrator is a script that spawns several of them, each
|
|
212
|
+
with a mode you choose:
|
|
190
213
|
|
|
191
214
|
```bash
|
|
192
215
|
node examples/orchestrate.mjs "what does this file do?" src/a.ts src/b.ts src/c.ts
|
|
@@ -195,14 +218,6 @@ node examples/orchestrate.mjs "what does this file do?" src/a.ts src/b.ts src/c.
|
|
|
195
218
|
[`examples/orchestrate.mjs`](examples/orchestrate.mjs) is ~140 lines: spawn, send
|
|
196
219
|
`labd/prompt`, read the notification stream, run three at a time.
|
|
197
220
|
|
|
198
|
-
**Why not a tool inside labd.** A `spawn_agent` tool has to decide what mode the
|
|
199
|
-
children run in, and every answer is bad. Inherit the parent's mode and one
|
|
200
|
-
approval becomes N unattended writes. Give children their own mode and the model
|
|
201
|
-
has been handed the one setting it is specifically not allowed to influence.
|
|
202
|
-
Outside, the mode of each child is set by whoever wrote the script, each child
|
|
203
|
-
asks *that script* for approval over the wire, and the orchestrator is code you
|
|
204
|
-
can read. (Pi reaches the same conclusion and suggests tmux.)
|
|
205
|
-
|
|
206
221
|
The protocol is small:
|
|
207
222
|
|
|
208
223
|
| you send | |
|
|
@@ -213,9 +228,9 @@ The protocol is small:
|
|
|
213
228
|
| labd sends | |
|
|
214
229
|
| `labd/ready` | first, on start: protocol, framing, session id, mode, root |
|
|
215
230
|
| `labd/text`, `labd/status`, `labd/done`, `labd/error` | notifications as the turn runs |
|
|
216
|
-
| `labd/tool` `{name, status, input, detail, preview, output}` | each tool step; `preview` is the diff or the command, `output` what came back |
|
|
217
|
-
| `labd/command_output` `{line}` | a running command's own output, as it happens |
|
|
218
|
-
| `labd/approve` `{call, preview}` | **a request to you**
|
|
231
|
+
| `labd/tool` `{name, status, input, detail, preview, output, helper?}` | each tool step; `preview` is the diff or the command, `output` what came back, `helper` `{id, label}` when a helper made the call |
|
|
232
|
+
| `labd/command_output` `{line, key?}` | a running command's own output, as it happens; `key` names a helper's call |
|
|
233
|
+
| `labd/approve` `{call, preview, helper?}` | **a request to you** - answer `{approved: true\|false}`; `helper` names the helper asking |
|
|
219
234
|
|
|
220
235
|
Closing stdin ends the session: any turn in flight finishes, the conversation is
|
|
221
236
|
handed over for memory, and the process exits 0.
|
|
@@ -256,7 +271,7 @@ in `~/.labd/extensions`.
|
|
|
256
271
|
## Development
|
|
257
272
|
|
|
258
273
|
```bash
|
|
259
|
-
npm run build # bundle to dist/labd.js
|
|
274
|
+
npm run build # bundle to dist/labd.js (and dist/labd.cjs)
|
|
260
275
|
npm test # vitest (build first — the e2e suite spawns the binary)
|
|
261
276
|
npm run check # typecheck + tests
|
|
262
277
|
```
|