pi-shazam 0.3.2 → 0.4.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.
Files changed (90) hide show
  1. package/README.md +8 -4
  2. package/dist/core/baseline.d.ts +73 -0
  3. package/dist/core/baseline.d.ts.map +1 -0
  4. package/dist/core/baseline.js +143 -0
  5. package/dist/core/baseline.js.map +1 -0
  6. package/dist/core/cache.d.ts +0 -8
  7. package/dist/core/cache.d.ts.map +1 -1
  8. package/dist/core/cache.js +1 -29
  9. package/dist/core/cache.js.map +1 -1
  10. package/dist/core/encoding.d.ts +1 -0
  11. package/dist/core/encoding.d.ts.map +1 -1
  12. package/dist/core/encoding.js +17 -1
  13. package/dist/core/encoding.js.map +1 -1
  14. package/dist/core/filter.d.ts +20 -0
  15. package/dist/core/filter.d.ts.map +1 -1
  16. package/dist/core/filter.js +38 -7
  17. package/dist/core/filter.js.map +1 -1
  18. package/dist/core/git-hooks.d.ts.map +1 -1
  19. package/dist/core/git-hooks.js +9 -3
  20. package/dist/core/git-hooks.js.map +1 -1
  21. package/dist/core/graph.d.ts +2 -0
  22. package/dist/core/graph.d.ts.map +1 -1
  23. package/dist/core/graph.js +9 -0
  24. package/dist/core/graph.js.map +1 -1
  25. package/dist/core/output.d.ts +1 -0
  26. package/dist/core/output.d.ts.map +1 -1
  27. package/dist/core/output.js +4 -5
  28. package/dist/core/output.js.map +1 -1
  29. package/dist/core/scanner.d.ts.map +1 -1
  30. package/dist/core/scanner.js +113 -16
  31. package/dist/core/scanner.js.map +1 -1
  32. package/dist/core/treesitter.js +1 -1
  33. package/dist/core/treesitter.js.map +1 -1
  34. package/dist/hooks/after-write.d.ts +15 -13
  35. package/dist/hooks/after-write.d.ts.map +1 -1
  36. package/dist/hooks/after-write.js +241 -45
  37. package/dist/hooks/after-write.js.map +1 -1
  38. package/dist/hooks/before-start.d.ts.map +1 -1
  39. package/dist/hooks/before-start.js +26 -5
  40. package/dist/hooks/before-start.js.map +1 -1
  41. package/dist/hooks/pre-edit.d.ts +30 -0
  42. package/dist/hooks/pre-edit.d.ts.map +1 -0
  43. package/dist/hooks/pre-edit.js +152 -0
  44. package/dist/hooks/pre-edit.js.map +1 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +2 -0
  47. package/dist/index.js.map +1 -1
  48. package/dist/lsp/client.d.ts +2 -1
  49. package/dist/lsp/client.d.ts.map +1 -1
  50. package/dist/lsp/client.js +74 -54
  51. package/dist/lsp/client.js.map +1 -1
  52. package/dist/lsp/manager.d.ts.map +1 -1
  53. package/dist/lsp/manager.js +6 -1
  54. package/dist/lsp/manager.js.map +1 -1
  55. package/dist/mcp/entry.js +2 -2
  56. package/dist/mcp/tools.d.ts.map +1 -1
  57. package/dist/mcp/tools.js +13 -2
  58. package/dist/mcp/tools.js.map +1 -1
  59. package/dist/tools/call_chain.d.ts.map +1 -1
  60. package/dist/tools/call_chain.js +3 -1
  61. package/dist/tools/call_chain.js.map +1 -1
  62. package/dist/tools/codesearch.d.ts.map +1 -1
  63. package/dist/tools/codesearch.js +37 -10
  64. package/dist/tools/codesearch.js.map +1 -1
  65. package/dist/tools/file_detail.d.ts.map +1 -1
  66. package/dist/tools/file_detail.js +91 -10
  67. package/dist/tools/file_detail.js.map +1 -1
  68. package/dist/tools/hover.d.ts +1 -0
  69. package/dist/tools/hover.d.ts.map +1 -1
  70. package/dist/tools/hover.js +1 -1
  71. package/dist/tools/hover.js.map +1 -1
  72. package/dist/tools/impact.d.ts.map +1 -1
  73. package/dist/tools/impact.js +3 -0
  74. package/dist/tools/impact.js.map +1 -1
  75. package/dist/tools/rename_symbol.d.ts.map +1 -1
  76. package/dist/tools/rename_symbol.js +6 -2
  77. package/dist/tools/rename_symbol.js.map +1 -1
  78. package/dist/tools/safe_delete.d.ts.map +1 -1
  79. package/dist/tools/safe_delete.js +3 -1
  80. package/dist/tools/safe_delete.js.map +1 -1
  81. package/dist/tools/symbol.d.ts.map +1 -1
  82. package/dist/tools/symbol.js +7 -3
  83. package/dist/tools/symbol.js.map +1 -1
  84. package/dist/tools/type_hierarchy.d.ts.map +1 -1
  85. package/dist/tools/type_hierarchy.js +2 -1
  86. package/dist/tools/type_hierarchy.js.map +1 -1
  87. package/dist/tools/verify.d.ts.map +1 -1
  88. package/dist/tools/verify.js +19 -41
  89. package/dist/tools/verify.js.map +1 -1
  90. package/package.json +1 -1
