pi-bro 0.15.1 → 0.17.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 (5) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +96 -53
  3. package/backend.ts +497 -10
  4. package/bro.ts +778 -160
  5. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  All notable changes to pi-bro are documented here.
4
4
 
5
+ ## [0.17.0] - 2026-09-24
6
+
7
+ ### Added
8
+
9
+ - Grok Build execution for explain, show, native multi-turn BTW (both modes), and advisor, with per-capability model/effort configuration, custom model IDs, and installation diagnostics. Agy remains the default.
10
+ - Capability-first Grok access: conversation-only intent uses prompt instructions when enforcement is unavailable, with truthful UI/docs rather than feature bans or speculative tool blacklists. Native tools remain available.
11
+ - Private temporary prompt files, backend-bound continuation, authoritative terminal completion checks and bounded cancellation. Backend/access changes start a fresh BTW thread instead of reusing incompatible native session IDs.
12
+ - Explain, show, and BTW modal headers show the model and reasoning effort each request used (`default` when the model's own effort applies); `/bro open` keeps the original label.
13
+
14
+ ### Changed
15
+
16
+ - The BTW header no longer shows a sandbox/conversation-only access label; the `full · edits repo` badge still marks `--full` threads.
17
+
18
+ ### Removed
19
+
20
+ - `/bro usage` is removed for now. Doctor still checks Agy account access.
21
+
22
+ ## [0.16.0] - 2026-09-24
23
+
24
+ ### Added
25
+
26
+ - Claude Code execution for explain, show and advisor, selected independently per capability through `/bro config`. Explain/show disable tools and customizations; advisor runs fresh with workspace tools. Claude-backed BTW is explicitly unsupported in this release.
27
+ - Backend-tagged model/effort selections with atomic per-capability overrides. Existing settings remain Agy selections and are migrated to version 2 only when saved; Agy remains the default.
28
+
5
29
  ## [0.15.1] - 2026-09-22
6
30
 
7
31
  ### Changed
package/README.md CHANGED
@@ -1,13 +1,14 @@
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
8
  It opens explanations in a separate modal and uses the
9
9
  [Google Antigravity CLI](https://antigravity.google/docs/cli-install) (`agy`)
10
- with your selected model.
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.
11
12
 
12
13
  ## Quick start
13
14
 
@@ -32,7 +33,7 @@ Restart Pi or run `/reload`, then try:
32
33
  Run `/bro doctor` after installation or whenever Bro is not working.
33
34
 
34
35
  Explain, show, BTW and advisor share an internal execution layer; Agy remains
35
- its only backend and existing settings are unchanged. Cancellation, host deadlines
36
+ the default backend. Claude Code can be selected per capability in `/bro config`. Cancellation, host deadlines
36
37
  and invalid execution streams terminate the subprocess group on POSIX, escalating
37
38
  after a five-second grace period. Windows cleanup targets the direct child only;
38
39
  descendant termination is not guaranteed. Unexpected signal exits are reported as
@@ -69,8 +70,7 @@ text directly captures a new source the same way.
69
70
  | `/bro open` | Reopen the latest explanation without calling the simplifier again. |
70
71
  | `/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. |
71
72
  | `/bro doctor` | Check Bro's settings, Agy installation, account, model, effort, and mode. |
72
- | `/bro usage [--provider agy]` | Show current Agy resource limits. |
73
- | `/bro model [id]` | View or choose the shared default Agy model. |
73
+ | `/bro model [id]` | View or choose the selected backend’s shared default model. |
74
74
  | `/bro effort [low\|medium\|high]` | View or choose the shared default reasoning effort. |
75
75
  | `/bro mode [brief\|balanced\|faithful]` | View or choose the explanation mode. |
76
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. |
@@ -109,6 +109,10 @@ a persistent mode with `/bro mode`:
109
109
  - **O**: Open the HTML diagram when a show reply contains one
110
110
  - **Esc**: Close the modal, or cancel while Bro is working
111
111
 
112
+ The modal header shows the model and reasoning effort the explanation or
113
+ drawing used (`default` when the model's own effort applies); `/bro open`
114
+ keeps the original label.
115
+
112
116
  Bro temporarily captures mouse input while its modal is open. Native mouse
113
117
  selection may be unavailable or visually extend outside the modal depending on
114
118
  your terminal mode; press **C** to copy the complete explanation reliably.
@@ -116,17 +120,19 @@ your terminal mode; press **C** to copy the complete explanation reliably.
116
120
  ## Bro btw (side conversation)
117
121
 
118
122
  `/bro btw` opens a separate multi-turn conversation in a modal, so you can ask
119
- a quick side question while the main agent keeps working. It runs through Agy,
120
- the same backend as the rest of Bro, and never adds anything to Pi's
123
+ 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
121
125
  conversation unless you explicitly insert it into the editor.
122
126
 
123
- - **Sandboxed by default**: the side conversation is read-only (no project
124
- access). Add `--full` to let it read and edit the workspace.
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.
125
131
  - `/bro btw <question>` asks immediately; `/bro btw` opens an empty thread.
126
132
  - `--fresh` starts a thread without seeding the main session's recent
127
133
  conversation text. Reopening without an access flag preserves the existing
128
- thread's access mode, including `--full`. Use `--sandbox` to return to sandbox
129
- mode; changing access mode starts a new thread. `--fresh` alone does not reset
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
130
136
  the access mode.
131
137
  - The first turn is seeded with up to the last 8 turns of user/assistant
132
138
  conversation text (40,000 characters max, with a truncation notice); the
@@ -139,7 +145,7 @@ conversation unless you explicitly insert it into the editor.
139
145
  - `/insert-all`: inserts the full thread into the main editor without submitting (use `/insert-all!` to replace an existing editor draft)
140
146
  - `/retry`: re-asks the last question (empty Enter does the same)
141
147
  - `/clear`: resets the thread
142
- 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.
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.
143
149
  - The thread lives in memory only — it clears when you switch Pi sessions,
144
150
  reload extensions, or quit Pi.
145
151
 
@@ -164,7 +170,7 @@ gives an `agy update` action when it is too old.
164
170
  summary. Bro captures a harness-neutral snapshot — the executor's system
165
171
  instructions, its active tools, and the conversation so far including tool
166
172
  calls and results — and sends it, along with an optional `question` the
167
- executor may pass, to a **fresh, standalone Agy process** for every
173
+ executor may pass, to a **fresh, standalone process of the selected backend** for every
168
174
  consultation. Nothing is resumed or reused across calls, including retries.
169
175
  - **Instructed to investigate, not implement**: the advisor process has real
170
176
  tool access in the workspace with permissions auto-approved
@@ -224,7 +230,7 @@ changes the form: it draws what you and the assistant said in the last few
224
230
  session turns as a shape instead of paragraphs. Capture keeps only user and
225
231
  assistant conversation text, including every intermediate assistant message in
226
232
  a turn — tool calls, tool results, reasoning, and images never leave the
227
- session. It runs the same isolated, sandboxed model call and shows the result
233
+ session. It runs the same backend-specific model call and shows the result
228
234
  in the same modal, never touching your conversation. `/bro show` uses its own
229
235
  draw prompt; the explanation modes and `bro-prompt.md` do not affect it.
230
236
 
@@ -694,32 +700,71 @@ Bro creates this user-editable settings file when the extension loads:
694
700
  ~/.pi/agent/bro-settings.json
695
701
  ```
696
702
 
697
- ```json
698
- {
699
- "model": "gemini-3.7-flash",
700
- "effort": "low",
701
- "mode": "balanced",
702
- "showTurns": 1
703
- }
704
- ```
705
-
706
- `model` and `effort` are the **shared default**: explain, show, and btw all use
707
- them unless a capability has its own override. An optional `overrides` object
708
- adds per-capability overrides, each a full `{ "model": ..., "effort": ... }`
709
- pair:
703
+ Existing flat model/effort files remain valid and select Agy. Explicit saves use
704
+ version 2 with backend-tagged selections:
710
705
 
711
706
  ```json
712
707
  {
713
- "model": "gemini-3.7-flash",
714
- "effort": "low",
708
+ "version": 2,
709
+ "default": { "backend": "agy", "model": "gemini-3.7-flash", "effort": "low" },
715
710
  "mode": "balanced",
716
711
  "showTurns": 1,
717
712
  "overrides": {
718
- "show": { "model": "gemini-3.7-pro", "effort": "high" }
713
+ "explain": { "backend": "claude", "model": "sonnet", "effort": "medium" },
714
+ "advisor": { "backend": "claude", "model": "opus", "effort": "high" }
719
715
  }
720
716
  }
721
717
  ```
722
718
 
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
+
723
768
  Use `/bro model`, `/bro effort`, and `/bro mode` to update the shared default
724
769
  and mode from Pi, `/bro config` to review or change the shared default and any
725
770
  per-capability (explain/show/btw/advisor) overrides interactively, or edit the file
@@ -749,9 +794,9 @@ PI_BRO_MODEL=gemini-3.7-flash-low pi
749
794
  ### Configuration precedence
750
795
 
751
796
  When resolving model and reasoning effort:
752
- 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.
753
- 2. **Shared default**: If no override is set for that capability, it inherits the root `model` and `effort` in `bro-settings.json`.
754
- 3. **Catalog normalization**: Bro normalizes the resolved `{ model, effort }` against Agy's installed model catalog (mapping suffixed variant IDs and handling fixed-effort models).
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).
755
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.
756
801
 
757
802
  When resolving turn count for `/bro show`:
@@ -799,30 +844,28 @@ run `/bro doctor` for the exact problem.
799
844
  - **External requests**: Bro sends the latest completed assistant response,
800
845
  pasted text, extracted document text, extracted webpage text, or recent
801
846
  session conversation text (tool calls, tool results, reasoning, and images
802
- omitted) to Agy and its configured model provider.
847
+ omitted) to the selected backend and its configured model provider.
803
848
  - **Side conversation requests**: `/bro btw` sends your side questions and, on
