pi-bro 0.17.0 → 0.18.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 CHANGED
@@ -5,22 +5,28 @@ 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,12 +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 model [id]` | View or choose the selected backend’s shared default model. |
74
- | `/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. |
75
72
  | `/bro mode [brief\|balanced\|faithful]` | View or choose the explanation mode. |
76
- | `/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. |
77
- | `/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. |
78
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`. |
79
76
  | `/bro advisor-steer` | View, edit, save, or clear the one persistent steering brief the advisor always sees. |
80
77
  | `/bro help` | Open the built-in quick reference. |
@@ -117,37 +114,47 @@ Bro temporarily captures mouse input while its modal is open. Native mouse
117
114
  selection may be unavailable or visually extend outside the modal depending on
118
115
  your terminal mode; press **C** to copy the complete explanation reliably.
119
116
 
117
+
120
118
  ## Bro btw (side conversation)
121
119
 
122
120
  `/bro btw` opens a separate multi-turn conversation in a modal, so you can ask
123
121
  a quick side question while the main agent keeps working. It runs through the
124
- selected Agy or Grok backend and never adds anything to Pi's
125
- conversation unless you explicitly insert it into the editor.
122
+ selected backend and never adds anything to Pi's conversation unless you
123
+ explicitly insert it into the editor.
126
124
 
127
- - **Conversation-only intent by default**: Agy uses its sandbox controls; Grok
128
- receives prompt instructions to stay within supplied context, with normal tools
129
- still available. Grok is not sandboxed. Add `--full` to explicitly invite
130
- workspace investigation and edits.
131
125
  - `/bro btw <question>` asks immediately; `/bro btw` opens an empty thread.
132
- - `--fresh` starts a thread without seeding the main session's recent
133
- conversation text. Reopening without an access flag preserves the existing
134
- thread's access mode, including `--full`. Use `--sandbox` to return to conversation-only
135
- intent; changing access mode starts a new thread. `--fresh` alone does not reset
136
- the access mode.
137
- - The first turn is seeded with up to the last 8 turns of user/assistant
138
- conversation text (40,000 characters max, with a truncation notice); the
139
- 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.
140
137
  - **In the modal**: type a question and press Enter (empty Enter re-asks the
141
138
  last question). Composer actions trigger only on these exact commands:
139
+ - `/mode`: toggles conversation-only / full permission, keeping the thread
142
140
  - `/copy`: copies the latest answer to the system clipboard
143
141
  - `/copy-all`: copies the full thread to the system clipboard
144
- - `/insert`: inserts the latest answer into the main editor without submitting (use `/insert!` to replace an existing editor draft)
145
- - `/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
146
144
  - `/retry`: re-asks the last question (empty Enter does the same)
147
145
  - `/clear`: resets the thread
148
- 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. The header shows the model and reasoning effort the latest turn used (`default` when the model's own effort applies), and a visible `full · edits repo` badge shows whenever `--full` mode is active.
149
- - The thread lives in memory only — it clears when you switch Pi sessions,
150
- 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.
151
158
 
152
159
  ## Bro advisor
153
160
 
@@ -162,66 +169,53 @@ depends entirely on this host's own tool restrictions.
162
169
  `/bro advisor` is a quick notice of whether `bro_advisor` is available right
163
170
  now, pointing at `/bro config`, `/bro advisor-steer`, and `/bro doctor`.
164
171
  `/bro doctor` has the full diagnostic: whether this host exposes and
165
- activates `bro_advisor`, its resolved model/effort, steering presence, and
166
- the Agy compatibility floor — it also checks the installed Agy version and
167
- 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).
168
175
 
169
176
  - **Automatic context, no prep needed**: the executor never assembles a
170
177
  summary. Bro captures a harness-neutral snapshot — the executor's system
171
178
  instructions, its active tools, and the conversation so far including tool
172
179
  calls and results — and sends it, along with an optional `question` the
173
- executor may pass, to a **fresh, standalone process of the selected backend** for every
174
- 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.
175
183
  - **Instructed to investigate, not implement**: the advisor process has real
176
- tool access in the workspace with permissions auto-approved
177
- (`--dangerously-skip-permissions`) — there is no enforced read-only
178
- isolation. It is instructed to verify claims itself and return advice,
179
- leaving edits to the executor, but that boundary is a behavioral prompt
180
- instruction rather than an enforced sandbox constraint, so treat its
181
- 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.
182
189
  - **Steering**: `/bro advisor-steer` opens an editor for one persistent
