@fyeeme/pi-review 1.0.0 → 1.0.2

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.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: simplify
3
- description: "Review the changed code for reuse, simplification, efficiency, and altitude cleanups, then apply the fixes. Quality only — it does not hunt for bugs; use /code-review for that. v2 (from Claude Code CLI v2.1.223) — 4 cleanup agents fan out in parallel when context allows, else a single-pass inline cleanup; either way the fixes are applied to the working tree."
3
+ description: "Review the changed code for reuse, simplification, efficiency, and altitude cleanups, then apply the fixes. Quality only — it does not hunt for bugs; use /code-review for that. v3 (from Claude Code CLI v2.1.227, symbol-level verified) — 4 cleanup agents fan out in parallel when context allows, else a single-pass inline cleanup; either way the fixes are applied, verified against the project's check command, and auto-reverted on failure, then reported as structured outcomes via review_report."
4
4
  ---
5
5
 
6
6
  <!--
7
- Origin: Claude Code built-in skill `/simplify` (CLI v2.1.223), reverse-
8
- engineered from bin/claude.exe strings. Pi registers it as /code-simplify.
7
+ Origin: Claude Code built-in skill `/simplify` (CLI v2.1.227), reverse-
8
+ engineered from bin/claude.exe raw bytes. Pi registers it as /code-simplify.
9
9
 
10
10
  Lineage:
11
11
  v2.1.220 → the first reconstruction (v1)
@@ -14,6 +14,27 @@ description: "Review the changed code for reuse, simplification, efficiency, and
14
14
  PARALLEL/SINGLE-PASS split are unchanged vs v2.1.220. The 4
15
15
  angle bodies are shared verbatim with code-review's cleanup
16
16
  angles (same source variables in the binary).
17
+ v2.1.227 → symbol-level verified 2026-08-11 from raw bytes: skill bodies
18
+ VBv/KBv (with interpolated c$e / m7t / u$e / d$e / p$e) are
19
+ unchanged; the mode guard is Dii (see below); fan-out defaults
20
+ nJu=20 / lKs=50 are now mirrored in the subagent tool.
21
+
22
+ CC 2.1.227 empirical evidence (symbol-level, extracted from bin/claude.exe):
23
+ - $u({name: "simplify", ..., getPromptForCommand(args, ctx)}) registers the
24
+ command; no getContext → default "inline" execution: the mode body is
25
+ injected into the main conversation and the model dispatches the 4
26
+ cleanup agents itself via the Agent tool (mi = "Agent", alias oj =
27
+ "Task"), "all in a single message so they run concurrently".
28
+ - Dii(ctx) — the PARALLEL/SINGLE-PASS guard: single-pass when
29
+ ctx.agentContext && ok(ctx.agentContext) >= wV() (ok = depth function:
30
+ main=0, subagent=depth; wV() = CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH,
31
+ default 3, feature flag tengu_hazel_trellis) OR the Agent tool is not in
32
+ the options.tools allowlist (Pa matches by name/aliases).
33
+ - VBv / KBv — the two mode-body templates; interpolated variables shared
34
+ with /code-review: c$e (Phase 0), m7t/u$e/d$e/p$e (the 4 cleanup angles).
35
+ - nJu() = CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS ?? 20; lKs =
36
+ FORKED_AGENT_DEFAULT_MAX_TURNS = 50 — mirrored as the subagent tool's
37
+ defaults (PI_MAX_CONCURRENT_SUBAGENTS env still overrides the ceiling).
17
38
 
18
39
  Bundled: ships inside the pi-review extension (skills/simplify/SKILL.md).
19
40
 
@@ -25,20 +46,22 @@ description: "Review the changed code for reuse, simplification, efficiency, and
25
46
  ════════════════════════════════════════════════════════════════════════
26
47
  1. Fan-out tool — CC uses the Agent tool; Pi uses the `subagent` tool
27
48
  (mode: parallel). Where CC says "the Agent tool", read `subagent`.