804
849
  the first turn, the seeded main-session conversation text to Agy. In `--full`
805
850
  mode the side agent additionally reads the workspace.
806
- - **Usage checks**: `/bro usage` checks your authenticated Agy limits without
807
- sending an assistant response or running a model turn.
808
851
  - **Setup checks**: `/bro doctor` checks Agy account and model availability
809
852
  without sending an assistant response or running a model turn.
810
853
  - **Context isolation**: Bro does not add explanations to Pi's conversation
811
854
  history, session files, or main-agent context.
812
- - **Side conversation (`/bro btw`)**: sandboxed by default — the side agent has
813
- no project access and runs in a temporary folder. With `--full` it runs in
814
- your workspace with auto-approved tools, so it can read and edit files while
815
- the main agent is also working; use `--full` only when you want that. The
816
- side thread is memory-only and clears when you switch sessions, reload
817
- extensions, or quit Pi.
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.
818
860
  - **Memory cache**: The latest explanation is stored only in process memory for
819
861
  `/bro open`. It clears when you switch Pi sessions, reload extensions, or quit
820
862
  Pi.
821
863
  - **File safety**: `/bro file` reads only regular files whose resolved path is
822
- inside Pi's current workspace, including after resolving symlinks. Bro does
823
- not modify them. It runs Agy in sandbox mode inside a temporary empty folder.
824
- This reduces project access, but it is not a security boundary. Bro only
825
- writes its own user settings file described above.
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.
826
869
  - **Web requests**: `/bro url` connects directly to the target website. The site
