@a-t-h-i/bot-lobby 0.6.41 → 0.6.43
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 +28 -187
- package/package.json +1 -1
- package/src/lobby/feed.ts +26 -1
- package/src/lobby/keys.ts +2 -2
- package/src/lobby/service.ts +2 -0
- package/webui/dist/assets/index-6Io6swto.css +2 -0
- package/webui/dist/assets/{index-DXDrQbgq.js → index-KFvb_oCk.js} +14 -13
- package/webui/dist/build.json +49 -33
- package/webui/dist/index.html +2 -2
- package/webui/dist/assets/index-Glz3FAPp.css +0 -2
package/README.md
CHANGED
|
@@ -4,8 +4,6 @@ A [Pi](https://pi.dev) extension for multi-agent software development. Describe
|
|
|
4
4
|
plan with the oracle, and follow the agents in a local browser lobby. Approvals, domain boundaries and QA
|
|
5
5
|
are enforced before anything is called done.
|
|
6
6
|
|
|
7
|
-

|
|
8
|
-
|
|
9
7
|
## Install
|
|
10
8
|
|
|
11
9
|
```bash
|
|
@@ -14,64 +12,35 @@ pi install npm:@a-t-h-i/bot-lobby
|
|
|
14
12
|
|
|
15
13
|
Try it first with `pi -e npm:@a-t-h-i/bot-lobby`, or from a checkout with `pi -e ./src/index.ts`.
|
|
16
14
|
The questionnaire and web tools are built in, so don't also install extensions with the same tool names.
|
|
15
|
+
Requires **Pi 1.0.x** (1.0.1 or later).
|
|
17
16
|
|
|
18
17
|
## Use
|
|
19
18
|
|
|
20
|
-
1. In Pi, run `/bot-lobby add a login page`.
|
|
21
|
-
|
|
19
|
+
1. In Pi, run `/bot-lobby add a login page`. The lobby opens in your browser. `Ctrl+Shift+M` or
|
|
20
|
+
`/bot-lobby on|off` switches bot-lobby on or off; a new Pi session starts with it off.
|
|
22
21
|
2. Answer the oracle's questions and approve its plan, or agree on one with the panel in **Plan** first.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
archive or delete them there. A plan saved as a task leaves that list.
|
|
26
|
-
3. Follow the agents in **Lobby** and **Tasks**: in a task's steps, the one being worked on reads
|
|
27
|
-
`active · 1m 12s`, and each task shows how long its agents have worked on it (idle time left out). Models, effort and time limits are in **Settings**.
|
|
28
|
-
|
|
29
|
-
**Issues** lists the repository's open issues (with `lobby.issues` on), and **Plan it** starts a
|
|
30
|
-
planning session from one. **Git** lists open pull requests; an agent reviews one on request,
|
|
31
|
-
read-only, and nothing is posted to GitHub. Both read GitHub through `gh`.
|
|
22
|
+
3. Follow the agents in **Lobby** and **Tasks**. Their steps fold into one line in the conversation
|
|
23
|
+
and open in place.
|
|
32
24
|
|
|
33
25
|
Small changes go to **Quick fix**. `--task` forces a full task, `--fast` / `--full` picks the workflow,
|
|
34
|
-
and `--branch` / `--worktree` isolates it in git.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
changed lines count, and QA judges any lint suppression a worker adds. **Settings → Linting** sets it
|
|
53
|
-
to off, advise or block. Visual questions come with mockups that expand and scroll side by side.
|
|
54
|
-
|
|
55
|
-
QA is sized to what was built, not to the request. Once the work is in, the classifier
|
|
56
|
-
reads the diff and sets the QA risk. A change with nothing that runs (docs, styles, comments) passes
|
|
57
|
-
on the engine's checks with no QA agent, and a small one gets a light check. One that touches
|
|
58
|
-
security, data, concurrency or orchestration gets a deep, adversarial review. The test budget is a
|
|
59
|
-
ceiling, never a quota, and the Tasks tab shows the classifier's read and why. With it off, the engine's rules decide.
|
|
60
|
-
|
|
61
|
-
If Pi crashes, is killed or loses its terminal, the lobby page keeps everything on screen and
|
|
62
|
-
reconnects when Pi is back. The next Pi started in the project carries on what was running. The
|
|
63
|
-
planning session returns as it was, and a round that was cut off runs again. Queued quick fixes
|
|
64
|
-
run, and every task's session starts again from its saved file, picking up where it stopped. A
|
|
65
|
-
quit on purpose stops this work, and `pi -c` brings back the planning session.
|
|
66
|
-
|
|
67
|
-
A task that is paused, or that no running session drives, shows **Resume** (`R`) in **Tasks**.
|
|
68
|
-
It carries the task on without moving your window: a paused task is unpaused where it runs, and a
|
|
69
|
-
stopped one carries on in a background session, which restarts its own session when its file is found.
|
|
70
|
-
|
|
71
|
-
The **Tasks** screen has **List** and **Board** subtabs. Board groups saved plans and new tasks
|
|
72
|
-
in **Backlog**, active work in **In progress**, and finished work in **Completed**. Abandoned
|
|
73
|
-
work stays labeled in Backlog until archived. Cards open the existing task details and actions;
|
|
74
|
-
archiving removes a card immediately, while the List view can still show the archive.
|
|
26
|
+
and `--branch` / `--worktree` isolates it in git. Workers never commit: the oracle commits only the
|
|
27
|
+
files the task changed, after the project's linter and a QA pass sized to the change's risk.
|
|
28
|
+
|
|
29
|
+
## The lobby
|
|
30
|
+
|
|
31
|
+
- **Lobby**: the conversation with the oracle, each run of agent steps inline, and **Thinking** for
|
|
32
|
+
their reasoning.
|
|
33
|
+
- **Plan**: plan with a panel of agents. **View plan** (`V`) opens the draft in a slide-out, where
|
|
34
|
+
any line takes a comment.
|
|
35
|
+
- **Tasks**: every task across sessions as a list or a board, with its steps, timings and **Resume**.
|
|
36
|
+
- **Issues** and **Git**: plan from an open issue, or have an agent review a pull request read-only.
|
|
37
|
+
Both read GitHub through `gh` and post nothing.
|
|
38
|
+
- **Knowledge**: what each agent has learned about the project, which you can edit, annotate or ask
|
|
39
|
+
about.
|
|
40
|
+
|
|
41
|
+
The rail on the left holds settings, the key list, the theme and sounds. The project switcher
|
|
42
|
+
(`P`) sits in the message box and opens any folder on the machine running bot-lobby. A task running
|
|
43
|
+
in a background session opens its conversation from **Tasks**.
|
|
75
44
|
|
|
76
45
|
| Agent | Does |
|
|
77
46
|
| --- | --- |
|
|
@@ -81,144 +50,16 @@ archiving removes a card immediately, while the List view can still show the arc
|
|
|
81
50
|
| QA | The final quality gate, at the depth the change's risk calls for |
|
|
82
51
|
| RESEARCH | External facts, with sources |
|
|
83
52
|
|
|
84
|
-
## Projects
|
|
85
|
-
|
|
86
|
-
Click the project name (or press `P`) to switch between running projects or choose **Open folder…**.
|
|
87
|
-
The folder browser lists directories on the machine running bot-lobby, not the browser's machine;
|
|
88
|
-
you can browse, go to a parent, or enter an absolute path. An existing project is reused; otherwise
|
|
89
|
-
a dedicated Pi session starts for the folder's detected project root. It loads this copy of bot-lobby
|
|
90
|
-
without other extensions and does not automatically trust project-local resources. Switching projects
|
|
91
|
-
reloads the page and discards unsent drafts. Projects opened this way stop when their hosting lobby
|
|
92
|
-
stops; opening a folder does not start a task or merge work.
|
|
93
|
-
|
|
94
|
-
## Knowledge
|
|
95
|
-
|
|
96
|
-
Each agent keeps what it learns about your project in `.pi/bot-lobby/<Agent>/knowledge/`:
|
|
97
|
-
stable facts (`knowledge.md`), its standards (design language, engineering or testing standards),
|
|
98
|
-
decisions with their reasons, and a short history of completed tasks. Workers only propose
|
|
99
|
-
knowledge and the oracle records it, so nothing gets in unchecked; research stays evidence until
|
|
100
|
-
the oracle keeps it. When a file is long, the classifier picks the parts that matter to each step, so prompts
|
|
101
|
-
stay short. A task cannot complete while a file is over `knowledge.compactionThreshold` (20,000
|
|
102
|
-
characters): the oracle rewrites it shorter, and the version before is kept under `archive/`.
|
|
103
|
-
|
|
104
|
-
The **Knowledge** tab shows the files as a tree, from the project to each agent and the model it
|
|
105
|
-
runs on. Open a file to edit, add or delete its entries, or leave a note on one ("outdated, we
|
|
106
|
-
moved to Redis"). A note travels with its entry into every agent's prompt.
|
|
107
|
-
|
|
108
|
-

|
|
109
|
-
|
|
110
|
-
Ask project questions directly from the **Knowledge** composer. The oracle checks saved knowledge
|
|
111
|
-
first, searches the codebase for missing information, and records verified findings in the relevant
|
|
112
|
-
agent's knowledge. Answers appear in the side pane; the **Chat / Docs** toggle inside the composer
|
|
113
|
-
switches back to the selected document. Questions do not create tasks.
|
|
114
|
-
|
|
115
|
-
## Scripts
|
|
116
|
-
|
|
117
|
-
Jobs that come back (seeding data, regenerating fixtures, a set of checks before review) are kept
|
|
118
|
-
as scripts in `.pi/bot-lobby/scripts/`, shared by every agent, so a step done once is run the next
|
|
119
|
-
time instead of being worked out again, which saves tokens and time. Each is named for what it
|
|
120
|
-
does, in snake_case with its language's extension (`seed_public_holidays.py`,
|
|
121
|
-
`run_changed_tests.sh`), and its first lines say what it is for and how to run it. The oracle
|
|
122
|
-
decides when a step is worth a script and saves it (`action=script`); workers only propose one, and
|
|
123
|
-
a replaced script is kept under `archive/`. For each step, the classifier picks the scripts that do part of it
|
|
124
|
-
and the agent is told to run them (**Settings → Classifier → Shared scripts**; with it off, scripts
|
|
125
|
-
whose names share words with the step are suggested).
|
|
126
|
-
|
|
127
|
-
## Less searching
|
|
128
|
-
|
|
129
|
-
Agents spend most of their time finding things, so bot-lobby hands them what it already knows:
|
|
130
|
-
|
|
131
|
-
- **Repository map.** Scouts, workers, quick fixes and the planner get the project's layout and the
|
|
132
|
-
files that match their step, each with what it says it is for and the names it declares. It is
|
|
133
|
-
read from the files themselves, so it needs no model and works with the classifier off
|
|
134
|
-
(`workflow.repoMap`).
|
|
135
|
-
- **Scout notes.** What a scout found about a file is kept and shown in the map as long as the file is
|
|
136
|
-
unchanged, so the next task starts from it. A changed file's note is dropped.
|
|
137
|
-
- **Reused scouts.** The same question for the same task on a tree with no changes reuses the earlier
|
|
138
|
-
findings instead of running again, for example after a crash and resume (`workflow.reuseScouts`).
|
|
139
|
-
- **Line anchors.** Scouts report `path:12-40`, and the oracle copies those anchors into each brief,
|
|
140
|
-
so a worker opens the exact place.
|
|
141
|
-
- **Tool budget.** A scout is told to wrap up after 60% of `scout.maxToolCalls` (30). Past the limit,
|
|
142
|
-
further calls are refused, so it reports with what it has (0 means no limit).
|
|
143
|
-
|
|
144
|
-
## Classifier
|
|
145
|
-
|
|
146
|
-
A fast classifier makes the small decisions so the large models don't spend tokens on them: who
|
|
147
|
-
sits on the planning panel, a task's size, how hard each step is, which files, knowledge and
|
|
148
|
-
scripts it needs, and how much QA a change warrants. It is off until you turn it on in
|
|
149
|
-
**Settings → Classifier**, and every decision falls back to plain rules when it is off or fails.
|
|
150
|
-
|
|
151
|
-
**Answered by** picks who answers, from the models your pi logins offer:
|
|
152
|
-
|
|
153
|
-
- **Jev on a host** (the default): TypeSafe's classifier on OpenCode Zen (free while it lasts),
|
|
154
|
-
TypeSafe, OpenRouter or the Vercel AI Gateway.
|
|
155
|
-
- **Another classifier model** pi lists for your logins, such as Cloudflare's clef, Liquid's d1,
|
|
156
|
-
Upstage's solar-decide or Inception's mercury-decide. These answer the same typed questions natively.
|
|
157
|
-
- **Any chat model you are signed in to** (an OpenAI, Anthropic or Google account, an API key,
|
|
158
|
-
OpenRouter, …). It answers the same questions as JSON with the least reasoning the model allows.
|
|
159
|
-
It is slower and less calibrated than a classifier model, so pick a small, fast one.
|
|
160
|
-
|
|
161
|
-
The thresholds in `config.json` are tuned for Jev; raise them if another model decides too eagerly.
|
|
162
|
-
|
|
163
53
|
## Keys
|
|
164
54
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
`p` switches project, `d` flips the theme and `?` lists every key. Alt and Ctrl shortcuts can be
|
|
168
|
-
rebound with `lobby.keys`. In Pi, `Alt+G` toggles auto mode and `Ctrl+Shift+M` turns bot-lobby on or off.
|
|
169
|
-
|
|
170
|
-
## Screenshots
|
|
171
|
-
|
|
172
|
-
| Planning | Tasks |
|
|
173
|
-
| --- | --- |
|
|
174
|
-
|  |  |
|
|
175
|
-
| **Thinking** | **Questionnaire** |
|
|
176
|
-
|  |  |
|
|
177
|
-
| **Issues** | **Git** |
|
|
178
|
-
|  |  |
|
|
55
|
+
Every action button shows its key. `Alt+1`…`Alt+9` switch tabs, `j` / `k` move through lists, `/`
|
|
56
|
+
focuses search or the message box, `p` switches project, `d` flips the theme and `?` lists every key.
|
|
179
57
|
|
|
180
58
|
## Configuration
|
|
181
59
|
|
|
182
60
|
Settings live in `~/.pi/bot-lobby/config.json` (`BOT_LOBBY_CONFIG_DIR` moves them), and
|
|
183
|
-
`/bot-lobby config` shows what is in effect.
|
|
184
|
-
are kept in `themes.json` beside it, so every Pi session and project shows them. Tasks and
|
|
61
|
+
`/bot-lobby config` shows what is in effect. Most are also in the lobby's **Settings**. Tasks and
|
|
185
62
|
project knowledge stay in `.pi/bot-lobby/` inside your project.
|
|
186
63
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
`delegate_subtasks` for useful, separable work. Delegation is optional. Each parent gets five child
|
|
190
|
-
slots total, shared across retries; the classifier selects each child’s model and reasoning effort from its brief, lowering
|
|
191
|
-
inference for simple work and raising reasoning for complex work on the configured
|
|
192
|
-
model. Children inherit the parent’s role,
|
|
193
|
-
permissions, worktree and remaining time. Children report to their parent, which
|
|
194
|
-
integrates and verifies the result. Children cannot delegate further. Active
|
|
195
|
-
children share `workflow.maxParallelWorkers`; waiting parents do not use those
|
|
196
|
-
child slots. Cancelling or finishing a parent stops its children and releases
|
|
197
|
-
their file claims. Full reports are saved under `.pi/bot-lobby/delegations/`.
|
|
198
|
-
|
|
199
|
-
Every assignment has a 15-minute total allowance (or its shorter configured limit),
|
|
200
|
-
including startup, tools, retries, children, compaction and reporting. Per-step
|
|
201
|
-
allowances persist across reassignments; only the user can extend them, including
|
|
202
|
-
in auto mode. Waiting for user answers pauses clocks.
|
|
203
|
-
|
|
204
|
-
In **Tasks**, a step being worked on shows how many agents are on it, for example
|
|
205
|
-
**Implement large feature (6 agents working)**. Click the count to see which agent is
|
|
206
|
-
doing what, with children under their parent. Queued and finished agents are left out,
|
|
207
|
-
and a child finishing does not complete a checklist step.
|
|
208
|
-
|
|
209
|
-
The oracle, agents and children compact at settled turn boundaries before context
|
|
210
|
-
reaches 64,000 estimated tokens, or earlier at 60% of the model window or Pi's
|
|
211
|
-
native reserve threshold. Recent messages and summaries retain unfinished work;
|
|
212
|
-
raw session history remains available. A failed summary leaves context intact.
|
|
213
|
-
Checkpoints preserve constraints, decisions, changed files, verification, failed
|
|
214
|
-
approaches, and next actions. A single large input can exceed the threshold before
|
|
215
|
-
the next settled boundary.
|
|
216
|
-
|
|
217
|
-
Pi's native MCP, `tool_search` and `codemode` are available. **MCP tools** in each
|
|
218
|
-
agent's Settings entry grants exact tool names, one per line, such as
|
|
219
|
-
`mcp__github__get_issue`. In `config.json` the same field is `mcpTools: ["mcp__github__get_issue"]`
|
|
220
|
-
on `master`, `agents.backend`, `agents.designer`, `agents.qa`, `scout`, `researcher`,
|
|
221
|
-
`quickFix` and `planner`. Grants default to empty and children inherit them.
|
|
222
|
-
Read-only roles also require the server's `readOnlyHint: true`; hidden tools and
|
|
223
|
-
ungranted calls are blocked, including calls nested inside codemode. Configure
|
|
224
|
-
server connections through Pi's native MCP settings.
|
|
64
|
+
The [guide](docs/guide.md) covers the rest: delivery and commits, crash recovery, knowledge and
|
|
65
|
+
shared scripts, the classifier, delegation, time limits, compaction and MCP tools.
|
package/package.json
CHANGED
package/src/lobby/feed.ts
CHANGED
|
@@ -46,6 +46,8 @@ export const MAX_ACTIVITY = 400;
|
|
|
46
46
|
export const MAX_THOUGHTS = 40;
|
|
47
47
|
/** Messages the conversation keeps in memory; earlier ones are loaded from the session when scrolled to. */
|
|
48
48
|
export const MAX_CHAT = 100;
|
|
49
|
+
/** Queued messages remembered for their delivery; older ones are let go. */
|
|
50
|
+
const MAX_QUEUED = 20;
|
|
49
51
|
/** Longest thought kept; a streaming thought keeps its newest text. */
|
|
50
52
|
export const MAX_THOUGHT_TEXT = 4000;
|
|
51
53
|
/** The streaming reply kept: several panes' worth; past it, whole blocks are dropped from its start. */
|
|
@@ -201,6 +203,25 @@ export class LobbyFeed {
|
|
|
201
203
|
this.touch();
|
|
202
204
|
}
|
|
203
205
|
|
|
206
|
+
/** What the user sent while the oracle was busy: shown at once, so its delivery later is not shown again. */
|
|
207
|
+
private queued: string[] = [];
|
|
208
|
+
|
|
209
|
+
/** Show a message the oracle will only read once its current turn lets it in (a steer). */
|
|
210
|
+
sayQueued(text: string, at = Date.now()): void {
|
|
211
|
+
const body = text.trim();
|
|
212
|
+
if (!body) return;
|
|
213
|
+
this.queued = [...this.queued, body].slice(-MAX_QUEUED);
|
|
214
|
+
this.say("you", body, at);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Whether `text` is a queued message already on show; it is forgotten once delivered. */
|
|
218
|
+
takeQueued(text: string): boolean {
|
|
219
|
+
const index = this.queued.indexOf(text.trim());
|
|
220
|
+
if (index < 0) return false;
|
|
221
|
+
this.queued.splice(index, 1);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
|
|
204
225
|
say(role: ChatRole, text: string, at = Date.now()): void {
|
|
205
226
|
const body = text.trim();
|
|
206
227
|
if (!body) return;
|
|
@@ -408,7 +429,11 @@ export function narrateEvent(feed: LobbyFeed, event: AgentEventLike, describe: (
|
|
|
408
429
|
}
|
|
409
430
|
}
|
|
410
431
|
if (message.role !== "user" && message.role !== "assistant") return;
|
|
411
|
-
for (const line of chatText(message.role, textOf(message.content)))
|
|
432
|
+
for (const line of chatText(message.role, textOf(message.content))) {
|
|
433
|
+
// A steer was shown when it was sent; its delivery is the same message.
|
|
434
|
+
if (line.role === "you" && feed.takeQueued(line.text)) continue;
|
|
435
|
+
feed.say(line.role, line.text);
|
|
436
|
+
}
|
|
412
437
|
return;
|
|
413
438
|
}
|
|
414
439
|
case "agent_end":
|
package/src/lobby/keys.ts
CHANGED
|
@@ -9,8 +9,8 @@ export const LOBBY_ACTIONS = {
|
|
|
9
9
|
help: { key: "alt+h", help: "show or hide this list" },
|
|
10
10
|
settings: { key: "alt+s", help: "settings: each agent's model and effort" },
|
|
11
11
|
savePlan: { key: "ctrl+s", help: "save the plan from the Plan tab" },
|
|
12
|
-
|
|
13
|
-
activity: { key: "alt+a", help: "
|
|
12
|
+
sidebar: { key: "alt+b", help: "open the sidebar on a phone" },
|
|
13
|
+
activity: { key: "alt+a", help: "open or fold every step in the Lobby conversation" },
|
|
14
14
|
thinking: { key: "alt+t", help: "show or hide Thinking on the Lobby" },
|
|
15
15
|
nextTab: { key: "alt+]", help: "next tab" },
|
|
16
16
|
prevTab: { key: "alt+[", help: "previous tab" },
|
package/src/lobby/service.ts
CHANGED
|
@@ -151,6 +151,8 @@ function toOracle(state: Runtime, text: string): string | undefined {
|
|
|
151
151
|
return "reading your request — a quick fix or a task, the oracle takes it from here";
|
|
152
152
|
}
|
|
153
153
|
state.pi.sendUserMessage(text, busy ? { deliverAs: "steer" } : undefined);
|
|
154
|
+
// A steer reaches the oracle only when its turn lets it in; the conversation shows it now.
|
|
155
|
+
if (busy) lobbyFeed.sayQueued(text);
|
|
154
156
|
return undefined;
|
|
155
157
|
}
|
|
156
158
|
|