28
- 2. Mode guard — CC's _Yo has two clauses: (a) spawn-depth — single-pass when
49
+ 2. Mode guard — CC's Dii has two clauses: (a) spawn-depth — single-pass when
29
50
  agent depth >= CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH (default 3); (b) the
30
51
  Agent tool must be in the allowlist. On Pi: (a) is N/A — the `subagent`
31
52
  tool spawns a fresh subprocess (always depth 0), so depth never accumulates
32
53
  — so decideSimplifyMode substitutes a context-fraction heuristic
33
54
  (tokens/contextWindow >= 0.8 → single-pass), a Pi addition NOT a mirror of
34
- _Yo; (b) is mirrored as "the `subagent` tool must be registered". The
55
+ Dii; (b) is mirrored as "the `subagent` tool must be registered". The
35
56
  decision is made DETERMINISTICALLY by the /code-simplify handler — it can
36
57
  read ctx.getContextUsage(), which a pure-prompt skill cannot — and announced
37
58
  in the trigger message; this skill just provides the two mode bodies.
38
59
  3. Command — CC: /simplify; Pi: /code-simplify.
39
60
 
40
61
  Prerequisite: the `subagent` tool (provided by the pi-review extension) for
41
- PARALLEL MODE. SINGLE-PASS MODE runs standalone.
62
+ PARALLEL MODE, and the `review_report` tool (same extension) for
63
+ the Phase 2 structured outcome report. SINGLE-PASS MODE runs
64
+ standalone apart from `review_report`.
42
65
  -->
43
66
 
44
67
  You are improving the quality of the changed code, not hunting for bugs. Review
@@ -66,44 +89,43 @@ review that target instead. Treat this diff as the review scope.
66
89
 
67
90
  ## Phase 1 — Review (4 cleanup agents in parallel)
68
91
 
69
- Launch **4 independent review agents** via the `subagent` tool, all in a single
70
- message so they run concurrently (mode: parallel). Pass each agent the diff and
71
- one of the four angles below. Each returns its findings with `file`, `line`, a
72
- one-line `summary`, and the concrete cost (what is duplicated, wasted, or harder
73
- to maintain).
92
+ Launch **4 independent review agents** via the subagent tool, all in a
93
+ single message so they run concurrently. Pass each agent the diff and one of
94
+ the four angles below. Each returns its findings with `file`, `line`, a
95
+ one-line `summary`, and the concrete cost (what is duplicated, wasted, or
96
+ harder to maintain).
74
97
 
75
98
  ### Reuse
76
- Flag new code that re-implements something the codebase already has — Grep
77
- shared/utility modules and files adjacent to the change, and name the existing
78
- helper to call instead.
99
+
100
+ Flag new code that re-implements something the codebase
101
+ already has — Grep shared/utility modules and files adjacent to the change,
102
+ and name the existing helper to call instead.
79
103
 
80
104
  ### Simplification
105
+
81
106
  Flag unnecessary complexity the diff adds: redundant or derivable state,
82
- copy-paste with slight variation, deep nesting, dead code left behind. Name the
83
- simpler form that does the same job.
107
+ copy-paste with slight variation, deep nesting, dead code left behind. Name
108
+ the simpler form that does the same job.
84
109
 
85
110
  ### Efficiency
111
+
86
112
  Flag wasted work the diff introduces: redundant computation or repeated I/O,
87
- independent operations run sequentially, blocking work added to startup or hot
88
- paths. Also flag long-lived objects built from closures or captured environments
89
- — they keep the entire enclosing scope alive for the object's lifetime (a memory
90
- leak when that scope holds large values); prefer a class/struct that copies only
91
- the fields it needs. Name the cheaper alternative.
113
+ independent operations run sequentially, blocking work added to startup or
114
+ hot paths. Also flag long-lived objects built from closures or captured
115
+ environments — they keep the entire enclosing scope alive for the object's
116
+ lifetime (a memory leak when that scope holds large values); prefer a
117
+ class/struct that copies only the fields it needs. Name the cheaper
118
+ alternative.
92
119
 