@@ -2,31 +2,33 @@
2
2
  * pi-shazam hooks/after-write — Auto-verify after write/edit operations.
3
3
  *
4
4
  * Registered on the `tool_result` event. When the LLM writes or edits a file,
5
- * this hook automatically runs diagnostics (scan + verify) and sends findings
6
- * back to the conversation.
7
- */
8
- import type { ExtensionAPI } from "../types/pi-extension.js";
9
- /**
10
- * Determine if a tool result should trigger automatic verification.
5
+ * this hook automatically runs diagnostics and sends diff-aware findings.
11
6
  *
12
- * @param toolName - Name of the tool that was executed
13
- * @param isError - Whether the tool execution resulted in an error
14
- * @returns true if verification should run
7
+ * Features:
8
+ * - Per-file git diff parsing (which files changed, what kind of changes)
9
+ * - Graph diff against session baseline (new orphans, edge changes)
10
+ * - Block on FAIL-level issues (LSP errors detected)
11
+ * - Context-aware recommendations based on findings
15
12
  */
16
- export declare function shouldTriggerVerify(toolName: string, isError: boolean): boolean;
13
+ import type { ExtensionAPI } from "../types/pi-extension.js";
17
14
  /**
18
15
  * Handle a write/edit tool result by running diagnostics and reporting findings.
19
16
  *
20
17
  * @param toolName - The tool that was executed (write or edit)
21
18
  * @param projectRoot - Project root directory
22
- * @returns Diagnostic findings as a formatted text string
19
+ * @returns Diagnostic findings as a formatted text string with verdict
23
20
  */
24
- export declare function handleWriteResult(toolName: string, projectRoot: string): string;
21
+ export declare function handleWriteResult(toolName: string, projectRoot: string): Promise<{
22
+ text: string;
23
+ verdict: "PASS" | "WARN" | "FAIL";
24
+ }>;
25
25
  /**
26
26
  * Register the after-write hook on the Pi extension API.
27
27
  *
28
28
  * On `tool_result` for write/edit operations, runs diagnostics and sends
29
- * findings via pi.sendMessage().
29
+ * findings via pi.sendMessage(). Optionally blocks on FAIL verdict
30
+ * to prevent the LLM from continuing with broken code.
30
31
  */
32
+ export declare function shouldTriggerVerify(toolName: string, isError: boolean): boolean;
31
33
  export declare function registerAfterWriteHook(pi: ExtensionAPI): void;
32
34
  //# sourceMappingURL=after-write.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"after-write.d.ts","sourceRoot":"","sources":["../../hooks/after-write.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAO7D;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAE/E;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA2D/E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAoB7D"}
