@a-t-h-i/bot-lobby 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +238 -10
- package/package.json +5 -2
- package/prompts/master.md +12 -0
- package/prompts/panel.md +44 -0
- package/prompts/planner.md +69 -0
- package/prompts/quickfix.md +41 -0
- package/src/execution/agent-runner.ts +7 -2
- package/src/execution/pi-runner.ts +25 -0
- package/src/index.ts +3 -0
- package/src/lobby/ask.ts +226 -0
- package/src/lobby/feed.ts +253 -0
- package/src/lobby/issues.ts +227 -0
- package/src/lobby/keys.ts +51 -0
- package/src/lobby/layout.ts +363 -0
- package/src/lobby/markdown.ts +48 -0
- package/src/lobby/planner.ts +581 -0
- package/src/lobby/quickfix.ts +227 -0
- package/src/lobby/runtime.ts +591 -0
- package/src/lobby/tabs/home.ts +242 -0
- package/src/lobby/tabs/issues.ts +72 -0
- package/src/lobby/tabs/metrics.ts +275 -0
- package/src/lobby/tabs/plan.ts +242 -0
- package/src/lobby/tabs/quickfix.ts +129 -0
- package/src/lobby/tabs/tasks.ts +243 -0
- package/src/lobby/view.ts +1610 -0
- package/src/pi/activity.ts +120 -0
- package/src/pi/commands.ts +19 -57
- package/src/pi/events.ts +5 -2
- package/src/pi/model-support.ts +34 -0
- package/src/pi/run-summary.ts +2 -0
- package/src/pi/settings-ui.ts +69 -1
- package/src/pi/start-task.ts +63 -0
- package/src/pi/tools.ts +2 -2
- package/src/pi/ui.ts +116 -55
- package/src/schemas/configuration.ts +102 -3
- package/src/schemas/findings.ts +6 -0
- package/src/schemas/task.ts +1 -0
- package/src/state/backlog.ts +106 -0
- package/src/state/comments.ts +136 -0
- package/src/state/metrics.ts +305 -0
- package/src/workflow/workflow.ts +39 -7
package/README.md
CHANGED
|
@@ -67,13 +67,17 @@ recorded in the task.
|
|
|
67
67
|
pi install npm:@juicesharp/rpiv-ask-user-question
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
It is optional. Without it `clarify` still works through Pi's
|
|
71
|
-
`select`/`input` prompts (or the Master asks in plain text), just with
|
|
72
|
-
structure.
|
|
70
|
+
It is optional for the Master. Without it `clarify` still works through Pi's
|
|
71
|
+
built-in `select`/`input` prompts (or the Master asks in plain text), just with
|
|
72
|
+
less structure. The lobby's planning panel uses the same questionnaire on its
|
|
73
|
+
own — the library ships as a bot-lobby dependency, so the panel's questions
|
|
74
|
+
arrive one at a time with options whether or not you install the tool for the
|
|
75
|
+
Master (see [The lobby](#the-lobby)).
|
|
73
76
|
|
|
74
77
|
## Usage
|
|
75
78
|
|
|
76
79
|
```
|
|
80
|
+
/bot-lobby Open the lobby (alt+l): tasks, planning, quick fixes, metrics
|
|
77
81
|
/bot-lobby <request> Start a task and hand it to the Master
|
|
78
82
|
/bot-lobby status [taskId] Active task, state, approvals, blockers, legal next states
|
|
79
83
|
/bot-lobby tasks Task list (plus any unreadable task state)
|
|
@@ -89,8 +93,181 @@ structure.
|
|
|
89
93
|
/bot-lobby-settings Same as the settings subcommand
|
|
90
94
|
/bot-lobby minimize|restore Hide or restore bot-lobby for this session (ctrl+shift+m)
|
|
91
95
|
/bot-lobby claim <taskId> Take ownership of an orphaned task
|
|
96
|
+
/bot-lobby lobby | help Open the lobby, or show this list
|
|
92
97
|
```
|
|
93
98
|
|
|
99
|
+
## The lobby
|
|
100
|
+
|
|
101
|
+
The lobby is bot-lobby's full-screen home: a tabbed view over every task in the
|
|
102
|
+
project, your planning, quick fixes and model performance, with one prompt at
|
|
103
|
+
the bottom whose target follows the tab. It opens by itself when
|
|
104
|
+
this session starts (or resumes) a task — the small zen widget returns whenever
|
|
105
|
+
you hide it — and `alt+l` or `/bot-lobby` opens and hides it at any time, with
|
|
106
|
+
or without a task.
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
◆ bot-lobby │ 1 Lobby 2 Tasks 2 3 Plan 2? 4 Quick fix ⠋ 5 Metrics ⠋ TASK-add-login implementing Alt+H keys
|
|
110
|
+
(the zen scene: the oracle, DEV · DESIGN · RESEARCH · QA, the plan checklist)
|
|
111
|
+
╭ Conversation · TASK-add-login ─────────────── Alt+C ╮ ╭ Activity ──────────────────────────────── Alt+A ╮
|
|
112
|
+
│ you ▸ add a login page with email + password │ │ 12:04 MASTER ✓ scouting designer, backend │
|
|
113
|
+
│ oracle ▸ Proposal │ │ 12:06 DEV ⠋ reading auth.ts… │
|
|
114
|
+
│ • LoginForm component │ │ 12:06 DESIGN ⠋ editing LoginForm.tsx… │
|
|
115
|
+
│ • POST /api/login with rate limiting │ │ 12:06 QUICK FIX ✓ done: rename getUser │
|
|
116
|
+
╰──────────────────────────────────────────────────────╯ ╰─────────────────────────────────────────────────╯
|
|
117
|
+
╭ Thinking ────────────────────────────────────────────────────────────────────────────────── DEV · 12s ago ╮
|
|
118
|
+
│ The auth module already exposes a session helper; reuse it rather than adding a new one. │
|
|
119
|
+
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
120
|
+
── message the oracle ───────────────────────────────────────────────────────────────────────────────────────
|
|
121
|
+
_
|
|
122
|
+
TYPE enter send shift+enter newline esc browse tab next tab alt+h keys alt+l hide
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- **1 Lobby** — the task's zen scene, then the conversation with the oracle
|
|
126
|
+
(its text only: no tool rows, no thinking), an activity log that narrates
|
|
127
|
+
every tool call in plain words (`reading index.html…`, `searching for
|
|
128
|
+
"router" in src`, `running npm test`, `delegating to backend: Step 2 …`) from
|
|
129
|
+
the Master and every subagent, and a single **Thinking** pane — the one place
|
|
130
|
+
thoughts show up: the oracle's live thought as it streams, and each finished
|
|
131
|
+
thought from a subagent, quick fix or the planner (pi's own transcript,
|
|
132
|
+
behind the lobby, still carries the oracle's thinking blocks; `ctrl+t`
|
|
133
|
+
collapses them there). The oracle's replies render as Markdown. Every pane
|
|
134
|
+
can be hidden and brought back — `alt+z` the scene, `alt+c` the
|
|
135
|
+
conversation, `alt+a` the activity log, `alt+k` thinking — and the rest take
|
|
136
|
+
its room; the choice is remembered (`lobby.panels`). Each pane scrolls on
|
|
137
|
+
its own (see **Scrolling** below), and a pane scrolled back stays on what
|
|
138
|
+
you are reading while new lines arrive. The prompt talks to the
|
|
139
|
+
oracle (while it works, enter steers the running turn; `esc` stops it); with
|
|
140
|
+
no task, it starts one.
|
|
141
|
+
- **2 Tasks** — every task in the project: this session's, the ones other pi
|
|
142
|
+
sessions are driving, pending plans saved from the planner, and recently
|
|
143
|
+
finished ones. The detail pane shows the request, the approved plan with its
|
|
144
|
+
step checklist, your comments on it, amendments, what the task waits on and
|
|
145
|
+
its recent runs. `c` comments on the selected task's plan (see below), `s`
|
|
146
|
+
starts a pending plan as a task in this session, `d` twice discards one.
|
|
147
|
+
- **3 Plan** — task planning mode with a planning panel. Describe what you
|
|
148
|
+
want and every seat grills you from its own domain, on the model and
|
|
149
|
+
thinking level its settings name: **DEV** (APIs, data, errors, security,
|
|
150
|
+
performance), **DESIGN** (flows, states, copy, visual language,
|
|
151
|
+
accessibility), **QA** (acceptance criteria, test strategy, edge cases,
|
|
152
|
+
definition of done) and **RESEARCH** (libraries, versions, docs and prior
|
|
153
|
+
art, with the web tools when `pi-web-access` is installed). The **oracle**
|
|
154
|
+
chairs on the Planner model: it reads the seats' questions and notes, folds
|
|
155
|
+
every answer into the draft plan (with a *Decisions by domain* section) and
|
|
156
|
+
asks only what no single seat owns. Each round the seats run in parallel,
|
|
157
|
+
read-only, then the oracle. Every question comes with two to four options,
|
|
158
|
+
the seat's recommendation first, and the oracle puts them to you **one at a
|
|
159
|
+
time** through the ask-user-question questionnaire: a tab per question
|
|
160
|
+
labelled with the seat that asked it (`QA`, `DEV`…), its options with what
|
|
161
|
+
each means, and a row to type your own answer or add a note (four questions
|
|
162
|
+
per questionnaire; more follow in the next one). It opens by itself when a
|
|
163
|
+
round ends while the Plan tab is showing (`lobby.autoAsk`), and otherwise
|
|
164
|
+
when you press `enter` on the empty prompt or `a` while browsing; `esc` puts
|
|
165
|
+
it away with your answers so far kept, and `enter` resumes. Your answers go
|
|
166
|
+
back attributed (`3. [QA] Which browsers must pass? → evergreen only`), and
|
|
167
|
+
every seat reads every answer the next round — so the agents that later
|
|
168
|
+
build the task start aligned. You can still type a free reply instead.
|
|
169
|
+
Without the library the same questions come through pi's own select and
|
|
170
|
+
input dialogs. A roster shows what each seat is doing and whether it is
|
|
171
|
+
READY; the plan is READY only when every seat and the oracle agree. The
|
|
172
|
+
draft plan renders as Markdown (headings, lists, code, tables) beside the
|
|
173
|
+
conversation, followed by what each seat said the plan must respect.
|
|
174
|
+
**Comment on any line of the draft**: click it, or press `enter` to move to
|
|
175
|
+
the draft, pick a line with `↑↓` and press `c`, then type the comment. The
|
|
176
|
+
line is marked `◆` with your comment beneath it, and the comment goes to the
|
|
177
|
+
panel with your answers — or starts a round by itself when no question is
|
|
178
|
+
open. While browsing, `1`–`4` seat or unseat DEV, DESIGN, QA and RESEARCH
|
|
179
|
+
for the next round, `s` saves the plan to the pending tasks list, `n` starts
|
|
180
|
+
over, `r` retries a round that failed or lost a seat, `x` stops one, and `m`
|
|
181
|
+
opens the oracle's (Planner) settings.
|
|
182
|
+
- **4 Quick fix** — a direct prompt, the way you would ask pi, that skips the
|
|
183
|
+
whole workflow: one coding agent (full tools) makes the change right away
|
|
184
|
+
while any task keeps running. Quick fixes run one at a time in the order you
|
|
185
|
+
send them; each shows its steps and final report, and `x` cancels one. A
|
|
186
|
+
request that turns out to be large is reported back instead of attempted.
|
|
187
|
+
`m` opens the quick fix agent's settings — model, thinking level, time
|
|
188
|
+
limit and instructions — right there (the same entry as in
|
|
189
|
+
`/bot-lobby settings`); the tab shows what it runs on.
|
|
190
|
+
- **5 Metrics** — model performance across every Master turn, subagent run,
|
|
191
|
+
quick fix, planning seat and oracle planning turn, as a dashboard: tiles for
|
|
192
|
+
runs (with a sparkline of recent run times), success rate, average and p90
|
|
193
|
+
run time, cost and tasks; average run time per model and thinking level as
|
|
194
|
+
bars; success rate per model as meters marked `✓` (≥90%), `!` (≥70%) or `✗`;
|
|
195
|
+
where the time goes as one bar split by agent, with a legend, and how long a
|
|
196
|
+
task takes from request to done by the oracle's model; then the full table —
|
|
197
|
+
runs, success, mean/median/p90 time, turns, tools, tokens, output tokens per
|
|
198
|
+
second and cost (columns drop from the right on narrow terminals). `g`
|
|
199
|
+
splits the table by agent, `s` cycles the sort (runs, average time, success,
|
|
200
|
+
cost).
|
|
201
|
+
|
|
202
|
+
The **Issues** tab (GitHub issues through the `gh` CLI, planned into tasks
|
|
203
|
+
through the Plan tab) is switched off for now; `"lobby": { "issues": true }`
|
|
204
|
+
brings it back as tab 5.
|
|
205
|
+
|
|
206
|
+
**Keys.** Like a modal editor, the lobby has a typing mode (keys go to the
|
|
207
|
+
prompt) and a browsing mode (`esc`; arrows move through lists, single keys run
|
|
208
|
+
the tab's commands, and on Lobby, Plan and Quick fix any other key resumes
|
|
209
|
+
typing). These work in both modes:
|
|
210
|
+
|
|
211
|
+
| Key | Does |
|
|
212
|
+
| --- | --- |
|
|
213
|
+
| `alt+l` | hide the lobby (back to pi) |
|
|
214
|
+
| `alt+h` (or `?` while browsing) | show every key, and the current tab's |
|
|
215
|
+
| `alt+s` | bot-lobby settings: every agent's model, thinking and time limit, and the lobby's switches |
|
|
216
|
+
| `ctrl+f` (or `/` while browsing) | search the current tab |
|
|
217
|
+
| `tab` / `shift+tab`, `alt+1`…`alt+5` | switch tabs |
|
|
218
|
+
| `alt+z` / `alt+c` / `alt+a` / `alt+k` | show or hide the zen scene / conversation / activity log / thinking |
|
|
219
|
+
| `pageup` / `pagedown` | scroll the focused pane a page |
|
|
220
|
+
| `ctrl+c` | clear the prompt, or hide the lobby when it is empty |
|
|
221
|
+
|
|
222
|
+
Every shortcut can be rebound under `lobby.keys` in the config, by action name:
|
|
223
|
+
`hide`, `help`, `settings`, `search`, `nextTab`, `prevTab`, `toggleScene`,
|
|
224
|
+
`toggleConversation`, `toggleActivity`, `toggleThinking`, `scrollUp`,
|
|
225
|
+
`scrollDown` — e.g. `"keys": { "toggleThinking": "alt+t" }`. Pick keys that
|
|
226
|
+
never type a character (`alt+…`, `ctrl+…`, `f1`…).
|
|
227
|
+
|
|
228
|
+
**Scrolling.** Every pane scrolls on its own and shows a scrollbar in its
|
|
229
|
+
right border when it holds more than fits. While browsing, `←`/`→` move
|
|
230
|
+
between the tab's panes (the conversation, activity log and thinking on
|
|
231
|
+
Lobby; the conversation and draft on Plan; the list and detail on Tasks and
|
|
232
|
+
Quick fix) and the focused one lights up; `↑`/`↓` scroll it a line (or move
|
|
233
|
+
a list's selection, or the draft's cursor), `pageup`/`pagedown` a page, and
|
|
234
|
+
`home`/`end` jump to its oldest line or back to its newest. The conversation,
|
|
235
|
+
activity log and thinking are newest-last: scrolled back, a pane shows `↓N`
|
|
236
|
+
for the lines below it and holds still while new ones arrive; `end` follows
|
|
237
|
+
the newest again. Details stop at their last line. The Thinking pane keeps
|
|
238
|
+
every recent thought, so earlier ones are a scroll away.
|
|
239
|
+
|
|
240
|
+
**Search.** `ctrl+f` opens a search bar above the prompt; as you type, the tab
|
|
241
|
+
narrows to what matches and every match is highlighted: the conversation,
|
|
242
|
+
activity log and thoughts on Lobby; tasks and plans (by id, title, request,
|
|
243
|
+
proposal or plan) on Tasks; the conversation on Plan (the draft stays whole,
|
|
244
|
+
highlighted); jobs on Quick fix; runs (by agent, model, thinking level, kind or
|
|
245
|
+
task) on Metrics. `enter` keeps the search while you browse the results,
|
|
246
|
+
`esc` clears it, and each tab keeps its own.
|
|
247
|
+
|
|
248
|
+
**Mouse.** Clicking a tab opens it, clicking a pane gives it the keys,
|
|
249
|
+
clicking a draft plan line comments on it, clicking the prompt starts typing,
|
|
250
|
+
and the wheel scrolls whichever pane is under the pointer. In pi's regular
|
|
251
|
+
screen the lobby turns mouse reporting on only while it is showing (hold
|
|
252
|
+
`shift` to select text with the mouse); in full-screen pi, pi reports the
|
|
253
|
+
mouse itself. `"lobby": { "mouse": false }` turns clicks off.
|
|
254
|
+
|
|
255
|
+
Anything that needs pi itself —
|
|
256
|
+
built-in slash commands, `/model`, the tool-row toggle — works with the lobby
|
|
257
|
+
hidden; bot-lobby's own `/bot-lobby …` commands also work from the Lobby
|
|
258
|
+
prompt. When the Master asks you something (an approval, a clarifying
|
|
259
|
+
question), the lobby steps aside for the dialog and comes back once you answer.
|
|
260
|
+
|
|
261
|
+
**Plan comments.** A comment on a task's plan is saved beside the task
|
|
262
|
+
(`comments.jsonl`) from any session, and the session that owns the task passes
|
|
263
|
+
new comments to its oracle — right away when you comment in that session,
|
|
264
|
+
within a few seconds from another one, held while the task is paused or the
|
|
265
|
+
session is minimized. The oracle treats a comment like an amendment and calls
|
|
266
|
+
`orchestrate action=plan` with the full revised plan, which replaces the
|
|
267
|
+
approved plan while implementing or reviewing, keeps finished steps done and
|
|
268
|
+
marks the comments addressed (`○` waiting, `◐` sent to the oracle, `✓` plan
|
|
269
|
+
amended). Before a plan exists, a comment asks for a revised proposal instead.
|
|
270
|
+
|
|
94
271
|
## Sessions and ownership
|
|
95
272
|
|
|
96
273
|
A task is owned by the pi session that started it (`ctx.sessionManager` id,
|
|
@@ -116,7 +293,8 @@ every in-flight subagent process.
|
|
|
116
293
|
|
|
117
294
|
While the owning session has a task active, its transcript switches to a zen view: `orchestrate` rows
|
|
118
295
|
and the built-in spinner are hidden, and a widget above the editor animates the
|
|
119
|
-
task
|
|
296
|
+
task (the same scene heads the lobby's first tab; the widget shows while the
|
|
297
|
+
lobby is hidden). At 72 columns and wider it draws a large scene: a header box with the task
|
|
120
298
|
title and state in its top border, a progress bar, and a metadata row with
|
|
121
299
|
elapsed time, quiet-mode hint and task id; an oracle tower with a twinkling
|
|
122
300
|
aura (drifting z's while dormant), a radiant orb crown, two window eyes, a
|
|
@@ -214,7 +392,7 @@ One tool, every workflow step. It is the Master's only way to move a task.
|
|
|
214
392
|
| `scout` | created…synthesizing | Run domain reconnaissance in parallel; repeat later to target-verify a claim |
|
|
215
393
|
| `research` | any active | Summon the read-only Researcher (domain + instruction) for cited internet evidence; persists the report for audit |
|
|
216
394
|
| `propose` | created…awaiting_approval | Record the proposal, request approval, handle approve/amend/decline |
|
|
217
|
-
| `plan` | planning | Record the internal plan (all §12 areas required) |
|
|
395
|
+
| `plan` | planning, implementing, reviewing | Record the internal plan (all §12 areas required); later, replace it with an amended plan (addresses lobby comments) |
|
|
218
396
|
| `implement` | planning, implementing, reviewing | Delegate a step to a domain Worker, or several domains at once with `assignments` (parallel, sharing files through the file desk) |
|
|
219
397
|
| `qa` | implementing, reviewing | Run the QA gate — the only review — over the whole feature |
|
|
220
398
|
| `knowledge` | any active | Record Master-approved knowledge or a decision |
|
|
@@ -339,6 +517,9 @@ top-level `/bot-lobby-settings`) and persist globally to
|
|
|
339
517
|
},
|
|
340
518
|
"scout": { "model": "anthropic/claude-haiku-4-5-20251001", "timeoutMs": 480000 },
|
|
341
519
|
"researcher": { "model": "anthropic/claude-sonnet-5", "thinking": "low", "instructions": "", "timeoutMs": 600000 },
|
|
520
|
+
"quickFix": { "model": "anthropic/claude-sonnet-5", "thinking": "low", "instructions": "", "timeoutMs": 600000 },
|
|
521
|
+
"planner": { "model": "anthropic/claude-sonnet-5", "thinking": "high", "instructions": "", "timeoutMs": 300000 },
|
|
522
|
+
"lobby": { "autoOpen": true, "planningPanel": ["backend", "designer", "qa", "researcher"], "autoAsk": true, "issues": false, "mouse": true },
|
|
342
523
|
"workflow": {
|
|
343
524
|
"maxReviewIterations": 2,
|
|
344
525
|
"maxParallelScouts": 3,
|
|
@@ -373,6 +554,38 @@ visible; only the master keeps `inherit`, since it is the session itself.
|
|
|
373
554
|
Each subagent entry has a `timeoutMs` (default 15 min; scouts 8, researcher 10),
|
|
374
555
|
falling back to `workflow.agentTimeoutMs`.
|
|
375
556
|
|
|
557
|
+
The lobby's two agents have entries of their own: `quickFix` (the direct-change
|
|
558
|
+
agent, `low` thinking and 10 minutes by default) and `planner` (the oracle
|
|
559
|
+
chairing the planning panel, `high` thinking; its time limit bounds one round
|
|
560
|
+
for every seat, 5 minutes by default). Both appear in `/bot-lobby settings`,
|
|
561
|
+
take custom instructions, and run on the session's model until you pin one.
|
|
562
|
+
Planning seats reuse their domain's entry — DEV the Backend's, DESIGN the
|
|
563
|
+
Designer's, QA the QA's, RESEARCH the Researcher's model, thinking and
|
|
564
|
+
instructions — so a seat plans on the model that will later build its part.
|
|
565
|
+
The `lobby` entry shapes the lobby itself; `/bot-lobby settings` → **Lobby**
|
|
566
|
+
flips its switches, and key rebinding lives in the file:
|
|
567
|
+
|
|
568
|
+
```json
|
|
569
|
+
"lobby": {
|
|
570
|
+
"autoOpen": true,
|
|
571
|
+
"planningPanel": ["backend", "designer", "qa", "researcher"],
|
|
572
|
+
"autoAsk": true,
|
|
573
|
+
"issues": false,
|
|
574
|
+
"mouse": true,
|
|
575
|
+
"panels": { "scene": true, "conversation": true, "activity": true, "thinking": true },
|
|
576
|
+
"keys": { "toggleThinking": "alt+t" }
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
`planningPanel` names the seats a new planning session starts with (every
|
|
581
|
+
seat by default; `[]` lets the oracle plan alone); `autoOpen` opens the lobby
|
|
582
|
+
by itself when this session starts or resumes a task; `autoAsk` puts the
|
|
583
|
+
panel's questions to you as soon as a round ends while the Plan tab is
|
|
584
|
+
showing (otherwise `enter` on the empty prompt does); `issues` shows the
|
|
585
|
+
GitHub Issues tab (off for now); `mouse` turns clicks and the wheel on;
|
|
586
|
+
`panels` is which Lobby panes show (the pane keys update it); `keys` rebinds
|
|
587
|
+
shortcuts by action name.
|
|
588
|
+
|
|
376
589
|
`thinking` must be one of `off`, `minimal`, `low`, `medium`, `high`, `xhigh`,
|
|
377
590
|
`max`; a legacy `inherit` or unknown value falls back to `medium`. The thinking
|
|
378
591
|
picker lists only the levels the selected model supports. Switching to a model
|
|
@@ -416,8 +629,11 @@ and the output contract — and an empty layer is dropped.
|
|
|
416
629
|
├── Backend/knowledge/ knowledge.md, engineering-standards.md, decisions.md, completed-tasks.md
|
|
417
630
|
├── QA/knowledge/ knowledge.md, testing-standards.md, decisions.md, completed-tasks.md
|
|
418
631
|
├── archive/<Agent>/ previous knowledge versions (outside all retrieval paths)
|
|
632
|
+
├── backlog/PLAN-<slug>.json pending tasks saved from the planner (optionally linked to an issue)
|
|
633
|
+
├── metrics.jsonl one line per finished run of any agent, for the Metrics tab
|
|
419
634
|
└── tasks/TASK-<stamp>/
|
|
420
635
|
├── state.json the task record (kept after completion)
|
|
636
|
+
├── comments.jsonl your lobby comments on the plan and their delivery (append-only)
|
|
421
637
|
├── proposal.md scratchpads: deleted on completion
|
|
422
638
|
├── plan.md
|
|
423
639
|
├── designer.md backend.md qa.md
|
|
@@ -465,10 +681,22 @@ src/
|
|
|
465
681
|
├── desk/ File desk for parallel workers: checkout table, socket, worker extension
|
|
466
682
|
├── knowledge/ Paths, store (single write path), selector, compactor
|
|
467
683
|
├── prompts/ Layer loader + compiler
|
|
468
|
-
├──
|
|
684
|
+
├── lobby/
|
|
685
|
+
│ ├── runtime.ts Mounts the full-screen lobby on pi's TUI, dialogs hand-off, comment delivery, Master metrics
|
|
686
|
+
│ ├── view.ts The tabbed view: tab bar, per-tab prompt, typing/browsing modes, search, help, mouse
|
|
687
|
+
│ ├── keys.ts The shortcut table and its config overrides
|
|
688
|
+
│ ├── ask.ts The panel's questions through the ask-user-question questionnaire (or pi's dialogs)
|
|
689
|
+
│ ├── markdown.ts Markdown through pi's renderer, cached per theme and width
|
|
690
|
+
│ ├── tabs/ Pure renderers: home, tasks, plan, quickfix, issues, metrics
|
|
691
|
+
│ ├── feed.ts Activity log, thinking pane and conversation store
|
|
692
|
+
│ ├── quickfix.ts Direct-change jobs, one at a time
|
|
693
|
+
│ ├── planner.ts The planning panel: seats and the oracle per round, reply parsing, saving a plan
|
|
694
|
+
│ ├── issues.ts GitHub issues through the gh CLI
|
|
695
|
+
│ └── layout.ts Boxes, exact-width columns, wrapping, highlights, bars, meters and sparklines
|
|
696
|
+
├── state/ Project root, config, task persistence, state mutation, comments, backlog, metrics
|
|
469
697
|
├── schemas/ Task, agent, findings, configuration types
|
|
470
698
|
└── pi/ Commands, lifecycle, orchestrate tool, status widget
|
|
471
|
-
prompts/ global, master, designer, backend, qa, scout, worker, reviewer, researcher
|
|
699
|
+
prompts/ global, master, designer, backend, qa, scout, worker, reviewer, researcher, quickfix, planner, panel
|
|
472
700
|
```
|
|
473
701
|
|
|
474
702
|
Prompts are composed, never duplicated: `global + domain + role + task context +
|
|
@@ -518,7 +746,7 @@ compaction, bounded review loops, dependency/architecture approval, retries,
|
|
|
518
746
|
cancellation, corrupted-state detection, and the commands/status UI.
|
|
519
747
|
|
|
520
748
|
Deliberately deferred (matching the build plan): worktree-based isolation for
|
|
521
|
-
parallel Workers (they share one working tree through the file desk)
|
|
522
|
-
dashboard, cost/token analytics beyond per-run usage, and
|
|
749
|
+
parallel Workers (they share one working tree through the file desk) and
|
|
523
750
|
cross-platform runtime abstractions. The internal module boundaries keep those
|
|
524
|
-
extractable.
|
|
751
|
+
extractable. The lobby (see above) has since added the full-screen dashboard
|
|
752
|
+
and per-model performance analytics.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a-t-h-i/bot-lobby",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Structured multi-agent software engineering orchestrator for Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,11 +38,14 @@
|
|
|
38
38
|
"typebox": "*"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@earendil-works/pi-coding-agent": "0.87.0",
|
|
42
41
|
"@earendil-works/pi-ai": "0.87.0",
|
|
42
|
+
"@earendil-works/pi-coding-agent": "0.87.0",
|
|
43
43
|
"@earendil-works/pi-tui": "0.87.0",
|
|
44
44
|
"@types/node": "^22.10.0",
|
|
45
45
|
"typebox": "1.3.27",
|
|
46
46
|
"typescript": "^5.7.0"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@juicesharp/rpiv-ask-user-question": "^2.11.0"
|
|
47
50
|
}
|
|
48
51
|
}
|
package/prompts/master.md
CHANGED
|
@@ -77,6 +77,18 @@ asked. If the user
|
|
|
77
77
|
amends the request, reassess affected assumptions — never silently reinterpret
|
|
78
78
|
an amendment.
|
|
79
79
|
|
|
80
|
+
## Lobby comments
|
|
81
|
+
|
|
82
|
+
The user can comment on the approved plan (or the proposal) from the lobby, in
|
|
83
|
+
this session or another one. Each comment reaches you as a message naming the
|
|
84
|
+
task; open ones are also listed under `Open plan comments` in your task
|
|
85
|
+
context. Treat a comment like an amendment: reassess what it affects, then call
|
|
86
|
+
`orchestrate action=plan` with the full revised plan (it replaces the current
|
|
87
|
+
one while implementing or reviewing, keeps finished steps done, and marks the
|
|
88
|
+
comments addressed) before delegating more work. Before a plan exists, revise
|
|
89
|
+
the proposal and call `action=propose` again. If a comment needs no change,
|
|
90
|
+
say why in one line.
|
|
91
|
+
|
|
80
92
|
## Delegation
|
|
81
93
|
|
|
82
94
|
Assign work to the correct domain; never ask one domain to do another's. A
|
package/prompts/panel.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Planning Panel Member
|
|
2
|
+
|
|
3
|
+
You sit on the planning panel for a task that has not started yet. The panel
|
|
4
|
+
is the oracle plus one member per domain — DEV, DESIGN, QA and RESEARCH — and
|
|
5
|
+
the user answers everyone's questions in one conversation, so every agent that
|
|
6
|
+
later works on the task starts from the same decisions.
|
|
7
|
+
|
|
8
|
+
You never write code or change files. You may read the repository (and, for
|
|
9
|
+
RESEARCH, the web) to ask sharper questions and to state facts.
|
|
10
|
+
|
|
11
|
+
## Each round
|
|
12
|
+
|
|
13
|
+
You receive the conversation so far, including every panel member's earlier
|
|
14
|
+
questions and the user's answers, and the oracle's current draft plan.
|
|
15
|
+
|
|
16
|
+
- Ask only what your seat owns (below), and only what would change how the
|
|
17
|
+
task is built or verified. Never repeat a question that has been answered,
|
|
18
|
+
or one another member already asked this round.
|
|
19
|
+
- Ask at most two questions, the most important first. Make each specific and
|
|
20
|
+
answerable, and give it two to four options the user can pick from, your
|
|
21
|
+
recommendation first with `(Recommended)` after its label. The user can
|
|
22
|
+
always type their own answer instead, so do not add an "Other" option.
|
|
23
|
+
- If an answer from the user is vague or conflicts with what you see in the
|
|
24
|
+
repository, say so and ask again.
|
|
25
|
+
- Report what the plan must respect from your seat under Notes: facts from
|
|
26
|
+
files you read (name them), constraints, risks, what "done" means for you.
|
|
27
|
+
- When nothing in your seat is open any more, set the status to READY and ask
|
|
28
|
+
nothing.
|
|
29
|
+
|
|
30
|
+
## Output format
|
|
31
|
+
|
|
32
|
+
## Status
|
|
33
|
+
OPEN or READY
|
|
34
|
+
|
|
35
|
+
## Questions
|
|
36
|
+
1. The question, ending with a question mark?
|
|
37
|
+
- Short label (Recommended) — what choosing it means
|
|
38
|
+
- Another label — what choosing it means
|
|
39
|
+
|
|
40
|
+
(Two to four options per question, labels of one to five words. Omit
|
|
41
|
+
Questions when READY.)
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
- …
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Task Planner
|
|
2
|
+
|
|
3
|
+
You are the oracle chairing a planning panel: you help the user turn an idea
|
|
4
|
+
(or a GitHub issue) into a task plan that the team of agents can execute
|
|
5
|
+
without guessing. The panel's domain members — DEV, DESIGN, QA and RESEARCH —
|
|
6
|
+
ask the user their own questions each round; you own the plan and the
|
|
7
|
+
questions no single domain owns. You are relentless: together you grill the
|
|
8
|
+
user until every decision that changes the implementation is made. You never
|
|
9
|
+
write code and never change files; you may read the repository to ask
|
|
10
|
+
informed questions and to ground the plan in what exists.
|
|
11
|
+
|
|
12
|
+
## Each turn
|
|
13
|
+
|
|
14
|
+
You receive the conversation so far (every member's questions and the user's
|
|
15
|
+
answers) and, under `## Panel this round`, each member's status, questions
|
|
16
|
+
and notes. Read the repository when it helps, then reply in the output format
|
|
17
|
+
below.
|
|
18
|
+
|
|
19
|
+
- Fold every member's notes and every answer into the draft plan, so each
|
|
20
|
+
domain's decisions are written down where all agents will read them. When
|
|
21
|
+
members disagree, say so and ask the user to decide.
|
|
22
|
+
- Ask at most three questions of your own, the most important first, and
|
|
23
|
+
only cross-cutting ones the members did not ask: scope and non-goals,
|
|
24
|
+
priorities, trade-offs between domains, sequencing, rollout and rollback.
|
|
25
|
+
Never repeat a member's question. Each one must be specific and answerable.
|
|
26
|
+
- Give every question two to four options the user can pick from, your
|
|
27
|
+
recommendation first with `(Recommended)` after its label. The user answers
|
|
28
|
+
the panel's questions one at a time and can always type their own answer,
|
|
29
|
+
so never add an "Other" option.
|
|
30
|
+
- Challenge answers that are vague, contradictory or risky, and ask again.
|
|
31
|
+
Do not accept "whatever you think" for a decision with real trade-offs:
|
|
32
|
+
propose one and ask the user to confirm it.
|
|
33
|
+
- Ground every claim about the codebase in files you read; name them.
|
|
34
|
+
- Keep a draft plan updated every turn so the user sees it converge.
|
|
35
|
+
|
|
36
|
+
Declare the plan READY only when every panel member is READY and nothing
|
|
37
|
+
that would change the implementation is still open. Until then the status is
|
|
38
|
+
GRILLING.
|
|
39
|
+
|
|
40
|
+
## Output format
|
|
41
|
+
|
|
42
|
+
## Status
|
|
43
|
+
GRILLING or READY
|
|
44
|
+
|
|
45
|
+
## Title
|
|
46
|
+
Three to six words naming the task.
|
|
47
|
+
|
|
48
|
+
## Questions
|
|
49
|
+
1. The most important open question?
|
|
50
|
+
- Short label (Recommended) — what choosing it means
|
|
51
|
+
- Another label — what choosing it means
|
|
52
|
+
2. …
|
|
53
|
+
|
|
54
|
+
(Two to four options per question, labels of one to five words. Omit the
|
|
55
|
+
Questions section when READY.)
|
|
56
|
+
|
|
57
|
+
## Plan
|
|
58
|
+
The current draft, in Markdown:
|
|
59
|
+
|
|
60
|
+
### Objective
|
|
61
|
+
### Scope and non-goals
|
|
62
|
+
### Acceptance criteria
|
|
63
|
+
### Affected areas
|
|
64
|
+
(files, modules and domains: designer, backend, qa)
|
|
65
|
+
### Decisions by domain
|
|
66
|
+
(what the user decided for DEV, DESIGN, QA and RESEARCH, one bullet each)
|
|
67
|
+
### Steps
|
|
68
|
+
1. …
|
|
69
|
+
### Risks and open points
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Quick Fix Agent
|
|
2
|
+
|
|
3
|
+
You make one small, direct code change the user asked for from the bot-lobby
|
|
4
|
+
lobby. There is no scouting, proposal, plan or review round: the user wants
|
|
5
|
+
the change now, the way they would ask pi directly.
|
|
6
|
+
|
|
7
|
+
## How to work
|
|
8
|
+
|
|
9
|
+
- Read only what you need to make the change safely; follow the file's
|
|
10
|
+
existing conventions.
|
|
11
|
+
- Make the smallest correct change that does exactly what was asked. Do not
|
|
12
|
+
refactor, rename or tidy anything else.
|
|
13
|
+
- If the request is ambiguous, pick the most reasonable reading and say which
|
|
14
|
+
one you chose in your report; do not stop to ask.
|
|
15
|
+
- If the change turns out to be large (many files, a new dependency, an
|
|
16
|
+
architecture change), make no edits and report what it would take, so the
|
|
17
|
+
user can plan it as a task instead.
|
|
18
|
+
- Run a quick targeted check when one exists (the nearest test file, a
|
|
19
|
+
typecheck of the touched package) with a bash `timeout`; never start dev
|
|
20
|
+
servers, watchers or background processes.
|
|
21
|
+
- Change files with `edit`/`write`, never through shell redirection or
|
|
22
|
+
`sed -i`.
|
|
23
|
+
|
|
24
|
+
## Other agents
|
|
25
|
+
|
|
26
|
+
A bot-lobby task may be running at the same time in this working tree. Touch
|
|
27
|
+
only the files the request needs, re-read a file right before editing it, and
|
|
28
|
+
never revert, reformat or "fix" changes you did not make.
|
|
29
|
+
|
|
30
|
+
## Report
|
|
31
|
+
|
|
32
|
+
End with a short report in this shape:
|
|
33
|
+
|
|
34
|
+
## Done
|
|
35
|
+
One or two sentences on what changed.
|
|
36
|
+
|
|
37
|
+
## Files
|
|
38
|
+
- path — what changed
|
|
39
|
+
|
|
40
|
+
## Checked
|
|
41
|
+
What you ran and the result, or "not checked" with the reason.
|
|
@@ -2,7 +2,7 @@ import type { Domain, Role } from "../schemas/agent.ts";
|
|
|
2
2
|
import type { AgentRun } from "../schemas/findings.ts";
|
|
3
3
|
import { roleSpec } from "../roles/registry.ts";
|
|
4
4
|
import { compilePrompt } from "../prompts/compiler.ts";
|
|
5
|
-
import { activityDetail, activityWord } from "../pi/activity.ts";
|
|
5
|
+
import { activityDetail, activityWord, describeToolCall } from "../pi/activity.ts";
|
|
6
6
|
import { shortDuration, truncate } from "../text.ts";
|
|
7
7
|
import { runPiAgent, spawnPiProcess, type PiStreamEvent, type ProcessRunner } from "./pi-runner.ts";
|
|
8
8
|
|
|
@@ -114,6 +114,7 @@ function baseRun(request: AgentRequest, runId: string, startedAt: string, attemp
|
|
|
114
114
|
output: "",
|
|
115
115
|
attempts,
|
|
116
116
|
startedAt,
|
|
117
|
+
...(request.thinking ? { thinking: request.thinking } : {}),
|
|
117
118
|
...(attempts > 1 ? { note: `retry ${attempts - 1} of ${(request.retries ?? 0)}`, noteKind: "warning" as const } : {}),
|
|
118
119
|
};
|
|
119
120
|
}
|
|
@@ -208,9 +209,13 @@ function createLiveRun(base: AgentRun, request: AgentRequest) {
|
|
|
208
209
|
case "tool_execution_start": {
|
|
209
210
|
const activity = activityWord(event.toolName);
|
|
210
211
|
const detail = activityDetail(event.toolName, event.args);
|
|
211
|
-
|
|
212
|
+
const step = describeToolCall(event.toolName, event.args);
|
|
213
|
+
emit({ activity, detail, step, tools: (state.tools ?? 0) + 1 }, changed(activity, detail) || step !== state.step);
|
|
212
214
|
return;
|
|
213
215
|
}
|
|
216
|
+
case "thought":
|
|
217
|
+
emit({ thought: event.text }, true);
|
|
218
|
+
return;
|
|
214
219
|
case "thinking":
|
|
215
220
|
case "writing":
|
|
216
221
|
emit({ activity: event.type, detail: undefined }, changed(event.type, undefined));
|
|
@@ -61,8 +61,13 @@ export type PiStreamEvent =
|
|
|
61
61
|
| { type: "compaction" }
|
|
62
62
|
| { type: "usage"; input: number; output: number; cost: number; model?: string }
|
|
63
63
|
| { type: "wrap_up" }
|
|
64
|
+
/** One finished thinking block, bounded to `MAX_THOUGHT_CHARS`. */
|
|
65
|
+
| { type: "thought"; text: string }
|
|
64
66
|
| { type: "heartbeat" };
|
|
65
67
|
|
|
68
|
+
/** Longest thought forwarded from a subagent stream. */
|
|
69
|
+
export const MAX_THOUGHT_CHARS = 1500;
|
|
70
|
+
|
|
66
71
|
export interface ProcessRunOptions {
|
|
67
72
|
cwd: string;
|
|
68
73
|
signal?: AbortSignal;
|
|
@@ -215,6 +220,11 @@ export function createStreamCollector(
|
|
|
215
220
|
phase = next;
|
|
216
221
|
onEvent?.({ type: next });
|
|
217
222
|
}
|
|
223
|
+
// One parse per finished thinking block (not per token) forwards the thought itself.
|
|
224
|
+
if (onEvent && line.includes('"thinking_end"')) {
|
|
225
|
+
const thought = finishedThought(line);
|
|
226
|
+
if (thought) onEvent({ type: "thought", text: thought });
|
|
227
|
+
}
|
|
218
228
|
};
|
|
219
229
|
const keep = (line: string) => {
|
|
220
230
|
deltaPhase(line);
|
|
@@ -261,6 +271,21 @@ export function createStreamCollector(
|
|
|
261
271
|
};
|
|
262
272
|
}
|
|
263
273
|
|
|
274
|
+
/** The text of a `thinking_end` message update, trimmed and bounded; undefined for anything else. */
|
|
275
|
+
export function finishedThought(line: string): string | undefined {
|
|
276
|
+
let event: { assistantMessageEvent?: { type?: string; content?: unknown } };
|
|
277
|
+
try {
|
|
278
|
+
event = JSON.parse(line) as typeof event;
|
|
279
|
+
} catch {
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
const update = event?.assistantMessageEvent;
|
|
283
|
+
if (update?.type !== "thinking_end" || typeof update.content !== "string") return undefined;
|
|
284
|
+
const text = update.content.trim();
|
|
285
|
+
if (!text) return undefined;
|
|
286
|
+
return text.length > MAX_THOUGHT_CHARS ? `${text.slice(0, MAX_THOUGHT_CHARS - 1)}…` : text;
|
|
287
|
+
}
|
|
288
|
+
|
|
264
289
|
/** Build the `pi` argv for one isolated, headless RPC agent run; the task goes over stdin. */
|
|
265
290
|
export function buildPiArgs(options: Omit<PiRunOptions, "task"> & { systemPromptFile?: string }): string[] {
|
|
266
291
|
const args = ["--mode", "rpc", "--no-session", "--no-prompt-templates", "--no-themes"];
|
package/src/index.ts
CHANGED
|
@@ -6,9 +6,12 @@ import { onTransition } from "./state/task-state.ts";
|
|
|
6
6
|
import { ping } from "./pi/notify.ts";
|
|
7
7
|
import { isSubagentProcess } from "./pi/quiet.ts";
|
|
8
8
|
import { registerDeskClient } from "./desk/client-extension.ts";
|
|
9
|
+
import { registerLobbyEvents } from "./lobby/runtime.ts";
|
|
9
10
|
|
|
10
11
|
export default function (pi: ExtensionAPI): void {
|
|
11
12
|
registerLifecycle(pi, CONFIG_DIR_NAME);
|
|
13
|
+
// After the lifecycle, so the lobby opens over a task the widget state already knows.
|
|
14
|
+
registerLobbyEvents(pi, CONFIG_DIR_NAME);
|
|
12
15
|
onTransition((task) => ping(task.state, task.title));
|
|
13
16
|
registerCommands(pi, CONFIG_DIR_NAME);
|
|
14
17
|
registerOrchestrateTool(pi, CONFIG_DIR_NAME);
|