183
190
  steering brief — e.g. "quick prototype; keep A and B careful, everything
184
191
  else minimal" — that the advisor always reads. **Ctrl+S** saves and keeps
185
192
  the editor open; **Enter** or **Shift+Enter** inserts a newline; **Ctrl+K**
186
193
  clears both the saved brief and draft while staying open; **Ctrl+C** copies
187
194
  the entire current draft, including unsaved edits; and **Esc** closes without
188
- saving unsaved edits. Actions and clipboard errors are reported inline. The
189
- brief is stored as session-only extension data and is **never added to Pi's
190
- conversation or sent to the main model** — the advisor is the only thing
191
- 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.
192
197
  - **Persistence**: the steering brief persists with the Pi session (not
193
198
  globally, not per project) as custom extension data in the session file and
194
199
  is restored on resume or reload. Forking a session inherits it; edits made
195
- after the fork are independent of the original branch. The advisor tool has
196
- no separate activation state persisted or toggled.
200
+ after the fork are independent of the original branch.
197
201
  - **Retries**: on an invocation failure (not a completed answer — "I need
198
202
  more evidence" is a normal result, not a failure), Bro retries with the
199
203
  identical snapshot, steering, and question: once after 5 seconds, once more
200
- after 10 seconds, then returns Agy's own diagnostic — including a
201
- context-length error, verbatim — as the failure. Cancelling the tool call
202
- aborts immediately and skips any pending retry wait.
203
- - **Progress and provenance**: while an attempt is running, Bro parses the
204
- advisor's own stream for the last thing it actually reported — either a
205
- tool name or a user-facing response line (hidden reasoning is never
206
- surfaced) — and shows it with how long ago it arrived, e.g. `last reported:
207
- Read src/app.ts (2s ago)`. Before Agy reports anything, this reads
208
- explicitly as "awaiting first activity from Agy" rather than guessing at
209
- what it might be doing. This is what was actually reported, not a live
210
- claim about Agy's current tool, and silence is never described as
211
- "stalled". Expanding a running consultation shows up to the last 4 reported
212
- activity lines. Each retry starts this trail over empty — a failed
213
- attempt's activity never carries into the next one. Elapsed running time
214
- still ticks once a second regardless of activity; a retry countdown with
215
- the last failure is shown the same way as before. The returned answer
216
- starts with model, effort, actual attempt count, duration, workspace,
217
- steering presence, snapshot size, no-Bro-truncation status, and known
218
- 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.
219
217
  - **Model/effort**: resolved the same way as explain/show/btw, through
220
- `/bro model`/`/bro effort` (shared default) or `/bro config` (per-capability
221
- override).
222
-
223
- See [docs/plans/2026-09-19-bro-advisor-design.md](docs/plans/2026-09-19-bro-advisor-design.md)
224
- for the full design.
218
+ `/bro config` (shared default or per-capability override).
225
219
 
226
220
  ## Bro show
227
221
 
@@ -680,29 +674,40 @@ understand images and video. Pages that depend on those features may fail.
680
674
  If Bro cannot read a page, copy its content into a `.txt` or `.md` file, or save
681
675
  it as a PDF, then use `/bro file <path>`.
682
676
 
677
+
683
678
  ## Check your setup
684
679
 
685
680
  Run `/bro doctor` when Bro is newly installed or something is not working. It
686
- checks Bro's settings and prompt, the installed Agy version, account access,
687
- available models, and the selected reasoning effort. Failed checks explain what
688
- 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.
689
684
 
690
- Doctor contacts Agy for its model catalog and account usage. It does not send an
691
- assistant response or run a model completion, so it does not consume a model
692
- turn. A successful check confirms the setup, but cannot guarantee that a later
693
- 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.
694
693
 
695
694
  ## Settings
696
695
 
697
- 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):
698
706
 
699
707
  ```text
700
708
  ~/.pi/agent/bro-settings.json
701
709
  ```
702
710
 
703
- Existing flat model/effort files remain valid and select Agy. Explicit saves use
704
- version 2 with backend-tagged selections:
705
-
706
711
  ```json
707
712
  {
708
713
  "version": 2,
@@ -711,102 +716,76 @@ version 2 with backend-tagged selections:
711
716
  "showTurns": 1,
712
717
  "overrides": {
713
718
  "explain": { "backend": "claude", "model": "sonnet", "effort": "medium" },
714
- "advisor": { "backend": "claude", "model": "opus", "effort": "high" }
719
+ "advisor": { "backend": "grok", "model": "grok-4.7", "effort": "high" }
715
720
  }
716
721
  }
717
722
  ```
