pi-bro 0.13.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +172 -20
- package/bro.ts +1302 -65
- package/package.json +8 -5
- package/prompt.ts +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to pi-bro are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.15.0] - 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- In the `/bro btw` modal, `/copy` and `/copy-all` now copy the latest answer or the full thread to the **system clipboard** instead of the main editor. New `/insert` and `/insert-all` commands (with `/insert!`/`/insert-all!` force variants to replace an existing main-editor draft) insert into the main editor without submitting. Removed the legacy `/send` aliases and the spaced `/copy all`/`/insert all` spellings.
|
|
10
|
+
|
|
11
|
+
## [0.14.0] - 2026-09-20
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `bro_advisor` — a tool the **executor agent** (not the human) can voluntarily call mid-task for a second opinion from a fresh, standalone Agy process with real, unsandboxed tool access in the workspace (`--dangerously-skip-permissions`). Bro automatically captures a harness-neutral snapshot of the executor's system instructions, active tools, and conversation so far (including tool calls and results) and sends it, plus an optional executor-supplied question, to the advisor. The advisor is instructed to investigate before advising and to leave edits to the executor, but that boundary is behavioral, not enforced. Invocation failures retry twice (5s, then 10s) with the identical snapshot before surfacing Agy's own diagnostic.
|
|
16
|
+
- `/bro advisor-steer` — an editor for one persistent, session-scoped steering brief the advisor always reads (e.g. "quick prototype; keep A and B careful, everything else minimal"). The brief is stored as session-only extension data, is never added to Pi's conversation or sent to the main model, persists across resume/reload, and is inherited by forks.
|
|
17
|
+
- `/bro advisor` — a quick notice of whether `bro_advisor` is currently exposed and active, pointing at `/bro config`, `/bro advisor-steer`, and `/bro doctor`. `/bro doctor` carries the full diagnostic, including the Agy 1.1.15+ compatibility check.
|
|
18
|
+
- `/bro config` — a production settings screen replacing the earlier configuration-only spike: a shared default model/effort (still owned by `/bro model`/`/bro effort`) plus optional per-capability overrides for `explain`, `show`, `btw`, and `advisor`. An override always pins both model and effort together and is only ever cleared by an explicit "Default" selection. Saves are serialized and coalesced, with in-place revert and an inline error notice on failure.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Requires Earendil Pi `>=0.84.2 <1` and `agy >=1.1.15` (up from `>=0.78.1 <1` and `>=1.1.11`).
|
|
23
|
+
|
|
5
24
|
## [0.13.2] - 2026-09-19
|
|
6
25
|
|
|
7
26
|
### Changed
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ with your selected model.
|
|
|
11
11
|
|
|
12
12
|
## Quick start
|
|
13
13
|
|
|
14
|
-
You need Earendil Pi `>=0.
|
|
14
|
+
You need Earendil Pi `>=0.84.2 <1`, Node.js `>=22.19.0`, and `agy >=1.1.15`
|
|
15
15
|
installed and available on your `PATH`. Run `agy` once in your terminal to sign
|
|
16
16
|
in, then install Bro:
|
|
17
17
|
|
|
@@ -63,10 +63,13 @@ text directly captures a new source the same way.
|
|
|
63
63
|
| `/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. |
|
|
64
64
|
| `/bro doctor` | Check Bro's settings, Agy installation, account, model, effort, and mode. |
|
|
65
65
|
| `/bro usage [--provider agy]` | Show current Agy resource limits. |
|
|
66
|
-
| `/bro model [id]` | View or choose the Agy model. |
|
|
67
|
-
| `/bro effort [low\|medium\|high]` | View or choose the
|
|
66
|
+
| `/bro model [id]` | View or choose the shared default Agy model. |
|
|
67
|
+
| `/bro effort [low\|medium\|high]` | View or choose the shared default reasoning effort. |
|
|
68
68
|
| `/bro mode [brief\|balanced\|faithful]` | View or choose the explanation mode. |
|
|
69
|
+
| `/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. |
|
|
69
70
|
| `/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. |
|
|
71
|
+
| `/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`. |
|
|
72
|
+
| `/bro advisor-steer` | View, edit, save, or clear the one persistent steering brief the advisor always sees. |
|
|
70
73
|
| `/bro help` | Open the built-in quick reference. |
|
|
71
74
|
|
|
72
75
|
Giving `/bro` the input directly works the same way:
|
|
@@ -108,25 +111,105 @@ your terminal mode; press **C** to copy the complete explanation reliably.
|
|
|
108
111
|
`/bro btw` opens a separate multi-turn conversation in a modal, so you can ask
|
|
109
112
|
a quick side question while the main agent keeps working. It runs through Agy,
|
|
110
113
|
the same backend as the rest of Bro, and never adds anything to Pi's
|
|
111
|
-
conversation unless you explicitly
|
|
114
|
+
conversation unless you explicitly insert it into the editor.
|
|
112
115
|
|
|
113
116
|
- **Sandboxed by default**: the side conversation is read-only (no project
|
|
114
117
|
access). Add `--full` to let it read and edit the workspace.
|
|
115
118
|
- `/bro btw <question>` asks immediately; `/bro btw` opens an empty thread.
|
|
116
119
|
- `--fresh` starts a thread without seeding the main session's recent
|
|
117
|
-
conversation text.
|
|
120
|
+
conversation text. Reopening without an access flag preserves the existing
|
|
121
|
+
thread's access mode, including `--full`. Use `--sandbox` to return to sandbox
|
|
122
|
+
mode; changing access mode starts a new thread. `--fresh` alone does not reset
|
|
123
|
+
the access mode.
|
|
118
124
|
- The first turn is seeded with up to the last 8 turns of user/assistant
|
|
119
125
|
conversation text (40,000 characters max, with a truncation notice); the
|
|
120
126
|
side agent can also read the repo itself when running in `--full` mode.
|
|
121
127
|
- **In the modal**: type a question and press Enter (empty Enter re-asks the
|
|
122
|
-
last question).
|
|
123
|
-
|
|
124
|
-
copies the full thread
|
|
125
|
-
the
|
|
126
|
-
|
|
128
|
+
last question). Composer actions trigger only on these exact commands:
|
|
129
|
+
- `/copy`: copies the latest answer to the system clipboard
|
|
130
|
+
- `/copy-all`: copies the full thread to the system clipboard
|
|
131
|
+
- `/insert`: inserts the latest answer into the main editor without submitting (use `/insert!` to replace an existing editor draft)
|
|
132
|
+
- `/insert-all`: inserts the full thread into the main editor without submitting (use `/insert-all!` to replace an existing editor draft)
|
|
133
|
+
- `/retry`: re-asks the last question (empty Enter does the same)
|
|
134
|
+
- `/clear`: resets the thread
|
|
135
|
+
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.
|
|
127
136
|
- The thread lives in memory only — it clears when you switch Pi sessions,
|
|
128
137
|
reload extensions, or quit Pi.
|
|
129
138
|
|
|
139
|
+
## Bro advisor
|
|
140
|
+
|
|
141
|
+
`bro_advisor` is a tool the **executor agent** — not you — can voluntarily
|
|
142
|
+
call mid-task for a second opinion. Unlike `/bro btw`, which is a side
|
|
143
|
+
conversation for you, `bro_advisor` is a tool for the model you're working
|
|
144
|
+
with; it shows up as a normal tool call/result in the transcript, not a
|
|
145
|
+
modal. It is registered like any other tool when the extension loads and has
|
|
146
|
+
no on/off switch of its own — whether the executor can actually call it
|
|
147
|
+
depends entirely on this host's own tool restrictions.
|
|
148
|
+
|
|
149
|
+
`/bro advisor` is a quick notice of whether `bro_advisor` is available right
|
|
150
|
+
now, pointing at `/bro config`, `/bro advisor-steer`, and `/bro doctor`.
|
|
151
|
+
`/bro doctor` has the full diagnostic: whether this host exposes and
|
|
152
|
+
activates `bro_advisor`, its resolved model/effort, steering presence, and
|
|
153
|
+
the Agy compatibility floor — it also checks the installed Agy version and
|
|
154
|
+
gives an `agy update` action when it is too old.
|
|
155
|
+
|
|
156
|
+
- **Automatic context, no prep needed**: the executor never assembles a
|
|
157
|
+
summary. Bro captures a harness-neutral snapshot — the executor's system
|
|
158
|
+
instructions, its active tools, and the conversation so far including tool
|
|
159
|
+
calls and results — and sends it, along with an optional `question` the
|
|
160
|
+
executor may pass, to a **fresh, standalone Agy process** for every
|
|
161
|
+
consultation. Nothing is resumed or reused across calls, including retries.
|
|
162
|
+
- **Instructed to investigate, not implement**: the advisor process has real
|
|
163
|
+
tool access in the workspace with permissions auto-approved
|
|
164
|
+
(`--dangerously-skip-permissions`) — there is no enforced read-only
|
|
165
|
+
isolation. It is instructed to verify claims itself and return advice,
|
|
166
|
+
leaving edits to the executor, but that boundary is a behavioral prompt
|
|
167
|
+
instruction rather than an enforced sandbox constraint, so treat its
|
|
168
|
+
findings as advice to verify, not a guaranteed hands-off review.
|
|
169
|
+
- **Steering**: `/bro advisor-steer` opens an editor for one persistent
|
|
170
|
+
steering brief — e.g. "quick prototype; keep A and B careful, everything
|
|
171
|
+
else minimal" — that the advisor always reads. **Ctrl+S** saves and keeps
|
|
172
|
+
the editor open; **Enter** or **Shift+Enter** inserts a newline; **Ctrl+K**
|
|
173
|
+
clears both the saved brief and draft while staying open; **Ctrl+C** copies
|
|
174
|
+
the entire current draft, including unsaved edits; and **Esc** closes without
|
|
175
|
+
saving unsaved edits. Actions and clipboard errors are reported inline. The
|
|
176
|
+
brief is stored as session-only extension data and is **never added to Pi's
|
|
177
|
+
conversation or sent to the main model** — the advisor is the only thing
|
|
178
|
+
that reads it.
|
|
179
|
+
- **Persistence**: the steering brief persists with the Pi session (not
|
|
180
|
+
globally, not per project) as custom extension data in the session file and
|
|
181
|
+
is restored on resume or reload. Forking a session inherits it; edits made
|
|
182
|
+
after the fork are independent of the original branch. The advisor tool has
|
|
183
|
+
no separate activation state persisted or toggled.
|
|
184
|
+
- **Retries**: on an invocation failure (not a completed answer — "I need
|
|
185
|
+
more evidence" is a normal result, not a failure), Bro retries with the
|
|
186
|
+
identical snapshot, steering, and question: once after 5 seconds, once more
|
|
187
|
+
after 10 seconds, then returns Agy's own diagnostic — including a
|
|
188
|
+
context-length error, verbatim — as the failure. Cancelling the tool call
|
|
189
|
+
aborts immediately and skips any pending retry wait.
|
|
190
|
+
- **Progress and provenance**: while an attempt is running, Bro parses the
|
|
191
|
+
advisor's own stream for the last thing it actually reported — either a
|
|
192
|
+
tool name or a user-facing response line (hidden reasoning is never
|
|
193
|
+
surfaced) — and shows it with how long ago it arrived, e.g. `last reported:
|
|
194
|
+
Read src/app.ts (2s ago)`. Before Agy reports anything, this reads
|
|
195
|
+
explicitly as "awaiting first activity from Agy" rather than guessing at
|
|
196
|
+
what it might be doing. This is what was actually reported, not a live
|
|
197
|
+
claim about Agy's current tool, and silence is never described as
|
|
198
|
+
"stalled". Expanding a running consultation shows up to the last 4 reported
|
|
199
|
+
activity lines. Each retry starts this trail over empty — a failed
|
|
200
|
+
attempt's activity never carries into the next one. Elapsed running time
|
|
201
|
+
still ticks once a second regardless of activity; a retry countdown with
|
|
202
|
+
the last failure is shown the same way as before. The returned answer
|
|
203
|
+
starts with model, effort, actual attempt count, duration, workspace,
|
|
204
|
+
steering presence, snapshot size, no-Bro-truncation status, and known
|
|
205
|
+
omission/compaction notes; the advisor's complete answer follows unchanged.
|
|
206
|
+
- **Model/effort**: resolved the same way as explain/show/btw, through
|
|
207
|
+
`/bro model`/`/bro effort` (shared default) or `/bro config` (per-capability
|
|
208
|
+
override).
|
|
209
|
+
|
|
210
|
+
See [docs/plans/2026-09-19-bro-advisor-design.md](docs/plans/2026-09-19-bro-advisor-design.md)
|
|
211
|
+
for the full design.
|
|
212
|
+
|
|
130
213
|
## Bro show
|
|
131
214
|
|
|
132
215
|
Where the explanation modes rewrite dense prose in simpler words, `/bro show`
|
|
@@ -160,11 +243,14 @@ changed in the auth flow`. The query is used as a lens on the captured turns,
|
|
|
160
243
|
not as additional evidence, and its casing is preserved as typed. Pressing
|
|
161
244
|
**R** retries with the same turn count and query.
|
|
162
245
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
on "
|
|
166
|
-
|
|
167
|
-
|
|
246
|
+
Any leading whitespace-delimited word that looks like a number is treated as the
|
|
247
|
+
requested turn count: for example, `/bro show 3 what changed` captures 3 turns
|
|
248
|
+
and steers on "what changed", while `/bro show 404 handler` parses "404" as the
|
|
249
|
+
turn count and "handler" as the steering query. To steer on a phrase that starts
|
|
250
|
+
with digits while choosing a turn count, specify the turn count explicitly
|
|
251
|
+
first: `/bro show 1 404 handler` captures 1 turn and steers on "404 handler".
|
|
252
|
+
If the first word is not a number, the whole input is treated as the steering
|
|
253
|
+
query using the saved `showTurns` default.
|
|
168
254
|
|
|
169
255
|
### A slow session-create, traced
|
|
170
256
|
|
|
@@ -610,15 +696,41 @@ Bro creates this user-editable settings file when the extension loads:
|
|
|
610
696
|
}
|
|
611
697
|
```
|
|
612
698
|
|
|
613
|
-
|
|
614
|
-
|
|
699
|
+
`model` and `effort` are the **shared default**: explain, show, and btw all use
|
|
700
|
+
them unless a capability has its own override. An optional `overrides` object
|
|
701
|
+
adds per-capability overrides, each a full `{ "model": ..., "effort": ... }`
|
|
702
|
+
pair:
|
|
703
|
+
|
|
704
|
+
```json
|
|
705
|
+
{
|
|
706
|
+
"model": "gemini-3.7-flash",
|
|
707
|
+
"effort": "low",
|
|
708
|
+
"mode": "balanced",
|
|
709
|
+
"showTurns": 1,
|
|
710
|
+
"overrides": {
|
|
711
|
+
"show": { "model": "gemini-3.7-pro", "effort": "high" }
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
Use `/bro model`, `/bro effort`, and `/bro mode` to update the shared default
|
|
717
|
+
and mode from Pi, `/bro config` to review or change the shared default and any
|
|
718
|
+
per-capability (explain/show/btw/advisor) overrides interactively, or edit the file
|
|
719
|
+
directly. Bro reads the file again before each explanation, so manual changes
|
|
615
720
|
apply to the next `/bro`. Use a model ID shown by `/bro model`; `effort` must be
|
|
616
721
|
one of the levels shown by `/bro effort`. Models without adjustable effort use
|
|
617
722
|
`default`. `mode` must be `brief`, `balanced`, or `faithful`; existing settings
|
|
618
723
|
without it use `balanced`. `showTurns` is the default number of turns `/bro
|
|
619
|
-
show` draws (default 1); `/bro show <n-turns>` overrides it for a single run.
|
|
620
|
-
|
|
621
|
-
you change them. `/bro help` shows the active
|
|
724
|
+
show` draws (default 1); `/bro show <n-turns>` overrides it for a single run. Settings
|
|
725
|
+
written before per-capability overrides existed load unchanged, with no overrides. The choices remain
|
|
726
|
+
active across Pi restarts until you change them. `/bro help` shows the active
|
|
727
|
+
settings, any overrides, and the exact file path.
|
|
728
|
+
|
|
729
|
+
`/bro config`'s changes save immediately as you make them. Pressing Esc inside
|
|
730
|
+
a model or effort picker cancels that pick without changing anything; pressing
|
|
731
|
+
Esc on the settings screen itself just closes it, keeping whatever was already
|
|
732
|
+
saved. If a save fails (for example, a read-only settings file), the screen
|
|
733
|
+
shows the error inline instead of losing the change silently.
|
|
622
734
|
|
|
623
735
|
If `PI_CODING_AGENT_DIR` is set, the file lives there instead. `PI_BRO_MODEL`
|
|
624
736
|
chooses the initial model only when Bro creates a missing settings file:
|
|
@@ -627,6 +739,23 @@ chooses the initial model only when Bro creates a missing settings file:
|
|
|
627
739
|
PI_BRO_MODEL=gemini-3.7-flash-low pi
|
|
628
740
|
```
|
|
629
741
|
|
|
742
|
+
### Configuration precedence
|
|
743
|
+
|
|
744
|
+
When resolving model and reasoning effort:
|
|
745
|
+
1. **Per-capability override**: If configured under `overrides.<capability>` (`explain`, `show`, `btw`, or `advisor`) in `bro-settings.json`, that capability pins its own `{ "model": ..., "effort": ... }` pair and ignores the shared default.
|
|
746
|
+
2. **Shared default**: If no override is set for that capability, it inherits the root `model` and `effort` in `bro-settings.json`.
|
|
747
|
+
3. **Catalog normalization**: Bro normalizes the resolved `{ model, effort }` against Agy's installed model catalog (mapping suffixed variant IDs and handling fixed-effort models).
|
|
748
|
+
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.
|
|
749
|
+
|
|
750
|
+
When resolving turn count for `/bro show`:
|
|
751
|
+
1. **Command argument**: An explicit count like `/bro show 3` or `/bro show 1 query` overrides for that single execution.
|
|
752
|
+
2. **Saved setting**: `showTurns` in `bro-settings.json` (defaults to 1; configurable interactively via `/bro config` or direct file edit).
|
|
753
|
+
|
|
754
|
+
When resolving explanation prompt (`explain` capability only):
|
|
755
|
+
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.
|
|
756
|
+
2. **Saved mode**: `mode` in `bro-settings.json` (`brief`, `balanced`, or `faithful`; defaults to `balanced`).
|
|
757
|
+
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`.
|
|
758
|
+
|
|
630
759
|
## Custom prompt
|
|
631
760
|
|
|
632
761
|
Bro uses a built-in prompt by default. To use your own, create:
|
|
@@ -705,6 +834,24 @@ run `/bro doctor` for the exact problem.
|
|
|
705
834
|
according to their own settings and privacy policies.
|
|
706
835
|
- **Clipboard**: Pressing **C** copies the text to your system clipboard, where
|
|
707
836
|
your operating system or clipboard manager may retain it.
|
|
837
|
+
- **Advisor requests**: `bro_advisor` sends the executor agent's system
|
|
838
|
+
instructions, active tool list (excluding `bro_advisor`), ordered
|
|
839
|
+
conversation history including tool calls and tool results (unlike Show, which
|
|
840
|
+
omits them), human steering brief, and the executor's optional question to
|
|
841
|
+
Agy and your configured model provider. Reasoning and image bodies are
|
|
842
|
+
omitted with explicit markers (`[reasoning omitted]`, `[image omitted]`).
|
|
843
|
+
- **Advisor tool execution & safety boundary**: The advisor process runs
|
|
844
|
+
directly in your workspace (`cwd`) with auto-approved permissions
|
|
845
|
+
(`--dangerously-skip-permissions`). It has real tool access (file reading,
|
|
846
|
+
search, command execution). The directive to only advise and leave edits to
|
|
847
|
+
the executor is a **behavioral prompt instruction**, not an enforced sandbox
|
|
848
|
+
or security boundary. Treat its findings as advice to verify before applying.
|
|
849
|
+
- **Advisor steering persistence**: The steering brief is saved as
|
|
850
|
+
session-scoped custom extension data (`bro-advisor-steering`) in the session
|
|
851
|
+
file. It persists across session resume and reload, and is inherited on
|
|
852
|
+
session fork (post-fork edits on branches remain independent). It is never
|
|
853
|
+
sent to the main model or added to Pi's conversation. The advisor tool has
|
|
854
|
+
no separate activation state.
|
|
708
855
|
|
|
709
856
|
## Troubleshooting and current limits
|
|
710
857
|
|
|
@@ -724,6 +871,11 @@ tool before giving it to Bro.
|
|
|
724
871
|
- `/bro btw` threads are memory-only and do not survive reloads or restarts.
|
|
725
872
|
The side conversation needs Agy's `--conversation` resume support; sandbox
|
|
726
873
|
mode caps a turn at 2 minutes and full mode at 10 minutes.
|
|
874
|
+
- `bro_advisor` requires Agy CLI `>=1.1.15` (for `--input-format stream-json`).
|
|
875
|
+
Consultations run directly in the workspace with auto-approved permissions
|
|
876
|
+
without enforced file-modification isolation; an attempt is capped at 10
|
|
877
|
+
minutes (`--print-timeout 10m`) and retries up to 2 times on invocation
|
|
878
|
+
failure (5-second, then 10-second backoff).
|
|
727
879
|
- Show captures only the conversation text of what already happened in the
|
|
728
880
|
current session — the last few turns' user and assistant messages, with
|
|
729
881
|
tool calls, tool results, reasoning, and images always omitted; it cannot
|