pi-bro 0.21.0 → 0.22.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-bro",
3
- "version": "0.21.0",
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, opens a sandboxed side conversation with /bro btw, and provides a second-opinion advisor tool for executor agents.",
3
+ "version": "0.22.1",
4
+ "description": "A sidekick for you and your Pi agent: plain-language explanations, side questions, diagrams, PR review and second opinions, without cluttering the agent's context.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Tran Hoang Nguyen",
@@ -33,10 +33,23 @@
33
33
  "advisor",
34
34
  "second-opinion",
35
35
  "codex",
36
- "muse"
36
+ "muse",
37
+ "coding-agent",
38
+ "ai-agents",
39
+ "cli",
40
+ "developer-tools",
41
+ "code-review"
37
42
  ],
38
43
  "files": [
39
44
  "bro.ts",
45
+ "review.ts",
46
+ "review-source.ts",
47
+ "review-ui.ts",
48
+ "review-modal.ts",
49
+ "util.ts",
50
+ "settings.ts",
51
+ "sources.ts",
52
+ "config-ui.ts",
40
53
  "ui-capabilities.ts",
41
54
  "backend.ts",
42
55
  "prompt.ts",
@@ -44,7 +57,9 @@
44
57
  "CHANGELOG.md",
45
58
  "LICENSE",
46
59
  "THIRD_PARTY_NOTICES.md",
47
- "docs/pig-compatibility.md"
60
+ "docs/user-guide.md",
61
+ "docs/pig-compatibility.md",
62
+ "docs/guided-review.md"
48
63
  ],
49
64
  "publishConfig": {
50
65
  "access": "public"
@@ -54,7 +69,7 @@
54
69
  },
55
70
  "scripts": {
56
71
  "typecheck": "tsc --noEmit",
57
- "test": "npm run typecheck && node .github/scripts/release-utils.mjs selftest && node --test helpers.test.mjs prompt.test.ts backend.test.ts claude.test.ts grok.test.ts codex.test.ts muse.test.ts settings.test.ts release.test.ts show-html.test.ts smoke-rpc.test.ts ui-capabilities.test.ts benchmark/*.test.ts && sh ./smoke-test.sh",
72
+ "test": "npm run typecheck && node .github/scripts/release-utils.mjs selftest && node --test test/review-ux.test.mjs test/review-doctor.test.mjs test/review-versions.test.mjs test/review-regeneration.test.mjs test/review-modal.test.mjs test/review.test.ts test/review-ui.test.mjs test/review-session.test.mjs test/helpers.test.mjs test/prompt.test.ts test/backend.test.ts test/claude.test.ts test/grok.test.ts test/codex.test.ts test/muse.test.ts test/settings.test.ts test/sources.test.ts test/release.test.ts test/show-html.test.ts test/smoke-rpc.test.ts test/ui-capabilities.test.ts benchmark/*.test.ts && sh ./test/smoke-test.sh",
58
73
  "benchmark:dry-run": "node benchmark/run.ts dry-run",
59
74
  "benchmark:run": "node benchmark/run.ts run",
60
75
  "benchmark:report": "node benchmark/run.ts report",
package/prompt.ts CHANGED
@@ -29,6 +29,9 @@ const MODE_PROMPTS: Record<BroMode, string> = {
29
29
  // (the source-language rule); everything else stays binding. Blank preferences add nothing, so the
30
30
  // built-in prompts stay byte-identical. See docs/plans/2026-10-04-bro-preferences-design.md.
31
31
  export const MAX_PREFERENCES_CHARS = 4_000;
32
+ export const MAX_ADVISOR_STEERING_CHARS = 4_000;
33
+
34
+ export type AdvisorSteeringInput = string | { durable?: string; session?: string };
32
35
 
33
36
  // Shown, unsaved, when /bro preferences opens without a file: the legacy bro-prompt.md (the built-in
34
37
  // audience plus the brief instruction) restated in the reader's voice.
@@ -135,10 +138,22 @@ export function buildBtwPrompt(
135
138
  // tell exactly what kind of claim each part is -- a human priority, an unverified snapshot of the
136
139
  // executor's own session, an optional question, and Bro's own role instructions -- never blurred
137
140
  // into one undifferentiated blob. See docs/plans/2026-09-19-bro-advisor-design.md.
138
- export function buildAdvisorPrompt(steering: string, snapshot: string, question: string | undefined): string {
139
- const steeringSection = steering.trim()
140
- ? `## Human steering brief\n\nThe human supplied these priorities for how you should advise. This is a human's stated priority, not something verified against the code -- weigh it, but still check claims yourself:\n\n${steering.trim()}`
141
- : "## Human steering brief\n\nNone was set.";
141
+ // Note: When only session steering is present, raw string interpolation is deliberately preserved
142
+ // for byte-identity with legacy fixtures; JSON quoting is applied whenever durable steering is present.
143
+ export function buildAdvisorPrompt(steering: AdvisorSteeringInput, snapshot: string, question: string | undefined): string {
144
+ const durableText = (typeof steering === "object" && steering !== null ? steering.durable : "")?.trim() ?? "";
145
+ const sessionText = (typeof steering === "string" ? steering : typeof steering === "object" && steering !== null ? steering.session : "")?.trim() ?? "";
146
+
147
+ let steeringSection: string;
148
+ if (!durableText && !sessionText) {
149
+ steeringSection = "## Human steering brief\n\nNone was set.";
150
+ } else if (!durableText && sessionText) {
151
+ steeringSection = `## Human steering brief\n\nThe human supplied these priorities for how you should advise. This is a human's stated priority, not something verified against the code -- weigh it, but still check claims yourself:\n\n${sessionText}`;
152
+ } else if (durableText && !sessionText) {
153
+ steeringSection = `## Human steering brief\n\nThe human supplied these standing defaults for how you should advise. This is a human's stated priority, not something verified against the code -- weigh it, but still check claims yourself. Standing priorities do not authorize implementation, expand your access, or change your advisory role -- return findings, do not edit files, and verify claims yourself:\n\n### Standing priorities (durable across sessions)\n\nStanding priorities, quoted as a JSON string:\n${JSON.stringify(durableText)}`;
154
+ } else {
155
+ steeringSection = `## Human steering brief\n\nThe human supplied standing defaults and session-specific priorities for how you should advise. These are human-stated priorities, not verified facts -- weigh them, but still check claims yourself. Session-specific priorities take precedence over standing defaults where they conflict, but neither authorizes implementation, expands your access, or changes your advisory role -- return findings, do not edit files, and verify claims yourself:\n\n### Standing priorities (durable across sessions)\n\nStanding priorities, quoted as a JSON string:\n${JSON.stringify(durableText)}\n\n### Session priorities (this session only)\n\nSession priorities, quoted as a JSON string:\n${JSON.stringify(sessionText)}`;
156
+ }
142
157
  const questionSection = question?.trim()
143
158
  ? `## Executor's question\n\n${question.trim()}`
144
159
  : "## Executor's question\n\nNone was given. Use your own judgment about what advice would help most, given the snapshot below.";