pi-bro 0.16.0 → 0.18.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.
Files changed (6) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +206 -222
  3. package/backend.ts +314 -23
  4. package/bro.ts +371 -396
  5. package/package.json +2 -2
  6. package/prompt.ts +17 -5
package/README.md CHANGED
@@ -1,26 +1,32 @@
1
1
  # pi-bro
2
2
 
3
3
  Turn a dense AI reply, pasted text, local document, or public webpage into a
4
- plain-language explanation — or open a sandboxed side conversation with
4
+ plain-language explanation — or open a separate side conversation with
5
5
  `/bro btw` — without adding anything to your main agent's context.
6
6
 
7
7
  `pi-bro` is an extension for [Earendil Pi](https://github.com/earendil-works/pi).
8
- It opens explanations in a separate modal and uses the
9
- [Google Antigravity CLI](https://antigravity.google/docs/cli-install) (`agy`)
10
- with your selected model. Claude Code is also supported for explain, show and
11
- advisor; Agy remains the default and is required for BTW.
8
+ It opens explanations in a separate modal and runs them through a CLI backend
9
+ you already have installed and signed in to. Explain, show, BTW, and the
10
+ advisor all work on all three backends:
11
+
12
+ - [Google Antigravity CLI](https://antigravity.google/docs/cli-install) (`agy`) — the default for new settings
13
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`)
14
+ - Grok Build (`grok`)
15
+
16
+ You only need the backend(s) you select; Agy is the default, not a requirement.
12
17
 
13
18
  ## Quick start
14
19
 
15
- You need Earendil Pi `>=0.84.2 <1`, Node.js `>=22.19.0`, and `agy >=1.1.15`
16
- installed and available on your `PATH`. Run `agy` once in your terminal to sign
17
- in, then install Bro:
20
+ You need Earendil Pi `>=0.84.2 <1`, Node.js `>=22.19.0`, and at least one
21
+ backend CLI on your `PATH`, signed in once from your terminal (`agy >=1.1.15`
22
+ for the default). Then install Bro:
18
23
 
19
24
  ```sh
20
25
  pi install npm:pi-bro
21
26
  ```
22
27
 
23
- Restart Pi or run `/reload`, then try:
28
+ Restart Pi or run `/reload`. If you use Claude Code or Grok instead of Agy,
29
+ choose it in `/bro config` (for everything, or per feature). Then try:
24
30
 
25
31
  ```text
26
32
  /bro
@@ -32,13 +38,6 @@ Restart Pi or run `/reload`, then try:
32
38
 
33
39
  Run `/bro doctor` after installation or whenever Bro is not working.
34
40
 
35
- Explain, show, BTW and advisor share an internal execution layer; Agy remains
36
- the default backend. Claude Code can be selected per capability in `/bro config`. Cancellation, host deadlines
37
- and invalid execution streams terminate the subprocess group on POSIX, escalating
38
- after a five-second grace period. Windows cleanup targets the direct child only;
39
- descendant termination is not guaranteed. Unexpected signal exits are reported as
40
- failures, not timeouts.
41
-
42
41
  To install from GitHub instead, use
43
42
  `pi install git:github.com/tranhoangnguyen03/pi-bro`. To try Bro without
44
43
  installing it, use `pi -e npm:pi-bro`.
@@ -69,13 +68,10 @@ text directly captures a new source the same way.
69
68
  | `/bro url <url>` | Explain one public, text-based webpage. |
70
69
  | `/bro open` | Reopen the latest explanation without calling the simplifier again. |
71
70
  | `/bro show [n-turns] [query]` | Draw recent session turns (default last 1) as shapes instead of prose, from user and assistant conversation text only — tool calls, tool results, reasoning, and images are omitted. An optional query steers what the shapes focus on, with or without a leading turn count. |
72
- | `/bro doctor` | Check Bro's settings, Agy installation, account, model, effort, and mode. |
73
- | `/bro usage [--provider agy]` | Show current Agy resource limits. |
74
- | `/bro model [id]` | View or choose the selected backend’s shared default model. |
75
- | `/bro effort [low\|medium\|high]` | View or choose the shared default reasoning effort. |
71
+ | `/bro doctor` | Check Bro's settings, prompt, and each selected backend, with the effective backend/model/effort per feature. |
76
72
  | `/bro mode [brief\|balanced\|faithful]` | View or choose the explanation mode. |
77
- | `/bro config` | Open an interactive settings screen for the shared default model/effort, explain mode, show turns, and per-capability (explain/show/btw/advisor) model and effort overrides. |
78
- | `/bro btw [--fresh] [--full] [question]` | Open a side conversation in a modal. Sandboxed (read-only) by default; `--full` lets it read and edit the workspace, `--fresh` skips main-session context. |
73
+ | `/bro config` | Open an interactive settings screen for the shared default backend/model/effort, explain mode, show turns, and per-capability (explain/show/btw/advisor) overrides. |
74
+ | `/bro btw [question]` | Open a side conversation in a modal, seeded with recent main-session context. Starts conversation-only; type `/mode` inside to toggle full permission (read and edit the workspace) without losing the thread. |
79
75
  | `/bro advisor` | Quick notice of whether the executor's `bro_advisor` tool is available right now, pointing at `/bro config`, `/bro advisor-steer`, and `/bro doctor`. |
80
76
  | `/bro advisor-steer` | View, edit, save, or clear the one persistent steering brief the advisor always sees. |
81
77
  | `/bro help` | Open the built-in quick reference. |
@@ -110,39 +106,55 @@ a persistent mode with `/bro mode`:
110
106
  - **O**: Open the HTML diagram when a show reply contains one
111
107
  - **Esc**: Close the modal, or cancel while Bro is working
112
108
 
109
+ The modal header shows the model and reasoning effort the explanation or
110
+ drawing used (`default` when the model's own effort applies); `/bro open`
111
+ keeps the original label.
112
+
113
113
  Bro temporarily captures mouse input while its modal is open. Native mouse
114
114
  selection may be unavailable or visually extend outside the modal depending on
115
115
  your terminal mode; press **C** to copy the complete explanation reliably.
116
116
 
117
+
117
118
  ## Bro btw (side conversation)
118
119
 
119
120
  `/bro btw` opens a separate multi-turn conversation in a modal, so you can ask
120
- a quick side question while the main agent keeps working. It runs through Agy,
121
- the same backend as the rest of Bro, and never adds anything to Pi's
122
- conversation unless you explicitly insert it into the editor.
121
+ a quick side question while the main agent keeps working. It runs through the
122
+ selected backend and never adds anything to Pi's conversation unless you
123
+ explicitly insert it into the editor.
123
124
 
124
- - **Sandboxed by default**: the side conversation is read-only (no project
125
- access). Add `--full` to let it read and edit the workspace.
126
125
  - `/bro btw <question>` asks immediately; `/bro btw` opens an empty thread.
127
- - `--fresh` starts a thread without seeding the main session's recent
128
- conversation text. Reopening without an access flag preserves the existing
129
- thread's access mode, including `--full`. Use `--sandbox` to return to sandbox
130
- mode; changing access mode starts a new thread. `--fresh` alone does not reset
131
- the access mode.
132
- - The first turn is seeded with up to the last 8 turns of user/assistant
133
- conversation text (40,000 characters max, with a truncation notice); the
134
- side agent can also read the repo itself when running in `--full` mode.
126
+ Reopening keeps the thread and its mode.
127
+ - **Two modes, toggled with `/mode`**: a new thread starts
128
+ **conversation-only**; type `/mode` in the modal to switch to **full
129
+ permission** (read and edit the workspace, run commands) and again to switch
130
+ back. The conversation is kept across switches. How conversation-only is
131
+ enforced depends on the backend — see
132
+ [Backends: access and retention](#backends-access-and-retention).
133
+ - Every new or cleared thread is seeded with up to the last 8 turns of
134
+ main-session user/assistant conversation text (40,000 characters max, with a
135
+ truncation notice). Later turns continue the backend's native session; in
136
+ full permission mode the side agent can also read the repo itself.
135
137
  - **In the modal**: type a question and press Enter (empty Enter re-asks the
136
138
  last question). Composer actions trigger only on these exact commands:
139
+ - `/mode`: toggles conversation-only / full permission, keeping the thread
137
140
  - `/copy`: copies the latest answer to the system clipboard
138
141
  - `/copy-all`: copies the full thread to the system clipboard
139
- - `/insert`: inserts the latest answer into the main editor without submitting (use `/insert!` to replace an existing editor draft)
140
- - `/insert-all`: inserts the full thread into the main editor without submitting (use `/insert-all!` to replace an existing editor draft)
142
+ - `/insert`: inserts the latest answer into the main editor without submitting
143
+ - `/insert-all`: inserts the full thread into the main editor without submitting
141
144
  - `/retry`: re-asks the last question (empty Enter does the same)
142
145
  - `/clear`: resets the thread
143
- Any other text or slash-prefixed input (such as `/send` or `/copy!`) is not a composer command and is submitted directly as a question to the side conversation. Esc closes the modal. A visible `full · edits repo` badge shows whenever `--full` mode is active.
144
- - The thread lives in memory only — it clears when you switch Pi sessions,
145
- reload extensions, or quit Pi.
146
+
147
+ `/insert` and `/insert-all` never replace an existing main-editor draft:
148
+ edit or clear it first. Any other text, including other slash-prefixed input
149
+ such as `/send`, is sent as a question. Esc closes the modal (or cancels a
150
+ running turn). The header shows the model and reasoning effort the latest
151
+ turn used (`default` when the model's own effort applies) and the current
152
+ mode.
153
+ - A turn is capped at 2 minutes in conversation-only mode and 10 minutes in
154
+ full permission mode.
155
+ - Bro's thread lives in memory only — it clears when you switch Pi sessions,
156
+ reload extensions, or quit Pi. Changing the BTW backend starts a fresh
157
+ thread; native session IDs never cross backends.
146
158
 
147
159
  ## Bro advisor
148
160
 
@@ -157,66 +169,53 @@ depends entirely on this host's own tool restrictions.
157
169
  `/bro advisor` is a quick notice of whether `bro_advisor` is available right
158
170
  now, pointing at `/bro config`, `/bro advisor-steer`, and `/bro doctor`.
159
171
  `/bro doctor` has the full diagnostic: whether this host exposes and
160
- activates `bro_advisor`, its resolved model/effort, steering presence, and
161
- the Agy compatibility floor — it also checks the installed Agy version and
162
- gives an `agy update` action when it is too old.
172
+ activates `bro_advisor`, its resolved backend/model/effort, steering
173
+ presence, and backend compatibility (for Agy, a minimum CLI version with an
174
+ `agy update` action when it is too old).
163
175
 
164
176
  - **Automatic context, no prep needed**: the executor never assembles a
165
177
  summary. Bro captures a harness-neutral snapshot — the executor's system
166
178
  instructions, its active tools, and the conversation so far including tool
167
179
  calls and results — and sends it, along with an optional `question` the
168
- executor may pass, to a **fresh, standalone process of the selected backend** for every
169
- consultation. Nothing is resumed or reused across calls, including retries.
180
+ executor may pass, to a **fresh, standalone process of the selected
181
+ backend** for every consultation. Nothing is resumed or reused across calls,
182
+ including retries.
170
183
  - **Instructed to investigate, not implement**: the advisor process has real
171
- tool access in the workspace with permissions auto-approved
172
- (`--dangerously-skip-permissions`) — there is no enforced read-only
173
- isolation. It is instructed to verify claims itself and return advice,
174
- leaving edits to the executor, but that boundary is a behavioral prompt
175
- instruction rather than an enforced sandbox constraint, so treat its
176
- findings as advice to verify, not a guaranteed hands-off review.
184
+ tool access in the workspace with permissions auto-approved — there is no
185
+ enforced read-only isolation. It is instructed to verify claims itself and
186
+ return advice, leaving edits to the executor, but that boundary is a
187
+ behavioral prompt instruction rather than an enforced sandbox constraint, so
188
+ treat its findings as advice to verify, not a guaranteed hands-off review.
177
189
  - **Steering**: `/bro advisor-steer` opens an editor for one persistent
178
190
  steering brief — e.g. "quick prototype; keep A and B careful, everything
179
191
  else minimal" — that the advisor always reads. **Ctrl+S** saves and keeps
180
192
  the editor open; **Enter** or **Shift+Enter** inserts a newline; **Ctrl+K**
181
193
  clears both the saved brief and draft while staying open; **Ctrl+C** copies
182
194
  the entire current draft, including unsaved edits; and **Esc** closes without
183
- saving unsaved edits. Actions and clipboard errors are reported inline. The
184
- brief is stored as session-only extension data and is **never added to Pi's
185
- conversation or sent to the main model** — the advisor is the only thing
186
- that reads it.
195
+ saving unsaved edits. The brief is **never added to Pi's conversation or
196
+ sent to the main model** — the advisor is the only thing that reads it.
187
197
  - **Persistence**: the steering brief persists with the Pi session (not
188
198
  globally, not per project) as custom extension data in the session file and
189
199
  is restored on resume or reload. Forking a session inherits it; edits made
190
- after the fork are independent of the original branch. The advisor tool has
191
- no separate activation state persisted or toggled.
200
+ after the fork are independent of the original branch.
192
201
  - **Retries**: on an invocation failure (not a completed answer — "I need
193
202
  more evidence" is a normal result, not a failure), Bro retries with the
194
203
  identical snapshot, steering, and question: once after 5 seconds, once more
195
- after 10 seconds, then returns Agy's own diagnostic — including a
196
- context-length error, verbatim — as the failure. Cancelling the tool call
197
- aborts immediately and skips any pending retry wait.
198
- - **Progress and provenance**: while an attempt is running, Bro parses the
199
- advisor's own stream for the last thing it actually reported — either a
200
- tool name or a user-facing response line (hidden reasoning is never
201
- surfaced) — and shows it with how long ago it arrived, e.g. `last reported:
202
- Read src/app.ts (2s ago)`. Before Agy reports anything, this reads
203
- explicitly as "awaiting first activity from Agy" rather than guessing at
204
- what it might be doing. This is what was actually reported, not a live
205
- claim about Agy's current tool, and silence is never described as
206
- "stalled". Expanding a running consultation shows up to the last 4 reported
207
- activity lines. Each retry starts this trail over empty — a failed
208
- attempt's activity never carries into the next one. Elapsed running time
209
- still ticks once a second regardless of activity; a retry countdown with
210
- the last failure is shown the same way as before. The returned answer
211
- starts with model, effort, actual attempt count, duration, workspace,
212
- steering presence, snapshot size, no-Bro-truncation status, and known
213
- omission/compaction notes; the advisor's complete answer follows unchanged.
204
+ after 10 seconds, then returns the backend's own diagnostic — including a
205
+ context-length error, verbatim — as the failure. Each attempt is capped at
206
+ 10 minutes. Cancelling the tool call aborts immediately and skips any
207
+ pending retry wait.
208
+ - **Progress and provenance**: while an attempt is running, Bro shows the last
209
+ thing the advisor actually reported — a tool name or a user-facing response
210
+ line, never hidden reasoning — and how long ago it arrived, e.g. `last
211
+ reported: Read src/app.ts (2s ago)`, or "awaiting first activity" before
212
+ anything arrives. Expanding a running consultation shows up to the last 4
213
+ reported activity lines; each retry starts the trail over. The returned
214
+ answer starts with backend, model, effort, attempt count, duration,
215
+ workspace, steering presence, snapshot size, and known omission/compaction
216
+ notes; the advisor's complete answer follows unchanged.
214
217
  - **Model/effort**: resolved the same way as explain/show/btw, through
215
- `/bro model`/`/bro effort` (shared default) or `/bro config` (per-capability
216
- override).
217
-
218
- See [docs/plans/2026-09-19-bro-advisor-design.md](docs/plans/2026-09-19-bro-advisor-design.md)
219
- for the full design.
218
+ `/bro config` (shared default or per-capability override).
220
219
 
221
220
  ## Bro show
222
221
 
@@ -225,7 +224,7 @@ changes the form: it draws what you and the assistant said in the last few
225
224
  session turns as a shape instead of paragraphs. Capture keeps only user and
226
225
  assistant conversation text, including every intermediate assistant message in
227
226
  a turn — tool calls, tool results, reasoning, and images never leave the
228
- session. It runs the same isolated, sandboxed model call and shows the result
227
+ session. It runs the same backend-specific model call and shows the result
229
228
  in the same modal, never touching your conversation. `/bro show` uses its own
230
229
  draw prompt; the explanation modes and `bro-prompt.md` do not affect it.
231
230
 
@@ -675,29 +674,40 @@ understand images and video. Pages that depend on those features may fail.
675
674
  If Bro cannot read a page, copy its content into a `.txt` or `.md` file, or save
676
675
  it as a PDF, then use `/bro file <path>`.
677
676
 
677
+
678
678
  ## Check your setup
679
679
 
680
680
  Run `/bro doctor` when Bro is newly installed or something is not working. It
681
- checks Bro's settings and prompt, the installed Agy version, account access,
682
- available models, and the selected reasoning effort. Failed checks explain what
683
- to fix.
681
+ checks Bro's settings and prompt, then probes only the backends some feature
682
+ actually selects, and reports the effective backend/model/effort for each
683
+ feature. Failed checks explain what to fix.
684
684
 
685
- Doctor contacts Agy for its model catalog and account usage. It does not send an
686
- assistant response or run a model completion, so it does not consume a model
687
- turn. A successful check confirms the setup, but cannot guarantee that a later
688
- provider request will succeed.
685
+ - **Agy**: installed version, model catalog, and account access.
686
+ - **Claude Code**: installed version and configured authentication.
687
+ - **Grok**: installed version only; authentication and connectivity are not
688
+ verified.
689
+
690
+ Doctor never sends source text or runs a model completion. A successful check
691
+ confirms the setup but cannot guarantee that a later provider request will
692
+ succeed.
689
693
 
690
694
  ## Settings
691
695
 
692
- Bro creates this user-editable settings file when the extension loads:
696
+ Use `/bro config` to review or change the shared default backend/model/effort
697
+ and any per-capability (explain/show/btw/advisor) overrides, the explanation
698
+ mode, and the default show turn count. Changes save immediately. Esc inside a
699
+ picker cancels that pick; Esc on the settings screen closes it, keeping
700
+ whatever was already saved. A failed save (for example, a read-only file) is
701
+ shown inline. `/bro mode` changes the mode directly, and `/bro help` shows the
702
+ active settings and file path.
703
+
704
+ Settings live in this user-editable file, created when the extension loads
705
+ (under `$PI_CODING_AGENT_DIR` instead when that is set):
693
706
 
694
707
  ```text
695
708
  ~/.pi/agent/bro-settings.json
696
709
  ```
697
710
 
698
- Existing flat model/effort files remain valid and select Agy. Explicit saves use
699
- version 2 with backend-tagged selections:
700
-
701
711
  ```json
702
712
  {
703
713
  "version": 2,
@@ -706,77 +716,76 @@ version 2 with backend-tagged selections:
706
716
  "showTurns": 1,
707
717
  "overrides": {
708
718
  "explain": { "backend": "claude", "model": "sonnet", "effort": "medium" },
709
- "advisor": { "backend": "claude", "model": "opus", "effort": "high" }
719
+ "advisor": { "backend": "grok", "model": "grok-4.7", "effort": "high" }
710
720
  }
711
721
  }
712
722
  ```
713
723
 
714
- Each override is a complete backend/model/effort selection, never a field-by-field
715
- merge. Omitted overrides inherit the shared default. Matching an override to the
716
- default does not unpin it; select Default explicitly to restore inheritance.
717
-
718
- ### Claude Code
719
-
720
- Install and authenticate `claude` independently (tested with Claude Code 2.1.281).
721
- Bro uses its CLI account and billing route, not Pi provider credentials. Choose
722
- Claude in `/bro config`; model aliases such as `sonnet` and `opus`, or explicit
723
- model IDs, are passed to the CLI. Claude efforts are `default` (omit the flag),
724
- `low`, `medium`, `high`, `xhigh`, and `max`; the chosen model/account must support
725
- the requested combination. Runtime rejection is surfaced without fallback.
726
-
727
- Explain/show use a scratch directory, safe mode, disabled tools, empty strict MCP
728
- configuration, disabled skills and no session persistence. This is a tool/configuration
729
- restriction, not an OS sandbox; built-in and managed Claude behavior can remain.
730
- Advisor uses safe mode and a fresh workspace process with permissions bypassed;
731
- it can modify files, and instructions to only advise remain behavioral. Running
732
- that mode as root may be rejected by Claude. BTW remains Agy-only: if a Claude
733
- shared default makes BTW unsupported, select an explicit Agy override.
734
-
735
- Doctor distinguishes CLI installation and configured authentication from a live
736
- request; it does not run a Claude model turn. `/bro usage` remains Agy-specific.
737
-
738
- Use `/bro model`, `/bro effort`, and `/bro mode` to update the shared default
739
- and mode from Pi, `/bro config` to review or change the shared default and any
740
- per-capability (explain/show/btw/advisor) overrides interactively, or edit the file
741
- directly. Bro reads the file again before each explanation, so manual changes
742
- apply to the next `/bro`. Use a model ID shown by `/bro model`; `effort` must be
743
- one of the levels shown by `/bro effort`. Models without adjustable effort use
744
- `default`. `mode` must be `brief`, `balanced`, or `faithful`; existing settings
745
- without it use `balanced`. `showTurns` is the default number of turns `/bro
746
- show` draws (default 1); `/bro show <n-turns>` overrides it for a single run. Settings
747
- written before per-capability overrides existed load unchanged, with no overrides. The choices remain
748
- active across Pi restarts until you change them. `/bro help` shows the active
749
- settings, any overrides, and the exact file path.
750
-
751
- `/bro config`'s changes save immediately as you make them. Pressing Esc inside
752
- a model or effort picker cancels that pick without changing anything; pressing
753
- Esc on the settings screen itself just closes it, keeping whatever was already
754
- saved. If a save fails (for example, a read-only settings file), the screen
755
- shows the error inline instead of losing the change silently.
756
-
757
- If `PI_CODING_AGENT_DIR` is set, the file lives there instead. `PI_BRO_MODEL`
758
- chooses the initial model only when Bro creates a missing settings file:
759
-
760
- ```sh
761
- PI_BRO_MODEL=gemini-3.7-flash-low pi
762
- ```
724
+ Bro reads the file again before each request, so manual edits apply next time.
725
+
726
+ - Each selection is one atomic backend/model/effort choice. An override pins
727
+ its own complete selection and ignores the shared default, even when it
728
+ happens to match it; select **Default** in `/bro config` to inherit again.
729
+ Omitted overrides inherit `default`.
730
+ - `effort` must be one the backend offers (`default` omits it and lets the
731
+ model decide). Agy selections are normalized against Agy's installed model
732
+ catalog. Claude and Grok accept seeded or custom model IDs; a model/effort
733
+ combination the account does not support fails with the backend's own error
734
+ instead of silently falling back.
735
+ - `mode` is `brief`, `balanced` (the default), or `faithful`. `showTurns` is
736
+ the default number of turns `/bro show` draws (default 1); `/bro show
737
+ <n-turns>` overrides it for one run.
738
+ - `PI_BRO_MODEL` picks the initial Agy model only when Bro creates a missing
739
+ settings file, for example `PI_BRO_MODEL=gemini-3.7-flash-low pi`.
740
+ - Older flat settings files (root `model`/`effort`) still load and mean Agy.
741
+
742
+ ## Backends: access and retention
743
+
744
+ Bro uses each CLI's own account and billing route, never Pi provider
745
+ credentials, and does not copy credentials or rewrite backend configuration.
746
+ Each backend and your model provider may retain sessions, logs, and request
747
+ data under their own settings and policies.
748
+
749
+ | | Explain / show | BTW conversation-only | BTW full permission | Advisor |
750
+ | --- | --- | --- | --- | --- |
751
+ | **Agy** | Temporary directory, Agy sandbox | Temporary directory, Agy sandbox | Workspace, permissions bypassed | Fresh workspace process, permissions bypassed |
752
+ | **Claude Code** | Scratch directory, tools/MCP/skills disabled, no session persistence | Workspace, tools disabled | Workspace, permissions bypassed | Fresh workspace process, permissions bypassed |
753
+ | **Grok** | Temporary directory, **prompt instruction only** | Workspace, **prompt instruction only** | Workspace, permissions bypassed | Fresh workspace process, permissions bypassed |
754
+
755
+ - Grok always runs with its sandbox off and permissions bypassed; its tools,
756
+ hooks, skills, plugins, and MCP may remain available. "Answer only from the
757
+ supplied context" is a request, not an enforced restriction.
758
+ - Claude's restrictions are tool/configuration settings (with safe mode), not
759
+ an OS sandbox; built-in and managed Claude behavior can remain. Running a
760
+ permission-bypassing mode as root may be rejected by Claude.
761
+ - BTW continues natively: Agy by conversation ID, Claude and Grok by
762
+ `--resume` of the same session, including across `/mode` switches. An Agy
763
+ conversation stays bound to the workspace it started in, so after a `/mode`
764
+ switch — or whenever a thread has turns but no native session ID — Bro starts
765
+ a fresh native session seeded with the main-session context and every
766
+ earlier turn.
767
+ - Cancellation, deadlines, and invalid output streams stop the backend's
768
+ process group on POSIX, escalating after a five-second grace period. On
769
+ Windows only the direct child is targeted. Detached shell work or external
770
+ services a backend started are not contained. Bro removes its private
771
+ temporary prompt files.
763
772
 
764
773
  ### Configuration precedence
765
774
 
766
- When resolving model and reasoning effort:
767
- 1. **Per-capability override**: If configured under `overrides.<capability>` (`explain`, `show`, `btw`, or `advisor`) in `bro-settings.json`, that capability pins its own complete backend/model/effort selection and ignores the shared default.
768
- 2. **Shared default**: If no override is set for that capability, it inherits `default` in version-2 settings (root model/effort in legacy settings).
769
- 3. **Catalog normalization**: For Agy selections, Bro normalizes the resolved `{ model, effort }` against Agy's installed model catalog (mapping suffixed variant IDs and handling fixed-effort models).
770
- 4. **Initial file creation only**: `PI_BRO_MODEL` selects the initial default model only when Bro creates a missing `bro-settings.json` file. It has no effect once the file exists.
775
+ When resolving backend, model, and reasoning effort:
776
+ 1. **Per-capability override**: `overrides.<capability>` (`explain`, `show`, `btw`, or `advisor`) pins that capability's complete selection.
777
+ 2. **Shared default**: otherwise the capability inherits `default` (root `model`/`effort` in older flat files).
778
+ 3. **Agy catalog normalization**: for Agy selections, Bro maps suffixed variant IDs and handles fixed-effort models.
779
+ 4. **Initial file creation only**: `PI_BRO_MODEL` has no effect once the settings file exists.
771
780
 
772
781
  When resolving turn count for `/bro show`:
773
- 1. **Command argument**: An explicit count like `/bro show 3` or `/bro show 1 query` overrides for that single execution.
774
- 2. **Saved setting**: `showTurns` in `bro-settings.json` (defaults to 1; configurable interactively via `/bro config` or direct file edit).
782
+ 1. **Command argument**: an explicit count like `/bro show 3` or `/bro show 1 query` overrides for that run.
783
+ 2. **Saved setting**: `showTurns` (defaults to 1).
775
784
 
776
- When resolving explanation prompt (`explain` capability only):
777
- 1. **Custom prompt**: `~/.pi/agent/bro-prompt.md` (or `$PI_CODING_AGENT_DIR/bro-prompt.md`), if present and valid (`{{response}}` exactly once), completely overrides all built-in modes.
778
- 2. **Saved mode**: `mode` in `bro-settings.json` (`brief`, `balanced`, or `faithful`; defaults to `balanced`).
779
- 3. Note: `bro-prompt.md` applies only to `/bro`, `/bro text`, `/bro file`, and `/bro url`; it does not affect `/bro show`, `/bro btw`, or `bro_advisor`.
785
+ When resolving the explanation prompt (`explain` capability only):
786
+ 1. **Custom prompt**: a valid `~/.pi/agent/bro-prompt.md` (or `$PI_CODING_AGENT_DIR/bro-prompt.md`) completely overrides all built-in modes.
787
+ 2. **Saved mode**: `mode` in `bro-settings.json` (defaults to `balanced`).
788
+ 3. `bro-prompt.md` applies only to `/bro`, `/bro text`, `/bro file`, and `/bro url`; it does not affect `/bro show`, `/bro btw`, or `bro_advisor`.
780
789
 
781
790
  ## Custom prompt
782
791
 
@@ -809,35 +818,40 @@ built-in mode again. If the custom prompt is invalid—for example, it has no
809
818
  `{{response}}` placeholder or has more than one—Bro blocks the explanation;
810
819
  run `/bro doctor` for the exact problem.
811
820
 
821
+
812
822
  ## Privacy and safety
813
823
 
814
824
  - **External requests**: Bro sends the latest completed assistant response,
815
825
  pasted text, extracted document text, extracted webpage text, or recent
816
826
  session conversation text (tool calls, tool results, reasoning, and images
817
827
  omitted) to the selected backend and its configured model provider.
818
- - **Side conversation requests**: `/bro btw` sends your side questions and, on
819
- the first turn, the seeded main-session conversation text to Agy. In `--full`
820
- mode the side agent additionally reads the workspace.
821
- - **Usage checks**: `/bro usage` checks your authenticated Agy limits without
822
- sending an assistant response or running a model turn.
823
- - **Setup checks**: `/bro doctor` checks Agy account and model availability
824
- without sending an assistant response or running a model turn.
825
- - **Context isolation**: Bro does not add explanations to Pi's conversation
826
- history, session files, or main-agent context.
827
- - **Side conversation (`/bro btw`)**: sandboxed by default — the side agent has
828
- no project access and runs in a temporary folder. With `--full` it runs in
829
- your workspace with auto-approved tools, so it can read and edit files while
830
- the main agent is also working; use `--full` only when you want that. The
831
- side thread is memory-only and clears when you switch sessions, reload
832
- extensions, or quit Pi.
833
- - **Memory cache**: The latest explanation is stored only in process memory for
834
- `/bro open`. It clears when you switch Pi sessions, reload extensions, or quit
835
- Pi.
828
+ - **Side conversation requests**: `/bro btw` sends your side questions and the
829
+ seeded main-session conversation text (plus earlier turns when a native
830
+ session is reseeded) to the selected backend. In full permission mode the
831
+ side agent can additionally read and edit the workspace.
832
+ - **Advisor requests**: `bro_advisor` sends the executor agent's system
833
+ instructions, active tool list (excluding `bro_advisor`), ordered
834
+ conversation history including tool calls and tool results (unlike Show,
835
+ which omits them), your steering brief, and the executor's optional question
836
+ to the selected backend. Reasoning and image bodies are omitted with explicit
837
+ markers (`[reasoning omitted]`, `[image omitted]`). The advisor process runs
838
+ in your workspace with auto-approved permissions; its instruction to only
839
+ advise is behavioral, not an enforced boundary.
840
+ - **Access enforcement** differs by backend; see
841
+ [Backends: access and retention](#backends-access-and-retention). Prompt
842
+ instructions are not access enforcement.
843
+ - **Context isolation**: Bro does not add explanations, BTW answers, or the
844
+ steering brief to Pi's conversation history or main-agent context. BTW text
845
+ reaches the main editor only through `/insert` or `/insert-all`, and advisor
846
+ results appear as normal tool results in the executor's transcript.
847
+ - **Memory**: the latest explanation (for `/bro open`) and the BTW thread live
848
+ only in process memory and clear when you switch Pi sessions, reload
849
+ extensions, or quit Pi. Backend-native sessions can persist independently.
850
+ The advisor steering brief is stored as session-scoped extension data
851
+ (`bro-advisor-steering`) in the session file.
836
852
  - **File safety**: `/bro file` reads only regular files whose resolved path is
837
- inside Pi's current workspace, including after resolving symlinks. Bro does
838
- not modify them. It runs Agy in sandbox mode inside a temporary empty folder.
839
- This reduces project access, but it is not a security boundary. Bro only
840
- writes its own user settings file described above.
853
+ inside Pi's current workspace, including after resolving symlinks. Bro's
854
+ extractor does not modify them.
841
855
  - **Web requests**: `/bro url` connects directly to the target website. The site
842
856
  sees your IP address and Bro's user agent. Bro sends no browser cookies,
843
857
  authorization, or referrer information, and it refuses local, private, and
@@ -845,35 +859,14 @@ run `/bro doctor` for the exact problem.
845
859
  URLs whose query string contains secrets.
846
860
  - **Web extraction**: Bro parses downloaded HTML locally without executing page
847
861
  scripts or loading page subresources. It sends the extracted readable text,
848
- including links preserved in that text, to the selected backend; it does not separately send
849
- the requested URL or raw page HTML. The URL, captured text, and explanation
850
- remain in process memory only and clear with the existing `/bro open` cache.
862
+ including links preserved in that text, to the selected backend; it does not
863
+ separately send the requested URL or raw page HTML.
851
864
  - **Show diagrams**: When a show reply ends in one self-contained HTML block,
852
865
  Bro writes it to `/tmp/pi-bro-<uid>/bro-show-<hash>.html` with a restrictive
853
866
  Content-Security-Policy, and opens it in your browser only when you press
854
867
  **O**. **C** copies the full reply, including the HTML.
855
- - **Provider data**: The selected CLI backend and your model provider may retain logs and request data
856
- according to their own settings and privacy policies.
857
- - **Clipboard**: Pressing **C** copies the text to your system clipboard, where
858
- your operating system or clipboard manager may retain it.
859
- - **Advisor requests**: `bro_advisor` sends the executor agent's system
860
- instructions, active tool list (excluding `bro_advisor`), ordered
861
- conversation history including tool calls and tool results (unlike Show, which
862
- omits them), human steering brief, and the executor's optional question to
863
- the selected backend and its configured model provider. Reasoning and image bodies are
864
- omitted with explicit markers (`[reasoning omitted]`, `[image omitted]`).
865
- - **Advisor tool execution & safety boundary**: The advisor process runs
866
- directly in your workspace (`cwd`) with auto-approved permissions
867
- (`--dangerously-skip-permissions`). It has real tool access (file reading,
868
- search, command execution). The directive to only advise and leave edits to
869
- the executor is a **behavioral prompt instruction**, not an enforced sandbox
870
- or security boundary. Treat its findings as advice to verify before applying.
871
- - **Advisor steering persistence**: The steering brief is saved as
872
- session-scoped custom extension data (`bro-advisor-steering`) in the session
873
- file. It persists across session resume and reload, and is inherited on
874
- session fork (post-fork edits on branches remain independent). It is never
875
- sent to the main model or added to Pi's conversation. The advisor tool has
876
- no separate activation state.
868
+ - **Clipboard**: **C**, `/copy`, and `/copy-all` copy text to your system
869
+ clipboard, where your operating system or clipboard manager may retain it.
877
870
 
878
871
  ## Troubleshooting and current limits
879
872
 
@@ -882,7 +875,8 @@ extracted, copy its content into a supported text file or save it as a PDF and
882
875
  use `/bro file`. If a PDF contains only scanned images, run OCR with another
883
876
  tool before giving it to Bro.
884
877
 
885
- - Supports Agy for all capabilities and Claude Code for explain/show/advisor. Claude BTW is not yet supported; unsupported selections fail without fallback.
878
+ - An unsupported model, effort, or missing backend fails with that backend's
879
+ diagnostic; Bro never falls back to another backend.
886
880
  - Document input supports `.md`, `.markdown`, `.txt`, `.pdf`, and `.docx` only;
887
881
  it does not perform OCR.
888
882
  - Webpage input supports one public HTML page, up to 5 MiB downloaded and
@@ -891,23 +885,16 @@ tool before giving it to Bro.
891
885
  - Direct webpage fetching does not currently use `HTTP_PROXY`, `HTTPS_PROXY`,
892
886
  or other proxy environment variables.
893
887
  - `/bro btw` threads are memory-only and do not survive reloads or restarts.
894
- The side conversation needs Agy's `--conversation` resume support; sandbox
895
- mode caps a turn at 2 minutes and full mode at 10 minutes.
896
- - `bro_advisor` requires Agy CLI `>=1.1.15` (for `--input-format stream-json`).
897
- Consultations run directly in the workspace with auto-approved permissions
898
- without enforced file-modification isolation; an attempt is capped at 10
899
- minutes (`--print-timeout 10m`) and retries up to 2 times on invocation
900
- failure (5-second, then 10-second backoff).
888
+ - The Agy advisor requires Agy CLI `>=1.1.15`.
901
889
  - Show captures only the conversation text of what already happened in the
902
890
  current session — the last few turns' user and assistant messages, with
903
- tool calls, tool results, reasoning, and images always omitted; it cannot
904
- read the repository or other files on its own, and its shapes reflect what
905
- was reported in the conversation, not independent verification.
891
+ tool calls, tool results, reasoning, and images always omitted; its shapes
892
+ reflect what was reported in the conversation, not independent verification.
906
893
  - HTML diagrams open in your default browser; pressing **O** on a remote or
907
894
  headless session with no display reports the failure instead of opening
908
895
  anything.
909
- - Keeps only the latest explanation in memory.
910
- - Does not store history or export directly to files.
896
+ - Keeps only the latest explanation in memory and does not store history or
897
+ export directly to files.
911
898
  - Bro temporarily captures mouse input while its modal is open so mouse-wheel
912
899
  and trackpad scrolling work in regular and fullscreen modes. Native mouse
913
900
  selection may be unavailable or visually extend outside the Bro window;
@@ -921,17 +908,14 @@ npm test
921
908
  pi --tui-mode fullscreen -e ./bro.ts
922
909
  ```
923
910
 
924
- The smoke test uses a fake `agy`, and Claude adapter tests use a fake `claude`, so automated tests do not call an external model. It
925
- verifies command routing, document and URL safety boundaries, HTML
926
- extraction, show capture (conversation text only, tool calls and results
927
- absent), and HTML-diagram handling, healthy and broken setup handling,
928
- settings, custom prompt handling, and context isolation.
911
+ `npm test` uses fake `agy`, `claude`, and `grok` executables and never calls an
912
+ external model. See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for the code
913
+ map and invariants, [docs/TESTING.md](docs/TESTING.md) for the manual
914
+ end-to-end checklist, and [docs/README.md](docs/README.md) for the docs index.
929
915
 
930
916
  The prompt benchmark is manual and makes live Agy calls. Read
931
917
  [`benchmark/README.md`](benchmark/README.md) before running it; it is never part
932
- of `npm test`. A separate `--track show` benchmark grades the show prompt
933
- against serialized-transcript fixtures — one per show-me form — and is also
934
- manual and never part of `npm test`.
918
+ of `npm test`.
935
919
 
936
920
  ## License
937
921