@shvmgyl15/tsgraph 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 (187) hide show
  1. package/AGENTS.md +64 -0
  2. package/README.md +128 -0
  3. package/TODOS.md +61 -0
  4. package/dist/analysis/analysis.test.d.ts +2 -0
  5. package/dist/analysis/analysis.test.d.ts.map +1 -0
  6. package/dist/analysis/analysis.test.js +359 -0
  7. package/dist/analysis/analysis.test.js.map +1 -0
  8. package/dist/analysis/complexity.d.ts +8 -0
  9. package/dist/analysis/complexity.d.ts.map +1 -0
  10. package/dist/analysis/complexity.js +88 -0
  11. package/dist/analysis/complexity.js.map +1 -0
  12. package/dist/analysis/coupling.d.ts +17 -0
  13. package/dist/analysis/coupling.d.ts.map +1 -0
  14. package/dist/analysis/coupling.js +71 -0
  15. package/dist/analysis/coupling.js.map +1 -0
  16. package/dist/analysis/hotspot.d.ts +10 -0
  17. package/dist/analysis/hotspot.d.ts.map +1 -0
  18. package/dist/analysis/hotspot.js +33 -0
  19. package/dist/analysis/hotspot.js.map +1 -0
  20. package/dist/analysis/index.d.ts +9 -0
  21. package/dist/analysis/index.d.ts.map +1 -0
  22. package/dist/analysis/index.js +5 -0
  23. package/dist/analysis/index.js.map +1 -0
  24. package/dist/boundaries/index.d.ts +25 -0
  25. package/dist/boundaries/index.d.ts.map +1 -0
  26. package/dist/boundaries/index.js +103 -0
  27. package/dist/boundaries/index.js.map +1 -0
  28. package/dist/boundaries/index.test.d.ts +2 -0
  29. package/dist/boundaries/index.test.d.ts.map +1 -0
  30. package/dist/boundaries/index.test.js +293 -0
  31. package/dist/boundaries/index.test.js.map +1 -0
  32. package/dist/changes/index.d.ts +28 -0
  33. package/dist/changes/index.d.ts.map +1 -0
  34. package/dist/changes/index.js +48 -0
  35. package/dist/changes/index.js.map +1 -0
  36. package/dist/changes/index.test.d.ts +2 -0
  37. package/dist/changes/index.test.d.ts.map +1 -0
  38. package/dist/changes/index.test.js +104 -0
  39. package/dist/changes/index.test.js.map +1 -0
  40. package/dist/cli/index.d.ts +3 -0
  41. package/dist/cli/index.d.ts.map +1 -0
  42. package/dist/cli/index.js +659 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/git/index.d.ts +16 -0
  45. package/dist/git/index.d.ts.map +1 -0
  46. package/dist/git/index.js +73 -0
  47. package/dist/git/index.js.map +1 -0
  48. package/dist/git/index.test.d.ts +2 -0
  49. package/dist/git/index.test.d.ts.map +1 -0
  50. package/dist/git/index.test.js +78 -0
  51. package/dist/git/index.test.js.map +1 -0
  52. package/dist/graph/types.d.ts +156 -0
  53. package/dist/graph/types.d.ts.map +1 -0
  54. package/dist/graph/types.js +166 -0
  55. package/dist/graph/types.js.map +1 -0
  56. package/dist/graph/types.test.d.ts +2 -0
  57. package/dist/graph/types.test.d.ts.map +1 -0
  58. package/dist/graph/types.test.js +326 -0
  59. package/dist/graph/types.test.js.map +1 -0
  60. package/dist/mcp/mcp.test.d.ts +2 -0
  61. package/dist/mcp/mcp.test.d.ts.map +1 -0
  62. package/dist/mcp/mcp.test.js +151 -0
  63. package/dist/mcp/mcp.test.js.map +1 -0
  64. package/dist/mcp/server.d.ts +2 -0
  65. package/dist/mcp/server.d.ts.map +1 -0
  66. package/dist/mcp/server.js +209 -0
  67. package/dist/mcp/server.js.map +1 -0
  68. package/dist/nextjs/index.d.ts +8 -0
  69. package/dist/nextjs/index.d.ts.map +1 -0
  70. package/dist/nextjs/index.js +16 -0
  71. package/dist/nextjs/index.js.map +1 -0
  72. package/dist/nextjs/nextjs.test.d.ts +2 -0
  73. package/dist/nextjs/nextjs.test.d.ts.map +1 -0
  74. package/dist/nextjs/nextjs.test.js +190 -0
  75. package/dist/nextjs/nextjs.test.js.map +1 -0
  76. package/dist/nextjs/pages.d.ts +4 -0
  77. package/dist/nextjs/pages.d.ts.map +1 -0
  78. package/dist/nextjs/pages.js +36 -0
  79. package/dist/nextjs/pages.js.map +1 -0
  80. package/dist/nextjs/react.d.ts +3 -0
  81. package/dist/nextjs/react.d.ts.map +1 -0
  82. package/dist/nextjs/react.js +86 -0
  83. package/dist/nextjs/react.js.map +1 -0
  84. package/dist/nextjs/router.d.ts +4 -0
  85. package/dist/nextjs/router.d.ts.map +1 -0
  86. package/dist/nextjs/router.js +86 -0
  87. package/dist/nextjs/router.js.map +1 -0
  88. package/dist/nextjs/routes.d.ts +4 -0
  89. package/dist/nextjs/routes.d.ts.map +1 -0
  90. package/dist/nextjs/routes.js +58 -0
  91. package/dist/nextjs/routes.js.map +1 -0
  92. package/dist/opencode/index.d.ts +7 -0
  93. package/dist/opencode/index.d.ts.map +1 -0
  94. package/dist/opencode/index.js +71 -0
  95. package/dist/opencode/index.js.map +1 -0
  96. package/dist/opencode/index.test.d.ts +2 -0
  97. package/dist/opencode/index.test.d.ts.map +1 -0
  98. package/dist/opencode/index.test.js +71 -0
  99. package/dist/opencode/index.test.js.map +1 -0
  100. package/dist/parser/index.d.ts +4 -0
  101. package/dist/parser/index.d.ts.map +1 -0
  102. package/dist/parser/index.js +282 -0
  103. package/dist/parser/index.js.map +1 -0
  104. package/dist/parser/parser.test.d.ts +2 -0
  105. package/dist/parser/parser.test.d.ts.map +1 -0
  106. package/dist/parser/parser.test.js +225 -0
  107. package/dist/parser/parser.test.js.map +1 -0
  108. package/dist/plan/index.d.ts +32 -0
  109. package/dist/plan/index.d.ts.map +1 -0
  110. package/dist/plan/index.js +107 -0
  111. package/dist/plan/index.js.map +1 -0
  112. package/dist/plan/index.test.d.ts +2 -0
  113. package/dist/plan/index.test.d.ts.map +1 -0
  114. package/dist/plan/index.test.js +143 -0
  115. package/dist/plan/index.test.js.map +1 -0
  116. package/dist/report/index.d.ts +9 -0
  117. package/dist/report/index.d.ts.map +1 -0
  118. package/dist/report/index.js +108 -0
  119. package/dist/report/index.js.map +1 -0
  120. package/dist/scanner/index.d.ts +13 -0
  121. package/dist/scanner/index.d.ts.map +1 -0
  122. package/dist/scanner/index.js +78 -0
  123. package/dist/scanner/index.js.map +1 -0
  124. package/dist/scanner/scanner.test.d.ts +2 -0
  125. package/dist/scanner/scanner.test.d.ts.map +1 -0
  126. package/dist/scanner/scanner.test.js +113 -0
  127. package/dist/scanner/scanner.test.js.map +1 -0
  128. package/dist/search/index.d.ts +32 -0
  129. package/dist/search/index.d.ts.map +1 -0
  130. package/dist/search/index.js +97 -0
  131. package/dist/search/index.js.map +1 -0
  132. package/dist/search/search.test.d.ts +2 -0
  133. package/dist/search/search.test.d.ts.map +1 -0
  134. package/dist/search/search.test.js +446 -0
  135. package/dist/search/search.test.js.map +1 -0
  136. package/dist/traversal/index.d.ts +5 -0
  137. package/dist/traversal/index.d.ts.map +1 -0
  138. package/dist/traversal/index.js +3 -0
  139. package/dist/traversal/index.js.map +1 -0
  140. package/dist/traversal/traversal.d.ts +31 -0
  141. package/dist/traversal/traversal.d.ts.map +1 -0
  142. package/dist/traversal/traversal.js +130 -0
  143. package/dist/traversal/traversal.js.map +1 -0
  144. package/dist/traversal/traversal.test.d.ts +2 -0
  145. package/dist/traversal/traversal.test.d.ts.map +1 -0
  146. package/dist/traversal/traversal.test.js +224 -0
  147. package/dist/traversal/traversal.test.js.map +1 -0
  148. package/opencode.json +24 -0
  149. package/package.json +29 -0
  150. package/src/analysis/analysis.test.ts +405 -0
  151. package/src/analysis/complexity.ts +107 -0
  152. package/src/analysis/coupling.ts +106 -0
  153. package/src/analysis/hotspot.ts +52 -0
  154. package/src/analysis/index.ts +17 -0
  155. package/src/boundaries/index.test.ts +335 -0
  156. package/src/boundaries/index.ts +137 -0
  157. package/src/changes/index.test.ts +114 -0
  158. package/src/changes/index.ts +95 -0
  159. package/src/cli/index.ts +736 -0
  160. package/src/git/index.test.ts +92 -0
  161. package/src/git/index.ts +86 -0
  162. package/src/graph/types.test.ts +383 -0
  163. package/src/graph/types.ts +353 -0
  164. package/src/mcp/mcp.test.ts +176 -0
  165. package/src/mcp/server.ts +217 -0
  166. package/src/nextjs/index.ts +23 -0
  167. package/src/nextjs/nextjs.test.ts +233 -0
  168. package/src/nextjs/pages.ts +43 -0
  169. package/src/nextjs/react.ts +100 -0
  170. package/src/nextjs/router.ts +102 -0
  171. package/src/nextjs/routes.ts +69 -0
  172. package/src/opencode/index.test.ts +90 -0
  173. package/src/opencode/index.ts +83 -0
  174. package/src/parser/index.ts +339 -0
  175. package/src/parser/parser.test.ts +282 -0
  176. package/src/plan/index.test.ts +162 -0
  177. package/src/plan/index.ts +161 -0
  178. package/src/report/index.ts +128 -0
  179. package/src/scanner/index.ts +97 -0
  180. package/src/scanner/scanner.test.ts +135 -0
  181. package/src/search/index.ts +163 -0
  182. package/src/search/search.test.ts +512 -0
  183. package/src/traversal/index.ts +5 -0
  184. package/src/traversal/traversal.test.ts +266 -0
  185. package/src/traversal/traversal.ts +185 -0
  186. package/tsconfig.json +20 -0
  187. package/vitest.config.ts +7 -0