827
870
  sees your IP address and Bro's user agent. Bro sends no browser cookies,
828
871
  authorization, or referrer information, and it refuses local, private, and
@@ -830,14 +873,14 @@ run `/bro doctor` for the exact problem.
830
873
  URLs whose query string contains secrets.
831
874
  - **Web extraction**: Bro parses downloaded HTML locally without executing page
832
875
  scripts or loading page subresources. It sends the extracted readable text,
833
- including links preserved in that text, to Agy; it does not separately send
876
+ including links preserved in that text, to the selected backend; it does not separately send
834
877
  the requested URL or raw page HTML. The URL, captured text, and explanation
835
878
  remain in process memory only and clear with the existing `/bro open` cache.
836
879
  - **Show diagrams**: When a show reply ends in one self-contained HTML block,
837
880
  Bro writes it to `/tmp/pi-bro-<uid>/bro-show-<hash>.html` with a restrictive
838
881
  Content-Security-Policy, and opens it in your browser only when you press
839
882
  **O**. **C** copies the full reply, including the HTML.
840
- - **Provider data**: Agy and your model provider may retain logs and request data
883
+ - **Provider data**: The selected CLI backend and your model provider may retain logs and request data
841
884
  according to their own settings and privacy policies.
842
885
  - **Clipboard**: Pressing **C** copies the text to your system clipboard, where