93
120
  ### Altitude
94
- Check that each change is implemented at the right depth, not as a fragile
95
- bandaid. Special cases layered on shared infrastructure are a sign the fix isn't
96
- deep enough — prefer generalizing the underlying mechanism over adding special
97
- cases.
98
121
 
99
- ## Phase 2 — Apply the fixes
122
+ Check that each change is implemented at the right depth, not as a fragile
123
+ bandaid. Special cases layered on shared infrastructure are a sign the fix
124
+ isn't deep enough — prefer generalizing the underlying mechanism over adding
125
+ special cases.
126
+ ## Phase 2 — Apply, verify, and report
100
127
 
101
- Wait for all four agents to complete, dedup findings that point at the same line
102
- or mechanism, and fix each remaining one directly. Skip any finding whose fix
103
- would change intended behavior, require changes well outside the reviewed diff,
104
- or that you judge to be a false positive — note the skip rather than arguing
105
- with it. Finish with a brief summary of what was fixed and what was skipped (or
106
- confirm the code was already clean).
128
+ Follow the shared **Phase 2** procedure at the end of this skill (snapshot → apply → verify → auto-revert on failure → report via `review_report`). The parallel fan-out only changes how findings are gathered (Phase 1); applying, verifying, and reporting are identical across modes. Set `fanned_out: true` in the report since the 4-agent fan-out actually ran.
107
129
 
108
130
  ---
109
131
 
@@ -111,47 +133,148 @@ confirm the code was already clean).
111
133
 
112
134
  `/code-simplify → subagent tool unavailable → single-pass inline cleanup → apply the fixes`
113
135
 
114
- The `subagent` tool isn't available in this context (or context is near-full), so
115
- the usual 4-agent fan-out can't run. Work through all four angles below yourself,
116
- in this same context, in one pass — do not skip an angle for lack of fan-out.
136
+ The subagent tool isn't available in this context, so the usual
137
+ 4-agent fan-out can't run. Work through all four angles below yourself, in
138
+ this same context, in one pass — do not skip an angle for lack of fan-out.
117
139
 
118
140
  ## Phase 1 — Review (4 cleanup angles, single pass)
119
141
 
120
142
  Review the diff against each angle below in turn. For each, note findings with
121
- `file`, `line`, a one-line `summary`, and the concrete cost (what is duplicated,
122
- wasted, or harder to maintain).
143
+ `file`, `line`, a one-line `summary`, and the concrete cost (what is
144
+ duplicated, wasted, or harder to maintain).
123
145
 
124
146
  ### Reuse
125
- Flag new code that re-implements something the codebase already has — Grep
126
- shared/utility modules and files adjacent to the change, and name the existing
127
- helper to call instead.
147
+
148
+ Flag new code that re-implements something the codebase
149
+ already has — Grep shared/utility modules and files adjacent to the change,
150
+ and name the existing helper to call instead.
128
151
 
129
152
  ### Simplification
153
+
130
154
  Flag unnecessary complexity the diff adds: redundant or derivable state,
131
- copy-paste with slight variation, deep nesting, dead code left behind. Name the
132
- simpler form that does the same job.
155
+ copy-paste with slight variation, deep nesting, dead code left behind. Name
156
+ the simpler form that does the same job.
133
157
 
134
158
  ### Efficiency
159
+
135
160
  Flag wasted work the diff introduces: redundant computation or repeated I/O,
136
- independent operations run sequentially, blocking work added to startup or hot
137
- paths. Also flag long-lived objects built from closures or captured environments
138
- — they keep the entire enclosing scope alive for the object's lifetime (a memory
139
- leak when that scope holds large values); prefer a class/struct that copies only
140
- the fields it needs. Name the cheaper alternative.
161
+ independent operations run sequentially, blocking work added to startup or
162
+ hot paths. Also flag long-lived objects built from closures or captured
163
+ environments — they keep the entire enclosing scope alive for the object's
164
+ lifetime (a memory leak when that scope holds large values); prefer a
165
+ class/struct that copies only the fields it needs. Name the cheaper
166
+ alternative.
141
167
 
