mcp-code-context 3.9.2 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/INSTRUCTIONS.md +15 -4
  3. package/README.md +109 -5
  4. package/dist/src/core/engine.d.ts +1 -1
  5. package/dist/src/core/engine.js +1 -1
  6. package/dist/src/core/indexManager.d.ts +1 -1
  7. package/dist/src/core/indexManager.js +1 -1
  8. package/dist/src/core/sessionManager.d.ts +1 -1
  9. package/dist/src/core/sessionManager.js +1 -1
  10. package/dist/src/core/validator.d.ts +1 -1
  11. package/dist/src/core/validator.js +1 -1
  12. package/dist/src/index.d.ts +4 -2
  13. package/dist/src/index.js +119 -14
  14. package/dist/src/index.js.map +1 -1
  15. package/dist/src/operations/apiRoutes.d.ts +31 -0
  16. package/dist/src/operations/apiRoutes.js +170 -0
  17. package/dist/src/operations/apiRoutes.js.map +1 -0
  18. package/dist/src/operations/architectureLinter.d.ts +45 -0
  19. package/dist/src/operations/architectureLinter.js +223 -0
  20. package/dist/src/operations/architectureLinter.js.map +1 -0
  21. package/dist/src/operations/astComplexity.d.ts +38 -0
  22. package/dist/src/operations/astComplexity.js +243 -0
  23. package/dist/src/operations/astComplexity.js.map +1 -0
  24. package/dist/src/operations/astMockGenerator.d.ts +34 -0
  25. package/dist/src/operations/astMockGenerator.js +203 -0
  26. package/dist/src/operations/astMockGenerator.js.map +1 -0
  27. package/dist/src/operations/astQuery.d.ts +47 -0
  28. package/dist/src/operations/astQuery.js +169 -0
  29. package/dist/src/operations/astQuery.js.map +1 -0
  30. package/dist/src/operations/astTransform.d.ts +1 -1
  31. package/dist/src/operations/astTransform.js +11 -2
  32. package/dist/src/operations/astTransform.js.map +1 -1
  33. package/dist/src/operations/asyncBlockers.d.ts +33 -0
  34. package/dist/src/operations/asyncBlockers.js +162 -0
  35. package/dist/src/operations/asyncBlockers.js.map +1 -0
  36. package/dist/src/operations/blastRadiusReport.d.ts +43 -0
  37. package/dist/src/operations/blastRadiusReport.js +236 -0
  38. package/dist/src/operations/blastRadiusReport.js.map +1 -0
  39. package/dist/src/operations/callHierarchy.d.ts +28 -0
  40. package/dist/src/operations/callHierarchy.js +166 -0
  41. package/dist/src/operations/callHierarchy.js.map +1 -0
  42. package/dist/src/operations/circularDependencies.d.ts +28 -0
  43. package/dist/src/operations/circularDependencies.js +201 -0
  44. package/dist/src/operations/circularDependencies.js.map +1 -0
  45. package/dist/src/operations/classHierarchyFlattener.d.ts +35 -0
  46. package/dist/src/operations/classHierarchyFlattener.js +185 -0
  47. package/dist/src/operations/classHierarchyFlattener.js.map +1 -0
  48. package/dist/src/operations/compress.d.ts +2 -2
  49. package/dist/src/operations/compress.js +154 -20
  50. package/dist/src/operations/compress.js.map +1 -1
  51. package/dist/src/operations/conceptSearch.d.ts +19 -0
  52. package/dist/src/operations/conceptSearch.js +176 -0
  53. package/dist/src/operations/conceptSearch.js.map +1 -0
  54. package/dist/src/operations/confirmationStore.d.ts +1 -1
  55. package/dist/src/operations/confirmationStore.js +1 -1
  56. package/dist/src/operations/conflictPredictor.d.ts +21 -0
  57. package/dist/src/operations/conflictPredictor.js +139 -0
  58. package/dist/src/operations/conflictPredictor.js.map +1 -0
  59. package/dist/src/operations/contextCompactor.d.ts +38 -0
  60. package/dist/src/operations/contextCompactor.js +348 -0
  61. package/dist/src/operations/contextCompactor.js.map +1 -0
  62. package/dist/src/operations/cstCodemod.d.ts +34 -0
  63. package/dist/src/operations/cstCodemod.js +205 -0
  64. package/dist/src/operations/cstCodemod.js.map +1 -0
  65. package/dist/src/operations/deadSymbols.d.ts +32 -0
  66. package/dist/src/operations/deadSymbols.js +178 -0
  67. package/dist/src/operations/deadSymbols.js.map +1 -0
  68. package/dist/src/operations/envContract.d.ts +35 -0
  69. package/dist/src/operations/envContract.js +194 -0
  70. package/dist/src/operations/envContract.js.map +1 -0
  71. package/dist/src/operations/errorAudit.d.ts +36 -0
  72. package/dist/src/operations/errorAudit.js +201 -0
  73. package/dist/src/operations/errorAudit.js.map +1 -0
  74. package/dist/src/operations/importIntegrity.d.ts +48 -0
  75. package/dist/src/operations/importIntegrity.js +395 -0
  76. package/dist/src/operations/importIntegrity.js.map +1 -0
  77. package/dist/src/operations/incrementalDiff.d.ts +47 -0
  78. package/dist/src/operations/incrementalDiff.js +216 -0
  79. package/dist/src/operations/incrementalDiff.js.map +1 -0
  80. package/dist/src/operations/lexicalScope.d.ts +51 -0
  81. package/dist/src/operations/lexicalScope.js +212 -0
  82. package/dist/src/operations/lexicalScope.js.map +1 -0
  83. package/dist/src/operations/read.d.ts +21 -0
  84. package/dist/src/operations/read.js +21 -0
  85. package/dist/src/operations/read.js.map +1 -1
  86. package/dist/src/operations/readCore.js +37 -17
  87. package/dist/src/operations/readCore.js.map +1 -1
  88. package/dist/src/operations/rename.js +35 -24
  89. package/dist/src/operations/rename.js.map +1 -1
  90. package/dist/src/operations/sqlValidator.d.ts +36 -0
  91. package/dist/src/operations/sqlValidator.js +202 -0
  92. package/dist/src/operations/sqlValidator.js.map +1 -0
  93. package/dist/src/operations/symbolQuery.js +112 -23
  94. package/dist/src/operations/symbolQuery.js.map +1 -1
  95. package/dist/src/operations/taintAnalysis.d.ts +46 -0
  96. package/dist/src/operations/taintAnalysis.js +220 -0
  97. package/dist/src/operations/taintAnalysis.js.map +1 -0
  98. package/dist/src/operations/testImpact.d.ts +31 -0
  99. package/dist/src/operations/testImpact.js +179 -0
  100. package/dist/src/operations/testImpact.js.map +1 -0
  101. package/dist/src/operations/typeInference.d.ts +54 -0
  102. package/dist/src/operations/typeInference.js +565 -0
  103. package/dist/src/operations/typeInference.js.map +1 -0
  104. package/dist/src/operations/wireContract.d.ts +34 -0
  105. package/dist/src/operations/wireContract.js +185 -0
  106. package/dist/src/operations/wireContract.js.map +1 -0
  107. package/dist/src/operations/write.d.ts +2 -2
  108. package/dist/src/operations/write.js +151 -82
  109. package/dist/src/operations/write.js.map +1 -1
  110. package/dist/src/parsers/base.d.ts +9 -1
  111. package/dist/src/parsers/base.js +61 -1
  112. package/dist/src/parsers/base.js.map +1 -1
  113. package/dist/src/parsers/csharp.d.ts +1 -1
  114. package/dist/src/parsers/csharp.js +1 -1
  115. package/dist/src/parsers/dartTreeSitter.d.ts +1 -1
  116. package/dist/src/parsers/dartTreeSitter.js +1 -1
  117. package/dist/src/parsers/go.d.ts +1 -1
  118. package/dist/src/parsers/go.js +1 -1
  119. package/dist/src/parsers/java.d.ts +1 -1
  120. package/dist/src/parsers/java.js +1 -1
  121. package/dist/src/parsers/kotlin.d.ts +1 -1
  122. package/dist/src/parsers/kotlin.js +1 -1
  123. package/dist/src/parsers/php.d.ts +1 -1
  124. package/dist/src/parsers/php.js +1 -1
  125. package/dist/src/parsers/python.d.ts +1 -1
  126. package/dist/src/parsers/python.js +1 -1
  127. package/dist/src/parsers/registry.d.ts +1 -1
  128. package/dist/src/parsers/registry.js +1 -1
  129. package/dist/src/parsers/ruby.d.ts +1 -1
  130. package/dist/src/parsers/ruby.js +1 -1
  131. package/dist/src/parsers/rust.d.ts +1 -1
  132. package/dist/src/parsers/rust.js +1 -1
  133. package/dist/src/parsers/typescript.d.ts +1 -1
  134. package/dist/src/parsers/typescript.js +1 -1
  135. package/dist/src/tools/context.d.ts +4 -0
  136. package/dist/src/tools/context.js +14 -0
  137. package/dist/src/tools/context.js.map +1 -1
  138. package/dist/src/tools/pipeline.js +26 -0
  139. package/dist/src/tools/pipeline.js.map +1 -1
  140. package/dist/src/tools/readHandlers.d.ts +150 -0
  141. package/dist/src/tools/readHandlers.js +622 -17
  142. package/dist/src/tools/readHandlers.js.map +1 -1
  143. package/dist/src/tools/toolDefinitions.d.ts +2184 -0
  144. package/dist/src/tools/toolDefinitionsCore.d.ts +2184 -0
  145. package/dist/src/tools/toolDefinitionsCore.js +381 -1
  146. package/dist/src/tools/toolDefinitionsCore.js.map +1 -1
  147. package/dist/src/tools/writeHandlers.js +3 -1
  148. package/dist/src/tools/writeHandlers.js.map +1 -1
  149. package/dist/src/utils/appDir.d.ts +1 -1
  150. package/dist/src/utils/appDir.js +1 -1
  151. package/dist/src/utils/auditLogger.d.ts +1 -1
  152. package/dist/src/utils/auditLogger.js +1 -1
  153. package/dist/src/utils/backupManager.d.ts +1 -1
  154. package/dist/src/utils/backupManager.js +1 -1
  155. package/dist/src/utils/conceptEngine.d.ts +56 -0
  156. package/dist/src/utils/conceptEngine.js +234 -0
  157. package/dist/src/utils/conceptEngine.js.map +1 -0
  158. package/dist/src/utils/constants.d.ts +1 -1
  159. package/dist/src/utils/constants.js +2 -1
  160. package/dist/src/utils/constants.js.map +1 -1
  161. package/dist/src/utils/diff.d.ts +1 -1
  162. package/dist/src/utils/diff.js +1 -1
  163. package/dist/src/utils/fileLock.d.ts +1 -1
  164. package/dist/src/utils/fileLock.js +1 -1
  165. package/dist/src/utils/fileWalker.d.ts +1 -1
  166. package/dist/src/utils/fileWalker.js +1 -1
  167. package/dist/src/utils/fileWatcher.d.ts +1 -1
  168. package/dist/src/utils/fileWatcher.js +1 -1
  169. package/dist/src/utils/fuzzySearch.d.ts +1 -1
  170. package/dist/src/utils/fuzzySearch.js +1 -1
  171. package/dist/src/utils/gemfileParser.d.ts +1 -1
  172. package/dist/src/utils/gemfileParser.js +1 -1
  173. package/dist/src/utils/logger.d.ts +1 -1
  174. package/dist/src/utils/logger.js +1 -1
  175. package/dist/src/utils/metaprogramming.d.ts +1 -1
  176. package/dist/src/utils/metaprogramming.js +1 -1
  177. package/dist/src/utils/railsRoutes.d.ts +1 -1
  178. package/dist/src/utils/railsRoutes.js +1 -1
  179. package/dist/src/utils/rateLimiter.d.ts +26 -1
  180. package/dist/src/utils/rateLimiter.js +26 -1
  181. package/dist/src/utils/rateLimiter.js.map +1 -1
  182. package/dist/src/utils/streaming.d.ts +1 -1
  183. package/dist/src/utils/streaming.js +1 -1
  184. package/dist/src/utils/telemetry.d.ts +1 -1
  185. package/dist/src/utils/telemetry.js +1 -1
  186. package/dist/src/utils/virtualSchema.d.ts +31 -0
  187. package/dist/src/utils/virtualSchema.js +367 -0
  188. package/dist/src/utils/virtualSchema.js.map +1 -0
  189. package/llms.txt +13 -3
  190. package/package.json +97 -95
  191. package/skills/code-context-logo.png +0 -0
  192. package/skills/code-context-pro/SKILL.md +149 -0
  193. package/skills/code-context-pro/references/benchmarks.md +25 -0
  194. package/skills/code-context-pro/references/decision-tree.md +32 -0
  195. package/skills/code-context-pro/references/multi-ide-setup.md +104 -0
  196. package/skills/code-context-pro.zip +0 -0
  197. package/HIRE_ME.md +0 -234
  198. package/SPONSORS.md +0 -104