843
886
  your operating system or clipboard manager may retain it.
@@ -845,11 +888,11 @@ run `/bro doctor` for the exact problem.
845
888
  instructions, active tool list (excluding `bro_advisor`), ordered
846
889
  conversation history including tool calls and tool results (unlike Show, which
847
890
  omits them), human steering brief, and the executor's optional question to
848
- Agy and your configured model provider. Reasoning and image bodies are
891
+ the selected backend and its configured model provider. Reasoning and image bodies are
849
892
  omitted with explicit markers (`[reasoning omitted]`, `[image omitted]`).
850
893
  - **Advisor tool execution & safety boundary**: The advisor process runs
851
894
  directly in your workspace (`cwd`) with auto-approved permissions
852
- (`--dangerously-skip-permissions`). It has real tool access (file reading,
895
+ (Agy/Claude permission bypass; Grok `--sandbox off --permission-mode bypassPermissions`). It has real tool access (file reading,
853
896
  search, command execution). The directive to only advise and leave edits to
854
897
  the executor is a **behavioral prompt instruction**, not an enforced sandbox
855
898
  or security boundary. Treat its findings as advice to verify before applying.
@@ -867,7 +910,7 @@ extracted, copy its content into a supported text file or save it as a PDF and
867
910
  use `/bro file`. If a PDF contains only scanned images, run OCR with another
868
911
  tool before giving it to Bro.
869
912
 
870
- - Uses Agy as its only provider.
913
+ - Supports Agy for all capabilities and Claude Code for explain/show/advisor. Claude BTW is not yet supported; unsupported selections fail without fallback.
871
914
  - Document input supports `.md`, `.markdown`, `.txt`, `.pdf`, and `.docx` only;
872
915
  it does not perform OCR.
873
916
  - Webpage input supports one public HTML page, up to 5 MiB downloaded and
@@ -876,7 +919,7 @@ tool before giving it to Bro.
876
919
  - Direct webpage fetching does not currently use `HTTP_PROXY`, `HTTPS_PROXY`,
877
920
  or other proxy environment variables.
878
921
  - `/bro btw` threads are memory-only and do not survive reloads or restarts.
879
- The side conversation needs Agy's `--conversation` resume support; sandbox
922
+ The side conversation uses Agy `--conversation` or Grok `--resume`; conversation-only
880
923
  mode caps a turn at 2 minutes and full mode at 10 minutes.
881
924
  - `bro_advisor` requires Agy CLI `>=1.1.15` (for `--input-format stream-json`).
882
925
  Consultations run directly in the workspace with auto-approved permissions
@@ -906,7 +949,7 @@ npm test
906
949
  pi --tui-mode fullscreen -e ./bro.ts
907
950
  ```
908
951
 
909
- The smoke test uses a fake `agy`, so it does not call an external model. It
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
910
953
  verifies command routing, document and URL safety boundaries, HTML
911
954
  extraction, show capture (conversation text only, tool calls and results
912
955
  absent), and HTML-diagram handling, healthy and broken setup handling,