pi-bro 0.13.0 → 0.13.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/CHANGELOG.md +6 -0
- package/README.md +3 -3
- package/bro.ts +42 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to pi-bro are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.13.1] - 2026-09-17
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Renamed `/bro btw` composer commands from `/send` and `/send all` to `/copy` and `/copy-all` (also accepts `/copy all`), with `/copy!` and `/copy-all!` force variants to replace existing main-editor drafts. Legacy `/send` commands remain supported as aliases.
|
|
10
|
+
|
|
5
11
|
## [0.13.0] - 2026-09-15
|
|
6
12
|
|
|
7
13
|
### Added
|
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ your terminal mode; press **C** to copy the complete explanation reliably.
|
|
|
108
108
|
`/bro btw` opens a separate multi-turn conversation in a modal, so you can ask
|
|
109
109
|
a quick side question while the main agent keeps working. It runs through Agy,
|
|
110
110
|
the same backend as the rest of Bro, and never adds anything to Pi's
|
|
111
|
-
conversation unless you explicitly
|
|
111
|
+
conversation unless you explicitly copy it into the editor.
|
|
112
112
|
|
|
113
113
|
- **Sandboxed by default**: the side conversation is read-only (no project
|
|
114
114
|
access). Add `--full` to let it read and edit the workspace.
|
|
@@ -119,8 +119,8 @@ conversation unless you explicitly send it back.
|
|
|
119
119
|
conversation text (40,000 characters max, with a truncation notice); the
|
|
120
120
|
side agent can also read the repo itself when running in `--full` mode.
|
|
121
121
|
- **In the modal**: type a question and press Enter (empty Enter re-asks the
|
|
122
|
-
last question). `/
|
|
123
|
-
without submitting (use `/
|
|
122
|
+
last question). `/copy` copies the latest answer into the main editor
|
|
123
|
+
without submitting (use `/copy!` to replace an existing draft); `/copy-all`
|
|
124
124
|
copies the full thread; `/retry` re-asks
|
|
125
125
|
the last question; `/clear` resets the thread; Esc closes. A visible
|
|
126
126
|
`full · edits repo` badge shows whenever `--full` mode is active.
|
package/bro.ts
CHANGED
|
@@ -1098,7 +1098,7 @@ Press **R** to simplify the captured source again. Run a new \`/bro text\`, \`/b
|
|
|
1098
1098
|
|
|
1099
1099
|
## Side conversation
|
|
1100
1100
|
|
|
1101
|
-
- \`/bro btw [--fresh] [--full] [question]\` — open a side conversation. Sandboxed (read-only) by default; add \`--full\` to let it read and edit the workspace, and \`--fresh\` to start without main-session context. Inside the side thread, type questions and press Enter (empty Enter re-asks); \`/
|
|
1101
|
+
- \`/bro btw [--fresh] [--full] [question]\` — open a side conversation. Sandboxed (read-only) by default; add \`--full\` to let it read and edit the workspace, and \`--fresh\` to start without main-session context. Inside the side thread, type questions and press Enter (empty Enter re-asks); \`/copy\` copies the latest answer to the main editor without submitting (use \`/copy!\` to replace an existing draft), \`/copy-all\` the full thread, \`/retry\` re-asks the last question, and \`/clear\` resets the thread. Esc closes.
|
|
1102
1102
|
|
|
1103
1103
|
## Current settings
|
|
1104
1104
|
|
|
@@ -1496,6 +1496,37 @@ export function parseBtwAgyLine(line: string): { delta?: string; result?: string
|
|
|
1496
1496
|
return { conversationId };
|
|
1497
1497
|
}
|
|
1498
1498
|
|
|
1499
|
+
export type BtwComposerAction =
|
|
1500
|
+
| { kind: "clear" }
|
|
1501
|
+
| { kind: "retry" }
|
|
1502
|
+
| { kind: "copy"; all: boolean; force: boolean }
|
|
1503
|
+
| { kind: "question"; text: string };
|
|
1504
|
+
|
|
1505
|
+
export function parseBtwComposerCommand(value: string): BtwComposerAction {
|
|
1506
|
+
const command = value.trim();
|
|
1507
|
+
if (command === "/clear") return { kind: "clear" };
|
|
1508
|
+
if (command === "/retry" || command === "") return { kind: "retry" };
|
|
1509
|
+
if (
|
|
1510
|
+
command === "/copy" ||
|
|
1511
|
+
command === "/copy!" ||
|
|
1512
|
+
command === "/copy-all" ||
|
|
1513
|
+
command === "/copy-all!" ||
|
|
1514
|
+
command === "/copy all" ||
|
|
1515
|
+
command === "/copy all!" ||
|
|
1516
|
+
command === "/send" ||
|
|
1517
|
+
command === "/send!" ||
|
|
1518
|
+
command === "/send all" ||
|
|
1519
|
+
command === "/send all!"
|
|
1520
|
+
) {
|
|
1521
|
+
const all =
|
|
1522
|
+
command.startsWith("/copy-all") ||
|
|
1523
|
+
command.startsWith("/copy all") ||
|
|
1524
|
+
command.startsWith("/send all");
|
|
1525
|
+
return { kind: "copy", all, force: command.endsWith("!") };
|
|
1526
|
+
}
|
|
1527
|
+
return { kind: "question", text: command };
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1499
1530
|
async function runBtwTurn(
|
|
1500
1531
|
prompt: string,
|
|
1501
1532
|
selection: ReturnType<typeof agySelection>,
|
|
@@ -1725,7 +1756,7 @@ class BtwModal implements Focusable {
|
|
|
1725
1756
|
|
|
1726
1757
|
const controls = this.running
|
|
1727
1758
|
? this.theme.fg("dim", "Thinking… · Esc cancel")
|
|
1728
|
-
: this.theme.fg("dim", "Enter ask · Esc close · /
|
|
1759
|
+
: this.theme.fg("dim", "Enter ask · Esc close · /copy · /copy-all · /clear · /retry");
|
|
1729
1760
|
|
|
1730
1761
|
const lines = [
|
|
1731
1762
|
this.borderLine(innerWidth, "top"),
|
|
@@ -1845,35 +1876,35 @@ async function openBtwModal(
|
|
|
1845
1876
|
const handoff = (all: boolean, force: boolean) => {
|
|
1846
1877
|
const text = all ? transcript() : (thread.turns.at(-1)?.answer ?? "");
|
|
1847
1878
|
if (!text.trim()) {
|
|
1848
|
-
modal.setNotice("Nothing to
|
|
1879
|
+
modal.setNotice("Nothing to copy yet.");
|
|
1849
1880
|
return;
|
|
1850
1881
|
}
|
|
1851
1882
|
if (ctx.ui.getEditorText().trim() && !force) {
|
|
1852
|
-
modal.setNotice("Main editor has a draft. Use /
|
|
1883
|
+
modal.setNotice("Main editor has a draft. Use /copy! (or /copy-all!) to replace it.");
|
|
1853
1884
|
return;
|
|
1854
1885
|
}
|
|
1855
1886
|
ctx.ui.setEditorText(text);
|
|
1856
|
-
modal.setNotice(all ? "
|
|
1887
|
+
modal.setNotice(all ? "Copied the full thread to the editor." : "Copied the latest answer to the editor.");
|
|
1857
1888
|
};
|
|
1858
1889
|
|
|
1859
1890
|
function submit(value: string): void {
|
|
1860
|
-
const
|
|
1861
|
-
if (
|
|
1891
|
+
const action = parseBtwComposerCommand(value);
|
|
1892
|
+
if (action.kind === "clear") {
|
|
1862
1893
|
modal.clearComposer();
|
|
1863
1894
|
clear();
|
|
1864
1895
|
return;
|
|
1865
1896
|
}
|
|
1866
|
-
if (
|
|
1897
|
+
if (action.kind === "copy") {
|
|
1867
1898
|
modal.clearComposer();
|
|
1868
|
-
handoff(
|
|
1899
|
+
handoff(action.all, action.force);
|
|
1869
1900
|
return;
|
|
1870
1901
|
}
|
|
1871
|
-
if (
|
|
1902
|
+
if (action.kind === "retry") {
|
|
1872
1903
|
modal.clearComposer();
|
|
1873
1904
|
retry();
|
|
1874
1905
|
return;
|
|
1875
1906
|
}
|
|
1876
|
-
void runTurn(
|
|
1907
|
+
void runTurn(action.text);
|
|
1877
1908
|
}
|
|
1878
1909
|
|
|
1879
1910
|
modal.setFull(thread.full);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-bro",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "An Earendil Pi extension that explains pasted text, assistant responses, local documents, public webpages, and recent session turns (as shapes) in a context-isolated window, and opens a sandboxed side conversation with /bro btw.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|