@zephyrdeng/pi-review 0.4.6 → 0.4.7

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/README.md CHANGED
@@ -20,6 +20,7 @@ Works as a standalone CLI, a Pi package (extension + skill), or integrated into
20
20
  - **Multiple review modes** — code review, multi-lens plan review, adversarial challenge review
21
21
  - **Structured output** — machine-readable `PI_REVIEW_META` JSON footer for automation
22
22
  - **Model-agnostic** — use any model available in your Pi installation
23
+ - **Live streaming** — child review output is forwarded as it arrives (use `--no-stream` to buffer)
23
24
  - **Session continuity** — keep sessions alive for follow-up questions with `--keep-session`
24
25
  - **Customizable presets** — extend or override review modes via JSON configuration
25
26
  - **Pi package integration** — `/rv` slash command and agent skill included
@@ -152,6 +153,7 @@ pi-review models [search]
152
153
  | `--keep-session` | Persist session for follow-up |
153
154
  | `--continue <handle>` | Continue an existing session |
154
155
  | `--name <name>` | Session name (with `--keep-session`) |
156
+ | `--no-stream` | Buffer child output until exit (default: stream live) |
155
157
 
156
158
  ## Configuration
157
159
 
package/README.zh-CN.md CHANGED
@@ -62,7 +62,7 @@ pi-review models
62
62
 
63
63
  跟进审查时,`--continue` 与首次 `/rv` 一样可**选填** `--mode`、`--model`(以及后续 CLI 支持的其它选项由 skill 直接调用 CLI 时传入)。
64
64
 
65
- `/rv` 会向主会话注入**英文任务说明**(按 `--mode` 等参数区分),由主 Agent 按 **pi-review** skill 调用 `pi-review` CLI 跑子会话。Tab 补全是固定选项提示,不是另一套实现。
65
+ `/rv` 会向主会话注入**英文任务说明**(按 `--mode` 等参数区分),由主 Agent 按 **pi-review** skill 调用 `pi-review` CLI 跑子会话。`pi-review` **默认流式转发**子进程输出,终端可实时看到审查进度;需要整段缓冲时加 `--no-stream`。Tab 补全是固定选项提示,不是另一套实现。
66
66
 
67
67
  ## 输出格式
68
68
 
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA6C7C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAmFpD"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8C7C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAuFpD"}
package/dist/args.js CHANGED
@@ -15,6 +15,7 @@ Options:
15
15
  --thinking <level> off|minimal|low|medium|high|xhigh
16
16
  --skill <path> Load an extra pi skill (repeatable)
17
17
  --tools <csv> Override allowed tools
18
+ --no-stream Buffer child output until exit (default: stream live)
18
19
  -h, --help Show help
19
20
 
20
21
  Session (requires Pi session support):