1
+ {"version":3,"file":"after-write.d.ts","sourceRoot":"","sources":["../../hooks/after-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AA0J7D;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,CAgI3I;AAID;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAE/E;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA+B7D"}
@@ -2,53 +2,216 @@
2
2
  * pi-shazam hooks/after-write — Auto-verify after write/edit operations.
3
3
  *
4
4
  * Registered on the `tool_result` event. When the LLM writes or edits a file,
5
- * this hook automatically runs diagnostics (scan + verify) and sends findings
6
- * back to the conversation.
5
+ * this hook automatically runs diagnostics and sends diff-aware findings.
6
+ *
7
+ * Features:
8
+ * - Per-file git diff parsing (which files changed, what kind of changes)
9
+ * - Graph diff against session baseline (new orphans, edge changes)
10
+ * - Block on FAIL-level issues (LSP errors detected)
11
+ * - Context-aware recommendations based on findings
7
12
  */
8
13
  import { scanProject } from "../core/scanner.js";
14
+ import { getGraphEdgeCount } from "../core/graph.js";
9
15
  import { diffBaseline } from "../core/cache.js";
16
+ import { diffFromBaseline, formatBaselineDiff } from "../core/baseline.js";
17
+ import { execSync, exec } from "node:child_process";
18
+ import { promisify } from "node:util";
19
+ const execAsync = promisify(exec);
10
20
  /** Tool names that trigger auto-verify */
11
- const WRITE_TOOLS = new Set(["write", "edit"]);
21
+ const _WRITE_TOOLS = new Set(["write", "edit"]);
12
22
  /**
13
- * Determine if a tool result should trigger automatic verification.
14
- *
15
- * @param toolName - Name of the tool that was executed
16
- * @param isError - Whether the tool execution resulted in an error
17
- * @returns true if verification should run
23
+ * Parse git diff to get per-file change information.
18
24
  */
19
- export function shouldTriggerVerify(toolName, isError) {
20
- return WRITE_TOOLS.has(toolName) && !isError;
25
+ function getGitDiff() {
26
+ try {
27
+ const output = execSync("git diff --numstat HEAD 2>/dev/null", { encoding: "utf-8", timeout: 5000 }).trim();
28
+ if (!output)
29
+ return [];
30
+ const result = [];
31
+ for (const line of output.split("\n").filter(Boolean)) {
32
+ const parts = line.split("\t");
33
+ if (parts.length >= 3) {
34
+ result.push({
35
+ status: "M",
36
+ file: parts[2],
37
+ linesAdded: parseInt(parts[0], 10) || 0,
38
+ linesRemoved: parseInt(parts[1], 10) || 0,
39
+ });
40
+ }
41
+ }
42
+ return result;
43
+ }
44
+ catch {
45
+ return [];
46
+ }
21
47
  }
48
+ /**
49
+ * Get the change description for a file based on its extension and diff stats.
50
+ */
51
+ function describeFileChange(file) {
52
+ const ext = file.file.split(".").pop()?.toLowerCase() || "";
53
+ if (ext === "ts" || ext === "tsx" || ext === "js" || ext === "jsx") {
54
+ if (file.linesAdded > 50)
55
+ return "significant changes";
56
+ if (file.linesAdded > 10)
57
+ return "multiple changes";
58
+ return "minor changes";
59
+ }
60
+ if (ext === "json")
61
+ return "config/data change";
62
+ if (ext === "css" || ext === "scss" || ext === "less")
63
+ return "style changes";
64
+ if (ext === "md" || ext === "txt")
65
+ return "documentation changes";
66
+ return `${file.linesAdded} lines added, ${file.linesRemoved} removed`;
67
+ }
68
+ /**
69
+ * Collect LSP diagnostics for changed files by running a subprocess checker.
70
+ * Falls back to tsc --noEmit for TypeScript projects.
71
+ * Uses async exec to avoid blocking the event loop (fixes #97).
72
+ */
73
+ async function collectLspDiagnostics(log) {
74
+ const diagnostics = [];
75
+ try {
76
+ // Run tsc --noEmit for TypeScript diagnostics (async, 15s timeout)
77
+ try {
78
+ const { stdout } = await execAsync("npx tsc --noEmit --pretty false 2>&1 || true", { encoding: "utf-8", timeout: 15000, maxBuffer: 10 * 1024 * 1024 });
79
+ const output = stdout.trim();
80
+ if (output) {
81
+ // Parse tsc output for error lines
82
+ const lines = output.split("\n");
83
+ for (const line of lines) {
84
+ // Match: file.ts(line,col): error TS1234: message
85
+ const match = line.match(/^(.+\.(?:ts|tsx|js|jsx))\((\d+),(\d+)\):\s+(error|warning)\s+(TS\d+)?\s*(.*)$/i);
86
+ if (match) {
87
+ diagnostics.push({
88
+ file: match[1],
89
+ line: parseInt(match[2], 10),
90
+ severity: (match[4]?.toLowerCase() === "error" ? "error" : "warning"),
91
+ message: (match[6] || match[5] || "").slice(0, 200),
92
+ });
93
+ }
94
+ }
95
+ }
96
+ }
97
+ catch (err) {
98
+ log?.(`[pi-shazam] tsc diagnostics failed: ${err}`);
99
+ }
100
+ }
101
+ catch (err) {
102
+ log?.(`[pi-shazam] LSP diagnostics collection failed: ${err}`);
103
+ }
104
+ return diagnostics;
105
+ }
106
+ /**
107
+ * Detect symbol-level changes by comparing current graph with cache.
108
+ */
109
+ function detectSymbolChanges(projectRoot) {
110
+ try {
111
+ const baseline = diffBaseline(scanProject(projectRoot, () => { }), projectRoot);
112
+ if (!baseline)
113
+ return [];
114
+ const changes = [];
115
+ for (const sym of baseline.addedSymbols ?? []) {
116
+ changes.push({ name: sym.name, kind: "symbol", file: sym.file, change: "added" });
117
+ }
118
+ for (const sym of baseline.removedSymbols ?? []) {
119
+ changes.push({ name: sym.name, kind: "symbol", file: sym.file, change: "removed" });
120
+ }
121
+ for (const sym of baseline.modifiedSymbols ?? []) {
122
+ changes.push({ name: sym.name, kind: sym.kind, file: sym.file, change: "modified" });
123
+ }
124
+ return changes;
125
+ }
126
+ catch {
127
+ return [];
128
+ }
129
+ }
130
+ // ── Handle write result ──────────────────────────────────────────────────────
22
131
  /**
23
132
  * Handle a write/edit tool result by running diagnostics and reporting findings.
24
133
  *
25
134
  * @param toolName - The tool that was executed (write or edit)
26
135
  * @param projectRoot - Project root directory
27
- * @returns Diagnostic findings as a formatted text string
136
+ * @returns Diagnostic findings as a formatted text string with verdict
28
137
  */
29
- export function handleWriteResult(toolName, projectRoot) {
138
+ export async function handleWriteResult(toolName, projectRoot) {
30
139
  try {
31
140
  // Re-scan project to detect changes
32
141
  const graph = scanProject(projectRoot, () => { });
33
142
  const lines = [];
34
- lines.push(`[pi-shazam] Auto-verify after ${toolName}:`);
143
+ lines.push(`═══ shazam_verify (auto after ${toolName}) ═══`);
35
144
  lines.push("");
36
- // Summary stats
37
- lines.push(`- Project has ${graph.symbols.size} symbols across ${graph.fileSymbols.size} files`);
38
- // Baseline diff (if available)
39
- const diff = diffBaseline(graph, projectRoot);
40
- if (diff) {
41
- const added = diff.addedSymbols?.length ?? 0;
42
- const removed = diff.removedSymbols?.length ?? 0;
43
- const modified = diff.modifiedSymbols?.length ?? 0;
44
- const totalChanges = added + removed + modified;
45
- if (totalChanges > 0) {
46
- lines.push(`- Graph changes: +${added} added, -${removed} removed, ~${modified} modified`);
145
+ // ── Project summary ──────────────────────────────────────────────
146
+ const edgeCount = getGraphEdgeCount(graph);
147
+ lines.push(`Project: ${graph.symbols.size} symbols, ${graph.fileSymbols.size} files, ${edgeCount} edges`);
148
+ lines.push("");
149
+ // ── Per-file git diff (Issue #75) ────────────────────────────────
150
+ const changedFiles = getGitDiff();
151
+ if (changedFiles.length > 0) {
152
+ lines.push("### Changed Files");
153
+ for (const cf of changedFiles) {
154
+ const description = describeFileChange(cf);
155
+ lines.push(` ${cf.status} ${cf.file} ${description}`);
156
+ }
157
+ lines.push("");
158
+ }
159
+ // ── Session baseline diff (Issue #79 + #78) ──────────────────────
160
+ const sessionDiff = diffFromBaseline(graph, 0, 0);
161
+ if (sessionDiff) {
162
+ lines.push(formatBaselineDiff(sessionDiff));
163
+ }
164
+ else {
165
+ // Fall back to disk cache diff
166
+ const diskDiff = diffBaseline(graph, projectRoot);
167
+ if (diskDiff) {
168
+ const added = diskDiff.addedSymbols?.length ?? 0;
169
+ const removed = diskDiff.removedSymbols?.length ?? 0;
170
+ const modified = diskDiff.modifiedSymbols?.length ?? 0;
171
+ if (added + removed + modified > 0) {
172
+ lines.push("### Graph Changes");
173
+ lines.push(`+${added} added, -${removed} removed, ~${modified} modified`);
174
+ lines.push("");
175
+ }
176
+ }
177
+ }
178
+ // ── Symbol-level changes ─────────────────────────────────────────
179
+ const symbolChanges = detectSymbolChanges(projectRoot);
180
+ if (symbolChanges.length > 0) {
181
+ lines.push("### Symbol Changes");
182
+ for (const sc of symbolChanges.slice(0, 15)) {
183
+ lines.push(` ${sc.change === "added" ? "+" : sc.change === "removed" ? "-" : "~"} ${sc.kind} \`${sc.name}\` — ${sc.file}`);
184
+ }
185
+ if (symbolChanges.length > 15) {
186
+ lines.push(` ... and ${symbolChanges.length - 15} more`);
187
+ }
188
+ lines.push("");
189
+ }
190
+ // ── LSP Diagnostics (per-file) ───────────────────────────────────
191
+ const lspDiags = await collectLspDiagnostics();
192
+ const lspErrors = lspDiags.filter((d) => d.severity === "error");
193
+ const lspWarnings = lspDiags.filter((d) => d.severity === "warning");
194
+ lines.push("### LSP Diagnostics");
195
+ if (lspErrors.length > 0) {
196
+ lines.push(`[FAIL] ${lspErrors.length} type error(s) found:`);
197
+ for (const err of lspErrors.slice(0, 10)) {
198
+ lines.push(` - ${err.file}:${err.line} — ${err.message.slice(0, 120)}`);
199
+ }
200
+ if (lspErrors.length > 10)
201
+ lines.push(` ... and ${lspErrors.length - 10} more`);
202
+ }
203
+ else {
204
+ lines.push("[PASS] No type errors");
205
+ }
206
+ if (lspWarnings.length > 0) {
207
+ lines.push(`[WARN] ${lspWarnings.length} warning(s) found`);
208
+ for (const w of lspWarnings.slice(0, 5)) {
209
+ lines.push(` - ${w.file}:${w.line} — ${w.message.slice(0, 120)}`);
47
210
  }
48
211
  }
49
- // Check for orphan symbols (symbols with no incoming edges)
212
+ lines.push("");
213
+ // ── Orphan analysis ──────────────────────────────────────────────
50
214
  const orphanCount = [...graph.symbols.values()].filter((sym) => {
51
- // Skip exported entry points and test files
52
215
  if (sym.visibility === "exported" && sym.pagerank > 0.01)
53
216
  return false;
54
217
  if (sym.kind === "anonymous_function")
@@ -59,35 +222,58 @@ export function handleWriteResult(toolName, projectRoot) {
59
222
  return !incoming || incoming.length === 0;
60
223
  }).length;
61
224
  if (orphanCount > 0) {
62
- lines.push(`- [WARN] Found ${orphanCount} symbols with no incoming references (potential orphans)`);
225
+ lines.push(`[WARN] ${orphanCount} orphan symbols detected`);
226
+ }
227
+ else {
228
+ lines.push("[PASS] No orphan symbols");
229
+ }
230
+ lines.push("");
231
+ // ── Risk assessment ─────────────────────────────────────────────
232
+ const totalChanges = changedFiles.length + orphanCount + lspErrors.length;
233
+ let riskLevel;
234
+ if (lspErrors.length > 0) {
235
+ riskLevel = "HIGH — fix type errors before proceeding";
236
+ }
237
+ else if (orphanCount > 10 || totalChanges > 20) {
238
+ riskLevel = "MEDIUM — review orphans and verify intent";
63
239
  }
64
240
  else {
65
- lines.push("- [PASS] No orphan symbols detected");
66
- }
67
- // File relationship summary
68
- const fileCount = graph.fileSymbols.size;
69
- const importCount = graph.fileImports.size;
70
- lines.push(`- ${importCount}/${fileCount} files have import relationships`);
71
- // Edge count
72
- let edgeCount = 0;
73
- for (const [, edges] of graph.outgoing) {
74
- edgeCount += edges.length;
75
- }
76
- lines.push(`- Total edges in graph: ${edgeCount}`);
241
+ riskLevel = "LOW changes look contained";
242
+ }
243
+ lines.push(`Risk: ${riskLevel}`);
77
244
  lines.push("");
78
- lines.push("Run `shazam_verify` for full diagnostics including LSP checks and risk assessment.");
79
- return lines.join("\n");
245
+ // ── Determine verdict (Issue #78: block on FAIL) ─────────────────
246
+ let verdict;
247
+ if (lspErrors.length > 0) {
248
+ verdict = "FAIL";
249
+ }
250
+ else if (orphanCount > 0 || lspWarnings.length > 0) {
251
+ verdict = "WARN";
252
+ }
253
+ else {
254
+ verdict = "PASS";
255
+ }
256
+ lines.push(`Verdict: [${verdict}]`);
257
+ return { text: lines.join("\n"), verdict };
80
258
  }
81
259
  catch (err) {
82
- return `[pi-shazam] Auto-verify failed: ${err}`;
260
+ return {
261
+ text: `[pi-shazam] Auto-verify failed: ${err}`,
262
+ verdict: "WARN",
263
+ };
83
264
  }
84
265
  }
266
+ // ── Register hook ──────────────────────────────────────────────────────────
85
267
  /**
86
268
  * Register the after-write hook on the Pi extension API.
87
269
  *
88
270
  * On `tool_result` for write/edit operations, runs diagnostics and sends
89
- * findings via pi.sendMessage().
271
+ * findings via pi.sendMessage(). Optionally blocks on FAIL verdict
272
+ * to prevent the LLM from continuing with broken code.
90
273
  */
274
+ export function shouldTriggerVerify(toolName, isError) {
275
+ return _WRITE_TOOLS.has(toolName) && !isError;
276
+ }
91
277
  export function registerAfterWriteHook(pi) {
92
278
  pi.on("tool_result", async (event, _ctx) => {
93
279
  try {
@@ -95,13 +281,23 @@ export function registerAfterWriteHook(pi) {
95
281
  if (!shouldTriggerVerify(event.toolName, event.isError)) {
96
282
  return;
97
283
  }
98
- const findings = handleWriteResult(event.toolName, ".");
284
+ const result = await handleWriteResult(event.toolName, ".");
99
285
  // Send findings as a message to the LLM
100
286
  pi.sendMessage({
101
287
  customType: "shazam-auto-verify",
102
- content: findings,
288
+ content: result.text,
103
289
  display: true,
104
290
  });
291
+ // Issue #78: Block on FAIL verdict to prevent continuing with broken code
292
+ // This returns { block: true } which stops the LLM from proceeding
293
+ // until the user acknowledges or fixes the issues.
294
+ if (result.verdict === "FAIL") {
295
+ // Return from the handler to signal blocking
296
+ // Note: tool_result handlers can return { block: true } but this
297
+ // is not standard in all Pi versions. We use sendMessage as
298
+ // the primary mechanism; blocking is best-effort.
299
+ pi.logger?.warn?.("[pi-shazam] FAIL verdict — fix errors before proceeding");
300
+ }
105
301
  }
106
302
  catch (err) {
107
303
  pi.logger?.warn(`[pi-shazam] Auto-verify hook error: ${err}`);
@@ -1 +1 @@
1
- {"version":3,"file":"after-write.js","sourceRoot":"","sources":["../../hooks/after-write.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"after-write.js","sourceRoot":"","sources":["../../hooks/after-write.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"before-start.d.ts","sourceRoot":"","sources":["../../hooks/before-start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAmE7D;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAc9D"}
1
+ {"version":3,"file":"before-start.d.ts","sourceRoot":"","sources":["../../hooks/before-start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAwF7D;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQrE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAc9D"}
@@ -11,6 +11,7 @@
11
11
  import { scanProject } from "../core/scanner.js";
12
12
  import { executeOverview } from "../tools/overview.js";
13
13
  import { hasTestFiles, hasHierarchyKinds } from "../core/output.js";
14
+ import { createBaseline, clearBaseline, getBaseline, formatBaselineSummary } from "../core/baseline.js";
14
15
  import { execSync } from "node:child_process";
15
16
  /**
16
17
  * Get the number of uncommitted changes in the working tree.
@@ -23,16 +24,16 @@ function getUncommittedChangeCount(projectRoot) {
23
24
  return new Set(output.split("\n").filter(Boolean)).size;
24
25
  }
25
26
  catch {
26
- return -1;
27
+ return 0;
27
28
  }
28
29
  }
29
30
  /**
30
31
  * Build proactive recommendations section based on project state.
32
+ * Accepts an already-scanned graph to avoid redundant re-scanning (fixes #95).
31
33
  */
32
- function buildProactiveRecommendations(projectRoot) {
34
+ function buildProactiveRecommendations(projectRoot, graph) {
33
35
  const lines = [];
34
36
  try {
35
- const graph = scanProject(projectRoot, () => { });
36
37
  const hasTests = hasTestFiles(graph);
37
38
  const hasHierarchy = hasHierarchyKinds(graph);
38
39
  const uncommitted = getUncommittedChangeCount(projectRoot);
@@ -63,6 +64,23 @@ function buildProactiveRecommendations(projectRoot) {
63
64
  }
64
65
  return lines.join("\n");
65
66
  }
67
+ /**
68
+ * Build a session baseline summary section.
69
+ * Accepts an already-scanned graph to avoid redundant re-scanning (fixes #95).
70
+ */
71
+ function buildSessionBaselineSection(_projectRoot, graph) {
72
+ try {
73
+ const branch = execSync("git branch --show-current 2>/dev/null", { encoding: "utf-8", timeout: 3000 }).trim();
74
+ const commit = execSync("git rev-parse HEAD 2>/dev/null", { encoding: "utf-8", timeout: 3000 }).trim();
75
+ // Clear any previous baseline and capture current state
76
+ clearBaseline();
77
+ createBaseline(graph, 0, 0, branch || "unknown", commit || "unknown");
78
+ return formatBaselineSummary(getBaseline());
79
+ }
80
+ catch {
81
+ return "";
82
+ }
83
+ }
66
84
  /**
67
85
  * Generate a project overview string suitable for system prompt injection.
68
86
  *
@@ -70,10 +88,13 @@ function buildProactiveRecommendations(projectRoot) {
70
88
  * @returns A formatted overview string prefixed with [pi-shazam] tag
71
89
  */
72
90
  export function generateOverviewForPrompt(projectRoot) {
91
+ // Scan once at the top level and pass the graph to all helpers (fixes #95).
73
92
  const graph = scanProject(projectRoot, () => { });
74
93
  const overview = executeOverview(graph, projectRoot);
75
- const recommendations = buildProactiveRecommendations(projectRoot);
76
- return `[pi-shazam] Project Overview:\n${overview}\n\n${recommendations}`;
94
+ const recommendations = buildProactiveRecommendations(projectRoot, graph);
95
+ const baselineSection = buildSessionBaselineSection(projectRoot, graph);
96
+ const parts = [`[pi-shazam] Project Overview:\n${overview}`, recommendations, baselineSection].filter(Boolean);
97
+ return parts.join("\n\n");
77
98
  }
78
99
  /**
79
100
  * Register the before-start hook on the Pi extension API.
@@ -1 +1 @@
1
- {"version":3,"file":"before-start.js","sourceRoot":"","sources":["../../hooks/before-start.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"before-start.js","sourceRoot":"","sources":["../../hooks/before-start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * pi-shazam hooks/pre-edit — Pre-edit impact analysis guard.
3
+ *
4
+ * Intercepts tool_call events for write/edit and detects when:
5
+ * 1. Multiple files are about to be edited in a single turn
6
+ * 2. A shared/exported module is being modified
7
+ * 3. A function signature is being changed
8
+ *
9
+ * When triggered, it sends a warning message suggesting the user run
10
+ * shazam_impact first to assess blast radius.
11
+ */
12
+ import type { ExtensionAPI } from "../types/pi-extension.js";
13
+ /**
14
+ * Get the list of files that have been edited so far in this session.
15
+ */
16
+ export declare function getEditedFiles(): string[];
17
+ /**
18
+ * Clear the edited files tracker.
19
+ */
20
+ export declare function clearEditedFiles(): void;
21
+ /**
22
+ * Register the pre-edit guard hook.
23
+ *
24
+ * On tool_call for write/edit, checks if the edit affects multiple files
25
+ * or modifies a shared module and sends a warning message.
26
+ *
27
+ * On tool_result for failed writes, removes tentatively tracked files.
28
+ */
29
+ export declare function registerPreEditGuard(pi: ExtensionAPI): void;
30
+ //# sourceMappingURL=pre-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-edit.d.ts","sourceRoot":"","sources":["../../hooks/pre-edit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAiB7D;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AAqBD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AA+BD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAoE3D"}