@@ -0,0 +1,108 @@
1
+ import { analyzeCoupling, findHotspots } from "../analysis/index.js";
2
+ import { checkBoundaries, loadBoundariesConfig } from "../boundaries/index.js";
3
+ import { getStale } from "../changes/index.js";
4
+ export function generateReport(graph, opts = {}) {
5
+ const lines = [];
6
+ lines.push("# tsgraph Report");
7
+ lines.push("");
8
+ lines.push(`Generated at: ${graph.generatedAt}`);
9
+ lines.push(`Root: \`${graph.root}\``);
10
+ lines.push("");
11
+ lines.push("## Packages");
12
+ lines.push("");
13
+ for (const pkg of graph.packages) {
14
+ lines.push(`- **${pkg.name}** — ${pkg.files.length} files`);
15
+ }
16
+ lines.push("");
17
+ if (graph.dependencies.length > 0) {
18
+ lines.push("## Dependencies");
19
+ lines.push("");
20
+ lines.push("| Module | Version |");
21
+ lines.push("| --- | --- |");
22
+ for (const dep of graph.dependencies) {
23
+ lines.push(`| \`${dep.module}\` | \`${dep.version}\` |`);
24
+ }
25
+ lines.push("");
26
+ }
27
+ lines.push("## Symbols");
28
+ lines.push("");
29
+ const kindCounts = new Map();
30
+ for (const sym of graph.symbols) {
31
+ kindCounts.set(sym.kind, (kindCounts.get(sym.kind) ?? 0) + 1);
32
+ }
33
+ for (const [kind, count] of [...kindCounts.entries()].sort()) {
34
+ lines.push(`- **${kind}**: ${count}`);
35
+ }
36
+ lines.push("");
37
+ if (opts.includeHotspots) {
38
+ lines.push("## Hotspots");
39
+ lines.push("");
40
+ const hotspots = findHotspots(graph, 10);
41
+ if (hotspots.length > 0) {
42
+ lines.push("| File | Score | Complexity | Lines |");
43
+ lines.push("| --- | --- | --- | --- |");
44
+ for (const h of hotspots) {
45
+ lines.push(`| \`${h.file}\` | ${h.score} | ${h.totalComplexity} | ${h.lines} |`);
46
+ }
47
+ lines.push("");
48
+ }
49
+ }
50
+ if (opts.includeBoundaries && opts.rootDir) {
51
+ const config = loadBoundariesConfig(opts.rootDir);
52
+ if (config) {
53
+ const result = checkBoundaries(graph, config);
54
+ lines.push("## Architecture Boundaries");
55
+ lines.push("");
56
+ lines.push(`- Layers: ${config.layers.map((l) => l.name).join(", ")}`);
57
+ lines.push(`- Allowed imports: ${result.allowed}`);
58
+ lines.push(`- Violations: ${result.violations.length}`);
59
+ if (result.violations.length > 0) {
60
+ lines.push("");
61
+ for (const v of result.violations.slice(0, 20)) {
62
+ lines.push(`- ❌ \`${v.fromFile}\` → \`${v.toFile}\`: ${v.rule}`);
63
+ }
64
+ if (result.violations.length > 20) {
65
+ lines.push(`- ... and ${result.violations.length - 20} more`);
66
+ }
67
+ }
68
+ lines.push("");
69
+ }
70
+ }
71
+ if (opts.includeStale && opts.rootDir) {
72
+ const stale = getStale(graph, opts.rootDir, 90);
73
+ if (stale.totalFiles > 0) {
74
+ lines.push("## Stale Files");
75
+ lines.push("");
76
+ lines.push(`Files untouched in 90+ days: ${stale.totalFiles}`);
77
+ for (const f of stale.files.slice(0, 20)) {
78
+ lines.push(`- \`${f.path}\` — ${f.symbolCount} symbol(s)`);
79
+ }
80
+ if (stale.files.length > 20) {
81
+ lines.push(`- ... and ${stale.files.length - 20} more`);
82
+ }
83
+ lines.push("");
84
+ }
85
+ }
86
+ if (graph.packages.length > 1) {
87
+ lines.push("## Coupling");
88
+ lines.push("");
89
+ const coupling = analyzeCoupling(graph).slice(0, 15);
90
+ if (coupling.length > 0) {
91
+ lines.push("| Package | Coupled To | Imports | Files |");
92
+ lines.push("| --- | --- | --- | --- |");
93
+ for (const c of coupling) {
94
+ lines.push(`| ${c.packageName} | ${c.coupledTo} | ${c.importCount} | ${c.fileCount} |`);
95
+ }
96
+ lines.push("");
97
+ }
98
+ }
99
+ lines.push("## Summary");
100
+ lines.push("");
101
+ lines.push(`- Files: ${graph.files.length}`);
102
+ lines.push(`- Symbols: ${graph.symbols.length}`);
103
+ lines.push(`- Calls: ${graph.calls.length}`);
104
+ lines.push(`- Imports: ${graph.imports.length}`);
105
+ lines.push(`- Dependencies: ${graph.dependencies.length}`);
106
+ return lines.join("\n") + "\n";
107
+ }
108
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type FileKind = "ts" | "tsx" | "js" | "jsx" | "json" | "other";
2
+ export interface ScannedFile {
3
+ path: string;
4
+ relativePath: string;
5
+ kind: FileKind;
6
+ isGenerated: boolean;
7
+ }
8
+ export interface ScanResult {
9
+ files: ScannedFile[];
10
+ errors: Error[];
11
+ }
12
+ export declare function scanFiles(rootDir: string): ScanResult;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAoCD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CA4CrD"}
@@ -0,0 +1,78 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import ignore from "ignore";
4
+ const ALWAYS_IGNORE = ["node_modules", ".git", "dist", ".tsgraph", ".gitignore"];
5
+ const GENERATED_PATTERNS = [
6
+ /@generated/,
7
+ /Code generated by/,
8
+ /auto-generated/,
9
+ /This file is generated/,
10
+ ];
11
+ const FILE_EXT_MAP = {
12
+ ".ts": "ts",
13
+ ".tsx": "tsx",
14
+ ".js": "js",
15
+ ".jsx": "jsx",
16
+ ".json": "json",
17
+ };
18
+ function classifyFile(filePath) {
19
+ return FILE_EXT_MAP[path.extname(filePath).toLowerCase()] ?? "other";
20
+ }
21
+ function checkGenerated(filePath) {
22
+ try {
23
+ const fd = fs.openSync(filePath, "r");
24
+ const buffer = Buffer.alloc(256);
25
+ const bytesRead = fs.readSync(fd, buffer, 0, 256, 0);
26
+ fs.closeSync(fd);
27
+ const firstChunk = buffer.toString("utf-8", 0, bytesRead).split("\n")[0];
28
+ return GENERATED_PATTERNS.some((p) => p.test(firstChunk));
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ export function scanFiles(rootDir) {
35
+ const ig = ignore().add(ALWAYS_IGNORE);
36
+ const gitignorePath = path.join(rootDir, ".gitignore");
37
+ try {
38
+ ig.add(fs.readFileSync(gitignorePath, "utf-8"));
39
+ }
40
+ catch {
41
+ // no .gitignore — built-in rules suffice
42
+ }
43
+ const files = [];
44
+ const errors = [];
45
+ function walk(dir) {
46
+ let entries;
47
+ try {
48
+ entries = fs.readdirSync(dir, { withFileTypes: true });
49
+ }
50
+ catch (err) {
51
+ errors.push(err);
52
+ return;
53
+ }
54
+ for (const entry of entries) {
55
+ const fullPath = path.join(dir, entry.name);
56
+ const relativePath = path.relative(rootDir, fullPath);
57
+ if (entry.isDirectory()) {
58
+ if (ig.ignores(relativePath + "/"))
59
+ continue;
60
+ walk(fullPath);
61
+ }
62
+ else if (entry.isFile()) {
63
+ if (ig.ignores(relativePath))
64
+ continue;
65
+ const kind = classifyFile(fullPath);
66
+ files.push({
67
+ path: fullPath,
68
+ relativePath,
69
+ kind,
70
+ isGenerated: checkGenerated(fullPath),
71
+ });
72
+ }
73
+ }
74
+ }
75
+ walk(rootDir);
76
+ return { files, errors };
77
+ }
78
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scanner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.test.d.ts","sourceRoot":"","sources":["../../src/scanner/scanner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import path from "node:path";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import { scanFiles } from "./index.js";
6
+ function createTempDir() {
7
+ return fs.mkdtempSync(path.join(os.tmpdir(), "tsgraph-test-"));
8
+ }
9
+ function writeFile(dir, relativePath, content) {
10
+ const fullPath = path.join(dir, relativePath);
11
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
12
+ fs.writeFileSync(fullPath, content, "utf-8");
13
+ }
14
+ describe("scanFiles", () => {
15
+ it("finds .ts files in a flat directory", () => {
16
+ const dir = createTempDir();
17
+ writeFile(dir, "index.ts", "");
18
+ writeFile(dir, "util.ts", "");
19
+ const result = scanFiles(dir);
20
+ const paths = result.files.map((f) => f.relativePath).sort();
21
+ expect(paths).toEqual(["index.ts", "util.ts"]);
22
+ expect(result.errors).toEqual([]);
23
+ fs.rmSync(dir, { recursive: true });
24
+ });
25
+ it("ignores node_modules by default", () => {
26
+ const dir = createTempDir();
27
+ writeFile(dir, "index.ts", "");
28
+ writeFile(dir, "node_modules/foo/index.ts", "");
29
+ writeFile(dir, "node_modules/bar/index.js", "");
30
+ const result = scanFiles(dir);
31
+ const paths = result.files.map((f) => f.relativePath);
32
+ expect(paths).toEqual(["index.ts"]);
33
+ fs.rmSync(dir, { recursive: true });
34
+ });
35
+ it("ignores .git, dist, .tsgraph by default", () => {
36
+ const dir = createTempDir();
37
+ writeFile(dir, "src/index.ts", "");
38
+ writeFile(dir, ".git/HEAD", "");
39
+ writeFile(dir, "dist/bundle.js", "");
40
+ writeFile(dir, ".tsgraph/graph.json", "");
41
+ const result = scanFiles(dir);
42
+ const paths = result.files.map((f) => f.relativePath).sort();
43
+ expect(paths).toEqual(["src/index.ts"]);
44
+ fs.rmSync(dir, { recursive: true });
45
+ });
46
+ it("respects .gitignore patterns", () => {
47
+ const dir = createTempDir();
48
+ writeFile(dir, ".gitignore", "*.log\n/build");
49
+ writeFile(dir, "src/index.ts", "");
50
+ writeFile(dir, "server.log", "");
51
+ writeFile(dir, "build/output.js", "");
52
+ const result = scanFiles(dir);
53
+ const paths = result.files.map((f) => f.relativePath);
54
+ expect(paths).toEqual(["src/index.ts"]);
55
+ fs.rmSync(dir, { recursive: true });
56
+ });
57
+ it("classifies file kinds correctly", () => {
58
+ const dir = createTempDir();
59
+ writeFile(dir, "a.ts", "");
60
+ writeFile(dir, "b.tsx", "");
61
+ writeFile(dir, "c.js", "");
62
+ writeFile(dir, "d.jsx", "");
63
+ writeFile(dir, "e.json", "");
64
+ writeFile(dir, "f.css", "");
65
+ const result = scanFiles(dir);
66
+ const kinds = Object.fromEntries(result.files.map((f) => [f.relativePath, f.kind]));
67
+ expect(kinds["a.ts"]).toBe("ts");
68
+ expect(kinds["b.tsx"]).toBe("tsx");
69
+ expect(kinds["c.js"]).toBe("js");
70
+ expect(kinds["d.jsx"]).toBe("jsx");
71
+ expect(kinds["e.json"]).toBe("json");
72
+ expect(kinds["f.css"]).toBe("other");
73
+ fs.rmSync(dir, { recursive: true });
74
+ });
75
+ it("detects generated files by first-line comment", () => {
76
+ const dir = createTempDir();
77
+ writeFile(dir, "generated.ts", "// @generated\nconst x = 1;\n");
78
+ writeFile(dir, "normal.ts", "const x = 1;\n");
79
+ writeFile(dir, "auto.ts", "// auto-generated\nconst y = 2;\n");
80
+ writeFile(dir, "codegen.ts", "// Code generated by protoc\nconst z = 3;\n");
81
+ const result = scanFiles(dir);
82
+ const genMap = Object.fromEntries(result.files.map((f) => [f.relativePath, f.isGenerated]));
83
+ expect(genMap["generated.ts"]).toBe(true);
84
+ expect(genMap["normal.ts"]).toBe(false);
85
+ expect(genMap["auto.ts"]).toBe(true);
86
+ expect(genMap["codegen.ts"]).toBe(true);
87
+ fs.rmSync(dir, { recursive: true });
88
+ });
89
+ it("handles missing .gitignore gracefully", () => {
90
+ const dir = createTempDir();
91
+ writeFile(dir, "index.ts", "");
92
+ // Intentionally no .gitignore
93
+ const result = scanFiles(dir);
94
+ expect(result.files.length).toBe(1);
95
+ expect(result.errors).toEqual([]);
96
+ fs.rmSync(dir, { recursive: true });
97
+ });
98
+ it("walks nested directories", () => {
99
+ const dir = createTempDir();
100
+ writeFile(dir, "src/index.ts", "");
101
+ writeFile(dir, "src/components/button.tsx", "");
102
+ writeFile(dir, "src/utils/helpers.ts", "");
103
+ const result = scanFiles(dir);
104
+ const paths = result.files.map((f) => f.relativePath).sort();
105
+ expect(paths).toEqual([
106
+ "src/components/button.tsx",
107
+ "src/index.ts",
108
+ "src/utils/helpers.ts",
109
+ ]);
110
+ fs.rmSync(dir, { recursive: true });
111
+ });
112
+ });
113
+ //# sourceMappingURL=scanner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.test.js","sourceRoot":"","sources":["../../src/scanner/scanner.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { Graph, SymbolNode, CallEdge, ImportEdge, FileNode, PackageNode } from "../graph/types.js";
2
+ export interface CallerResult {
3
+ callerSymbol: SymbolNode;
4
+ edges: CallEdge[];
5
+ }
6
+ export interface CalleeResult {
7
+ calleeRaw: string;
8
+ edges: CallEdge[];
9
+ }
10
+ export interface FocusResult {
11
+ pkg: PackageNode;
12
+ files: FileNode[];
13
+ symbols: SymbolNode[];
14
+ imports: ImportEdge[];
15
+ }
16
+ export interface ContextResult {
17
+ node?: SymbolNode;
18
+ source?: string;
19
+ callers: CallerResult[];
20
+ callees: CalleeResult[];
21
+ }
22
+ export declare function loadGraph(graphPath: string): Graph;
23
+ export declare function findCallers(graph: Graph, name: string): CallerResult[];
24
+ export declare function findCallees(graph: Graph, name: string): CalleeResult[];
25
+ export declare function findNode(graph: Graph, name: string): SymbolNode | undefined;
26
+ export declare function readSource(graph: Graph, symbol: SymbolNode): string;
27
+ export declare function querySymbols(graph: Graph, pattern: string): SymbolNode[];
28
+ export declare function findImports(graph: Graph, importPath: string): ImportEdge[];
29
+ export declare function findPublic(graph: Graph, packageName?: string): SymbolNode[];
30
+ export declare function focusPackage(graph: Graph, packageName: string): FocusResult | undefined;
31
+ export declare function context(graph: Graph, symbolName: string): ContextResult;
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,KAAK,EACL,UAAU,EACV,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,UAAU,CAAC;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAGlD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CAiBtE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CActE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE3E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAcnE;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,GACd,UAAU,EAAE,CAQd;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,GACjB,UAAU,EAAE,CAKd;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,KAAK,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,UAAU,EAAE,CAMd;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,MAAM,GAClB,WAAW,GAAG,SAAS,CAWzB;AAED,wBAAgB,OAAO,CACrB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,GACjB,aAAa,CAaf"}
@@ -0,0 +1,97 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { deserialize } from "../graph/types.js";
4
+ export function loadGraph(graphPath) {
5
+ const raw = fs.readFileSync(graphPath, "utf-8");
6
+ return deserialize(raw);
7
+ }
8
+ export function findCallers(graph, name) {
9
+ const matchingEdges = graph.calls.filter((c) => c.calleeRaw === name);
10
+ const callerMap = new Map();
11
+ for (const edge of matchingEdges) {
12
+ const caller = graph.symbols.find((s) => s.id === edge.callerSymbolId);
13
+ if (!caller)
14
+ continue;
15
+ const key = caller.id;
16
+ let result = callerMap.get(key);
17
+ if (!result) {
18
+ result = { callerSymbol: caller, edges: [] };
19
+ callerMap.set(key, result);
20
+ }
21
+ result.edges.push(edge);
22
+ }
23
+ return [...callerMap.values()];
24
+ }
25
+ export function findCallees(graph, name) {
26
+ const sym = graph.symbols.find((s) => s.name === name);
27
+ if (!sym)
28
+ return [];
29
+ const edges = graph.calls.filter((c) => c.callerSymbolId === sym.id);
30
+ const calleeMap = new Map();
31
+ for (const edge of edges) {
32
+ let result = calleeMap.get(edge.calleeRaw);
33
+ if (!result) {
34
+ result = { calleeRaw: edge.calleeRaw, edges: [] };
35
+ calleeMap.set(edge.calleeRaw, result);
36
+ }
37
+ result.edges.push(edge);
38
+ }
39
+ return [...calleeMap.values()];
40
+ }
41
+ export function findNode(graph, name) {
42
+ return graph.symbols.find((s) => s.name === name);
43
+ }
44
+ export function readSource(graph, symbol) {
45
+ const filePath = path.join(graph.root, symbol.file);
46
+ const content = fs.readFileSync(filePath, "utf-8");
47
+ const lines = content.split("\n");
48
+ const start = Math.max(0, symbol.line - 1);
49
+ const end = Math.min(lines.length, symbol.endLine);
50
+ const snippet = lines.slice(start, end);
51
+ const padLen = String(end).length;
52
+ return snippet
53
+ .map((line, i) => {
54
+ const lineNum = symbol.line + i;
55
+ return `${String(lineNum).padStart(padLen)} ${line}`;
56
+ })
57
+ .join("\n");
58
+ }
59
+ export function querySymbols(graph, pattern) {
60
+ const lower = pattern.toLowerCase();
61
+ return graph.symbols.filter((s) => s.name.toLowerCase().includes(lower) ||
62
+ s.file.toLowerCase().includes(lower) ||
63
+ s.packageName.toLowerCase().includes(lower));
64
+ }
65
+ export function findImports(graph, importPath) {
66
+ const lower = importPath.toLowerCase();
67
+ return graph.imports.filter((i) => i.importPath.toLowerCase().includes(lower));
68
+ }
69
+ export function findPublic(graph, packageName) {
70
+ return graph.symbols.filter((s) => s.isExported &&
71
+ (packageName === undefined || s.packageName === packageName));
72
+ }
73
+ export function focusPackage(graph, packageName) {
74
+ const pkg = graph.packages.find((p) => p.name === packageName);
75
+ if (!pkg)
76
+ return undefined;
77
+ const files = graph.files.filter((f) => f.packageName === packageName);
78
+ const symbols = graph.symbols.filter((s) => s.packageName === packageName);
79
+ const imports = graph.imports.filter((i) => i.fromPackage === packageName);
80
+ return { pkg, files, symbols, imports };
81
+ }
82
+ export function context(graph, symbolName) {
83
+ const node = findNode(graph, symbolName);
84
+ let source;
85
+ if (node) {
86
+ try {
87
+ source = readSource(graph, node);
88
+ }
89
+ catch {
90
+ // source file not available
91
+ }
92
+ }
93
+ const callers = findCallers(graph, symbolName);
94
+ const callees = findCallees(graph, symbolName);
95
+ return { node, source, callers, callees };
96
+ }
97
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.d.ts","sourceRoot":"","sources":["../../src/search/search.test.ts"],"names":[],"mappings":""}