@@ -43,16 +44,16 @@ export function parseArgs(argv) {
43
44
  if (argv.length === 0 || argv[0] === "-h" || argv[0] === "--help")
44
45
  usage(0);
45
46
  if (argv[0] === "models") {
46
- return { command: "models", search: argv.slice(1), mode: "code", skills: [], payload: [], keepSession: false };
47
+ return { command: "models", search: argv.slice(1), mode: "code", skills: [], payload: [], keepSession: false, stream: true };
47
48
  }
48
49
  if (argv[0] === "install-skill") {
49
- return { command: "install-skill", extraArgs: argv.slice(1), mode: "code", skills: [], payload: [], keepSession: false };
50
+ return { command: "install-skill", extraArgs: argv.slice(1), mode: "code", skills: [], payload: [], keepSession: false, stream: true };
50
51
  }
51
52
  if (argv[0] === "uninstall-skill") {
52
- return { command: "uninstall-skill", extraArgs: argv.slice(1), mode: "code", skills: [], payload: [], keepSession: false };
53
+ return { command: "uninstall-skill", extraArgs: argv.slice(1), mode: "code", skills: [], payload: [], keepSession: false, stream: true };
53
54
  }
54
55
  if (argv[0] === "update") {
55
- return { command: "update", mode: "code", skills: [], payload: [], keepSession: false };
56
+ return { command: "update", mode: "code", skills: [], payload: [], keepSession: false, stream: true };
56
57
  }
57
58
  let mode = "code";
58
59
  if (argv[0] && !argv[0].startsWith("-")) {
@@ -64,6 +65,7 @@ export function parseArgs(argv) {
64
65
  skills: [],
65
66
  payload: [],
66
67
  keepSession: false,
68
+ stream: true,
67
69
  };
68
70
  while (argv.length > 0) {
69
71
  const arg = argv.shift();
@@ -103,6 +105,9 @@ export function parseArgs(argv) {
103
105
  case "--name":
104
106
  options.name = requireValue(arg, argv);
105
107
  break;
108
+ case "--no-stream":
109
+ options.stream = false;
110
+ break;
106
111
  default:
107
112
  if (arg.startsWith("--")) {
108
113
  process.stderr.write(`pi-review: unknown option: ${arg}\n`);
package/dist/args.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export type ChildRunResult = {
2
+ status: number | null;
3
+ signal: NodeJS.Signals | null;
4
+ stdout: string;
5
+ stderr: string;
6
+ error?: Error;
7
+ };
8
+ export declare const DEFAULT_STREAM_CAPTURE_LIMIT: number;
9
+ type SpawnCommon = {
10
+ cwd?: string;
11
+ env?: NodeJS.ProcessEnv;
12
+ };
13
+ export declare function spawnBufferedChild(command: string, argv: string[], options: SpawnCommon): ChildRunResult;
14
+ export declare function spawnStreamingChild(command: string, argv: string[], options: SpawnCommon & {
15
+ stdoutSink?: NodeJS.WritableStream;
16
+ stderrSink?: NodeJS.WritableStream;
17
+ maxCaptureChars?: number;
18
+ }): Promise<ChildRunResult>;
19
+ export {};
20
+ //# sourceMappingURL=child-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-process.d.ts","sourceRoot":"","sources":["../src/child-process.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAE7D,KAAK,WAAW,GAAG;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,CAAC;AAQF,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,WAAW,GACnB,cAAc,CAchB;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,WAAW,GAAG;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,OAAO,CAAC,cAAc,CAAC,CAqDzB"}
@@ -0,0 +1,73 @@
1
+ import { spawn, spawnSync } from "node:child_process";
2
+ export const DEFAULT_STREAM_CAPTURE_LIMIT = 50 * 1024 * 1024;
3
+ function appendBoundedTail(current, chunk, limit) {
4
+ if (limit <= 0)
5
+ return "";
6
+ const next = current + chunk;
7
+ return next.length > limit ? next.slice(next.length - limit) : next;
8
+ }
9
+ export function spawnBufferedChild(command, argv, options) {
10
+ const child = spawnSync(command, argv, {
11
+ cwd: options.cwd,
12
+ env: options.env,
13
+ encoding: "utf8",
14
+ maxBuffer: 50 * 1024 * 1024,
15
+ });
16
+ return {
17
+ status: child.status,
18
+ signal: child.signal,
19
+ stdout: child.stdout || "",
20
+ stderr: child.stderr || "",
21
+ error: child.error,
22
+ };
23
+ }
24
+ export async function spawnStreamingChild(command, argv, options) {
25
+ const stdoutSink = options.stdoutSink ?? process.stdout;
26
+ const stderrSink = options.stderrSink ?? process.stderr;
27
+ const maxCaptureChars = options.maxCaptureChars ?? DEFAULT_STREAM_CAPTURE_LIMIT;
28
+ return new Promise((resolve) => {
29
+ const spawnOpts = {
30
+ cwd: options.cwd,
31
+ env: options.env,
32
+ stdio: ["ignore", "pipe", "pipe"],
33
+ };
34
+ const child = spawn(command, argv, spawnOpts);
35
+ let stdout = "";
36
+ let stderr = "";
37
+ let settled = false;
38
+ const finish = (result) => {
39
+ if (settled)
40
+ return;
41
+ settled = true;
42
+ resolve(result);
43
+ };
44
+ child.stdout?.setEncoding("utf8");
45
+ child.stderr?.setEncoding("utf8");
46
+ child.stdout?.on("data", (chunk) => {
47
+ stdout = appendBoundedTail(stdout, chunk, maxCaptureChars);
48
+ stdoutSink.write(chunk);
49
+ });
50
+ child.stderr?.on("data", (chunk) => {
51
+ stderr = appendBoundedTail(stderr, chunk, maxCaptureChars);
52
+ stderrSink.write(chunk);
53
+ });
54
+ child.on("error", (error) => {
55
+ finish({
56
+ status: null,
57
+ signal: null,
58
+ stdout,
59
+ stderr,
60
+ error,
61
+ });
62
+ });
63
+ child.on("close", (status, signal) => {
64
+ finish({
65
+ status,
66
+ signal,
67
+ stdout,
68
+ stderr,
69
+ });
70
+ });
71
+ });
72
+ }
73
+ //# sourceMappingURL=child-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-process.js","sourceRoot":"","sources":["../src/child-process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=child-process.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-process.test.d.ts","sourceRoot":"","sources":["../src/child-process.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import assert from "node:assert/strict";
2
+ import { Writable } from "node:stream";
3
+ import { test } from "node:test";
4
+ import { spawnBufferedChild, spawnStreamingChild } from "./child-process.js";
5
+ function collectSink() {
6
+ const chunks = [];
7
+ const stream = new Writable({
8
+ write(chunk, _enc, cb) {
9
+ chunks.push(String(chunk));
10
+ cb();
11
+ },
12
+ });
13
+ return { stream, chunks };
14
+ }
15
+ test("spawnBufferedChild captures stdout", () => {
16
+ const r = spawnBufferedChild(process.execPath, ["-e", "console.log('buf')"], {});
17
+ assert.equal(r.status, 0);
18
+ assert.match(r.stdout, /buf/);
19
+ });
20
+ test("spawnStreamingChild reports signal when child is killed", async () => {
21
+ const { stream } = collectSink();
22
+ const r = await spawnStreamingChild(process.execPath, ["-e", "process.kill(process.pid, 'SIGTERM')"], { stdoutSink: stream, stderrSink: stream });
23
+ assert.equal(r.status, null);
24
+ assert.equal(r.signal, "SIGTERM");
25
+ });
26
+ test("spawnStreamingChild forwards chunks and collects full stdout", async () => {
27
+ const script = [
28
+ "console.log('line1');",
29
+ "setTimeout(() => console.log('line2'), 30);",
30
+ ].join("");
31
+ const { stream, chunks } = collectSink();
32
+ const r = await spawnStreamingChild(process.execPath, ["-e", script], {
33
+ stdoutSink: stream,
34
+ stderrSink: stream,
35
+ });
36
+ assert.equal(r.status, 0);
37
+ assert.match(r.stdout, /line1/);
38
+ assert.match(r.stdout, /line2/);
39
+ const forwarded = chunks.join("");
40
+ assert.match(forwarded, /line1/);
41
+ assert.match(forwarded, /line2/);
42
+ });
43
+ test("spawnStreamingChild keeps captured stdout bounded while forwarding all output", async () => {
44
+ const script = "process.stdout.write('abcde'); process.stdout.write('fghij');";
45
+ const { stream, chunks } = collectSink();
46
+ const r = await spawnStreamingChild(process.execPath, ["-e", script], {
47
+ stdoutSink: stream,
48
+ stderrSink: stream,
49
+ maxCaptureChars: 6,
50
+ });
51
+ assert.equal(r.status, 0);
52
+ assert.equal(r.stdout, "efghij");
53
+ assert.equal(chunks.join(""), "abcdefghij");
54
+ });
55
+ //# sourceMappingURL=child-process.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-process.test.js","sourceRoot":"","sources":["../src/child-process.test.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -19,6 +19,6 @@ else if (parsed.command === "uninstall-skill") {
19
19
  uninstallSkill(parsed.extraArgs);
20
20
  }
21
21
  else {
22
- runReview(parsed);
22
+ await runReview(parsed);
23
23
  }
24
24
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhD,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;IACvC,SAAS,EAAE,CAAC;AACd,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;IAC9C,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,EAAE,CAAC;IAChD,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC;KAAM,CAAC;IACN,SAAS,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhD,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;IACvC,SAAS,EAAE,CAAC;AACd,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;IAC9C,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,EAAE,CAAC;IAChD,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC;KAAM,CAAC;IACN,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC"}
package/dist/review.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import type { ParsedArgs } from "./types.js";
2
+ import { type ChildRunResult } from "./child-process.js";
3
+ /** Ensures PI_REVIEW_META is on its own line after streamed child stdout. */
4
+ export declare function metaLinePrefix(childStdout: string, streamMode: boolean): string;
5
+ export declare function childRuntimeError(child: Pick<ChildRunResult, "status" | "signal" | "error">): string | undefined;
2
6
  export declare function runModels(piBin: string, args: string[]): never;
3
- export declare function runReview(parsed: ParsedArgs): void;
7
+ export declare function runReview(parsed: ParsedArgs): Promise<void>;
4
8
  //# sourceMappingURL=review.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../src/review.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA4B,MAAM,YAAY,CAAC;AAkCvE,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAM9D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAkFlD"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../src/review.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AACzD,OAAO,EAA2C,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAkClG,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CAG/E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAKhH;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAM9D;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFjE"}
package/dist/review.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import os from "node:os";
2
2
  import path from "node:path";
3
3
  import { spawnSync } from "node:child_process";
4
+ import { spawnBufferedChild, spawnStreamingChild } from "./child-process.js";
4
5
  import { loadPresets, loadSystemPrompt } from "./presets.js";
5
6
  import { splitPayload, buildPrompt } from "./prompt.js";
6
7
  import { parseVerdict } from "./verdict.js";
@@ -32,6 +33,21 @@ function childEnv(piBin) {
32
33
  PATH: [...new Set(pathEntries.join(":").split(":").filter(Boolean))].join(":"),
33
34
  };
34
35
  }
36
+ /** Ensures PI_REVIEW_META is on its own line after streamed child stdout. */
37
+ export function metaLinePrefix(childStdout, streamMode) {
38
+ if (!streamMode || !childStdout)
39
+ return "";
40
+ return childStdout.endsWith("\n") ? "" : "\n";
41
+ }
42
+ export function childRuntimeError(child) {
43
+ if (child.error)
44
+ return child.error.message;
45
+ if (child.signal)
46
+ return `child pi terminated by signal ${child.signal}`;
47
+ if ((child.status ?? 0) !== 0)
48
+ return `child pi exited with status ${child.status}`;
49
+ return undefined;
50
+ }
35
51
  export function runModels(piBin, args) {
36
52
  const result = spawnSync(piBin, ["--list-models", ...args], {
37
53
  stdio: "inherit",
@@ -39,7 +55,7 @@ export function runModels(piBin, args) {
39
55
  });
40
56
  process.exit(result.status ?? (result.error ? 1 : 0));
41
57
  }
42
- export function runReview(parsed) {
58
+ export async function runReview(parsed) {
43
59
  const config = resolveConfig();
44
60
  const presets = loadPresets(config.presetsFile);
45
61
  const preset = presets[parsed.mode];
@@ -82,28 +98,29 @@ export function runReview(parsed) {
82
98
  }
83
99
  args.push(...payload.fileRefs, prompt);
84
100
  const startedAt = Date.now();
85
- const child = spawnSync(config.piBin, args, {
86
- cwd: process.cwd(),
87
- env: childEnv(config.piBin),
88
- encoding: "utf8",
89
- maxBuffer: 50 * 1024 * 1024,
90
- });
101
+ const spawnOpts = { cwd: process.cwd(), env: childEnv(config.piBin) };
102
+ const child = parsed.stream
103
+ ? await spawnStreamingChild(config.piBin, args, spawnOpts)
104
+ : spawnBufferedChild(config.piBin, args, spawnOpts);
91
105
  const durationMs = Date.now() - startedAt;
92
106
  const stdout = child.stdout || "";
93
107
  const stderr = child.stderr || "";
94
- if (stdout)
95
- process.stdout.write(stdout.endsWith("\n") ? stdout : `${stdout}\n`);
96
- if (stderr)
97
- process.stderr.write(stderr.endsWith("\n") ? stderr : `${stderr}\n`);
108
+ if (!parsed.stream) {
109
+ if (stdout)
110
+ process.stdout.write(stdout.endsWith("\n") ? stdout : `${stdout}\n`);
111
+ if (stderr)
112
+ process.stderr.write(stderr.endsWith("\n") ? stderr : `${stderr}\n`);
113
+ }
98
114
  if (parsed.keepSession) {
99
115
  sessionHandle = newestJsonl(runSessionDir);
100
116
  }
101
117
  let verdictInfo = parseVerdict(stdout);
102
- if ((child.status ?? 0) !== 0) {
118
+ const runtimeError = childRuntimeError(child);
119
+ if (runtimeError) {
103
120
  verdictInfo = {
104
121
  verdict: "blocked",
105
122
  verdictSource: "runtime_error",
106
- parseError: child.error ? child.error.message : `child pi exited with status ${child.status}`,
123
+ parseError: runtimeError,
107
124
  };
108
125
  }
109
126
  const meta = {
@@ -115,7 +132,10 @@ export function runReview(parsed) {
115
132
  sessionHandle: sessionHandle || undefined,
116
133
  parseError: verdictInfo.parseError || undefined,
117
134
  };
135
+ const metaPrefix = metaLinePrefix(stdout, parsed.stream);
136
+ if (metaPrefix)
137
+ process.stdout.write(metaPrefix);
118
138
  process.stdout.write(`PI_REVIEW_META: ${JSON.stringify(meta)}\n`);
119
- process.exit(child.status ?? (child.error ? 1 : 0));
139
+ process.exit(child.status ?? (child.error || child.signal ? 1 : 0));
120
140
  }
121
141
  //# sourceMappingURL=review.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"review.js","sourceRoot":"","sources":["../src/review.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../src/review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=review.meta.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.meta.test.d.ts","sourceRoot":"","sources":["../src/review.meta.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { childRuntimeError, metaLinePrefix } from "./review.js";
4
+ test("metaLinePrefix adds newline when streamed stdout lacks trailing newline", () => {
5
+ assert.equal(metaLinePrefix("hello", true), "\n");
6
+ assert.equal(metaLinePrefix("hello\n", true), "");
7
+ assert.equal(metaLinePrefix("", true), "");
8
+ });
9
+ test("metaLinePrefix is empty in buffered mode", () => {
10
+ assert.equal(metaLinePrefix("hello", false), "");
11
+ });
12
+ test("childRuntimeError treats spawn errors as runtime errors", () => {
13
+ assert.equal(childRuntimeError({ status: null, signal: null, error: new Error("spawn ENOENT") }), "spawn ENOENT");
14
+ });
15
+ //# sourceMappingURL=review.meta.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.meta.test.js","sourceRoot":"","sources":["../src/review.meta.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,IAAI,CAAC,yEAAyE,EAAE,GAAG,EAAE;IACnF,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACpD,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACnE,MAAM,CAAC,KAAK,CACV,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,EACnF,cAAc,CACf,CAAC;AACJ,CAAC,CAAC,CAAC"}
package/dist/types.d.ts CHANGED
@@ -7,6 +7,8 @@ export interface ParsedArgs {
7
7
  skills: string[];
8
8
  payload: string[];
9
9
  keepSession: boolean;
10
+ /** When false, buffer child output and print after exit (legacy / scripting). Default: stream. */
11
+ stream: boolean;
10
12
  continueHandle?: string;
11
13
  model?: string;
12
14
  provider?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,2EAA4E,CAAC;AAClG,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IAC9E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,QAAQ,GAAG,UAAU,GAAG,eAAe,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,2EAA4E,CAAC;AAClG,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IAC9E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,kGAAkG;IAClG,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,QAAQ,GAAG,UAAU,GAAG,eAAe,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -9,7 +9,7 @@ import {
9
9
  export default function piReviewExtension(pi: ExtensionAPI) {
10
10
  pi.registerCommand("rv", {
11
11
  description:
12
- "Delegate pi-review to the agent. Usage: /rv [--mode plan|challenge] [--model id] [--keep-session] @target | /rv --continue <handle> [opts] [text] | models",
12
+ "Delegate pi-review to the agent. Usage: /rv [--mode plan|challenge] [--model id] [--keep-session] [--no-stream] @target | /rv --continue <handle> [opts] [text] | models",
13
13
  getArgumentCompletions: (prefix) => {
14
14
  const filtered = RV_COMPLETIONS.filter((item) => item.value.startsWith(prefix));
15
15
  return filtered.length
@@ -25,6 +25,18 @@ describe("parseRvArgs / validateRvParsed", () => {
25
25
  assert.equal(v.ok, false);
26
26
  });
27
27
 
28
+ it("parses --no-stream into CLI argv", () => {
29
+ const p = parseRvArgs("--no-stream @src/foo.ts");
30
+ assert.equal(p.noStream, true);
31
+ assert.equal(p.target, "@src/foo.ts");
32
+ assert.deepEqual(buildPiReviewArgv(p, "@src/foo.ts"), [
33
+ "pi-review",
34
+ "--no-stream",
35
+ "--",
36
+ "@src/foo.ts",
37
+ ]);
38
+ });
39
+
28
40
  it("buildPiReviewArgv matches for initial and continue", () => {
29
41
  const initial = parseRvArgs("--mode plan --model m/a @doc.md");
30
42
  assert.deepEqual(buildPiReviewArgv(initial, "@doc.md"), [
@@ -9,6 +9,7 @@ export type RvParsed = {
9
9
  mode: string;
10
10
  model?: string;
11
11
  keepSession: boolean;
12
+ noStream: boolean;
12
13
  continueHandle?: string;
13
14
  modelsOnly: boolean;
14
15
  target: string;
@@ -25,6 +26,7 @@ export function parseRvArgs(raw: string): RvParsed {
25
26
  let mode = "code";
26
27
  let model: string | undefined;
27
28
  let keepSession = false;
29
+ let noStream = false;
28
30
  let continueHandle: string | undefined;
29
31
  let modelsOnly = false;
30
32
  const rest: string[] = [];
@@ -39,6 +41,10 @@ export function parseRvArgs(raw: string): RvParsed {
39
41
  keepSession = true;
40
42
  continue;
41
43
  }
44
+ if (t === "--no-stream") {
45
+ noStream = true;
46
+ continue;
47
+ }
42
48
  if (t === "--mode") {
43
49
  const m = cleaned[i + 1];
44
50
  if (!m || m.startsWith("--")) {
@@ -73,6 +79,7 @@ export function parseRvArgs(raw: string): RvParsed {
73
79
  mode,
74
80
  model,
75
81
  keepSession,
82
+ noStream,
76
83
  continueHandle,
77
84
  modelsOnly,
78
85
  target: rest.join(" ").trim(),
@@ -101,6 +108,7 @@ export function buildPiReviewArgv(parsed: RvParsed, target: string): string[] {
101
108
  }
102
109
  if (parsed.mode !== "code") parts.push("--mode", parsed.mode);
103
110
  if (parsed.model) parts.push("--model", parsed.model);
111
+ if (parsed.noStream) parts.push("--no-stream");
104
112
  parts.push("--", target);
105
113
  return parts;
106
114
  }
@@ -111,6 +119,7 @@ function baseRules(): string {
111
119
  "Run pi-review in an isolated child session; return only the review conclusion.",
112
120
  "Do not edit, patch, commit, or implement findings unless the user asks separately.",
113
121
  "Preserve the final PI_REVIEW_META line from pi-review output.",
122
+ "pi-review streams child output by default so the user sees live progress; use --no-stream only if buffering is required.",
114
123
  ].join(" ");
115
124
  }
116
125
 
@@ -131,7 +140,7 @@ export function buildRvOrchestrationPrompt(parsed: RvParsed): string {
131
140
  if (!target && !parsed.continueHandle) {
132
141
  return [
133
142
  "/rv needs a review target.",
134
- "Usage: /rv [--mode code|plan|challenge] [--model provider/model] [--keep-session] @files-or-brief",
143
+ "Usage: /rv [--mode code|plan|challenge] [--model provider/model] [--keep-session] [--no-stream] @files-or-brief",
135
144
  "Continue: /rv --continue <handle> [--mode ...] [--model ...] [follow-up text]",
136
145
  "Examples: /rv @src/foo.ts | /rv --mode challenge @docs/design.md | /rv models",
137
146
  ].join("\n\n");
@@ -188,5 +197,6 @@ export const RV_COMPLETIONS: { value: string; hint: string }[] = [
188
197
  { value: "--mode challenge", hint: "adversarial plan review" },
189
198
  { value: "--model ", hint: "provider/model from pi-review models" },
190
199
  { value: "--keep-session", hint: "persist session for follow-up" },
200
+ { value: "--no-stream", hint: "buffer child output until exit" },
191
201
  { value: "--continue ", hint: "resume session; same optional flags as initial /rv" },
192
202
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zephyrdeng/pi-review",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "Isolated AI-powered code and plan reviews from the command line",
5
5
  "type": "module",
6
6
  "author": "ZephyrDeng <zephyrTang@aliyun.com>",
@@ -67,6 +67,7 @@
67
67
  "build": "tsc",
68
68
  "check": "tsc --noEmit",
69
69
  "smoke": "node dist/cli.js --help >/dev/null",
70
+ "test": "npx --yes tsx --test src/child-process.test.ts src/review.meta.test.ts extensions/rv-prompts.test.ts",
70
71
  "test:rv": "npx --yes tsx --test extensions/rv-prompts.test.ts",
71
72
  "prepublishOnly": "npm run build",
72
73
  "pack:dry": "npm pack --dry-run"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pi-review
3
- description: Use pi-review to delegate isolated code, diff, repository, architecture, or plan reviews to a fresh Pi session and return only the review conclusion. Use when the user asks for Pi review, isolated review, code review, plan review, challenge review, or wants to avoid context pollution.
3
+ description: Use pi-review to delegate isolated code, diff, repository, architecture, or plan reviews to a fresh Pi session and return only the review conclusion. Use when the user asks for Pi review, isolated review, code review, plan review, challenge review, review status/progress, or wants to avoid context pollution.
4
4
  ---
5
5
 
6
6
  # Pi Review
@@ -23,6 +23,36 @@ node ../../bin/pi-review.js --help
23
23
 
24
24
  When resolving this fallback, use the actual directory that contains this `SKILL.md`.
25
25
 
26
+ ## Streaming vs agent hosts
27
+
28
+ - `pi-review` **streams** child `pi` stdout/stderr to the process terminal by default (`--no-stream` buffers until exit).
29
+ - **Pi** with `/rv` or a foreground bash that inherits stdio: users often see output arrive live.
30
+ - **Claude Code, Cursor, Codex**, and similar hosts usually **buffer tool stdout** until the bash command exits, so the chat may show the review **all at once** even though the CLI is streaming. That is expected—not a misconfiguration.
31
+ - For **live** progress in those hosts: ask the user to run the same `pi-review` command in a **local terminal** (split pane), or accept one-shot review output in chat.
32
+
33
+ ## Review status (no slash command)
34
+
35
+ There is **no** `/status` slash in this skill. When the user asks for **review status**, **progress**, **is pi-review still running**, or **/status** in the sense of review progress, run read-only checks and summarize—do **not** start a new review.
36
+
37
+ 1. **In-flight review (heuristic)** — list likely `pi-review` / child `pi -p` processes:
38
+ ```bash
39
+ pgrep -fl 'pi-review' 2>/dev/null || true
40
+ pgrep -fl 'pi.*-p' 2>/dev/null | head -20 || true
41
+ ```
42
+ If matches exist, say a review **may still be running** (heuristic; other `pi -p` jobs can match). If none, say **no obvious in-flight pi-review** from process list—not that the last review failed.
43
+
44
+ 2. **Persisted sessions** (only after `--keep-session` / `--continue`) — default dir `~/.pi/pi-review/sessions`, overridable with `PI_REVIEW_SESSION_DIR`:
45
+ ```bash
46
+ ls -lt "${PI_REVIEW_SESSION_DIR:-$HOME/.pi/pi-review/sessions}" 2>/dev/null | head -15 || true
47
+ ```
48
+ Mention newest folders and that `sessionHandle` from `PI_REVIEW_META` is used with `--continue`.
49
+
50
+ 3. **Last conclusion** — if this conversation already has a `PI_REVIEW_META` line, quote `verdict`, `durationMs`, and `sessionHandle` instead of re-running review.
51
+
52
+ 4. **Live output** — remind that chat tools may not stream; for live text, use a **terminal** running `pi-review` (default streaming).
53
+
54
+ Do not implement findings from a status check; status is informational only.
55
+
26
56
  ## Steps
27
57
 
28
58
  1. Prime the model catalog:
@@ -52,6 +82,7 @@ When resolving this fallback, use the actual directory that contains this `SKILL
52
82
  - Use `--continue <handle>` only with a previous `PI_REVIEW_META.sessionHandle`.
53
83
  - Put file references as `@path` after `--`.
54
84
  - Do not ask `pi-review` to edit, patch, commit, or implement.
85
+ - Default streams child output live; add `--no-stream` only when the caller must buffer until exit.
55
86
  Completion criterion: the command includes the resolved model/default choice and a concrete review target.
56
87
 
57
88
  4. Return the result:
@@ -67,3 +98,8 @@ pi-review --model openai/gpt-5.5 -- @src/foo.ts
67
98
  pi-review --mode challenge --keep-session -- @docs/design.md
68
99
  pi-review --mode challenge --continue <sessionHandle> -- "expand finding 2"
69
100
  ```
101
+
102
+ ## Status examples (user phrasing)
103
+
104
+ - "review status" / "is the review still running?" → run **Review status** checks above.
105
+ - "show streaming in Claude Code" → explain tool buffering; offer terminal `pi-review` or Pi `/rv` for live output.