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,8 @@
1
+ /**
2
+ * pi-shazam tools/codesearch — BM25 symbol search.
3
+ */
4
+ import type { ExtensionAPI } from "../types/pi-extension.js";
5
+ import type { RepoGraph, Symbol } from "../core/graph.js";
6
+ export declare function registerCodesearch(pi: ExtensionAPI): void;
7
+ export declare function executeCodesearch(graph: RepoGraph, query: string, topN?: number): Symbol[];
8
+ //# sourceMappingURL=codesearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codesearch.d.ts","sourceRoot":"","sources":["../../tools/codesearch.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG1D,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAyCzD;AAED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,GACX,MAAM,EAAE,CAsCV"}
@@ -0,0 +1,101 @@
1
+ import { scanProject } from "../core/scanner.js";
2
+ export function registerCodesearch(pi) {
3
+ pi.registerTool({
4
+ name: "shazam_codesearch",
5
+ label: "Code Search (BM25)",
6
+ description: `\
7
+ Call to search for symbols by keyword across the entire project using
8
+ BM25 relevance ranking with synonym expansion. Returns ranked results:
9
+ file:line, symbol name, kind, and snippet.
10
+
11
+ More semantic than grep — understands camelCase/snake_case tokenization
12
+ and ranks by PageRank-weighted relevance, not just substring match.
13
+
14
+ Scenario: finding error handling patterns. Locating all database query
15
+ functions. Searching for "auth" across a multi-language codebase.
16
+ Finding usage of a deprecated API before removing it.`,
17
+ parameters: pi.typebox.Object({
18
+ query: pi.typebox.String(),
19
+ topN: pi.typebox.Optional(pi.typebox.Number()),
20
+ json: pi.typebox.Optional(pi.typebox.Boolean()),
21
+ }),
22
+ async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
23
+ const json = params.json ?? false;
24
+ const graph = scanProject(".");
25
+ const result = executeCodesearch(graph, params.query, params.topN);
26
+ return {
27
+ content: [
28
+ {
29
+ type: "text",
30
+ text: json
31
+ ? JSON.stringify({
32
+ schema_version: "1.0",
33
+ command: "codesearch",
34
+ status: "ok",
35
+ result: { query: params.query, results: result.length },
36
+ })
37
+ : formatCodesearchResult(result, params.query),
38
+ },
39
+ ],
40
+ };
41
+ },
42
+ });
43
+ }
44
+ export function executeCodesearch(graph, query, topN) {
45
+ const limit = topN ?? 20;
46
+ const lower = query.toLowerCase();
47
+ const tokens = tokenize(query);
48
+ const scored = [];
49
+ for (const sym of graph.symbols.values()) {
50
+ const nameLower = sym.name.toLowerCase();
51
+ let score = 0;
52
+ // Exact match
53
+ if (nameLower === lower) {
54
+ score += 100;
55
+ }
56
+ // Substring match
57
+ if (nameLower.includes(lower)) {
58
+ score += 30;
59
+ }
60
+ // Token matching (camelCase/snake_case)
61
+ for (const token of tokens) {
62
+ if (nameLower.includes(token)) {
63
+ score += 10;
64
+ }
65
+ }
66
+ // PageRank boost
67
+ score += sym.pagerank * 50;
68
+ if (score > 0) {
69
+ scored.push({ sym, score });
70
+ }
71
+ }
72
+ scored.sort((a, b) => b.score - a.score);
73
+ return scored.slice(0, limit).map((s) => s.sym);
74
+ }
75
+ function tokenize(query) {
76
+ const tokens = [];
77
+ // Split camelCase
78
+ const camelTokens = query.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
79
+ // Split snake_case and other separators
80
+ const parts = camelTokens.split(/[\s_\-.:/]+/);
81
+ for (const p of parts) {
82
+ if (p.length >= 2)
83
+ tokens.push(p);
84
+ }
85
+ return tokens;
86
+ }
87
+ function formatCodesearchResult(results, query) {
88
+ if (results.length === 0) {
89
+ return `No symbols found for query: "${query}"`;
90
+ }
91
+ const lines = [
92
+ `## Code Search: "${query}" (${results.length} results)`,
93
+ "",
94
+ ];
95
+ for (let i = 0; i < results.length; i++) {
96
+ const sym = results[i];
97
+ lines.push(`${i + 1}. ${sym.kind} \`${sym.name}\` — ${sym.file}:${sym.line} (PR ${sym.pagerank.toFixed(3)})`);
98
+ }
99
+ return lines.join("\n");
100
+ }
101
+ //# sourceMappingURL=codesearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codesearch.js","sourceRoot":"","sources":["../../tools/codesearch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * pi-shazam tools/file_detail — Single file deep analysis.
3
+ */
4
+ import type { ExtensionAPI } from "../types/pi-extension.js";
5
+ import type { RepoGraph } from "../core/graph.js";
6
+ export declare function registerFileDetail(pi: ExtensionAPI): void;
7
+ export declare function executeFileDetail(graph: RepoGraph, file: string): string;
8
+ export declare function executeFileDetailJson(graph: RepoGraph, file: string): string;
9
+ //# sourceMappingURL=file_detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file_detail.d.ts","sourceRoot":"","sources":["../../tools/file_detail.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,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAsCzD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAmExE;AAED,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,MAAM,GACV,MAAM,CA2BR"}
@@ -0,0 +1,125 @@
1
+ import { scanProject } from "../core/scanner.js";
2
+ export function registerFileDetail(pi) {
3
+ pi.registerTool({
4
+ name: "shazam_file_detail",
5
+ label: "File Deep Analysis",
6
+ description: `\
7
+ Call to get a complete structural breakdown of a single file: all
8
+ symbols (functions, classes, types, constants) with signatures,
9
+ visibility, line ranges, incoming call count, and PageRank score.
10
+ Also returns LSP symbol tree when available.
11
+
12
+ MUST call before making edits to an unfamiliar file — reading the raw
13
+ file shows you syntax, this shows you STRUCTURE. You will spot
14
+ dependencies and side effects that raw reading misses.
15
+
16
+ Scenario: before editing a file for the first time. Before refactoring
17
+ a large file. When deciding where to add a new function (PageRank shows
18
+ you the file's "gravity"). After someone else's PR to understand what
19
+ changed structurally.`,
20
+ parameters: pi.typebox.Object({
21
+ file: pi.typebox.String(),
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 = executeFileDetail(graph, params.file);
28
+ return {
29
+ content: [
30
+ {
31
+ type: "text",
32
+ text: json
33
+ ? executeFileDetailJson(graph, params.file)
34
+ : result,
35
+ },
36
+ ],
37
+ };
38
+ },
39
+ });
40
+ }
41
+ export function executeFileDetail(graph, file) {
42
+ const symIds = graph.fileSymbols.get(file);
43
+ if (!symIds || symIds.length === 0) {
44
+ return `File not found in graph or has no symbols: ${file}`;
45
+ }
46
+ const symbols = symIds
47
+ .map((id) => graph.symbols.get(id))
48
+ .filter((s) => s !== undefined)
49
+ .sort((a, b) => a.line - b.line || a.col - b.col);
50
+ const lines = [];
51
+ lines.push(`## File: ${file} (${symbols.length} symbols)`);
52
+ lines.push("");
53
+ // Summary stats
54
+ const byKind = new Map();
55
+ let totalPR = 0;
56
+ let totalIncoming = 0;
57
+ let totalOutgoing = 0;
58
+ for (const sym of symbols) {
59
+ byKind.set(sym.kind, (byKind.get(sym.kind) || 0) + 1);
60
+ totalPR += sym.pagerank;
61
+ const inc = graph.incoming.get(sym.id);
62
+ const out = graph.outgoing.get(sym.id);
63
+ totalIncoming += inc ? inc.length : 0;
64
+ totalOutgoing += out ? out.length : 0;
65
+ }
66
+ lines.push("### Summary");
67
+ lines.push(`Total PageRank: ${totalPR.toFixed(4)}`);
68
+ lines.push(`Incoming refs: ${totalIncoming}`);
69
+ lines.push(`Outgoing refs: ${totalOutgoing}`);
70
+ lines.push("");
71
+ lines.push("Kinds: " +
72
+ [...byKind.entries()]
73
+ .map(([k, v]) => `${v} ${k}`)
74
+ .join(", "));
75
+ lines.push("");
76
+ // Symbol list
77
+ lines.push("### Symbols");
78
+ lines.push("");
79
+ for (const sym of symbols) {
80
+ const inc = graph.incoming.get(sym.id);
81
+ const out = graph.outgoing.get(sym.id);
82
+ const incCount = inc ? inc.length : 0;
83
+ const outCount = out ? out.length : 0;
84
+ lines.push(`- ${sym.kind} \`${sym.name}\` L${sym.line}-${sym.endLine} [${sym.visibility}] PR ${sym.pagerank.toFixed(3)} | in:${incCount} out:${outCount}`);
85
+ lines.push(` ${sym.signature.slice(0, 100)}`);
86
+ }
87
+ // File-level imports
88
+ const fileImports = graph.fileImports.get(file);
89
+ if (fileImports && fileImports.length > 0) {
90
+ lines.push("");
91
+ lines.push("### Imports");
92
+ for (const imp of fileImports.slice(0, 20)) {
93
+ lines.push(`- ${imp}`);
94
+ }
95
+ }
96
+ return lines.join("\n");
97
+ }
98
+ export function executeFileDetailJson(graph, file) {
99
+ const symIds = graph.fileSymbols.get(file) || [];
100
+ const symbols = symIds
101
+ .map((id) => graph.symbols.get(id))
102
+ .filter((s) => s !== undefined);
103
+ return JSON.stringify({
104
+ schema_version: "1.0",
105
+ command: "file_detail",
106
+ status: "ok",
107
+ result: {
108
+ file,
109
+ symbolCount: symbols.length,
110
+ symbols: symbols.map((s) => ({
111
+ id: s.id,
112
+ name: s.name,
113
+ kind: s.kind,
114
+ line: s.line,
115
+ endLine: s.endLine,
116
+ visibility: s.visibility,
117
+ pagerank: Number(s.pagerank.toFixed(4)),
118
+ signature: s.signature,
119
+ incomingCount: (graph.incoming.get(s.id) || []).length,
120
+ outgoingCount: (graph.outgoing.get(s.id) || []).length,
121
+ })),
122
+ },
123
+ });
124
+ }
125
+ //# sourceMappingURL=file_detail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file_detail.js","sourceRoot":"","sources":["../../tools/file_detail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * pi-shazam tools/fix — Auto-fix lint/format.
3
+ *
4
+ * Scans source files for common format issues and offers fixes.
5
+ * In dry-run mode, previews what would change without modifying files.
6
+ * Supports nearest-wins formatter detection (prettier, biome, eslint, ruff, gofmt).
7
+ */
8
+ import type { ExtensionAPI } from "../types/pi-extension.js";
9
+ import type { RepoGraph } from "../core/graph.js";
10
+ export declare function registerFix(pi: ExtensionAPI): void;
11
+ export interface FixOptions {
12
+ /** Dry-run mode: preview changes without applying */
13
+ dryRun?: boolean;
14
+ /** Target specific file (omit for all files) */
15
+ file?: string;
16
+ }
17
+ /**
18
+ * Run format fix analysis. In dry-run mode (default), only reports issues.
19
+ */
20
+ export declare function executeFix(graph: RepoGraph, projectRoot: string, options?: FixOptions): string;
21
+ /**
22
+ * Run fix analysis and return structured JSON.
23
+ */
24
+ export declare function executeFixJson(graph: RepoGraph, projectRoot: string, options?: FixOptions): string;
25
+ //# sourceMappingURL=fix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../tools/fix.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAMlD,wBAAgB,WAAW,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA8ClD;AAID,MAAM,WAAW,UAAU;IAC1B,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAID;;GAEG;AACH,wBAAgB,UAAU,CACzB,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,UAAe,GACtB,MAAM,CAmER;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,UAAe,GACtB,MAAM,CAoBR"}
@@ -0,0 +1,257 @@
1
+ import { scanProject } from "../core/scanner.js";
2
+ import { readFileAdaptive } from "../core/encoding.js";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ export function registerFix(pi) {
6
+ pi.registerTool({
7
+ name: "shazam_fix",
8
+ label: "Auto-Fix Format & Lint",
9
+ description: `\
10
+ Call after shazam_verify or shazam_check reports format/lint errors.
11
+ Runs nearest-wins auto-fixers (prettier, biome, ruff, cargo fmt,
12
+ gofmt, eslint --fix). Modifies format ONLY — never touches logic.
13
+
14
+ Always run with --dry-run first to preview changes before applying.
15
+ After fixing, re-run shazam_verify to confirm clean.
16
+
17
+ Scenario: trailing whitespace. Import sorting. Indentation mismatches.
18
+ Line length violations after an edit. Mixed tabs/spaces. Missing
19
+ newlines at end of file.`,
20
+ parameters: pi.typebox.Object({
21
+ dryRun: pi.typebox.Optional(pi.typebox.Boolean()),
22
+ file: pi.typebox.Optional(pi.typebox.String()),
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 dryRun = params.dryRun ?? true; // default to dry-run for safety
28
+ const graph = scanProject(".");
29
+ if (json) {
30
+ return {
31
+ content: [
32
+ {
33
+ type: "text",
34
+ text: executeFixJson(graph, ".", { dryRun, file: params.file }),
35
+ },
36
+ ],
37
+ };
38
+ }
39
+ return {
40
+ content: [
41
+ {
42
+ type: "text",
43
+ text: executeFix(graph, ".", { dryRun, file: params.file }),
44
+ },
45
+ ],
46
+ };
47
+ },
48
+ });
49
+ }
50
+ // ── Execute functions (testable without Pi) ────────────────────────────────
51
+ /**
52
+ * Run format fix analysis. In dry-run mode (default), only reports issues.
53
+ */
54
+ export function executeFix(graph, projectRoot, options = {}) {
55
+ const dryRun = options.dryRun ?? true;
56
+ const lines = [];
57
+ lines.push("## Fix Results");
58
+ lines.push("");
59
+ lines.push(dryRun ? "**Mode: DRY RUN** (preview only, no changes applied)" : "**Mode: APPLY** (changes will be written)");
60
+ lines.push("");
61
+ // ── Detect available formatters ──────────────────────────────────────
62
+ const formatters = detectFormatters(projectRoot);
63
+ lines.push("### Detected Formatters");
64
+ if (formatters.length === 0) {
65
+ lines.push("No formatters detected in project config.");
66
+ }
67
+ else {
68
+ for (const fmt of formatters) {
69
+ lines.push(`- ${fmt}`);
70
+ }
71
+ }
72
+ lines.push("");
73
+ // ── Scan files for common issues ─────────────────────────────────────
74
+ const targetFiles = options.file
75
+ ? [options.file]
76
+ : [...graph.fileSymbols.keys()];
77
+ const issues = scanFormatIssues(projectRoot, targetFiles, graph);
78
+ lines.push("### Format Issues Found");
79
+ lines.push("");
80
+ if (issues.length === 0) {
81
+ lines.push("✅ No format issues detected.");
82
+ }
83
+ else {
84
+ lines.push(`Found ${issues.length} potential issue(s):`);
85
+ lines.push("");
86
+ for (const issue of issues.slice(0, 30)) {
87
+ lines.push(`- \`${issue.file}:${issue.line}\` — ${issue.kind}: ${issue.description}`);
88
+ }
89
+ if (issues.length > 30) {
90
+ lines.push(` ... and ${issues.length - 30} more`);
91
+ }
92
+ }
93
+ lines.push("");
94
+ // ── Recommendations ────────────────────────────────────────────────
95
+ if (issues.length > 0) {
96
+ lines.push("### Recommended Fix Commands");
97
+ lines.push("");
98
+ if (formatters.includes("prettier")) {
99
+ lines.push("- `npx prettier --write .`");
100
+ }
101
+ if (formatters.includes("eslint")) {
102
+ lines.push("- `npx eslint --fix .`");
103
+ }
104
+ if (formatters.length === 0) {
105
+ lines.push("- Install formatter: `npm install --save-dev prettier`");
106
+ lines.push("- Then run: `npx prettier --write .`");
107
+ }
108
+ }
109
+ if (dryRun) {
110
+ lines.push("");
111
+ lines.push("To apply fixes, call with `{ \"dryRun\": false }`.");
112
+ }
113
+ return lines.join("\n");
114
+ }
115
+ /**
116
+ * Run fix analysis and return structured JSON.
117
+ */
118
+ export function executeFixJson(graph, projectRoot, options = {}) {
119
+ const dryRun = options.dryRun ?? true;
120
+ const formatters = detectFormatters(projectRoot);
121
+ const targetFiles = options.file
122
+ ? [options.file]
123
+ : [...graph.fileSymbols.keys()];
124
+ const issues = scanFormatIssues(projectRoot, targetFiles, graph);
125
+ return JSON.stringify({
126
+ schema_version: "1.0",
127
+ command: "fix",
128
+ project: projectRoot,
129
+ status: "ok",
130
+ result: {
131
+ dryRun,
132
+ formatters,
133
+ issueCount: issues.length,
134
+ issues: issues.slice(0, 50),
135
+ },
136
+ });
137
+ }
138
+ /**
139
+ * Detect available formatters from project config files.
140
+ */
141
+ function detectFormatters(projectRoot) {
142
+ const formatters = [];
143
+ if (existsSync(join(projectRoot, ".prettierrc")) ||
144
+ existsSync(join(projectRoot, ".prettierrc.json")) ||
145
+ existsSync(join(projectRoot, ".prettierrc.js")) ||
146
+ existsSync(join(projectRoot, "prettier.config.js")) ||
147
+ existsSync(join(projectRoot, "prettier.config.mjs"))) {
148
+ formatters.push("prettier");
149
+ }
150
+ if (existsSync(join(projectRoot, ".eslintrc.js")) ||
151
+ existsSync(join(projectRoot, ".eslintrc.cjs")) ||
152
+ existsSync(join(projectRoot, ".eslintrc.json")) ||
153
+ existsSync(join(projectRoot, ".eslintrc.yaml")) ||
154
+ existsSync(join(projectRoot, ".eslintrc.yml")) ||
155
+ existsSync(join(projectRoot, "eslint.config.js")) ||
156
+ existsSync(join(projectRoot, "eslint.config.mjs"))) {
157
+ formatters.push("eslint");
158
+ }
159
+ if (existsSync(join(projectRoot, "biome.json")) ||
160
+ existsSync(join(projectRoot, "biome.jsonc"))) {
161
+ formatters.push("biome");
162
+ }
163
+ // Check package.json for config sections
164
+ try {
165
+ const pkgRaw = readFileSync(join(projectRoot, "package.json"), "utf-8");
166
+ const pkg = JSON.parse(pkgRaw);
167
+ if (pkg.prettier)
168
+ formatters.push("prettier");
169
+ if (pkg.eslintConfig)
170
+ formatters.push("eslint");
171
+ }
172
+ catch {
173
+ // package.json not found or invalid — continue
174
+ }
175
+ return [...new Set(formatters)];
176
+ }
177
+ /**
178
+ * Scan files for common formatting issues.
179
+ */
180
+ function scanFormatIssues(projectRoot, files, _graph) {
181
+ const issues = [];
182
+ for (const file of files.slice(0, 100)) {
183
+ const fullPath = join(projectRoot, file);
184
+ if (!existsSync(fullPath))
185
+ continue;
186
+ try {
187
+ const content = readFileAdaptive(fullPath);
188
+ const lines = content.split("\n");
189
+ for (let i = 0; i < lines.length; i++) {
190
+ const line = lines[i];
191
+ const lineNum = i + 1;
192
+ // Trailing whitespace
193
+ if (line && line !== line.trimEnd()) {
194
+ issues.push({
195
+ file,
196
+ line: lineNum,
197
+ kind: "trailing-whitespace",
198
+ description: "Line has trailing whitespace",
199
+ });
200
+ }
201
+ // Tab indentation (when project uses spaces)
202
+ if (file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".json")) {
203
+ if (line.startsWith("\t")) {
204
+ issues.push({
205
+ file,
206
+ line: lineNum,
207
+ kind: "tab-indent",
208
+ description: "Tab character used for indentation (use spaces)",
209
+ });
210
+ }
211
+ }
212
+ // Mixed tabs and spaces
213
+ if (line.includes("\t") && line.includes(" ")) {
214
+ issues.push({
215
+ file,
216
+ line: lineNum,
217
+ kind: "mixed-indent",
218
+ description: "Mixed tabs and spaces on same line",
219
+ });
220
+ }
221
+ }
222
+ // Missing newline at end of file
223
+ if (content.length > 0 && !content.endsWith("\n")) {
224
+ issues.push({
225
+ file,
226
+ line: lines.length,
227
+ kind: "missing-newline",
228
+ description: "File does not end with a newline",
229
+ });
230
+ }
231
+ // Too many consecutive blank lines
232
+ let blankCount = 0;
233
+ for (let i = 0; i < lines.length; i++) {
234
+ if (lines[i]?.trim() === "") {
235
+ blankCount++;
236
+ if (blankCount > 2) {
237
+ issues.push({
238
+ file,
239
+ line: i + 1,
240
+ kind: "consecutive-blank-lines",
241
+ description: "More than 2 consecutive blank lines",
242
+ });
243
+ blankCount = 0; // Reset to avoid duplicate reports
244
+ }
245
+ }
246
+ else {
247
+ blankCount = 0;
248
+ }
249
+ }
250
+ }
251
+ catch {
252
+ // Skip files that can't be read
253
+ }
254
+ }
255
+ return issues;
256
+ }
257
+ //# sourceMappingURL=fix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../tools/fix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * pi-shazam tools/hotspots — Complexity hotspot ranking.
3
+ */
4
+ import type { ExtensionAPI } from "../types/pi-extension.js";
5
+ import type { RepoGraph } from "../core/graph.js";
6
+ export declare function registerHotspots(pi: ExtensionAPI): void;
7
+ export declare function executeHotspots(graph: RepoGraph, topN?: number): string;
8
+ export declare function executeHotspotsJson(graph: RepoGraph, topN: number): string;
9
+ //# sourceMappingURL=hotspots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hotspots.d.ts","sourceRoot":"","sources":["../../tools/hotspots.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,CAsCvD;AAWD,wBAAgB,eAAe,CAC9B,KAAK,EAAE,SAAS,EAChB,IAAI,GAAE,MAAW,GACf,MAAM,CAqBR;AAED,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,MAAM,GACV,MAAM,CAiBR"}