@@ -0,0 +1,201 @@
1
+ /**
2
+ * AST Circular Import Cycle Detector (Tarjan's SCC Algorithm)
3
+ * v7.0.1 Enterprise AST Intelligence
4
+ */
5
+ import * as fs from "node:fs/promises";
6
+ import * as path from "node:path";
7
+ import { existsSync } from "node:fs";
8
+ import { ParserRegistry } from "../parsers/registry.js";
9
+ import { CodeContextEngine } from "../core/engine.js";
10
+ /**
11
+ * Extracts imported relative module paths from AST
12
+ */
13
+ function extractRelativeImports(rootNode) {
14
+ const imports = [];
15
+ function walk(n) {
16
+ // import ... from './x'
17
+ if (n.type === "import_statement") {
18
+ const srcNode = n.childForFieldName("source");
19
+ if (srcNode) {
20
+ const raw = srcNode.text.replace(/^["']|["']$/g, "");
21
+ if (raw.startsWith("."))
22
+ imports.push(raw);
23
+ }
24
+ }
25
+ // require('./x')
26
+ if (n.type === "call_expression") {
27
+ const fn = n.childForFieldName("function")?.text;
28
+ if (fn === "require") {
29
+ const arg = n.childForFieldName("arguments")?.namedChild(0)?.text;
30
+ if (arg) {
31
+ const raw = arg.replace(/^["']|["']$/g, "");
32
+ if (raw.startsWith("."))
33
+ imports.push(raw);
34
+ }
35
+ }
36
+ }
37
+ for (let i = 0; i < n.namedChildCount; i++) {
38
+ const child = n.namedChild(i);
39
+ if (child)
40
+ walk(child);
41
+ }
42
+ }
43
+ walk(rootNode);
44
+ return imports;
45
+ }
46
+ /**
47
+ * Normalizes an imported path against its parent file
48
+ */
49
+ function resolveImportPath(parentFile, importPath) {
50
+ const dir = path.dirname(parentFile);
51
+ let resolved = path.join(dir, importPath).replace(/\\/g, "/");
52
+ // Normalize extensions
53
+ if (resolved.endsWith(".js"))
54
+ resolved = resolved.slice(0, -3);
55
+ if (resolved.endsWith(".ts"))
56
+ resolved = resolved.slice(0, -3);
57
+ return resolved;
58
+ }
59
+ /**
60
+ * Tarjan's Strongly Connected Components algorithm for finding cycles
61
+ */
62
+ function findCyclesTarjan(adjList) {
63
+ let index = 0;
64
+ const indices = new Map();
65
+ const lowlinks = new Map();
66
+ const onStack = new Set();
67
+ const stack = [];
68
+ const sccs = [];
69
+ function strongConnect(u) {
70
+ indices.set(u, index);
71
+ lowlinks.set(u, index);
72
+ index++;
73
+ stack.push(u);
74
+ onStack.add(u);
75
+ const neighbors = adjList.get(u) || [];
76
+ for (const v of neighbors) {
77
+ if (!indices.has(v)) {
78
+ strongConnect(v);
79
+ lowlinks.set(u, Math.min(lowlinks.get(u), lowlinks.get(v)));
80
+ }
81
+ else if (onStack.has(v)) {
82
+ lowlinks.set(u, Math.min(lowlinks.get(u), indices.get(v)));
83
+ }
84
+ }
85
+ if (lowlinks.get(u) === indices.get(u)) {
86
+ const scc = [];
87
+ let w = "";
88
+ do {
89
+ w = stack.pop();
90
+ onStack.delete(w);
91
+ scc.push(w);
92
+ } while (w !== u);
93
+ // A component with > 1 node or a self-loop is a cycle
94
+ if (scc.length > 1) {
95
+ sccs.push(scc.reverse());
96
+ }
97
+ else if (scc.length === 1 && (adjList.get(scc[0]) || []).includes(scc[0])) {
98
+ sccs.push([scc[0], scc[0]]);
99
+ }
100
+ }
101
+ }
102
+ for (const node of adjList.keys()) {
103
+ if (!indices.has(node)) {
104
+ strongConnect(node);
105
+ }
106
+ }
107
+ return sccs;
108
+ }
109
+ /**
110
+ * Detects circular import dependencies across codebase
111
+ */
112
+ export async function detectCircularDependencies(params) {
113
+ const projectRoot = params.projectRoot || ".";
114
+ try {
115
+ let registry = params.registry;
116
+ if (!registry) {
117
+ const engine = new CodeContextEngine();
118
+ await engine.init();
119
+ registry = new ParserRegistry(engine);
120
+ await registry.init();
121
+ }
122
+ const parser = registry.getParser(".ts");
123
+ if (!parser) {
124
+ return {
125
+ success: false,
126
+ error: "No TypeScript parser available for dependency analysis",
127
+ };
128
+ }
129
+ const filesToAnalyze = new Map();
130
+ if (params.filesMap) {
131
+ for (const [f, c] of Object.entries(params.filesMap)) {
132
+ let norm = f.replace(/\\/g, "/");
133
+ if (norm.endsWith(".ts"))
134
+ norm = norm.slice(0, -3);
135
+ if (norm.endsWith(".js"))
136
+ norm = norm.slice(0, -3);
137
+ filesToAnalyze.set(norm, c);
138
+ }
139
+ }
140
+ else if (params.filePaths) {
141
+ for (const f of params.filePaths) {
142
+ if (existsSync(f)) {
143
+ const content = await fs.readFile(f, "utf-8");
144
+ let norm = path.relative(projectRoot, f).replace(/\\/g, "/");
145
+ if (norm.endsWith(".ts"))
146
+ norm = norm.slice(0, -3);
147
+ if (norm.endsWith(".js"))
148
+ norm = norm.slice(0, -3);
149
+ filesToAnalyze.set(norm, content);
150
+ }
151
+ }
152
+ }
153
+ const adjList = new Map();
154
+ for (const [fileKey, content] of filesToAnalyze.entries()) {
155
+ let tree = null;
156
+ try {
157
+ tree = parser.parse(content);
158
+ const rawImports = extractRelativeImports(tree.rootNode);
159
+ const resolved = rawImports.map(imp => resolveImportPath(fileKey, imp));
160
+ adjList.set(fileKey, resolved.filter(r => filesToAnalyze.has(r)));
161
+ }
162
+ finally {
163
+ if (tree) {
164
+ try {
165
+ tree.delete();
166
+ }
167
+ catch {
168
+ // ignore
169
+ }
170
+ }
171
+ }
172
+ }
173
+ const sccs = findCyclesTarjan(adjList);
174
+ const cycles = sccs.map(scc => {
175
+ const cycleLoop = [...scc, scc[0]];
176
+ return {
177
+ cycleLength: scc.length,
178
+ cyclePath: cycleLoop,
179
+ recommendation: `Break circular dependency: Extract shared interfaces or types from '${scc[0]}' into a separate 'types.ts' module or inject dependency.`,
180
+ };
181
+ });
182
+ const report = {
183
+ projectRoot,
184
+ totalFilesAnalyzed: filesToAnalyze.size,
185
+ totalCyclesFound: cycles.length,
186
+ cycles,
187
+ summary: `Analyzed ${filesToAnalyze.size} modules. Found ${cycles.length} circular dependency cycles.`,
188
+ };
189
+ return {
190
+ success: true,
191
+ content: JSON.stringify(report, null, 2),
192
+ };
193
+ }
194
+ catch (error) {
195
+ return {
196
+ success: false,
197
+ error: `detect_circular_dependencies failed: ${error instanceof Error ? error.message : String(error)}`,
198
+ };
199
+ }
200
+ }
201
+ //# sourceMappingURL=circularDependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circularDependencies.js","sourceRoot":"","sources":["../../../src/operations/circularDependencies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Trait, Mixin & Inheritance Class Hierarchy Flattener
3
+ * v7.0.1 Enterprise AST Intelligence
4
+ */
5
+ import { ParserRegistry } from "../parsers/registry.js";
6
+ import type { ReadResult } from "./readCore.js";
7
+ export interface FlatClassMethod {
8
+ name: string;
9
+ source: "self" | "trait" | "parent";
10
+ originName: string;
11
+ visibility: "public" | "protected" | "private";
12
+ isStatic: boolean;
13
+ signature: string;
14
+ line?: number;
15
+ }
16
+ export interface FlattenedClassReport {
17
+ className: string;
18
+ parentClass?: string;
19
+ traitsUsed: string[];
20
+ totalMethods: number;
21
+ methods: FlatClassMethod[];
22
+ summary: string;
23
+ }
24
+ export interface ClassFlattenerOptions {
25
+ filePath?: string;
26
+ className?: string;
27
+ code?: string;
28
+ content?: string;
29
+ projectRoot?: string;
30
+ registry?: ParserRegistry;
31
+ }
32
+ /**
33
+ * Flattens class traits, mixins and methods
34
+ */
35
+ export declare function flattenClassHierarchy(params: ClassFlattenerOptions): Promise<ReadResult>;
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Trait, Mixin & Inheritance Class Hierarchy Flattener
3
+ * v7.0.1 Enterprise AST Intelligence
4
+ */
5
+ import * as fs from "node:fs/promises";
6
+ import * as path from "node:path";
7
+ import { existsSync } from "node:fs";
8
+ import { ParserRegistry } from "../parsers/registry.js";
9
+ import { CodeContextEngine } from "../core/engine.js";
10
+ /**
11
+ * Parses method declarations from a class or trait body
12
+ */
13
+ function extractClassMethods(bodyNode, source, originName) {
14
+ const methods = [];
15
+ for (let i = 0; i < bodyNode.namedChildCount; i++) {
16
+ const m = bodyNode.namedChild(i);
17
+ if (!m)
18
+ continue;
19
+ if (m.type === "method_declaration" ||
20
+ m.type === "method_definition" ||
21
+ m.type === "function_definition") {
22
+ const name = m.childForFieldName("name")?.text || "anonymous";
23
+ const text = m.text;
24
+ let visibility = "public";
25
+ if (text.includes("private "))
26
+ visibility = "private";
27
+ else if (text.includes("protected "))
28
+ visibility = "protected";
29
+ const isStatic = text.includes("static ");
30
+ const firstLine = text.split("\n")[0].replace(/\{.*$/, "").trim();
31
+ methods.push({
32
+ name,
33
+ source,
34
+ originName,
35
+ visibility,
36
+ isStatic,
37
+ signature: firstLine,
38
+ line: m.startPosition.row + 1,
39
+ });
40
+ }
41
+ }
42
+ return methods;
43
+ }
44
+ /**
45
+ * Flattens class traits, mixins and methods
46
+ */
47
+ export async function flattenClassHierarchy(params) {
48
+ let tree = null;
49
+ try {
50
+ const targetPath = params.filePath || "in_memory.php";
51
+ let content = params.code ?? params.content;
52
+ if (content === undefined) {
53
+ if (params.filePath && existsSync(params.filePath)) {
54
+ content = await fs.readFile(params.filePath, "utf-8");
55
+ }
56
+ else {
57
+ return {
58
+ success: false,
59
+ error: `File does not exist: ${params.filePath || "none"}`,
60
+ };
61
+ }
62
+ }
63
+ const ext = path.extname(targetPath).toLowerCase();
64
+ let registry = params.registry;
65
+ if (!registry) {
66
+ const engine = new CodeContextEngine();
67
+ await engine.init();
68
+ registry = new ParserRegistry(engine);
69
+ await registry.init();
70
+ }
71
+ const parser = registry.getParser(ext === ".php" ? ".php" : ext === ".py" ? ".py" : ".ts");
72
+ if (!parser) {
73
+ return {
74
+ success: false,
75
+ error: `No parser available for extension: ${ext}`,
76
+ };
77
+ }
78
+ tree = parser.parse(content);
79
+ // Locate target class
80
+ let classNode = null;
81
+ let resolvedClassName = params.className || "UnknownClass";
82
+ let parentClass = undefined;
83
+ const traitsUsed = [];
84
+ function findClass(n) {
85
+ if (n.type === "class_declaration" ||
86
+ n.type === "class_definition") {
87
+ const nameNode = n.childForFieldName("name");
88
+ if (!params.className || nameNode?.text === params.className) {
89
+ classNode = n;
90
+ resolvedClassName = nameNode?.text || resolvedClassName;
91
+ return;
92
+ }
93
+ }
94
+ for (let i = 0; i < n.namedChildCount; i++) {
95
+ if (!classNode) {
96
+ const child = n.namedChild(i);
97
+ if (child)
98
+ findClass(child);
99
+ }
100
+ }
101
+ }
102
+ findClass(tree.rootNode);
103
+ if (!classNode) {
104
+ return {
105
+ success: false,
106
+ error: `Class '${params.className || "first"}' not found in AST.`,
107
+ };
108
+ }
109
+ const targetClass = classNode;
110
+ // Check base class (extends)
111
+ const baseNode = targetClass.childForFieldName("base") || targetClass.childForFieldName("superclasses");
112
+ if (baseNode) {
113
+ parentClass = baseNode.text.replace(/^extends\s+/i, "");
114
+ }
115
+ const classBody = targetClass.childForFieldName("body") || targetClass.namedChild(targetClass.namedChildCount - 1);
116
+ const methods = [];
117
+ if (classBody) {
118
+ // 1. Detect trait usages: use PluginManagementTrait, ThemeManagementTrait;
119
+ for (let i = 0; i < classBody.namedChildCount; i++) {
120
+ const child = classBody.namedChild(i);
121
+ if (!child)
122
+ continue;
123
+ if (child.type === "use_declaration" || child.text.startsWith("use ")) {
124
+ // Extract trait names from use statement
125
+ const traitMatches = child.text.replace(/^use\s+/, "").replace(/;.*$/, "").split(",");
126
+ for (const rawTrait of traitMatches) {
127
+ const cleanTrait = rawTrait.trim();
128
+ if (cleanTrait)
129
+ traitsUsed.push(cleanTrait);
130
+ }
131
+ }
132
+ }
133
+ // 2. Extract self methods
134
+ const selfMethods = extractClassMethods(classBody, "self", resolvedClassName);
135
+ methods.push(...selfMethods);
136
+ }
137
+ // 3. Synthesize virtual trait methods if defined in same file
138
+ for (const traitName of traitsUsed) {
139
+ function findTrait(n) {
140
+ if (n.type === "trait_declaration" && n.childForFieldName("name")?.text === traitName) {
141
+ const traitBody = n.childForFieldName("body") || n.namedChild(n.namedChildCount - 1);
142
+ if (traitBody) {
143
+ const traitMethods = extractClassMethods(traitBody, "trait", traitName);
144
+ methods.push(...traitMethods);
145
+ }
146
+ }
147
+ for (let i = 0; i < n.namedChildCount; i++) {
148
+ const child = n.namedChild(i);
149
+ if (child)
150
+ findTrait(child);
151
+ }
152
+ }
153
+ findTrait(tree.rootNode);
154
+ }
155
+ const report = {
156
+ className: resolvedClassName,
157
+ parentClass,
158
+ traitsUsed,
159
+ totalMethods: methods.length,
160
+ methods,
161
+ summary: `Flattened class '${resolvedClassName}'. Uses ${traitsUsed.length} traits. Total resolved methods: ${methods.length}.`,
162
+ };
163
+ return {
164
+ success: true,
165
+ content: JSON.stringify(report, null, 2),
166
+ };
167
+ }
168
+ catch (error) {
169
+ return {
170
+ success: false,
171
+ error: `flatten_class_hierarchy failed: ${error instanceof Error ? error.message : String(error)}`,
172
+ };
173
+ }
174
+ finally {
175
+ if (tree) {
176
+ try {
177
+ tree.delete();
178
+ }
179
+ catch {
180
+ // ignore
181
+ }
182
+ }
183
+ }
184
+ }
185
+ //# sourceMappingURL=classHierarchyFlattener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classHierarchyFlattener.js","sourceRoot":"","sources":["../../../src/operations/classHierarchyFlattener.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Semantic Compression - v3.9.2
2
+ * Semantic Compression - v7.0.1
3
3
  * IMPROVEMENTS: Centralized constants + size limits + timeout + index feeding
4
4
  */
5
5
  import { ParserRegistry } from "../parsers/registry.js";
@@ -14,7 +14,7 @@ export interface CompressionResult {
14
14
  declare function compressRepository(params: {
15
15
  directoryPath: string;
16
16
  projectRoot: string;
17
- format?: "xml" | "markdown";
17
+ format?: "xml" | "markdown" | "html";
18
18
  registry: ParserRegistry;
19
19
  maxDepth?: number;
20
20
  includeSymbols?: boolean;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Semantic Compression - v3.9.2
2
+ * Semantic Compression - v7.0.1
3
3
  * IMPROVEMENTS: Centralized constants + size limits + timeout + index feeding
4
4
  */
5
5
  import * as fs from "node:fs/promises";
@@ -8,7 +8,8 @@ import * as crypto from "node:crypto";
8
8
  import { EXCLUDE_DIRS, MAX_FILES_REPO_MAP, MAX_TOTAL_SIZE_BYTES } from "../utils/constants.js";
9
9
  import { walkDir } from "../utils/fileWalker.js";
10
10
  import { IndexManager } from "../core/indexManager.js";
11
- import { loadRailsSchema, modelToTable, findRailsConcerns } from "../utils/railsSchema.js";
11
+ import { modelToTable, findRailsConcerns } from "../utils/railsSchema.js";
12
+ import { loadUnifiedVirtualSchema } from "../utils/virtualSchema.js";
12
13
  import { parseGemfile } from "../utils/gemfileParser.js";
13
14
  /**
14
15
  * Generate semantic repository map
@@ -36,31 +37,42 @@ async function compressRepository(params) {
36
37
  .update(content)
37
38
  .digest("hex");
38
39
  const symbols = await (async () => {
39
- // Skip re-parsing if index is up to date
40
- if (!(await indexManager.isStale(fullPath, fileHash))) {
41
- const tree = parser.parse(content);
42
- return parser.findSymbols(tree);
40
+ let tree;
41
+ try {
42
+ tree = parser.parse(content);
43
+ const syms = parser.findSymbols(tree);
44
+ // Skip re-indexing if index is up to date
45
+ if (await indexManager.isStale(fullPath, fileHash)) {
46
+ // Extract import dependencies
47
+ const deps = extractImports(content, fullPath, params.directoryPath);
48
+ // Feed index (fire-and-forget, never blocks the repo map)
49
+ indexManager.indexFile(fullPath, fileHash, syms, deps).catch(() => {
50
+ // Index feeding is fire-and-forget — never blocks repo map generation
51
+ });
52
+ }
53
+ return syms;
54
+ }
55
+ finally {
56
+ try {
57
+ tree?.delete();
58
+ }
59
+ catch {
60
+ // Safe disposal of WASM tree
61
+ }
43
62
  }
44
- const tree = parser.parse(content);
45
- const syms = parser.findSymbols(tree);
46
- // Extract import dependencies
47
- const deps = extractImports(content, fullPath, params.directoryPath);
48
- // Feed index (fire-and-forget, never blocks the repo map)
49
- indexManager.indexFile(fullPath, fileHash, syms, deps).catch(() => {
50
- // Index feeding is fire-and-forget — never blocks repo map generation
51
- });
52
- return syms;
53
63
  })();
54
64
  totalSymbols += symbols.length;
55
- // R1: Rails AR schema injection for .rb files in repo map
65
+ // R1: Virtual ORM schema injection for .rb, .php, .py, .ts, .tsx in repo map
56
66
  let fileSymbols = symbols.map(s => ({ type: s.type, name: s.name }));
57
- if (path.extname(fullPath) === ".rb") {
58
- const schema = await loadRailsSchema(params.projectRoot).catch(() => null);
67
+ const ext = path.extname(fullPath);
68
+ if (ext === ".rb" || ext === ".php" || ext === ".py" || ext === ".ts" || ext === ".tsx") {
69
+ const unified = await loadUnifiedVirtualSchema(params.projectRoot, ext).catch(() => null);
70
+ const schema = unified?.schema;
59
71
  if (schema) {
60
72
  for (const sym of symbols) {
61
- if (sym.type === "class") {
73
+ if (sym.type === "class" || sym.type === "interface" || sym.type === "variable_declarator") {
62
74
  const tableName = modelToTable(sym.name);
63
- const columns = schema[tableName];
75
+ const columns = schema[tableName] || schema[sym.name.toLowerCase()] || schema[sym.name];
64
76
  if (columns && Object.keys(columns).length > 0) {
65
77
  const dbCols = Object.entries(columns).map(([col, type]) => ({
66
78
  type: "db_column",
@@ -96,6 +108,128 @@ async function compressRepository(params) {
96
108
  const includeSymbols = params.includeSymbols !== false && files.length <= 100 && totalSymbols <= 1000;
97
109
  // Project-wide metadata: Gemfile + Concerns
98
110
  let projectMetadata = "";
111
+ if (format === "html") {
112
+ const escapedPath = params.directoryPath.replace(/</g, "&lt;").replace(/>/g, "&gt;");
113
+ const filesJson = JSON.stringify(files.map(f => ({
114
+ path: f.path,
115
+ symbols: f.symbols
116
+ }))).replace(/</g, "\\u003c");
117
+ const html = `<!DOCTYPE html>
118
+ <html lang="en">
119
+ <head>
120
+ <meta charset="UTF-8">
121
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
122
+ <title>Architecture Map - ${escapedPath}</title>
123
+ <style>
124
+ :root {
125
+ --bg: #0f172a;
126
+ --card-bg: #1e293b;
127
+ --border: #334155;
128
+ --text: #f8fafc;
129
+ --text-muted: #94a3b8;
130
+ --accent: #f26419;
131
+ --badge-class: #38bdf8;
132
+ --badge-fn: #4ade80;
133
+ --badge-db: #f59e0b;
134
+ --badge-other: #a78bfa;
135
+ }
136
+ * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace; }
137
+ body { background: var(--bg); color: var(--text); padding: 24px; }
138
+ header { margin-bottom: 24px; border-bottom: 1px solid var(--border); padding-bottom: 16px; }
139
+ h1 { font-size: 1.5rem; display: flex; align-items: center; gap: 10px; }
140
+ .badge { font-size: 0.75rem; padding: 2px 8px; border-radius: 9999px; background: var(--accent); color: white; font-weight: bold; }
141
+ .stats { display: flex; gap: 16px; margin-top: 12px; font-size: 0.875rem; color: var(--text-muted); }
142
+ .stat-val { color: var(--text); font-weight: bold; }
143
+ .controls { margin-bottom: 20px; display: flex; gap: 12px; }
144
+ input#search { flex: 1; padding: 10px 14px; background: var(--card-bg); border: 1px solid var(--border); border-radius: 8px; color: var(--text); font-size: 0.9rem; }
145
+ input#search:focus { outline: 2px solid var(--accent); border-color: transparent; }
146
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 16px; }
147
+ .card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px; transition: border-color 0.2s; }
148
+ .card:hover { border-color: var(--accent); }
149
+ .card-path { font-weight: bold; font-size: 0.875rem; color: #38bdf8; word-break: break-all; margin-bottom: 8px; }
150
+ .symbols-list { display: flex; flex-wrap: wrap; gap: 6px; }
151
+ .sym-badge { font-size: 0.75rem; padding: 3px 6px; border-radius: 4px; background: #0f172a; border: 1px solid var(--border); }
152
+ .sym-class { border-color: var(--badge-class); color: var(--badge-class); }
153
+ .sym-function { border-color: var(--badge-fn); color: var(--badge-fn); }
154
+ .sym-db { border-color: var(--badge-db); color: var(--badge-db); }
155
+ .empty-note { font-size: 0.75rem; color: var(--text-muted); font-style: italic; }
156
+ </style>
157
+ </head>
158
+ <body>
159
+ <header>
160
+ <h1><span>Architecture & Semantic Repo Map</span> <span class="badge">v4.0.0 Enterprise</span></h1>
161
+ <div class="stats">
162
+ <div>Files: <span class="stat-val">${files.length}</span></div>
163
+ <div>Indexed Symbols: <span class="stat-val">${totalSymbols}</span></div>
164
+ <div>Path: <span class="stat-val">${escapedPath}</span></div>
165
+ </div>
166
+ </header>
167
+
168
+ <div class="controls">
169
+ <input type="text" id="search" placeholder="Filter files or symbols (e.g. User, Controller, handle, schema)..." autofocus>
170
+ </div>
171
+
172
+ <div class="grid" id="fileGrid"></div>
173
+
174
+ <script>
175
+ const files = ${filesJson};
176
+ const grid = document.getElementById("fileGrid");
177
+ const search = document.getElementById("search");
178
+
179
+ function render(list) {
180
+ grid.innerHTML = "";
181
+ if (list.length === 0) {
182
+ grid.innerHTML = '<div style="color: var(--text-muted); grid-column: 1/-1;">No matching files found.</div>';
183
+ return;
184
+ }
185
+ for (const f of list) {
186
+ const card = document.createElement("div");
187
+ card.className = "card";
188
+
189
+ const pathEl = document.createElement("div");
190
+ pathEl.className = "card-path";
191
+ pathEl.textContent = f.path;
192
+ card.appendChild(pathEl);
193
+
194
+ const symListEl = document.createElement("div");
195
+ symListEl.className = "symbols-list";
196
+
197
+ if (f.symbols.length > 0) {
198
+ for (const s of f.symbols) {
199
+ const badge = document.createElement("span");
200
+ const cls = s.type === "class" ? "sym-class" : s.type === "db_column" ? "sym-db" : "sym-function";
201
+ badge.className = "sym-badge " + cls;
202
+ badge.textContent = s.type + ": " + s.name;
203
+ symListEl.appendChild(badge);
204
+ }
205
+ } else {
206
+ const emptyNote = document.createElement("span");
207
+ emptyNote.className = "empty-note";
208
+ emptyNote.textContent = "No exported AST symbols";
209
+ symListEl.appendChild(emptyNote);
210
+ }
211
+
212
+ card.appendChild(symListEl);
213
+ grid.appendChild(card);
214
+ }
215
+ }
216
+
217
+ search.addEventListener("input", (e) => {
218
+ const q = e.target.value.toLowerCase().trim();
219
+ if (!q) { render(files); return; }
220
+ const filtered = files.filter(f =>
221
+ f.path.toLowerCase().includes(q) ||
222
+ f.symbols.some(s => s.name.toLowerCase().includes(q) || s.type.toLowerCase().includes(q))
223
+ );
224
+ render(filtered);
225
+ });
226
+
227
+ render(files);
228
+ </script>
229
+ </body>
230
+ </html>`;
231
+ return { success: true, content: html };
232
+ }
99
233
  if (format === "xml") {
100
234
  try {
101
235
  const gemfileResult = await parseGemfile(params.projectRoot);