structx 1.0.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 (94) hide show
  1. package/dist/benchmark/baseline.d.ts +10 -0
  2. package/dist/benchmark/baseline.d.ts.map +1 -0
  3. package/dist/benchmark/baseline.js +84 -0
  4. package/dist/benchmark/baseline.js.map +1 -0
  5. package/dist/benchmark/questions.d.ts +2 -0
  6. package/dist/benchmark/questions.d.ts.map +1 -0
  7. package/dist/benchmark/questions.js +14 -0
  8. package/dist/benchmark/questions.js.map +1 -0
  9. package/dist/benchmark/reporter.d.ts +8 -0
  10. package/dist/benchmark/reporter.d.ts.map +1 -0
  11. package/dist/benchmark/reporter.js +120 -0
  12. package/dist/benchmark/reporter.js.map +1 -0
  13. package/dist/benchmark/runner.d.ts +24 -0
  14. package/dist/benchmark/runner.d.ts.map +1 -0
  15. package/dist/benchmark/runner.js +110 -0
  16. package/dist/benchmark/runner.js.map +1 -0
  17. package/dist/cli.d.ts +3 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +753 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/config.d.ts +15 -0
  22. package/dist/config.d.ts.map +1 -0
  23. package/dist/config.js +83 -0
  24. package/dist/config.js.map +1 -0
  25. package/dist/db/connection.d.ts +5 -0
  26. package/dist/db/connection.d.ts.map +1 -0
  27. package/dist/db/connection.js +89 -0
  28. package/dist/db/connection.js.map +1 -0
  29. package/dist/db/queries.d.ts +122 -0
  30. package/dist/db/queries.d.ts.map +1 -0
  31. package/dist/db/queries.js +191 -0
  32. package/dist/db/queries.js.map +1 -0
  33. package/dist/db/schema.sql +85 -0
  34. package/dist/ingest/differ.d.ts +13 -0
  35. package/dist/ingest/differ.d.ts.map +1 -0
  36. package/dist/ingest/differ.js +63 -0
  37. package/dist/ingest/differ.js.map +1 -0
  38. package/dist/ingest/parser.d.ts +15 -0
  39. package/dist/ingest/parser.d.ts.map +1 -0
  40. package/dist/ingest/parser.js +154 -0
  41. package/dist/ingest/parser.js.map +1 -0
  42. package/dist/ingest/relationships.d.ts +8 -0
  43. package/dist/ingest/relationships.d.ts.map +1 -0
  44. package/dist/ingest/relationships.js +93 -0
  45. package/dist/ingest/relationships.js.map +1 -0
  46. package/dist/ingest/scanner.d.ts +2 -0
  47. package/dist/ingest/scanner.d.ts.map +1 -0
  48. package/dist/ingest/scanner.js +67 -0
  49. package/dist/ingest/scanner.js.map +1 -0
  50. package/dist/instructions/claude.md +41 -0
  51. package/dist/instructions/copilot.md +39 -0
  52. package/dist/instructions/cursor.md +39 -0
  53. package/dist/instructions/generic.md +41 -0
  54. package/dist/query/answerer.d.ts +9 -0
  55. package/dist/query/answerer.d.ts.map +1 -0
  56. package/dist/query/answerer.js +46 -0
  57. package/dist/query/answerer.js.map +1 -0
  58. package/dist/query/classifier.d.ts +10 -0
  59. package/dist/query/classifier.d.ts.map +1 -0
  60. package/dist/query/classifier.js +60 -0
  61. package/dist/query/classifier.js.map +1 -0
  62. package/dist/query/context-builder.d.ts +3 -0
  63. package/dist/query/context-builder.d.ts.map +1 -0
  64. package/dist/query/context-builder.js +104 -0
  65. package/dist/query/context-builder.js.map +1 -0
  66. package/dist/query/retriever.d.ts +23 -0
  67. package/dist/query/retriever.d.ts.map +1 -0
  68. package/dist/query/retriever.js +142 -0
  69. package/dist/query/retriever.js.map +1 -0
  70. package/dist/semantic/analyzer.d.ts +15 -0
  71. package/dist/semantic/analyzer.d.ts.map +1 -0
  72. package/dist/semantic/analyzer.js +179 -0
  73. package/dist/semantic/analyzer.js.map +1 -0
  74. package/dist/semantic/cost.d.ts +11 -0
  75. package/dist/semantic/cost.d.ts.map +1 -0
  76. package/dist/semantic/cost.js +31 -0
  77. package/dist/semantic/cost.js.map +1 -0
  78. package/dist/semantic/prompt.d.ts +11 -0
  79. package/dist/semantic/prompt.d.ts.map +1 -0
  80. package/dist/semantic/prompt.js +71 -0
  81. package/dist/semantic/prompt.js.map +1 -0
  82. package/dist/semantic/validator.d.ts +15 -0
  83. package/dist/semantic/validator.d.ts.map +1 -0
  84. package/dist/semantic/validator.js +95 -0
  85. package/dist/semantic/validator.js.map +1 -0
  86. package/dist/utils/logger.d.ts +9 -0
  87. package/dist/utils/logger.d.ts.map +1 -0
  88. package/dist/utils/logger.js +48 -0
  89. package/dist/utils/logger.js.map +1 -0
  90. package/dist/utils/tokens.d.ts +3 -0
  91. package/dist/utils/tokens.d.ts.map +1 -0
  92. package/dist/utils/tokens.js +21 -0
  93. package/dist/utils/tokens.js.map +1 -0
  94. package/package.json +39 -0
