pi-shazam 0.1.0

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 (121) hide show
  1. package/dist/core/cache.d.ts +50 -0
  2. package/dist/core/cache.d.ts.map +1 -0
  3. package/dist/core/cache.js +116 -0
  4. package/dist/core/cache.js.map +1 -0
  5. package/dist/core/encoding.d.ts +25 -0
  6. package/dist/core/encoding.d.ts.map +1 -0
  7. package/dist/core/encoding.js +109 -0
  8. package/dist/core/encoding.js.map +1 -0
  9. package/dist/core/graph.d.ts +146 -0
  10. package/dist/core/graph.d.ts.map +1 -0
  11. package/dist/core/graph.js +224 -0
  12. package/dist/core/graph.js.map +1 -0
  13. package/dist/core/pagerank.d.ts +19 -0
  14. package/dist/core/pagerank.d.ts.map +1 -0
  15. package/dist/core/pagerank.js +106 -0
  16. package/dist/core/pagerank.js.map +1 -0
  17. package/dist/core/scanner.d.ts +19 -0
  18. package/dist/core/scanner.d.ts.map +1 -0
  19. package/dist/core/scanner.js +266 -0
  20. package/dist/core/scanner.js.map +1 -0
  21. package/dist/core/treesitter-queries.d.ts +19 -0
  22. package/dist/core/treesitter-queries.d.ts.map +1 -0
  23. package/dist/core/treesitter-queries.js +222 -0
  24. package/dist/core/treesitter-queries.js.map +1 -0
  25. package/dist/core/treesitter.d.ts +67 -0
  26. package/dist/core/treesitter.d.ts.map +1 -0
  27. package/dist/core/treesitter.js +624 -0
  28. package/dist/core/treesitter.js.map +1 -0
  29. package/dist/hooks/after-write.d.ts +32 -0
  30. package/dist/hooks/after-write.d.ts.map +1 -0
  31. package/dist/hooks/after-write.js +111 -0
  32. package/dist/hooks/after-write.js.map +1 -0
  33. package/dist/hooks/before-start.d.ts +23 -0
  34. package/dist/hooks/before-start.d.ts.map +1 -0
  35. package/dist/hooks/before-start.js +43 -0
  36. package/dist/hooks/before-start.js.map +1 -0
  37. package/dist/index.d.ts +13 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +106 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/lsp/client.d.ts +77 -0
  42. package/dist/lsp/client.d.ts.map +1 -0
  43. package/dist/lsp/client.js +355 -0
  44. package/dist/lsp/client.js.map +1 -0
  45. package/dist/lsp/manager.d.ts +85 -0
  46. package/dist/lsp/manager.d.ts.map +1 -0
  47. package/dist/lsp/manager.js +362 -0
  48. package/dist/lsp/manager.js.map +1 -0
  49. package/dist/lsp/servers.d.ts +43 -0
  50. package/dist/lsp/servers.d.ts.map +1 -0
  51. package/dist/lsp/servers.js +140 -0
  52. package/dist/lsp/servers.js.map +1 -0
  53. package/dist/lsp/setup.d.ts +24 -0
  54. package/dist/lsp/setup.d.ts.map +1 -0
  55. package/dist/lsp/setup.js +140 -0
  56. package/dist/lsp/setup.js.map +1 -0
  57. package/dist/tools/call_chain.d.ts +9 -0
  58. package/dist/tools/call_chain.d.ts.map +1 -0
  59. package/dist/tools/call_chain.js +151 -0
  60. package/dist/tools/call_chain.js.map +1 -0
  61. package/dist/tools/check.d.ts +18 -0
  62. package/dist/tools/check.d.ts.map +1 -0
  63. package/dist/tools/check.js +141 -0
  64. package/dist/tools/check.js.map +1 -0
  65. package/dist/tools/codequery.d.ts +19 -0
  66. package/dist/tools/codequery.d.ts.map +1 -0
  67. package/dist/tools/codequery.js +128 -0
  68. package/dist/tools/codequery.js.map +1 -0
  69. package/dist/tools/codesearch.d.ts +8 -0
  70. package/dist/tools/codesearch.d.ts.map +1 -0
  71. package/dist/tools/codesearch.js +101 -0
  72. package/dist/tools/codesearch.js.map +1 -0
  73. package/dist/tools/file_detail.d.ts +9 -0
  74. package/dist/tools/file_detail.d.ts.map +1 -0
  75. package/dist/tools/file_detail.js +125 -0
  76. package/dist/tools/file_detail.js.map +1 -0
  77. package/dist/tools/fix.d.ts +25 -0
  78. package/dist/tools/fix.d.ts.map +1 -0
  79. package/dist/tools/fix.js +257 -0
  80. package/dist/tools/fix.js.map +1 -0
  81. package/dist/tools/hotspots.d.ts +9 -0
  82. package/dist/tools/hotspots.d.ts.map +1 -0
  83. package/dist/tools/hotspots.js +107 -0
  84. package/dist/tools/hotspots.js.map +1 -0
  85. package/dist/tools/impact.d.ts +14 -0
  86. package/dist/tools/impact.d.ts.map +1 -0
  87. package/dist/tools/impact.js +160 -0
  88. package/dist/tools/impact.js.map +1 -0
  89. package/dist/tools/orphan.d.ts +9 -0
  90. package/dist/tools/orphan.d.ts.map +1 -0
  91. package/dist/tools/orphan.js +124 -0
  92. package/dist/tools/orphan.js.map +1 -0
  93. package/dist/tools/overview.d.ts +9 -0
  94. package/dist/tools/overview.d.ts.map +1 -0
  95. package/dist/tools/overview.js +137 -0
  96. package/dist/tools/overview.js.map +1 -0
  97. package/dist/tools/ready.d.ts +18 -0
  98. package/dist/tools/ready.d.ts.map +1 -0
  99. package/dist/tools/ready.js +145 -0
  100. package/dist/tools/ready.js.map +1 -0
  101. package/dist/tools/refs.d.ts +9 -0
  102. package/dist/tools/refs.d.ts.map +1 -0
  103. package/dist/tools/refs.js +129 -0
  104. package/dist/tools/refs.js.map +1 -0
  105. package/dist/tools/routes.d.ts +8 -0
  106. package/dist/tools/routes.d.ts.map +1 -0
  107. package/dist/tools/routes.js +83 -0
  108. package/dist/tools/routes.js.map +1 -0
  109. package/dist/tools/state_map.d.ts +8 -0
  110. package/dist/tools/state_map.d.ts.map +1 -0
  111. package/dist/tools/state_map.js +95 -0
  112. package/dist/tools/state_map.js.map +1 -0
  113. package/dist/tools/symbol.d.ts +9 -0
  114. package/dist/tools/symbol.d.ts.map +1 -0
  115. package/dist/tools/symbol.js +84 -0
  116. package/dist/tools/symbol.js.map +1 -0
  117. package/dist/tools/verify.d.ts +24 -0
  118. package/dist/tools/verify.d.ts.map +1 -0
  119. package/dist/tools/verify.js +212 -0
  120. package/dist/tools/verify.js.map +1 -0
  121. package/package.json +70 -0