142
168
  ### Altitude
169
+
143
170
  Check that each change is implemented at the right depth, not as a fragile
144
- bandaid. Special cases layered on shared infrastructure are a sign the fix isn't
145
- deep enough — prefer generalizing the underlying mechanism over adding special
146
- cases.
147
-
148
- ## Phase 2 — Apply the fixes
149
-
150
- Dedup findings that point at the same line or mechanism, and fix each remaining
151
- one directly. Skip any finding whose fix would change intended behavior, require
152
- changes well outside the reviewed diff, or that you judge to be a false positive
153
- — note the skip rather than arguing with it. Finish with a brief summary of what
154
- was fixed and what was skipped (or confirm the code was already clean). State
155
- clearly in your summary that this was a single-pass review done without the
156
- `subagent` tool, not the full 4-agent fan-out, so whoever reads it isn't misled
157
- about what actually ran.
171
+ bandaid. Special cases layered on shared infrastructure are a sign the fix
172
+ isn't deep enough — prefer generalizing the underlying mechanism over adding
173
+ special cases.
174
+ ## Phase 2 — Apply, verify, and report
175
+
176
+ Follow the shared **Phase 2** procedure at the end of this skill (snapshot → apply → verify → auto-revert on failure → report via `review_report`). Single-pass vs parallel only changes how findings are gathered (Phase 1); applying, verifying, and reporting are identical across modes. Set `fanned_out: false` in the report so a reader is not misled into thinking the 4-agent fan-out ran.
177
+
178
+ ---
179
+
180
+ # Phase 2 — Apply, verify, and report (shared by both modes)
181
+
182
+ Dedup findings that point at the same line or mechanism first. Then apply,
183
+ verify, and report. This safety net is what distinguishes `/code-simplify` from
184
+ a blind cleanup: a finding is only "done" once it is applied AND the project
185
+ still verifies — otherwise it is reverted.
186
+
187
+ ## Step 1 — Snapshot the baseline
188
+
189
+ Before applying any fix, snapshot every file you are about to edit so a failed
190
+ verification can be reverted cleanly. For each touched file, copy its current
191
+ content into a temp dir:
192
+
193
+ ```
194
+ mkdir -p /tmp/pi-simplify-baseline/$(dirname <file>)
195
+ cp <file> /tmp/pi-simplify-baseline/<file>
196
+ ```
197
+
198
+ `$(dirname <file>)` keeps the target's parent dir (e.g. `src/`) inside the
199
+ baseline — a bare `cp <file> /tmp/pi-simplify-baseline/<file>` fails with ENOENT
200
+ for any file in a subdirectory. If a fix CREATES a new file, record its path so
201
+ Step 3a can remove it on rollback (it has no baseline entry).
202
+
203
+ This baseline captures the working-tree state **including** the user's
204
+ uncommitted changes — reverting to it undoes only `/code-simplify`'s fixes,
205
+ never the user's diff. Do **not** use `git checkout` / `git restore` to revert:
206
+ that would discard the user's intended changes too.
207
+
208
+ ## Step 2 — Apply the fixes
209
+
210
+ Apply each surviving finding directly. Skip any finding whose fix would change
211
+ intended behavior, require changes well outside the reviewed diff, or that you
212
+ judge to be a false positive — note the skip (it will be reported as
213
+ `skipped`).
214
+
215
+ ## Step 3 — Verify, branching on the result
216
+
217
+ Run the verification command the handler injected in the trigger message (e.g.
218
+ `npm run check`), then branch:
219
+
220
+ - **No verification command was detected** → keep the applied changes, mark each
221
+ applied finding `fixed`, and say in the report that NO verification
222
+ was run. Verification is opportunistic — never block on its absence.
223
+ - **Verification passes** → keep the changes; applied findings are
224
+ `fixed`.
225
+ - **Verification fails** → the working tree is verified-broken; go to Step 3a.
226
+
227
+ ### Step 3a — Auto-revert (hybrid granularity, only on failure)
228
+
229
+ 1. Revert ALL touched files from the Step 1 baseline (working-tree parent dirs
230
+ already exist, so copying back is safe):
231
+ ```
232
+ cp /tmp/pi-simplify-baseline/<file> <file>
233
+ ```
234
+ 2. Remove any files the fixes CREATED (they have no baseline entry and would
235
+ otherwise survive the rollback).
236
+ 3. Re-apply ONE file's findings at a time, running the verification command
237
+ after each file. Keep only files whose verification passes; revert any file
238
+ whose verification fails back to its baseline.
239
+ 4. If NO file passes on its own, leave everything reverted and mark every
240
+ finding `skipped` — a clean tree is the safe outcome, not a broken one.
241
+
242
+ This caps the cost: the common case (clean apply) runs verification exactly
243
+ once; only a failure escalates to one verification per touched file.
244
+
245
+ ## Step 4 — Report via `review_report`
246
+
247
+ Call the `review_report` tool **once** with `level: "simplify"` and one finding
248
+ entry per cleanup, ranked most-severe first. Generate a `report_id` (e.g.
249
+ `review-<ts>`) on this first call; reuse it on any re-report (fixed-later
250
+ 义务:本会话后续若再修复已上报项,必须先再次调用 `review_report` 更新
251
+ `outcome`,先于任何文字总结)。Each entry carries `file`, `line` (optional),
252
+ `category` (`reuse` / `simplification` / `efficiency` / `altitude`),
253
+ `short_summary` (≤60 字符纯声明标签,去掉理由与后果——汇总表概述列优先用它),
254
+ `summary` (one line, Chinese,含理由与后果), `failure_scenario` (the concrete
255
+ cost — Chinese), and `outcome`:
256
+
257
+ - `fixed` — applied and verification passed (or no verification command existed
258
+ and the change was kept).
259
+ - `skipped` — real but not applied: judged a false positive / behavior-
260
+ changing, or reverted by the auto-revert in Step 3a. Partial applies (per-file
261
+ rollback kept only some files) also count as `skipped` — the per-file detail
262
+ goes into `summary`.
263
+ - `no_change_needed` — not applicable or already handled.
264
+
265
+ Do **not** write a free-text summary as the primary record — the structured
266
+ `review_report` call IS the summary (it renders the report AND writes JSON to
267
+ `<cwd>/.pi/review/` for CI). If `review_report` is unavailable, fall back to a
268
+ brief text summary listing each finding's outcome.
269
+
270
+ Set `fanned_out` honestly in the call: `true` only if the 4-agent fan-out
271
+ (subagent) actually ran; `false` for single-pass. The report header shows this
272
+ so a reader is not misled about what ran.
273
+
274
+ ## Step 5 — Clean up
275
+
276
+ ```
277
+ rm -rf /tmp/pi-simplify-baseline
278
+ ```
279
+
280
+ Remove the baseline snapshots once the report is delivered.
@@ -1,4 +1,6 @@
1
1
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
2
4
  import { bundledSkillPath } from "../skills.ts";