@@ -0,0 +1,85 @@
1
+ -- StructX Database Schema
2
+
3
+ CREATE TABLE IF NOT EXISTS files (
4
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
5
+ path TEXT NOT NULL UNIQUE,
6
+ content_hash TEXT NOT NULL,
7
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
8
+ );
9
+
10
+ CREATE TABLE IF NOT EXISTS functions (
11
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
12
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
13
+ name TEXT NOT NULL,
14
+ signature TEXT NOT NULL,
15
+ body TEXT NOT NULL,
16
+ code_hash TEXT NOT NULL,
17
+ start_line INTEGER NOT NULL,
18
+ end_line INTEGER NOT NULL,
19
+ is_exported BOOLEAN DEFAULT 0,
20
+ is_async BOOLEAN DEFAULT 0,
21
+ purpose TEXT,
22
+ behavior_summary TEXT,
23
+ side_effects_json TEXT,
24
+ domain TEXT,
25
+ complexity TEXT,
26
+ semantic_analyzed_at DATETIME,
27
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
28
+ );
29
+
30
+ CREATE TABLE IF NOT EXISTS relationships (
31
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
32
+ caller_function_id INTEGER NOT NULL REFERENCES functions(id) ON DELETE CASCADE,
33
+ callee_function_id INTEGER REFERENCES functions(id) ON DELETE SET NULL,
34
+ callee_name TEXT NOT NULL,
35
+ relation_type TEXT NOT NULL,
36
+ UNIQUE(caller_function_id, callee_name, relation_type)
37
+ );
38
+
39
+ CREATE TABLE IF NOT EXISTS analysis_queue (
40
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
41
+ function_id INTEGER NOT NULL REFERENCES functions(id) ON DELETE CASCADE,
42
+ priority INTEGER DEFAULT 0,
43
+ reason TEXT NOT NULL,
44
+ status TEXT DEFAULT 'pending',
45
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
46
+ processed_at DATETIME
47
+ );
48
+
49
+ CREATE TABLE IF NOT EXISTS semantic_cache (
50
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
51
+ function_id INTEGER NOT NULL REFERENCES functions(id) ON DELETE CASCADE,
52
+ prompt_hash TEXT NOT NULL,
53
+ model TEXT NOT NULL,
54
+ input_tokens INTEGER,
55
+ output_tokens INTEGER,
56
+ cost_usd REAL,
57
+ response_json TEXT NOT NULL,
58
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
59
+ UNIQUE(function_id, prompt_hash)
60
+ );
61
+
62
+ CREATE TABLE IF NOT EXISTS qa_runs (
63
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
64
+ mode TEXT NOT NULL,
65
+ question TEXT NOT NULL,
66
+ input_tokens INTEGER,
67
+ output_tokens INTEGER,
68
+ total_tokens INTEGER,
69
+ cost_usd REAL,
70
+ response_time_ms INTEGER,
71
+ files_accessed INTEGER,
72
+ functions_retrieved INTEGER,
73
+ graph_query_time_ms INTEGER,
74
+ answer_text TEXT,
75
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
76
+ );
77
+
78
+ -- Indexes
79
+ CREATE INDEX IF NOT EXISTS idx_functions_name ON functions(name);
80
+ CREATE INDEX IF NOT EXISTS idx_functions_domain ON functions(domain);
81
+ CREATE INDEX IF NOT EXISTS idx_functions_file_id ON functions(file_id);
82
+ CREATE INDEX IF NOT EXISTS idx_relationships_caller ON relationships(caller_function_id);
83
+ CREATE INDEX IF NOT EXISTS idx_relationships_callee ON relationships(callee_function_id);
84
+ CREATE INDEX IF NOT EXISTS idx_analysis_queue_status ON analysis_queue(status, priority DESC);
85
+ CREATE INDEX IF NOT EXISTS idx_semantic_cache_lookup ON semantic_cache(function_id, prompt_hash);
@@ -0,0 +1,13 @@
1
+ import type { FunctionRow } from '../db/queries';
2
+ export interface DiffResult {
3
+ signatureChanged: boolean;
4
+ bodyChangedRatio: number;
5
+ depsChanged: boolean;
6
+ }
7
+ export declare function shouldReanalyze(oldFunction: FunctionRow, newSignature: string, newCodeHash: string, newBody: string, threshold?: number): {
8
+ reanalyze: boolean;
9
+ reason: string;
10
+ };
11
+ export declare function calculateDiffRatio(oldText: string, newText: string): number;
12
+ export declare function getPriority(reason: string, isExported: boolean): number;
13
+ //# sourceMappingURL=differ.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"differ.d.ts","sourceRoot":"","sources":["../../src/ingest/differ.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAY,GACtB;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAuBxC;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAiB3E;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CAWvE"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shouldReanalyze = shouldReanalyze;
4
+ exports.calculateDiffRatio = calculateDiffRatio;
5
+ exports.getPriority = getPriority;
6
+ function shouldReanalyze(oldFunction, newSignature, newCodeHash, newBody, threshold = 0.3) {
7
+ // New function (no old record)
8
+ if (!oldFunction) {
9
+ return { reanalyze: true, reason: 'new' };
10
+ }
11
+ // Code hash unchanged — nothing changed
12
+ if (oldFunction.code_hash === newCodeHash) {
13
+ return { reanalyze: false, reason: 'unchanged' };
14
+ }
15
+ // Signature changed
16
+ if (oldFunction.signature !== newSignature) {
17
+ return { reanalyze: true, reason: 'signature_changed' };
18
+ }
19
+ // Body changed significantly
20
+ const diffRatio = calculateDiffRatio(oldFunction.body, newBody);
21
+ if (diffRatio > threshold) {
22
+ return { reanalyze: true, reason: 'body_changed' };
23
+ }
24
+ return { reanalyze: false, reason: 'minor_change' };
25
+ }
26
+ function calculateDiffRatio(oldText, newText) {
27
+ const oldLines = oldText.split('\n');
28
+ const newLines = newText.split('\n');
29
+ const oldSet = new Set(oldLines.map(l => l.trim()));
30
+ const newSet = new Set(newLines.map(l => l.trim()));
31
+ let changed = 0;
32
+ for (const line of newSet) {
33
+ if (!oldSet.has(line))
34
+ changed++;
35
+ }
36
+ for (const line of oldSet) {
37
+ if (!newSet.has(line))
38
+ changed++;
39
+ }
40
+ const total = Math.max(oldLines.length, newLines.length, 1);
41
+ return changed / total;
42
+ }
43
+ function getPriority(reason, isExported) {
44
+ let base = 0;
45
+ switch (reason) {
46
+ case 'new':
47
+ base = 5;
48
+ break;
49
+ case 'signature_changed':
50
+ base = 10;
51
+ break;
52
+ case 'body_changed':
53
+ base = 7;
54
+ break;
55
+ case 'deps_changed':
56
+ base = 3;
57
+ break;
58
+ default: base = 1;
59
+ }
60
+ // Exported functions get higher priority
61
+ return isExported ? base + 5 : base;
62
+ }
63
+ //# sourceMappingURL=differ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"differ.js","sourceRoot":"","sources":["../../src/ingest/differ.ts"],"names":[],"mappings":";;AAQA,0CA6BC;AAED,gDAiBC;AAED,kCAWC;AA7DD,SAAgB,eAAe,CAC7B,WAAwB,EACxB,YAAoB,EACpB,WAAmB,EACnB,OAAe,EACf,YAAoB,GAAG;IAEvB,+BAA+B;IAC/B,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,wCAAwC;IACxC,IAAI,WAAW,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;QAC1C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IAED,oBAAoB;IACpB,IAAI,WAAW,CAAC,SAAS,KAAK,YAAY,EAAE,CAAC;QAC3C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC1D,CAAC;IAED,6BAA6B;IAC7B,MAAM,SAAS,GAAG,kBAAkB,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChE,IAAI,SAAS,GAAG,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACrD,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;AACtD,CAAC;AAED,SAAgB,kBAAkB,CAAC,OAAe,EAAE,OAAe;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEpD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;IACnC,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D,OAAO,OAAO,GAAG,KAAK,CAAC;AACzB,CAAC;AAED,SAAgB,WAAW,CAAC,MAAc,EAAE,UAAmB;IAC7D,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK;YAAE,IAAI,GAAG,CAAC,CAAC;YAAC,MAAM;QAC5B,KAAK,mBAAmB;YAAE,IAAI,GAAG,EAAE,CAAC;YAAC,MAAM;QAC3C,KAAK,cAAc;YAAE,IAAI,GAAG,CAAC,CAAC;YAAC,MAAM;QACrC,KAAK,cAAc;YAAE,IAAI,GAAG,CAAC,CAAC;YAAC,MAAM;QACrC,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACpB,CAAC;IACD,yCAAyC;IACzC,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACtC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Project } from 'ts-morph';
2
+ export interface ExtractedFunction {
3
+ name: string;
4
+ signature: string;
5
+ body: string;
6
+ startLine: number;
7
+ endLine: number;
8
+ isExported: boolean;
9
+ isAsync: boolean;
10
+ codeHash: string;
11
+ }
12
+ export declare function createProject(repoPath: string): Project;
13
+ export declare function parseFile(project: Project, filePath: string): ExtractedFunction[];
14
+ export declare function hashFileContent(content: string): string;
15
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/ingest/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA4G,MAAM,UAAU,CAAC;AAG7I,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CASvD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAuCjF;AA2ED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createProject = createProject;
37
+ exports.parseFile = parseFile;
38
+ exports.hashFileContent = hashFileContent;
39
+ const ts_morph_1 = require("ts-morph");
40
+ const crypto = __importStar(require("crypto"));
41
+ function createProject(repoPath) {
42
+ return new ts_morph_1.Project({
43
+ tsConfigFilePath: undefined,
44
+ skipAddingFilesFromTsConfig: true,
45
+ compilerOptions: {
46
+ allowJs: true,
47
+ jsx: 2, // React
48
+ },
49
+ });
50
+ }
51
+ function parseFile(project, filePath) {
52
+ const sourceFile = project.addSourceFileAtPath(filePath);
53
+ const functions = [];
54
+ // Extract top-level function declarations
55
+ for (const fn of sourceFile.getFunctions()) {
56
+ const extracted = extractFunctionDeclaration(fn);
57
+ if (extracted)
58
+ functions.push(extracted);
59
+ }
60
+ // Extract arrow functions assigned to variables
61
+ for (const varStmt of sourceFile.getVariableStatements()) {
62
+ for (const decl of varStmt.getDeclarations()) {
63
+ const initializer = decl.getInitializer();
64
+ if (initializer && ts_morph_1.Node.isArrowFunction(initializer)) {
65
+ const extracted = extractArrowFunction(decl, initializer, varStmt.isExported());
66
+ if (extracted)
67
+ functions.push(extracted);
68
+ }
69
+ // Also handle function expressions: const foo = function() {}
70
+ if (initializer && ts_morph_1.Node.isFunctionExpression(initializer)) {
71
+ const extracted = extractArrowFunction(decl, initializer, varStmt.isExported());
72
+ if (extracted)
73
+ functions.push(extracted);
74
+ }
75
+ }
76
+ }
77
+ // Extract class methods
78
+ for (const cls of sourceFile.getClasses()) {
79
+ const className = cls.getName() || 'AnonymousClass';
80
+ for (const method of cls.getMethods()) {
81
+ const extracted = extractMethodDeclaration(method, className);
82
+ if (extracted)
83
+ functions.push(extracted);
84
+ }
85
+ }
86
+ // Remove the source file from project to prevent memory bloat
87
+ project.removeSourceFile(sourceFile);
88
+ return functions;
89
+ }
90
+ function extractFunctionDeclaration(fn) {
91
+ const name = fn.getName();
92
+ if (!name)
93
+ return null; // Skip anonymous functions
94
+ const body = fn.getFullText();
95
+ const signature = buildSignature(fn);
96
+ return {
97
+ name,
98
+ signature,
99
+ body,
100
+ startLine: fn.getStartLineNumber(),
101
+ endLine: fn.getEndLineNumber(),
102
+ isExported: fn.isExported(),
103
+ isAsync: fn.isAsync(),
104
+ codeHash: hashCode(body),
105
+ };
106
+ }
107
+ function extractArrowFunction(decl, arrow, isExported) {
108
+ const name = decl.getName();
109
+ if (!name)
110
+ return null;
111
+ const body = decl.getFullText();
112
+ const params = arrow.getParameters().map(p => p.getText()).join(', ');
113
+ const returnType = arrow.getReturnType()?.getText() ?? 'unknown';
114
+ return {
115
+ name,
116
+ signature: `const ${name} = (${params}) => ${returnType}`,
117
+ body,
118
+ startLine: decl.getStartLineNumber(),
119
+ endLine: decl.getEndLineNumber(),
120
+ isExported,
121
+ isAsync: arrow.isAsync(),
122
+ codeHash: hashCode(body),
123
+ };
124
+ }
125
+ function extractMethodDeclaration(method, className) {
126
+ const name = method.getName();
127
+ const body = method.getFullText();
128
+ const params = method.getParameters().map(p => p.getText()).join(', ');
129
+ const returnType = method.getReturnType()?.getText() ?? 'unknown';
130
+ return {
131
+ name: `${className}.${name}`,
132
+ signature: `${className}.${name}(${params}): ${returnType}`,
133
+ body,
134
+ startLine: method.getStartLineNumber(),
135
+ endLine: method.getEndLineNumber(),
136
+ isExported: true, // Class methods accessible if class is exported
137
+ isAsync: method.isAsync(),
138
+ codeHash: hashCode(body),
139
+ };
140
+ }
141
+ function buildSignature(fn) {
142
+ const name = fn.getName() || 'anonymous';
143
+ const params = fn.getParameters().map(p => p.getText()).join(', ');
144
+ const returnType = fn.getReturnType()?.getText() ?? 'unknown';
145
+ const asyncPrefix = fn.isAsync() ? 'async ' : '';
146
+ return `${asyncPrefix}function ${name}(${params}): ${returnType}`;
147
+ }
148
+ function hashCode(code) {
149
+ return crypto.createHash('sha256').update(code).digest('hex');
150
+ }
151
+ function hashFileContent(content) {
152
+ return crypto.createHash('sha256').update(content).digest('hex');
153
+ }
154
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/ingest/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Project } from 'ts-morph';
2
+ export interface ExtractedCall {
3
+ callerName: string;
4
+ calleeName: string;
5
+ relationType: 'calls' | 'imports';
6
+ }
7
+ export declare function extractCallsFromFile(project: Project, filePath: string): ExtractedCall[];
8
+ //# sourceMappingURL=relationships.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/ingest/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAoB,MAAM,UAAU,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CA+ExF"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractCallsFromFile = extractCallsFromFile;
4
+ const ts_morph_1 = require("ts-morph");
5
+ function extractCallsFromFile(project, filePath) {
6
+ const sourceFile = project.addSourceFileAtPath(filePath);
7
+ const calls = [];
8
+ // Extract calls from top-level functions
9
+ for (const fn of sourceFile.getFunctions()) {
10
+ const name = fn.getName();
11
+ if (!name)
12
+ continue;
13
+ const callExpressions = fn.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
14
+ for (const call of callExpressions) {
15
+ const calleeName = extractCalleeName(call);
16
+ if (calleeName && calleeName !== name) {
17
+ calls.push({ callerName: name, calleeName, relationType: 'calls' });
18
+ }
19
+ }
20
+ }
21
+ // Extract calls from arrow functions assigned to variables
22
+ for (const varStmt of sourceFile.getVariableStatements()) {
23
+ for (const decl of varStmt.getDeclarations()) {
24
+ const name = decl.getName();
25
+ const initializer = decl.getInitializer();
26
+ if (!initializer || (!ts_morph_1.Node.isArrowFunction(initializer) && !ts_morph_1.Node.isFunctionExpression(initializer)))
27
+ continue;
28
+ const callExpressions = initializer.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
29
+ for (const call of callExpressions) {
30
+ const calleeName = extractCalleeName(call);
31
+ if (calleeName && calleeName !== name) {
32
+ calls.push({ callerName: name, calleeName, relationType: 'calls' });
33
+ }
34
+ }
35
+ }
36
+ }
37
+ // Extract calls from class methods
38
+ for (const cls of sourceFile.getClasses()) {
39
+ const className = cls.getName() || 'AnonymousClass';
40
+ for (const method of cls.getMethods()) {
41
+ const methodName = `${className}.${method.getName()}`;
42
+ const callExpressions = method.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
43
+ for (const call of callExpressions) {
44
+ const calleeName = extractCalleeName(call);
45
+ if (calleeName && calleeName !== methodName) {
46
+ calls.push({ callerName: methodName, calleeName, relationType: 'calls' });
47
+ }
48
+ }
49
+ }
50
+ }
51
+ // Extract import relationships
52
+ for (const importDecl of sourceFile.getImportDeclarations()) {
53
+ const namedImports = importDecl.getNamedImports();
54
+ for (const named of namedImports) {
55
+ calls.push({
56
+ callerName: '__file__',
57
+ calleeName: named.getName(),
58
+ relationType: 'imports',
59
+ });
60
+ }
61
+ const defaultImport = importDecl.getDefaultImport();
62
+ if (defaultImport) {
63
+ calls.push({
64
+ callerName: '__file__',
65
+ calleeName: defaultImport.getText(),
66
+ relationType: 'imports',
67
+ });
68
+ }
69
+ }
70
+ project.removeSourceFile(sourceFile);
71
+ // Deduplicate
72
+ const seen = new Set();
73
+ return calls.filter(c => {
74
+ const key = `${c.callerName}|${c.calleeName}|${c.relationType}`;
75
+ if (seen.has(key))
76
+ return false;
77
+ seen.add(key);
78
+ return true;
79
+ });
80
+ }
81
+ function extractCalleeName(callExpression) {
82
+ const expression = callExpression.getChildAtIndex(0);
83
+ if (!expression)
84
+ return null;
85
+ const text = expression.getText();
86
+ // Handle property access: obj.method() -> "obj.method"
87
+ // Handle simple calls: foo() -> "foo"
88
+ // Skip complex expressions like foo()() or arr[0]()
89
+ if (text.includes('(') || text.includes('['))
90
+ return null;
91
+ return text;
92
+ }
93
+ //# sourceMappingURL=relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/ingest/relationships.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function scanDirectory(rootPath: string): string[];
2
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/ingest/scanner.ts"],"names":[],"mappings":"AAMA,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAIxD"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scanDirectory = scanDirectory;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const SKIP_DIRS = new Set(['node_modules', 'dist', '.git', '.structx', 'coverage', '.next', 'build', 'out']);
40
+ const TS_EXTENSIONS = new Set(['.ts', '.tsx']);
41
+ function scanDirectory(rootPath) {
42
+ const results = [];
43
+ walk(rootPath, results);
44
+ return results.sort();
45
+ }
46
+ function walk(dir, results) {
47
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
48
+ for (const entry of entries) {
49
+ const fullPath = path.join(dir, entry.name);
50
+ if (entry.isDirectory()) {
51
+ if (!SKIP_DIRS.has(entry.name)) {
52
+ walk(fullPath, results);
53
+ }
54
+ continue;
55
+ }
56
+ if (!entry.isFile())
57
+ continue;
58
+ const ext = path.extname(entry.name);
59
+ if (!TS_EXTENSIONS.has(ext))
60
+ continue;
61
+ // Skip declaration files
62
+ if (entry.name.endsWith('.d.ts'))
63
+ continue;
64
+ results.push(fullPath);
65
+ }
66
+ }
67
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/ingest/scanner.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,sCAIC;AAVD,uCAAyB;AACzB,2CAA6B;AAE7B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7G,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/C,SAAgB,aAAa,CAAC,QAAgB;IAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxB,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,IAAI,CAAC,GAAW,EAAE,OAAiB;IAC1C,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC1B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,SAAS;QAE9B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAEtC,yBAAyB;QACzB,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QAE3C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,41 @@
1
+ # StructX — Code Intelligence Graph
2
+
3
+ This project uses **StructX**, a graph-powered code intelligence tool for TypeScript.
4
+ StructX maintains a function-level knowledge graph of the codebase that you should use
5
+ instead of reading raw source files when answering code questions.
6
+
7
+ ## Rules
8
+
9
+ 1. **On session start:** Run `npx structx status` to check if the graph is initialized.
10
+ If not initialized, run `npx structx setup .` to bootstrap (init + ingest + analyze).
11
+
12
+ 2. **Before answering code questions:** Run `npx structx ask "your question" --repo .`
13
+ instead of reading raw files. The graph provides function signatures, purposes,
14
+ relationships, and semantic metadata that raw file reads miss.
15
+
16
+ 3. **After making code changes:** Run `npx structx ingest .` to update the function graph
17
+ with your changes.
18
+
19
+ 4. **After ingestion queues new functions:** Run `npx structx analyze . --yes` to enrich
20
+ newly discovered or changed functions with semantic metadata.
21
+
22
+ 5. **For impact analysis:** Before modifying a function, run
23
+ `npx structx ask "what breaks if I change <functionName>" --repo .`
24
+ to understand downstream effects.
25
+
26
+ ## Available Commands
27
+
28
+ | Command | Description |
29
+ |---------|-------------|
30
+ | `npx structx status` | Check if graph is initialized and view stats |
31
+ | `npx structx setup .` | One-step bootstrap (init + ingest + analyze) |
32
+ | `npx structx ingest .` | Re-parse codebase after changes |
33
+ | `npx structx analyze . --yes` | Run semantic analysis on new/changed functions |
34
+ | `npx structx ask "question" --repo .` | Query the function graph |
35
+
36
+ ## When to Use StructX vs Raw File Reads
37
+
38
+ - **Use StructX** for: understanding function purposes, finding callers/callees,
39
+ impact analysis, discovering related functions, understanding code architecture.
40
+ - **Use raw file reads** for: viewing exact implementation details, making edits,
41
+ reading config files, non-TypeScript files.
@@ -0,0 +1,39 @@
1
+ # StructX — Code Intelligence Graph
2
+
3
+ This project uses **StructX**, a graph-powered code intelligence tool for TypeScript.
4
+ StructX maintains a function-level knowledge graph of the codebase that you should use
5
+ instead of reading raw source files when answering code questions.
6
+
7
+ ## Rules
8
+
9
+ 1. **On session start:** Run `npx structx status` to check if the graph is initialized.
10
+ If not initialized, run `npx structx setup .` to bootstrap (init + ingest + analyze).
11
+
12
+ 2. **Before answering code questions:** Run `npx structx ask "your question" --repo .`
13
+ instead of reading raw files. The graph provides function signatures, purposes,
14
+ relationships, and semantic metadata that raw file reads miss.
15
+
16
+ 3. **After making code changes:** Run `npx structx ingest .` to update the function graph
17
+ with your changes.
18
+
19
+ 4. **After ingestion queues new functions:** Run `npx structx analyze . --yes` to enrich
20
+ newly discovered or changed functions with semantic metadata.
21
+
22
+ 5. **For impact analysis:** Before modifying a function, run
23
+ `npx structx ask "what breaks if I change <functionName>" --repo .`
24
+ to understand downstream effects.
25
+
26
+ ## Available Commands
27
+
28
+ - `npx structx status` — Check if graph is initialized and view stats
29
+ - `npx structx setup .` — One-step bootstrap (init + ingest + analyze)
30
+ - `npx structx ingest .` — Re-parse codebase after changes
31
+ - `npx structx analyze . --yes` — Run semantic analysis on new/changed functions
32
+ - `npx structx ask "question" --repo .` — Query the function graph
33
+
34
+ ## When to Use StructX vs Raw File Reads
35
+
36
+ - **Use StructX** for: understanding function purposes, finding callers/callees,
37
+ impact analysis, discovering related functions, understanding code architecture.
38
+ - **Use raw file reads** for: viewing exact implementation details, making edits,
39
+ reading config files, non-TypeScript files.