pi-bro 0.24.0 → 0.25.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 +36 -0
- package/README.md +29 -15
- package/docs/README.md +32 -14
- package/docs/elevate.md +125 -0
- package/docs/examples.md +268 -0
- package/docs/features/advisor.md +65 -0
- package/docs/features/btw.md +51 -0
- package/docs/features/explain.md +92 -0
- package/docs/features/show.md +154 -0
- package/docs/getting-started.md +47 -0
- package/docs/pig-compatibility.md +1 -0
- package/docs/reference/commands.md +50 -0
- package/docs/reference/data-and-permissions.md +130 -0
- package/docs/reference/settings.md +108 -0
- package/docs/reference/troubleshooting.md +55 -0
- package/docs/user-guide.md +50 -900
- package/package.json +12 -3
- package/src/advisor.ts +72 -144
- package/src/backend.ts +4 -5
- package/src/bro.ts +25 -0
- package/src/elevate-engine.ts +214 -0
- package/src/elevate.ts +597 -0
- package/src/explain-modal.ts +12 -6
- package/src/modal-kit.ts +35 -2
- package/src/prompt.ts +3 -3
package/src/modal-kit.ts
CHANGED
|
@@ -71,6 +71,9 @@ export type FrameParts = {
|
|
|
71
71
|
notice?: string;
|
|
72
72
|
/** Omit when the body prints its own hints (config's SettingsList). */
|
|
73
73
|
hints?: string;
|
|
74
|
+
/** Lines rendered under the hints, e.g. a focusable action row. Wrapped by the caller; a line
|
|
75
|
+
* wider than the frame is truncated, so keep a single label narrower than the modal. */
|
|
76
|
+
footerAfterHints?: string;
|
|
74
77
|
/** false: size to the content instead of padding the body to the full height. */
|
|
75
78
|
fill?: boolean;
|
|
76
79
|
/** Body rows the notice must leave free; it shrinks to one line before taking them. */
|
|
@@ -94,10 +97,12 @@ export function renderFrame(theme: Theme, width: number, height: number, parts:
|
|
|
94
97
|
const footer = parts.footer ?? [];
|
|
95
98
|
// Wrapped, not truncated: Esc comes last in every hint line and must not be cut off.
|
|
96
99
|
const hints = parts.hints ? wrapTextWithAnsi(theme.fg("dim", parts.hints), inner) : [];
|
|
100
|
+
// The action row is already wrapped by the caller, so keep its own line breaks.
|
|
101
|
+
const belowHints = parts.footerAfterHints ? parts.footerAfterHints.split("\n").map((line) => truncateToWidth(line, inner, "")) : [];
|
|
97
102
|
const notice = parts.notice ? wrapTextWithAnsi(parts.notice, inner).slice(0, 3) : [];
|
|
98
|
-
while (notice.length > 1 && height - 5 - footer.length - hints.length - notice.length < (parts.minBody ?? 0)) notice.pop();
|
|
103
|
+
while (notice.length > 1 && height - 5 - footer.length - hints.length - belowHints.length - notice.length < (parts.minBody ?? 0)) notice.pop();
|
|
99
104
|
// The notice sits above the footer so it is dropped before a composer when space runs out.
|
|
100
|
-
const below = [...notice, ...footer, ...hints];
|
|
105
|
+
const below = [...notice, ...footer, ...hints, ...belowHints];
|
|
101
106
|
const bodyRows = Math.max(0, height - 5 - below.length);
|
|
102
107
|
const body = bodyRows ? parts.body(bodyRows, inner).slice(0, bodyRows) : [];
|
|
103
108
|
if (parts.fill !== false) while (body.length < bodyRows) body.push("");
|
|
@@ -174,6 +179,34 @@ export class Scroller {
|
|
|
174
179
|
}
|
|
175
180
|
}
|
|
176
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Render a focusable action row: the focused button carries a leading marker and accent colour, so a
|
|
184
|
+
* keypress always has exactly one visible target. Callers own focus, keys and activation; this only
|
|
185
|
+
* draws, which is why Guided Review can keep its own navigation and layout.
|
|
186
|
+
*/
|
|
187
|
+
export function buttonLabels(theme: Theme, labels: readonly string[], focused?: number): string[] {
|
|
188
|
+
return labels.map((label, index) => {
|
|
189
|
+
const text = `${index === focused ? "›" : ""}[${label}]`;
|
|
190
|
+
return index === focused ? theme.bold(theme.fg("accent", text)) : text;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Pack whole buttons onto lines with `visibleWidth`, never splitting one: a label broken mid-word
|
|
196
|
+
* makes the focused target ambiguous, which is the misclick this row exists to prevent.
|
|
197
|
+
*/
|
|
198
|
+
export function wrapButtons(buttons: readonly string[], width: number): string[] {
|
|
199
|
+
const lines: string[] = [];
|
|
200
|
+
let line = "";
|
|
201
|
+
for (const button of buttons) {
|
|
202
|
+
if (!line) { line = button; continue; }
|
|
203
|
+
if (visibleWidth(`${line} ${button}`) <= width) line += ` ${button}`;
|
|
204
|
+
else { lines.push(line); line = button; }
|
|
205
|
+
}
|
|
206
|
+
if (line) lines.push(line);
|
|
207
|
+
return lines;
|
|
208
|
+
}
|
|
209
|
+
|
|
177
210
|
/**
|
|
178
211
|
* Forward a pointer event to a pi-tui child drawn at `area` inside the overlay, in the child's own
|
|
179
212
|
* coordinates (without `area`, the event already is). Pi 0.84 components have no handleMouse, hence
|
package/src/prompt.ts
CHANGED
|
@@ -159,7 +159,7 @@ export function buildAdvisorPrompt(steering: AdvisorSteeringInput, snapshot: str
|
|
|
159
159
|
const questionSection = question?.trim()
|
|
160
160
|
? `## Executor's question\n\n${question.trim()}`
|
|
161
161
|
: "## Executor's question\n\nNone was given. Use your own judgment about what advice would help most, given the snapshot below.";
|
|
162
|
-
return `You are the Bro advisor: a separate process an executor coding agent voluntarily consulted mid-task, in the pi-bro Pi extension. You have real tool access in this workspace and are running with permissions auto-approved -- you can freely read files, search, and run read-oriented commands
|
|
162
|
+
return `You are the Bro advisor: a separate process an executor coding agent voluntarily consulted mid-task, in the pi-bro Pi extension. You have real tool access in this workspace and are running with permissions auto-approved -- you can freely read files, search, and run read-oriented commands when needed. Use the snapshot below first; only read files or run commands when something you need is missing from the snapshot, may be stale after later edits, or a key claim is in doubt.
|
|
163
163
|
|
|
164
164
|
Your job is strictly advisory. Return findings and recommendations in your reply; do not edit files or otherwise implement the change yourself -- the executor remains responsible for implementation.
|
|
165
165
|
|
|
@@ -167,11 +167,11 @@ ${steeringSection}
|
|
|
167
167
|
|
|
168
168
|
## Context snapshot from the executor's session
|
|
169
169
|
|
|
170
|
-
This is background/evidence captured from the executor's own conversation. It is the executor's own account of what happened, not independently verified by you --
|
|
170
|
+
This is background/evidence captured from the executor's own conversation, including its tool calls and results. It is the executor's own account of what happened, not independently verified by you -- rely on the tool outputs already shown here before running new checks:
|
|
171
171
|
|
|
172
172
|
${snapshot}
|
|
173
173
|
|
|
174
174
|
${questionSection}
|
|
175
175
|
|
|
176
|
-
Begin with a one-line answer or verdict. Then give concise findings, evidence, and recommended next actions grounded in
|
|
176
|
+
Begin with a one-line answer or verdict. Then give concise findings, evidence, and recommended next actions grounded in the snapshot and any workspace checks you needed. Omit investigation narration, waiting updates, and progress reports.`;
|
|
177
177
|
}
|