718
723
 
719
- Each override is a complete backend/model/effort selection, never a field-by-field
720
- merge. Omitted overrides inherit the shared default. Matching an override to the
721
- default does not unpin it; select Default explicitly to restore inheritance.
722
-
723
- ### Claude Code
724
-
725
- Install and authenticate `claude` independently (tested with Claude Code 2.1.281).
726
- Bro uses its CLI account and billing route, not Pi provider credentials. Choose
727
- Claude in `/bro config`; model aliases such as `sonnet` and `opus`, or explicit
728
- model IDs, are passed to the CLI. Claude efforts are `default` (omit the flag),
729
- `low`, `medium`, `high`, `xhigh`, and `max`; the chosen model/account must support
730
- the requested combination. Runtime rejection is surfaced without fallback.
731
-
732
- Explain/show use a scratch directory, safe mode, disabled tools, empty strict MCP
733
- configuration, disabled skills and no session persistence. This is a tool/configuration
734
- restriction, not an OS sandbox; built-in and managed Claude behavior can remain.
735
- Advisor uses safe mode and a fresh workspace process with permissions bypassed;
736
- it can modify files, and instructions to only advise remain behavioral. Running
737
- that mode as root may be rejected by Claude. Claude BTW continuation is not wired yet (tracked in #58): if a Claude
738
- shared default makes BTW unsupported, select an explicit Agy or Grok override.
739
-
740
- Doctor distinguishes CLI installation and configured authentication from a live
741
- request; it does not run a Claude model turn.
742
-
743
- ### Grok Build
744
-
745
- Grok supports **explain, show, BTW (both modes), and advisor**, using the
746
- separately authenticated `grok` CLI (tested with 1.0.41). Seeded choices are
747
- `grok-4.7` and `grok-4.7-build-fast`; custom IDs are accepted. Efforts are
748
- `default` (omit the flag), `low`, `medium`, `high`, and `xhigh`; model-specific
749
- rejection is surfaced without silently changing your selection.
750
-
751
- Grok runs with `--sandbox off --permission-mode bypassPermissions`. For
752
- explain/show and ordinary BTW, Bro asks it to answer from supplied context
753
- without investigating or modifying the workspace. **That is a prompt instruction,
754
- not an enforced access restriction.** Tools, hooks, skills, plugins and MCP may
755
- remain available. Explain/show start in a temporary directory; BTW uses your
756
- workspace consistently because native resumed sessions retain their original cwd.
757
- `--full` invites workspace access rather than imposing conversation-only intent.
758
- Advisor runs fresh with workspace access. Bro does not blacklist tools merely
759
- because they are more powerful than the immediate task requires.
760
-
761
- BTW resumes using Grok's native session ID. Changing backend or access mode
762
- starts a fresh Bro thread; IDs are never passed between backends. Bro removes
763
- its private temporary prompt file, but Grok may retain sessions/logs under its
764
- own settings. Bro does not copy credentials or change Grok configuration.
765
- Cancellation targets the managed process group, not independently detached shell
766
- work or external services. Doctor checks version, not authenticated connectivity.
767
-
768
- Use `/bro model`, `/bro effort`, and `/bro mode` to update the shared default
769
- and mode from Pi, `/bro config` to review or change the shared default and any
770
- per-capability (explain/show/btw/advisor) overrides interactively, or edit the file
771
- directly. Bro reads the file again before each explanation, so manual changes
772
- apply to the next `/bro`. Use a model ID shown by `/bro model`; `effort` must be
773
- one of the levels shown by `/bro effort`. Models without adjustable effort use
774
- `default`. `mode` must be `brief`, `balanced`, or `faithful`; existing settings
775
- without it use `balanced`. `showTurns` is the default number of turns `/bro
776
- show` draws (default 1); `/bro show <n-turns>` overrides it for a single run. Settings
777
- written before per-capability overrides existed load unchanged, with no overrides. The choices remain
778
- active across Pi restarts until you change them. `/bro help` shows the active
779
- settings, any overrides, and the exact file path.
780
-
781
- `/bro config`'s changes save immediately as you make them. Pressing Esc inside
782
- a model or effort picker cancels that pick without changing anything; pressing
783
- Esc on the settings screen itself just closes it, keeping whatever was already
784
- saved. If a save fails (for example, a read-only settings file), the screen
785
- shows the error inline instead of losing the change silently.
786
-
787
- If `PI_CODING_AGENT_DIR` is set, the file lives there instead. `PI_BRO_MODEL`
788
- chooses the initial model only when Bro creates a missing settings file:
789
-
790
- ```sh
791
- PI_BRO_MODEL=gemini-3.7-flash-low pi
792
- ```
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.
793
772
 
794
773
  ### Configuration precedence
795
774
 
796
- When resolving model and reasoning effort:
797
- 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.
798
- 2. **Shared default**: If no override is set for that capability, it inherits `default` in version-2 settings (root model/effort in legacy settings).
799
- 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).
800
- 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.
801
780
 