@@ -0,0 +1,107 @@
1
+ import { scanProject } from "../core/scanner.js";
2
+ export function registerHotspots(pi) {
3
+ pi.registerTool({
4
+ name: "shazam_hotspots",
5
+ label: "Complexity Hotspots",
6
+ description: `\
7
+ Call to find complexity hotspots: files ranked by (symbol density ×
8
+ PageRank score). The top 5 results are the files where bugs are most
9
+ expensive — these files have the highest incoming dependency weight,
10
+ meaning changes here cascade into the largest blast radius.
11
+
12
+ Use this to decide where to focus code review, where to write tests
13
+ first, and which files a new developer should read to understand the
14
+ project's core.
15
+
16
+ Scenario: code review prioritization. Deciding which tests to write
17
+ next. Understanding where a new team member should start reading.
18
+ Triaging bug reports (is the affected file a hotspot?).`,
19
+ parameters: pi.typebox.Object({
20
+ topN: pi.typebox.Optional(pi.typebox.Number()),
21
+ json: pi.typebox.Optional(pi.typebox.Boolean()),
22
+ }),
23
+ async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
24
+ const json = params.json ?? false;
25
+ const graph = scanProject(".");
26
+ const topN = params.topN ?? 10;
27
+ const result = executeHotspots(graph, topN);
28
+ return {
29
+ content: [
30
+ {
31
+ type: "text",
32
+ text: json
33
+ ? executeHotspotsJson(graph, topN)
34
+ : result,
35
+ },
36
+ ],
37
+ };
38
+ },
39
+ });
40
+ }
41
+ export function executeHotspots(graph, topN = 10) {
42
+ const hotspots = computeHotspots(graph, topN);
43
+ const lines = [];
44
+ lines.push(`## Complexity Hotspots (Top ${topN})`);
45
+ lines.push("");
46
+ lines.push("Ranked by symbol density × PageRank score.");
47
+ lines.push("");
48
+ for (let i = 0; i < hotspots.length; i++) {
49
+ const h = hotspots[i];
50
+ lines.push(`${i + 1}. \`${h.file}\` — score: ${h.hotspotScore.toFixed(2)}`);
51
+ lines.push(` ${h.symbolCount} symbols | PageRank: ${h.totalPagerank.toFixed(2)} | in:${h.incomingRefs} out:${h.outgoingRefs}`);
52
+ lines.push("");
53
+ }
54
+ return lines.join("\n");
55
+ }
56
+ export function executeHotspotsJson(graph, topN) {
57
+ const hotspots = computeHotspots(graph, topN);
58
+ return JSON.stringify({
59
+ schema_version: "1.0",
60
+ command: "hotspots",
61
+ status: "ok",
62
+ result: {
63
+ hotspots: hotspots.map((h) => ({
64
+ file: h.file,
65
+ symbolCount: h.symbolCount,
66
+ totalPagerank: Number(h.totalPagerank.toFixed(4)),
67
+ incomingRefs: h.incomingRefs,
68
+ outgoingRefs: h.outgoingRefs,
69
+ hotspotScore: Number(h.hotspotScore.toFixed(2)),
70
+ })),
71
+ },
72
+ });
73
+ }
74
+ function computeHotspots(graph, topN) {
75
+ const fileStats = new Map();
76
+ for (const [file, symIds] of graph.fileSymbols) {
77
+ let totalPR = 0;
78
+ let incoming = 0;
79
+ let outgoing = 0;
80
+ for (const id of symIds) {
81
+ const sym = graph.symbols.get(id);
82
+ if (sym) {
83
+ totalPR += sym.pagerank;
84
+ }
85
+ const inc = graph.incoming.get(id);
86
+ if (inc)
87
+ incoming += inc.length;
88
+ const out = graph.outgoing.get(id);
89
+ if (out)
90
+ outgoing += out.length;
91
+ }
92
+ // Hotspot score = symbolCount * totalPagerank (normalized)
93
+ const hotspotScore = symIds.length * totalPR;
94
+ fileStats.set(file, {
95
+ file,
96
+ symbolCount: symIds.length,
97
+ totalPagerank: totalPR,
98
+ incomingRefs: incoming,
99
+ outgoingRefs: outgoing,
100
+ hotspotScore,
101
+ });
102
+ }
103
+ return [...fileStats.values()]
104
+ .sort((a, b) => b.hotspotScore - a.hotspotScore)
105
+ .slice(0, topN);
106
+ }
107
+ //# sourceMappingURL=hotspots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hotspots.js","sourceRoot":"","sources":["../../tools/hotspots.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * pi-shazam tools/impact — Change blast radius analysis.
3
+ */
4
+ import type { ExtensionAPI } from "../types/pi-extension.js";
5
+ import type { RepoGraph } from "../core/graph.js";
6
+ export declare function registerImpact(pi: ExtensionAPI): void;
7
+ interface ImpactOptions {
8
+ withSymbols: boolean;
9
+ compact: boolean;
10
+ }
11
+ export declare function executeImpact(graph: RepoGraph, files: string[], opts?: ImpactOptions): string;
12
+ export declare function executeImpactJson(graph: RepoGraph, files: string[]): string;
13
+ export {};
14
+ //# sourceMappingURL=impact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.d.ts","sourceRoot":"","sources":["../../tools/impact.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAU,MAAM,kBAAkB,CAAC;AAG1D,wBAAgB,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAyCrD;AAED,UAAU,aAAa;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,aAAa,CAC5B,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,GAAE,aAAsD,GAC1D,MAAM,CA4FR;AAED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EAAE,GACb,MAAM,CAsCR"}
@@ -0,0 +1,160 @@
1
+ import { scanProject } from "../core/scanner.js";
2
+ export function registerImpact(pi) {
3
+ pi.registerTool({
4
+ name: "shazam_impact",
5
+ label: "Change Impact Analysis",
6
+ description: `\
7
+ MUST call before editing 2+ files or any shared/exported module.
8
+ Returns: exact list of files affected by planned changes, symbols at
9
+ risk, test files that need re-running. Also surfaces untested code
10
+ paths in the blast zone. Skipping this = guessing which tests to run
11
+ and which callers to update.
12
+
13
+ Scenario: refactoring. Adding a parameter to a shared function.
14
+ Changing a type definition. Before any PR that touches >1 file.
15
+
16
+ Pass --with-symbols for per-symbol risk breakdown. Pass --compact for
17
+ concise output (file names only). Supports multiple --files.`,
18
+ parameters: pi.typebox.Object({
19
+ files: pi.typebox.Array(pi.typebox.String()),
20
+ withSymbols: pi.typebox.Optional(pi.typebox.Boolean()),
21
+ compact: pi.typebox.Optional(pi.typebox.Boolean()),
22
+ json: pi.typebox.Optional(pi.typebox.Boolean()),
23
+ }),
24
+ async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
25
+ const json = params.json ?? false;
26
+ const graph = scanProject(".");
27
+ const result = executeImpact(graph, params.files, {
28
+ withSymbols: params.withSymbols ?? false,
29
+ compact: params.compact ?? false,
30
+ });
31
+ return {
32
+ content: [
33
+ {
34
+ type: "text",
35
+ text: json
36
+ ? executeImpactJson(graph, params.files)
37
+ : result,
38
+ },
39
+ ],
40
+ };
41
+ },
42
+ });
43
+ }
44
+ export function executeImpact(graph, files, opts = { withSymbols: false, compact: false }) {
45
+ const affectedFiles = new Set();
46
+ const affectedSymbols = [];
47
+ // For each file, find its symbols and trace outgoing edges
48
+ for (const file of files) {
49
+ affectedFiles.add(file);
50
+ const symIds = graph.fileSymbols.get(file) || [];
51
+ // Trace one level outward: what calls/imports symbols from this file?
52
+ for (const id of symIds) {
53
+ const incoming = graph.incoming.get(id);
54
+ if (incoming) {
55
+ for (const edge of incoming) {
56
+ const callerSym = graph.symbols.get(edge.source);
57
+ if (callerSym && !files.includes(callerSym.file)) {
58
+ affectedFiles.add(callerSym.file);
59
+ if (opts.withSymbols) {
60
+ affectedSymbols.push(callerSym);
61
+ }
62
+ }
63
+ }
64
+ }
65
+ // Also: what does this file's symbols depend on?
66
+ const outgoing = graph.outgoing.get(id);
67
+ if (outgoing) {
68
+ for (const edge of outgoing) {
69
+ const calleeSym = graph.symbols.get(edge.target);
70
+ if (calleeSym && !files.includes(calleeSym.file)) {
71
+ affectedFiles.add(calleeSym.file);
72
+ if (opts.withSymbols) {
73
+ affectedSymbols.push(calleeSym);
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ if (opts.compact) {
81
+ return [...affectedFiles]
82
+ .filter((f) => !files.includes(f))
83
+ .sort()
84
+ .join("\n");
85
+ }
86
+ const lines = [];
87
+ lines.push("## Impact Analysis");
88
+ lines.push("");
89
+ lines.push(`Target files: ${files.join(", ")}`);
90
+ lines.push(`Affected files: ${affectedFiles.size - files.length}`);
91
+ lines.push("");
92
+ if (affectedFiles.size > files.length) {
93
+ lines.push("### Affected Files");
94
+ for (const f of [...affectedFiles].sort()) {
95
+ if (files.includes(f))
96
+ continue;
97
+ lines.push(`- \`${f}\``);
98
+ }
99
+ }
100
+ if (opts.withSymbols && affectedSymbols.length > 0) {
101
+ lines.push("");
102
+ lines.push("### Affected Symbols");
103
+ for (const sym of affectedSymbols.slice(0, 30)) {
104
+ lines.push(`- ${sym.kind} \`${sym.name}\` — ${sym.file}:${sym.line}`);
105
+ }
106
+ if (affectedSymbols.length > 30) {
107
+ lines.push(` ... and ${affectedSymbols.length - 30} more`);
108
+ }
109
+ }
110
+ // Identify test files in affected set
111
+ const testFiles = [...affectedFiles].filter((f) => f.includes(".test.") ||
112
+ f.includes(".spec.") ||
113
+ f.includes("__tests__") ||
114
+ f.startsWith("tests/"));
115
+ if (testFiles.length > 0) {
116
+ lines.push("");
117
+ lines.push("### Affected Test Files (must re-run)");
118
+ for (const f of testFiles) {
119
+ lines.push(`- \`${f}\``);
120
+ }
121
+ }
122
+ return lines.join("\n");
123
+ }
124
+ export function executeImpactJson(graph, files) {
125
+ const affectedFiles = new Set();
126
+ const affectedSymbols = [];
127
+ for (const file of files) {
128
+ const symIds = graph.fileSymbols.get(file) || [];
129
+ for (const id of symIds) {
130
+ const incoming = graph.incoming.get(id);
131
+ if (incoming) {
132
+ for (const edge of incoming) {
133
+ const callerSym = graph.symbols.get(edge.source);
134
+ if (callerSym && !files.includes(callerSym.file)) {
135
+ affectedFiles.add(callerSym.file);
136
+ affectedSymbols.push(callerSym);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ return JSON.stringify({
143
+ schema_version: "1.0",
144
+ command: "impact",
145
+ status: "ok",
146
+ result: {
147
+ targetFiles: files,
148
+ affectedFileCount: affectedFiles.size - files.length,
149
+ affectedFiles: [...affectedFiles].filter((f) => !files.includes(f)).sort(),
150
+ affectedSymbols: affectedSymbols.slice(0, 50).map((s) => ({
151
+ id: s.id,
152
+ name: s.name,
153
+ kind: s.kind,
154
+ file: s.file,
155
+ line: s.line,
156
+ })),
157
+ },
158
+ });
159
+ }
160
+ //# sourceMappingURL=impact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.js","sourceRoot":"","sources":["../../tools/impact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * pi-shazam tools/orphan — Dead code detection.
3
+ */
4
+ import type { ExtensionAPI } from "../types/pi-extension.js";
5
+ import type { RepoGraph } from "../core/graph.js";
6
+ export declare function registerOrphan(pi: ExtensionAPI): void;
7
+ export declare function executeOrphan(graph: RepoGraph, file?: string, minConfidence?: number): string;
8
+ export declare function executeOrphanJson(graph: RepoGraph, file?: string, minConfidence?: number): string;
9
+ //# sourceMappingURL=orphan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orphan.d.ts","sourceRoot":"","sources":["../../tools/orphan.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAU,MAAM,kBAAkB,CAAC;AAG1D,wBAAgB,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2CrD;AAQD,wBAAgB,aAAa,CAC5B,KAAK,EAAE,SAAS,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,aAAa,GAAE,MAAW,GACxB,MAAM,CAqCR;AAED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,SAAS,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,aAAa,GAAE,MAAW,GACxB,MAAM,CAmBR"}
@@ -0,0 +1,124 @@
1
+ import { scanProject } from "../core/scanner.js";
2
+ export function registerOrphan(pi) {
3
+ pi.registerTool({
4
+ name: "shazam_orphan",
5
+ label: "Dead Code Detection",
6
+ description: `\
7
+ Call to find dead code: symbols with zero incoming references across
8
+ the entire project. Confidence ≥ 70 means LIKELY safe to delete.
9
+ Confidence < 70 means check for dynamic references (string dispatch,
10
+ reflection, macros, event listeners, test-only usage).
11
+
12
+ MUST call shazam_refs on each candidate before actual deletion to
13
+ confirm zero references. A "dead" function that's called via
14
+ getattr/dlsym/Reflect is still live — orphan detection cannot see
15
+ dynamic dispatch.
16
+
17
+ Scenario: cleaning up unused code. Finding abandoned modules. Before a
18
+ major refactor to identify removable surface area. After removing a
19
+ feature to find orphaned helpers.`,
20
+ parameters: pi.typebox.Object({
21
+ file: pi.typebox.Optional(pi.typebox.String()),
22
+ minConfidence: pi.typebox.Optional(pi.typebox.Number()),
23
+ json: pi.typebox.Optional(pi.typebox.Boolean()),
24
+ }),
25
+ async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
26
+ const json = params.json ?? false;
27
+ const graph = scanProject(".");
28
+ const result = executeOrphan(graph, params.file, params.minConfidence ?? 50);
29
+ return {
30
+ content: [
31
+ {
32
+ type: "text",
33
+ text: json
34
+ ? executeOrphanJson(graph, params.file, params.minConfidence ?? 50)
35
+ : result,
36
+ },
37
+ ],
38
+ };
39
+ },
40
+ });
41
+ }
42
+ export function executeOrphan(graph, file, minConfidence = 50) {
43
+ const candidates = findOrphans(graph, file, minConfidence);
44
+ if (candidates.length === 0) {
45
+ return "No orphan symbols detected.";
46
+ }
47
+ const lines = [];
48
+ lines.push(`## Orphan Symbols (${candidates.length} candidates, min confidence ${minConfidence}%)`);
49
+ lines.push("");
50
+ lines.push("Symbols with zero incoming references. Confidence ≥ 70 = likely safe to delete.");
51
+ lines.push("ALWAYS verify with shazam_refs before actual deletion.");
52
+ lines.push("");
53
+ // Group by file
54
+ const byFile = new Map();
55
+ for (const c of candidates) {
56
+ const arr = byFile.get(c.symbol.file) || [];
57
+ arr.push(c);
58
+ byFile.set(c.symbol.file, arr);
59
+ }
60
+ for (const [f, cands] of [...byFile.entries()].sort()) {
61
+ lines.push(`### ${f}`);
62
+ for (const c of cands) {
63
+ lines.push(`- ${c.symbol.kind} \`${c.symbol.name}\` L${c.symbol.line} — confidence ${c.confidence}% (${c.reason})`);
64
+ }
65
+ lines.push("");
66
+ }
67
+ return lines.join("\n").trim();
68
+ }
69
+ export function executeOrphanJson(graph, file, minConfidence = 50) {
70
+ const candidates = findOrphans(graph, file, minConfidence);
71
+ return JSON.stringify({
72
+ schema_version: "1.0",
73
+ command: "orphan",
74
+ status: "ok",
75
+ result: {
76
+ count: candidates.length,
77
+ candidates: candidates.map((c) => ({
78
+ id: c.symbol.id,
79
+ name: c.symbol.name,
80
+ kind: c.symbol.kind,
81
+ file: c.symbol.file,
82
+ line: c.symbol.line,
83
+ confidence: c.confidence,
84
+ reason: c.reason,
85
+ })),
86
+ },
87
+ });
88
+ }
89
+ function findOrphans(graph, file, minConfidence = 50) {
90
+ const candidates = [];
91
+ for (const sym of graph.symbols.values()) {
92
+ if (file && sym.file !== file)
93
+ continue;
94
+ const incoming = graph.incoming.get(sym.id);
95
+ const outgoing = graph.outgoing.get(sym.id);
96
+ const incCount = incoming ? incoming.length : 0;
97
+ if (incCount > 0)
98
+ continue; // Has references, not orphan
99
+ // Determine confidence based on visibility and outgoing edges
100
+ let confidence = 0;
101
+ let reason = "";
102
+ if (sym.visibility === "private") {
103
+ confidence = 90;
104
+ reason = "private symbol with no incoming references";
105
+ }
106
+ else if (sym.name.startsWith("_")) {
107
+ confidence = 85;
108
+ reason = "underscore-prefixed with no incoming references";
109
+ }
110
+ else if (!outgoing || outgoing.length === 0) {
111
+ confidence = 70;
112
+ reason = "no incoming or outgoing references; possibly dead";
113
+ }
114
+ else {
115
+ confidence = 50;
116
+ reason = "has outgoing refs but no incoming; may be test-only or entry point";
117
+ }
118
+ if (confidence >= minConfidence) {
119
+ candidates.push({ symbol: sym, confidence, reason });
120
+ }
121
+ }
122
+ return candidates.sort((a, b) => b.confidence - a.confidence);
123
+ }
124
+ //# sourceMappingURL=orphan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orphan.js","sourceRoot":"","sources":["../../tools/orphan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * pi-shazam tools/overview — Project structure summary.
3
+ */
4
+ import type { ExtensionAPI } from "../types/pi-extension.js";
5
+ import type { RepoGraph } from "../core/graph.js";
6
+ export declare function registerOverview(pi: ExtensionAPI): void;
7
+ export declare function executeOverview(graph: RepoGraph, _projectRoot: string): string;
8
+ export declare function executeOverviewJson(graph: RepoGraph, projectRoot: string): string;
9
+ //# sourceMappingURL=overview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../tools/overview.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAkCvD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CA2F9E;AAED,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,MAAM,GACjB,MAAM,CA6BR"}
@@ -0,0 +1,137 @@
1
+ import { scanProject } from "../core/scanner.js";
2
+ export function registerOverview(pi) {
3
+ pi.registerTool({
4
+ name: "shazam_overview",
5
+ label: "Project Overview",
6
+ description: `\
7
+ MUST call before touching ANY code in an unfamiliar project or repo.
8
+ Returns: module dependency map, top-10 highest-PageRank files (the
9
+ "spine" of the codebase), entry points, and suggested reading order.
10
+ Skipping this = navigating blind — you WILL miss cross-module ripple
11
+ effects and waste turns on dead-end reads.
12
+
13
+ Scenario: first turn in a new repo. After git clone. After switching
14
+ to an unfamiliar project directory.
15
+
16
+ Output: plain text summary by default. Pass { json: true } for
17
+ structured output with file lists and PageRank scores.`,
18
+ parameters: pi.typebox.Object({
19
+ json: pi.typebox.Optional(pi.typebox.Boolean()),
20
+ }),
21
+ async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
22
+ const json = params.json ?? false;
23
+ const graph = scanProject(".");
24
+ return {
25
+ content: [
26
+ {
27
+ type: "text",
28
+ text: json
29
+ ? executeOverviewJson(graph, ".")
30
+ : executeOverview(graph, "."),
31
+ },
32
+ ],
33
+ };
34
+ },
35
+ });
36
+ }
37
+ export function executeOverview(graph, _projectRoot) {
38
+ const lines = [];
39
+ // Summary stats
40
+ lines.push("## Project Overview");
41
+ lines.push("");
42
+ lines.push(`${graph.symbols.size} symbols across ${graph.fileSymbols.size} files`);
43
+ // Calculate per-file symbol counts and aggregate PageRank
44
+ const fileStats = new Map();
45
+ for (const [file, symIds] of graph.fileSymbols) {
46
+ let totalPR = 0;
47
+ let topPR = 0;
48
+ let topName = "";
49
+ for (const id of symIds) {
50
+ const sym = graph.symbols.get(id);
51
+ if (sym) {
52
+ totalPR += sym.pagerank;
53
+ if (sym.pagerank > topPR) {
54
+ topPR = sym.pagerank;
55
+ topName = sym.name;
56
+ }
57
+ }
58
+ }
59
+ fileStats.set(file, { count: symIds.length, pagerank: totalPR, topSym: topName });
60
+ }
61
+ // Top files by PageRank
62
+ const topFiles = [...fileStats.entries()]
63
+ .sort((a, b) => b[1].pagerank - a[1].pagerank)
64
+ .slice(0, 10);
65
+ lines.push("");
66
+ lines.push("### Top 10 Files by PageRank");
67
+ lines.push("");
68
+ for (let i = 0; i < topFiles.length; i++) {
69
+ const [file, stats] = topFiles[i];
70
+ lines.push(`${i + 1}. \`${file}\` — ${stats.count} symbols, PageRank ${stats.pagerank.toFixed(2)}, top symbol: ${stats.topSym}`);
71
+ }
72
+ // Entry points (files with high PageRank and export visibility)
73
+ const entryPoints = [...graph.symbols.values()]
74
+ .filter((s) => s.visibility === "exported" && s.pagerank > 0.01)
75
+ .sort((a, b) => b.pagerank - a.pagerank)
76
+ .slice(0, 10);
77
+ if (entryPoints.length > 0) {
78
+ lines.push("");
79
+ lines.push("### Entry Points");
80
+ lines.push("");
81
+ for (const sym of entryPoints) {
82
+ lines.push(`- ${sym.kind} \`${sym.name}\` — ${sym.file}:${sym.line} (PR ${sym.pagerank.toFixed(3)})`);
83
+ }
84
+ }
85
+ // Module dependency summary
86
+ lines.push("");
87
+ lines.push("### Module Structure");
88
+ lines.push("");
89
+ const dirs = new Set();
90
+ for (const file of graph.fileSymbols.keys()) {
91
+ const dir = file.includes("/") ? file.split("/")[0] : "(root)";
92
+ dirs.add(dir);
93
+ }
94
+ const sortedDirs = [...dirs].sort();
95
+ for (const dir of sortedDirs) {
96
+ const dirFiles = [...graph.fileSymbols.keys()].filter((f) => f.startsWith(dir + "/") || (dir === "(root)" && !f.includes("/")));
97
+ lines.push(`- \`${dir}/\` — ${dirFiles.length} files`);
98
+ }
99
+ lines.push("");
100
+ lines.push("### Suggested Reading Order");
101
+ lines.push("");
102
+ if (topFiles.length > 0) {
103
+ for (let i = 0; i < Math.min(5, topFiles.length); i++) {
104
+ lines.push(`${i + 1}. Start with \`${topFiles[i][0]}\``);
105
+ }
106
+ }
107
+ return lines.join("\n");
108
+ }
109
+ export function executeOverviewJson(graph, projectRoot) {
110
+ const fileStats = new Map();
111
+ for (const [file, symIds] of graph.fileSymbols) {
112
+ let totalPR = 0;
113
+ for (const id of symIds) {
114
+ totalPR += graph.symbols.get(id)?.pagerank ?? 0;
115
+ }
116
+ fileStats.set(file, { count: symIds.length, pagerank: totalPR });
117
+ }
118
+ const topFiles = [...fileStats.entries()]
119
+ .sort((a, b) => b[1].pagerank - a[1].pagerank)
120
+ .slice(0, 10);
121
+ return JSON.stringify({
122
+ schema_version: "1.0",
123
+ command: "overview",
124
+ project: projectRoot,
125
+ status: "ok",
126
+ result: {
127
+ totalSymbols: graph.symbols.size,
128
+ totalFiles: graph.fileSymbols.size,
129
+ topFiles: topFiles.map(([file, stats]) => ({
130
+ file,
131
+ symbolCount: stats.count,
132
+ pagerank: Number(stats.pagerank.toFixed(4)),
133
+ })),
134
+ },
135
+ });
136
+ }
137
+ //# sourceMappingURL=overview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.js","sourceRoot":"","sources":["../../tools/overview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * pi-shazam tools/ready — Pre-commit readiness check.
3
+ *
4
+ * Composes verify + check into a single pre-commit gate.
5
+ * This is the FINAL GATE before shipping code.
6
+ */
7
+ import type { ExtensionAPI } from "../types/pi-extension.js";
8
+ import type { RepoGraph } from "../core/graph.js";
9
+ export declare function registerReady(pi: ExtensionAPI): void;
10
+ /**
11
+ * Run pre-commit readiness check, composing verify + check results.
12
+ */
13
+ export declare function executeReady(graph: RepoGraph, projectRoot: string): string;
14
+ /**
15
+ * Run readiness check and return structured JSON.
16
+ */
17
+ export declare function executeReadyJson(graph: RepoGraph, projectRoot: string): string;
18
+ //# sourceMappingURL=ready.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ready.d.ts","sourceRoot":"","sources":["../../tools/ready.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAuBlD,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAwCpD;AAID;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAgE1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,MAAM,GACjB,MAAM,CAwCR"}