3
5
 
4
6
  /** Context fraction at which we fall back to single-pass — a Pi-specific heuristic (see decideSimplifyMode). */
@@ -6,16 +8,46 @@ const CONTEXT_NEAR_FULL_THRESHOLD = 0.8;
6
8
 
7
9
  export type SimplifyMode = "parallel" | "single-pass";
8
10
 
11
+ /** Priority order for picking a verification command from package.json scripts. */
12
+ const VERIFY_SCRIPT_PRIORITY = ["check", "test", "lint", "typecheck"] as const;
13
+
14
+ /**
15
+ * Pick the project verification command from a package.json `scripts` map, in
16
+ * priority order (check → test → lint → typecheck). Pure — unit-testable.
17
+ * Returns the runnable command (e.g. `npm run check`) or null when none exists.
18
+ */
19
+ export function detectVerifyCommand(scripts: Record<string, string> | null): string | null {
20
+ if (!scripts) return null;
21
+ for (const key of VERIFY_SCRIPT_PRIORITY) {
22
+ const v = scripts[key];
23
+ if (typeof v === "string" && v.trim() !== "") return `npm run ${key}`;
24
+ }
25
+ return null;
26
+ }
27
+
28
+ /** Read package.json scripts from `cwd`; returns null when absent/unparseable. */
29
+ function readScriptsAt(cwd: string): Record<string, string> | null {
30
+ try {
31
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf8")) as {
32
+ scripts?: Record<string, string>;
33
+ };
34
+ return pkg.scripts ?? null;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+
9
40
  /**
10
41
  * Decide simplify mode deterministically from real context usage + tool availability.
11
42
  * Pure function — unit-testable.
12
43
  *
13
- * CC parity note: CC's /simplify guard (_Yo) is a SPAWN-DEPTH recursion limit, NOT a
14
- * context check — `RO(ctx) >= dne()` where RO returns the agent's depth and dne()
15
- * returns CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH (default 3). That is N/A on Pi: the
44
+ * CC parity note: CC's /simplify guard (Dii, verified in the 2.1.227 binary) is
45
+ * a SPAWN-DEPTH recursion limit, NOT a context check — `ok(ctx.agentContext) >= wV()`
46
+ * where ok() returns the agent's depth (main=0) and wV() returns
47
+ * CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH (default 3). That is N/A on Pi: the
16
48
  * `subagent` tool spawns a fresh subprocess (depth 0), so depth never accumulates.
17
49
  * The context-fraction heuristic below is a Pi-specific substitute (don't fan out
18
- * when the parent's context is near-full), NOT a mirror of _Yo. The other _Yo clause
50
+ * when the parent's context is near-full), NOT a mirror of Dii. The other Dii clause
19
51
  * — the Agent tool must be in the allowlist — IS mirrored here as `hasSubagent`.
20
52
  */
21
53
  export function decideSimplifyMode(opts: {
@@ -48,18 +80,20 @@ export function registerSimplify(pi: ExtensionAPI): void {
48
80
  contextWindow: usage?.contextWindow ?? 0,
49
81
  hasSubagent,
50
82
  });
51
- const pct =
52
- usage && usage.tokens != null && usage.contextWindow > 0
53
- ? Math.round((usage.tokens / usage.contextWindow) * 100) + "%"
54
- : "?";
83
+ const pct = usage && usage.percent != null ? `${Math.round(usage.percent)}%` : "?";
55
84
  const bodyLabel = mode === "parallel" ? "PARALLEL MODE" : "SINGLE-PASS MODE";
85
+ const verifyCmd = detectVerifyCommand(readScriptsAt(ctx.cwd));
86
+ const verifyLine = verifyCmd
87
+ ? `Verification command: \`${verifyCmd}\` (detected from package.json scripts). After applying Phase 2 fixes, run it; on failure, follow the skill's auto-revert procedure — never leave the working tree verified-broken.`
88
+ : `No verification command detected in package.json (looked for check/test/lint/typecheck). Apply fixes and report outcomes, but state in the report that no verification was run (verification is opportunistic, never blocking).`;
56
89
  pi.sendUserMessage(
57
90
  `Clean up the changed code now. Target: ${args || "(whole diff)"}.\n\n` +
58
91
  `Handler decided ${mode} mode (context ${pct} full, subagent ${hasSubagent ? "available" : "absent"}). ` +
59
92
  `Load ${bundledSkillPath("simplify/SKILL.md")} via the read tool and follow the ${bodyLabel} body. ` +
60
93
  (mode === "parallel"
61
94
  ? `Use the \`subagent\` tool (mode: parallel) for the 4-agent fan-out.`
62
- : `Work the four angles inline — do not fake fan-out.`),
95
+ : `Work the four angles inline — do not fake fan-out.`) +
96
+ `\n${verifyLine}`,
63
97
  );
64
98
  },
65
99
  });