802
781
  When resolving turn count for `/bro show`:
803
- 1. **Command argument**: An explicit count like `/bro show 3` or `/bro show 1 query` overrides for that single execution.
804
- 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).
805
784
 
806
- When resolving explanation prompt (`explain` capability only):
807
- 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.
808
- 2. **Saved mode**: `mode` in `bro-settings.json` (`brief`, `balanced`, or `faithful`; defaults to `balanced`).
809
- 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`.
810
789
 
811
790
  ## Custom prompt
812
791
 
@@ -839,33 +818,40 @@ built-in mode again. If the custom prompt is invalid—for example, it has no
839
818
  `{{response}}` placeholder or has more than one—Bro blocks the explanation;
840
819
  run `/bro doctor` for the exact problem.
841
820
 
821
+
842
822
  ## Privacy and safety
843
823
 
844
824
  - **External requests**: Bro sends the latest completed assistant response,
845
825
  pasted text, extracted document text, extracted webpage text, or recent
846
826
  session conversation text (tool calls, tool results, reasoning, and images
847
827
  omitted) to the selected backend and its configured model provider.
848
- - **Side conversation requests**: `/bro btw` sends your side questions and, on
849
- the first turn, the seeded main-session conversation text to Agy. In `--full`
850
- mode the side agent additionally reads the workspace.
851
- - **Setup checks**: `/bro doctor` checks Agy account and model availability
852
- without sending an assistant response or running a model turn.
853
- - **Context isolation**: Bro does not add explanations to Pi's conversation
854
- history, session files, or main-agent context.
855
- - **Side conversation (`/bro btw`)**: Agy uses sandbox controls by default;
856
- Grok uses conversation-only prompt instructions with normal workspace authority.
857
- `--full` explicitly invites workspace access. Bro's thread state clears when
858
- you switch sessions, reload extensions, or quit Pi; backend-native sessions
859
- can persist independently. Prompt instructions are not access enforcement.
860
- - **Memory cache**: The latest explanation is stored only in process memory for
861
- `/bro open`. It clears when you switch Pi sessions, reload extensions, or quit
862
- 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.
863
852
  - **File safety**: `/bro file` reads only regular files whose resolved path is
864
- inside Pi's current workspace, including after resolving symlinks. Bro's extractor does
865
- not modify them. The selected backend then receives extracted text: Agy uses
866
- sandbox controls, Claude tool/config restrictions, and Grok prompt instructions
867
- in a temporary directory. Grok retains normal tool authority; a request not
868
- to modify files is behavioral, not a technical guarantee.
853
+ inside Pi's current workspace, including after resolving symlinks. Bro's
854
+ extractor does not modify them.
869
855
  - **Web requests**: `/bro url` connects directly to the target website. The site
870
856
  sees your IP address and Bro's user agent. Bro sends no browser cookies,
871
857
  authorization, or referrer information, and it refuses local, private, and
@@ -873,35 +859,14 @@ run `/bro doctor` for the exact problem.
873
859
  URLs whose query string contains secrets.
874
860
  - **Web extraction**: Bro parses downloaded HTML locally without executing page
875
861
  scripts or loading page subresources. It sends the extracted readable text,
876
- including links preserved in that text, to the selected backend; it does not separately send
877
- the requested URL or raw page HTML. The URL, captured text, and explanation
878
- 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.
879
864
  - **Show diagrams**: When a show reply ends in one self-contained HTML block,
880
865
  Bro writes it to `/tmp/pi-bro-<uid>/bro-show-<hash>.html` with a restrictive
881
866
  Content-Security-Policy, and opens it in your browser only when you press
882
867
  **O**. **C** copies the full reply, including the HTML.
883
- - **Provider data**: The selected CLI backend and your model provider may retain logs and request data
884
- according to their own settings and privacy policies.
885
- - **Clipboard**: Pressing **C** copies the text to your system clipboard, where
886
- your operating system or clipboard manager may retain it.
887
- - **Advisor requests**: `bro_advisor` sends the executor agent's system
888
- instructions, active tool list (excluding `bro_advisor`), ordered
889
- conversation history including tool calls and tool results (unlike Show, which
890
- omits them), human steering brief, and the executor's optional question to
891
- the selected backend and its configured model provider. Reasoning and image bodies are
892
- omitted with explicit markers (`[reasoning omitted]`, `[image omitted]`).
893
- - **Advisor tool execution & safety boundary**: The advisor process runs
894
- directly in your workspace (`cwd`) with auto-approved permissions
895
- (Agy/Claude permission bypass; Grok `--sandbox off --permission-mode bypassPermissions`). It has real tool access (file reading,
896
- search, command execution). The directive to only advise and leave edits to
897
- the executor is a **behavioral prompt instruction**, not an enforced sandbox
898
- or security boundary. Treat its findings as advice to verify before applying.
899
- - **Advisor steering persistence**: The steering brief is saved as
900
- session-scoped custom extension data (`bro-advisor-steering`) in the session
901
- file. It persists across session resume and reload, and is inherited on
902
- session fork (post-fork edits on branches remain independent). It is never
903
- sent to the main model or added to Pi's conversation. The advisor tool has
904
- 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.
905
870
 
906
871
  ## Troubleshooting and current limits
907
872
 
@@ -910,7 +875,8 @@ extracted, copy its content into a supported text file or save it as a PDF and
910
875
  use `/bro file`. If a PDF contains only scanned images, run OCR with another
911
876
  tool before giving it to Bro.
912
877
 
913
- - 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.
914
880
  - Document input supports `.md`, `.markdown`, `.txt`, `.pdf`, and `.docx` only;
915
881
  it does not perform OCR.
916
882
  - Webpage input supports one public HTML page, up to 5 MiB downloaded and
@@ -919,23 +885,16 @@ tool before giving it to Bro.
919
885
  - Direct webpage fetching does not currently use `HTTP_PROXY`, `HTTPS_PROXY`,
920
886
  or other proxy environment variables.
921
887
  - `/bro btw` threads are memory-only and do not survive reloads or restarts.
922
- The side conversation uses Agy `--conversation` or Grok `--resume`; conversation-only
923
- mode caps a turn at 2 minutes and full mode at 10 minutes.
924
- - `bro_advisor` requires Agy CLI `>=1.1.15` (for `--input-format stream-json`).
925
- Consultations run directly in the workspace with auto-approved permissions
926
- without enforced file-modification isolation; an attempt is capped at 10
927
- minutes (`--print-timeout 10m`) and retries up to 2 times on invocation
928
- failure (5-second, then 10-second backoff).
888
+ - The Agy advisor requires Agy CLI `>=1.1.15`.
929
889
  - Show captures only the conversation text of what already happened in the
930
890
  current session — the last few turns' user and assistant messages, with
931
- tool calls, tool results, reasoning, and images always omitted; it cannot
932
- read the repository or other files on its own, and its shapes reflect what
933
- 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.
934
893
  - HTML diagrams open in your default browser; pressing **O** on a remote or
935
894
  headless session with no display reports the failure instead of opening
936
895
  anything.
937
- - Keeps only the latest explanation in memory.
938
- - 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.
939
898
  - Bro temporarily captures mouse input while its modal is open so mouse-wheel
940
899
  and trackpad scrolling work in regular and fullscreen modes. Native mouse
941
900
  selection may be unavailable or visually extend outside the Bro window;
@@ -949,17 +908,14 @@ npm test
949
908
  pi --tui-mode fullscreen -e ./bro.ts
950
909
  ```
951
910
 
952
- 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
953
- verifies command routing, document and URL safety boundaries, HTML
954
- extraction, show capture (conversation text only, tool calls and results
955
- absent), and HTML-diagram handling, healthy and broken setup handling,
956
- 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.
957
915
 
958
916
  The prompt benchmark is manual and makes live Agy calls. Read
959
917
  [`benchmark/README.md`](benchmark/README.md) before running it; it is never part
960
- of `npm test`. A separate `--track show` benchmark grades the show prompt
961
- against serialized-transcript fixtures — one per show-me form — and is also
962
- manual and never part of `npm test`.
918
+ of `npm test`.
963
919
 
964
920
  ## License
965
921