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,178 @@
1
+ /**
2
+ * AST Reachability & Zombie Export Eliminator
3
+ * v5.7.0 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
+ * Checks for unreachable code following return or throw statements
12
+ */
13
+ function findUnreachableStatements(node, lines) {
14
+ const unreachable = [];
15
+ function walk(n) {
16
+ if (n.type === "statement_block" || n.type === "block") {
17
+ let terminated = false;
18
+ let terminatingStatement = null;
19
+ for (let i = 0; i < n.namedChildCount; i++) {
20
+ const child = n.namedChild(i);
21
+ if (!child)
22
+ continue;
23
+ if (terminated) {
24
+ unreachable.push({
25
+ name: child.text.slice(0, 30),
26
+ kind: "variable",
27
+ line: child.startPosition.row + 1,
28
+ column: child.startPosition.column,
29
+ reason: "UNREACHABLE_AFTER_RETURN",
30
+ snippet: lines[child.startPosition.row] || child.text,
31
+ });
32
+ }
33
+ if (child.type === "return_statement" ||
34
+ child.type === "throw_statement") {
35
+ terminated = true;
36
+ terminatingStatement = child;
37
+ }
38
+ }
39
+ }
40
+ for (let i = 0; i < n.namedChildCount; i++) {
41
+ const child = n.namedChild(i);
42
+ if (child)
43
+ walk(child);
44
+ }
45
+ }
46
+ walk(node);
47
+ return unreachable;
48
+ }
49
+ /**
50
+ * Extracts declared symbols and counts their identifier references
51
+ */
52
+ export async function detectDeadAstSymbols(params) {
53
+ let tree = null;
54
+ try {
55
+ const targetPath = params.filePath || "in_memory.ts";
56
+ let content = params.code ?? params.content;
57
+ if (content === undefined) {
58
+ if (params.filePath && existsSync(params.filePath)) {
59
+ content = await fs.readFile(params.filePath, "utf-8");
60
+ }
61
+ else {
62
+ return {
63
+ success: false,
64
+ error: `File does not exist: ${params.filePath || "none"}`,
65
+ };
66
+ }
67
+ }
68
+ const ext = path.extname(targetPath).toLowerCase();
69
+ let registry = params.registry;
70
+ if (!registry) {
71
+ const engine = new CodeContextEngine();
72
+ await engine.init();
73
+ registry = new ParserRegistry(engine);
74
+ await registry.init();
75
+ }
76
+ const parser = registry.getParser(ext === ".py" ? ".py" : ".ts");
77
+ if (!parser) {
78
+ return {
79
+ success: false,
80
+ error: `No parser available for extension: ${ext}`,
81
+ };
82
+ }
83
+ tree = parser.parse(content);
84
+ const lines = content.split("\n");
85
+ const declaredSymbols = [];
86
+ const identifierUsages = new Map();
87
+ function walkAST(n) {
88
+ // Check declarations
89
+ const isExported = n.parent?.type === "export_statement" || n.text.startsWith("export ");
90
+ if (n.type === "function_declaration" ||
91
+ n.type === "function_definition") {
92
+ const name = n.childForFieldName("name")?.text;
93
+ if (name) {
94
+ declaredSymbols.push({ name, kind: "function", isExported, node: n });
95
+ }
96
+ }
97
+ else if (n.type === "class_declaration" ||
98
+ n.type === "class_definition") {
99
+ const name = n.childForFieldName("name")?.text;
100
+ if (name) {
101
+ declaredSymbols.push({ name, kind: "class", isExported, node: n });
102
+ }
103
+ }
104
+ else if (n.type === "interface_declaration") {
105
+ const name = n.childForFieldName("name")?.text;
106
+ if (name) {
107
+ declaredSymbols.push({ name, kind: "interface", isExported, node: n });
108
+ }
109
+ }
110
+ else if (n.type === "variable_declarator") {
111
+ const name = n.childForFieldName("name")?.text;
112
+ if (name) {
113
+ declaredSymbols.push({ name, kind: "variable", isExported, node: n });
114
+ }
115
+ }
116
+ // Count identifier references
117
+ if ((n.type === "identifier" || n.type === "type_identifier") &&
118
+ n.parent?.type !== "function_declaration" &&
119
+ n.parent?.type !== "class_declaration" &&
120
+ n.parent?.type !== "interface_declaration" &&
121
+ n.parent?.type !== "variable_declarator") {
122
+ identifierUsages.set(n.text, (identifierUsages.get(n.text) || 0) + 1);
123
+ }
124
+ for (let i = 0; i < n.namedChildCount; i++) {
125
+ const child = n.namedChild(i);
126
+ if (child)
127
+ walkAST(child);
128
+ }
129
+ }
130
+ walkAST(tree.rootNode);
131
+ const deadSymbols = [];
132
+ // 1. Identify declared symbols with zero references
133
+ for (const sym of declaredSymbols) {
134
+ const usages = identifierUsages.get(sym.name) || 0;
135
+ if (usages === 0) {
136
+ deadSymbols.push({
137
+ name: sym.name,
138
+ kind: sym.kind,
139
+ line: sym.node.startPosition.row + 1,
140
+ column: sym.node.startPosition.column,
141
+ reason: sym.isExported ? "UNUSED_EXPORT" : "UNUSED_INTERNAL",
142
+ snippet: lines[sym.node.startPosition.row] || sym.name,
143
+ });
144
+ }
145
+ }
146
+ // 2. Identify unreachable statements
147
+ const unreachable = findUnreachableStatements(tree.rootNode, lines);
148
+ deadSymbols.push(...unreachable);
149
+ const report = {
150
+ filePath: params.filePath,
151
+ totalSymbolsScanned: declaredSymbols.length,
152
+ deadSymbolsCount: deadSymbols.length,
153
+ deadSymbols,
154
+ summary: `Scanned ${declaredSymbols.length} declared symbols. Found ${deadSymbols.length} dead/unreachable AST items.`,
155
+ };
156
+ return {
157
+ success: true,
158
+ content: JSON.stringify(report, null, 2),
159
+ };
160
+ }
161
+ catch (error) {
162
+ return {
163
+ success: false,
164
+ error: `detect_dead_ast_symbols failed: ${error instanceof Error ? error.message : String(error)}`,
165
+ };
166
+ }
167
+ finally {
168
+ if (tree) {
169
+ try {
170
+ tree.delete();
171
+ }
172
+ catch {
173
+ // ignore
174
+ }
175
+ }
176
+ }
177
+ }
178
+ //# sourceMappingURL=deadSymbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deadSymbols.js","sourceRoot":"","sources":["../../../src/operations/deadSymbols.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Environment Variable AST Drift & Parity Verifier
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 EnvReference {
8
+ name: string;
9
+ line: number;
10
+ column: number;
11
+ snippet: string;
12
+ }
13
+ export interface EnvContractReport {
14
+ filePath?: string;
15
+ envExamplePath?: string;
16
+ totalReferencedInCode: number;
17
+ totalInExample: number;
18
+ undocumentedInCode: string[];
19
+ zombieInExample: string[];
20
+ coveragePercent: number;
21
+ references: EnvReference[];
22
+ summary: string;
23
+ }
24
+ export interface EnvContractOptions {
25
+ filePath?: string;
26
+ code?: string;
27
+ content?: string;
28
+ envExampleContent?: string;
29
+ projectRoot?: string;
30
+ registry?: ParserRegistry;
31
+ }
32
+ /**
33
+ * Verifies environment variable contract drift
34
+ */
35
+ export declare function verifyEnvContractDrift(params: EnvContractOptions): Promise<ReadResult>;
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Environment Variable AST Drift & Parity Verifier
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 .env.example into a Set of variable names
12
+ */
13
+ function parseEnvExample(content) {
14
+ const vars = new Set();
15
+ const lines = content.split("\n");
16
+ for (const rawLine of lines) {
17
+ const line = rawLine.trim();
18
+ if (!line || line.startsWith("#"))
19
+ continue;
20
+ const match = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=/);
21
+ if (match && match[1]) {
22
+ vars.add(match[1]);
23
+ }
24
+ }
25
+ return vars;
26
+ }
27
+ /**
28
+ * Extracts environment variable accesses from AST
29
+ */
30
+ function extractEnvReferences(rootNode, lines) {
31
+ const refs = [];
32
+ function walk(n) {
33
+ // 1. Node.js / TS: process.env.XYZ or process.env['XYZ']
34
+ if (n.type === "member_expression") {
35
+ const obj = n.childForFieldName("object")?.text;
36
+ const prop = n.childForFieldName("property")?.text;
37
+ if (obj === "process.env" && prop) {
38
+ const cleanProp = prop.replace(/^["']|["']$/g, "");
39
+ refs.push({
40
+ name: cleanProp,
41
+ line: n.startPosition.row + 1,
42
+ column: n.startPosition.column,
43
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
44
+ });
45
+ }
46
+ }
47
+ // 2. Python / PHP / generic function call: os.getenv("XYZ"), getenv("XYZ"), env("XYZ")
48
+ if (n.type === "call_expression" || n.type === "call") {
49
+ const fn = n.childForFieldName("function")?.text;
50
+ if (fn === "os.getenv" || fn === "getenv" || fn === "env" || fn === "os.environ.get") {
51
+ const args = n.childForFieldName("arguments") || n.namedChild(1);
52
+ const firstArg = args?.namedChild(0)?.text;
53
+ if (firstArg) {
54
+ const varName = firstArg.replace(/^["']|["']$/g, "");
55
+ refs.push({
56
+ name: varName,
57
+ line: n.startPosition.row + 1,
58
+ column: n.startPosition.column,
59
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
60
+ });
61
+ }
62
+ }
63
+ }
64
+ // 3. Python subscription: os.environ["XYZ"] or PHP: $_ENV["XYZ"]
65
+ if (n.type === "subscript" || n.type === "subscript_expression") {
66
+ const obj = (n.childForFieldName("value") || n.namedChild(0))?.text;
67
+ const idx = (n.childForFieldName("subscript") || n.namedChild(1))?.text;
68
+ if ((obj === "os.environ" || obj === "$_ENV" || obj === "$_SERVER") && idx) {
69
+ const varName = idx.replace(/^["']|["']$/g, "");
70
+ refs.push({
71
+ name: varName,
72
+ line: n.startPosition.row + 1,
73
+ column: n.startPosition.column,
74
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
75
+ });
76
+ }
77
+ }
78
+ for (let i = 0; i < n.namedChildCount; i++) {
79
+ const child = n.namedChild(i);
80
+ if (child)
81
+ walk(child);
82
+ }
83
+ }
84
+ walk(rootNode);
85
+ return refs;
86
+ }
87
+ /**
88
+ * Verifies environment variable contract drift
89
+ */
90
+ export async function verifyEnvContractDrift(params) {
91
+ let tree = null;
92
+ try {
93
+ const targetPath = params.filePath || "in_memory.ts";
94
+ let content = params.code ?? params.content;
95
+ if (content === undefined) {
96
+ if (params.filePath && existsSync(params.filePath)) {
97
+ content = await fs.readFile(params.filePath, "utf-8");
98
+ }
99
+ else {
100
+ return {
101
+ success: false,
102
+ error: `File does not exist: ${params.filePath || "none"}`,
103
+ };
104
+ }
105
+ }
106
+ const ext = path.extname(targetPath).toLowerCase();
107
+ let registry = params.registry;
108
+ if (!registry) {
109
+ const engine = new CodeContextEngine();
110
+ await engine.init();
111
+ registry = new ParserRegistry(engine);
112
+ await registry.init();
113
+ }
114
+ const parser = registry.getParser(ext === ".py" ? ".py" : ".ts");
115
+ if (!parser) {
116
+ return {
117
+ success: false,
118
+ error: `No parser available for extension: ${ext}`,
119
+ };
120
+ }
121
+ tree = parser.parse(content);
122
+ const lines = content.split("\n");
123
+ const references = extractEnvReferences(tree.rootNode, lines);
124
+ const referencedNames = new Set(references.map(r => r.name));
125
+ // Resolve .env.example
126
+ let exampleVars = new Set();
127
+ let envExamplePath = undefined;
128
+ if (params.envExampleContent !== undefined) {
129
+ exampleVars = parseEnvExample(params.envExampleContent);
130
+ }
131
+ else if (params.projectRoot) {
132
+ const candidatePaths = [
133
+ path.join(params.projectRoot, ".env.example"),
134
+ path.join(params.projectRoot, ".env.template"),
135
+ path.join(params.projectRoot, ".env"),
136
+ ];
137
+ for (const p of candidatePaths) {
138
+ if (existsSync(p)) {
139
+ envExamplePath = p;
140
+ const exampleStr = await fs.readFile(p, "utf-8");
141
+ exampleVars = parseEnvExample(exampleStr);
142
+ break;
143
+ }
144
+ }
145
+ }
146
+ const undocumented = [];
147
+ for (const refName of referencedNames) {
148
+ if (!exampleVars.has(refName)) {
149
+ undocumented.push(refName);
150
+ }
151
+ }
152
+ const zombie = [];
153
+ for (const exName of exampleVars) {
154
+ if (!referencedNames.has(exName)) {
155
+ zombie.push(exName);
156
+ }
157
+ }
158
+ const totalReferenced = referencedNames.size;
159
+ const documentedCount = totalReferenced - undocumented.length;
160
+ const coveragePercent = totalReferenced > 0 ? Math.round((documentedCount / totalReferenced) * 100) : 100;
161
+ const report = {
162
+ filePath: params.filePath,
163
+ envExamplePath,
164
+ totalReferencedInCode: totalReferenced,
165
+ totalInExample: exampleVars.size,
166
+ undocumentedInCode: undocumented,
167
+ zombieInExample: zombie,
168
+ coveragePercent,
169
+ references,
170
+ summary: `Analyzed ${totalReferenced} env references in code vs ${exampleVars.size} in .env.example. Coverage: ${coveragePercent}%. Undocumented in example: ${undocumented.length}.`,
171
+ };
172
+ return {
173
+ success: true,
174
+ content: JSON.stringify(report, null, 2),
175
+ };
176
+ }
177
+ catch (error) {
178
+ return {
179
+ success: false,
180
+ error: `verify_env_contract_drift failed: ${error instanceof Error ? error.message : String(error)}`,
181
+ };
182
+ }
183
+ finally {
184
+ if (tree) {
185
+ try {
186
+ tree.delete();
187
+ }
188
+ catch {
189
+ // ignore
190
+ }
191
+ }
192
+ }
193
+ }
194
+ //# sourceMappingURL=envContract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envContract.js","sourceRoot":"","sources":["../../../src/operations/envContract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * AST Exception & Error Swallowing Guard
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 CatchClauseFinding {
8
+ line: number;
9
+ column: number;
10
+ caughtType?: string;
11
+ variableName?: string;
12
+ findingType: "EMPTY_CATCH" | "GENERIC_SWALLOW" | "MISSING_TELEMETRY" | "SUPPRESSED_CRITICAL";
13
+ severity: "CRITICAL" | "HIGH" | "MEDIUM";
14
+ snippet: string;
15
+ recommendation: string;
16
+ }
17
+ export interface ErrorAuditReport {
18
+ filePath?: string;
19
+ totalCatchBlocks: number;
20
+ cleanCatchBlocks: number;
21
+ riskyCatchBlocks: number;
22
+ resilienceScore: number;
23
+ findings: CatchClauseFinding[];
24
+ summary: string;
25
+ }
26
+ export interface ErrorAuditOptions {
27
+ filePath?: string;
28
+ code?: string;
29
+ content?: string;
30
+ projectRoot?: string;
31
+ registry?: ParserRegistry;
32
+ }
33
+ /**
34
+ * Audits error handling patterns across AST
35
+ */
36
+ export declare function auditErrorHandlingContracts(params: ErrorAuditOptions): Promise<ReadResult>;
@@ -0,0 +1,201 @@
1
+ /**
2
+ * AST Exception & Error Swallowing Guard
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
+ * Checks if a block contains any logging or rethrow statements
12
+ */
13
+ function inspectCatchBody(bodyNode) {
14
+ let hasLogging = false;
15
+ let hasRethrow = false;
16
+ // Check if empty or contains only comments
17
+ const stripped = bodyNode.text.replace(/(\/\*[\s\S]*?\*\/|\/\/.*|\{|\}|\s)/g, "");
18
+ if (bodyNode.namedChildCount === 0 || stripped === "" || stripped === "pass") {
19
+ return { hasLogging: false, hasRethrow: false, isEmpty: true };
20
+ }
21
+ function walk(n) {
22
+ if (n.type === "throw_statement" ||
23
+ n.type === "raise_statement") {
24
+ hasRethrow = true;
25
+ }
26
+ if (n.type === "call_expression" || n.type === "call") {
27
+ const fn = n.childForFieldName("function")?.text || "";
28
+ if (fn.includes("log") ||
29
+ fn.includes("error") ||
30
+ fn.includes("warn") ||
31
+ fn.includes("telemetry") ||
32
+ fn.includes("audit")) {
33
+ hasLogging = true;
34
+ }
35
+ }
36
+ for (let i = 0; i < n.namedChildCount; i++) {
37
+ const child = n.namedChild(i);
38
+ if (child)
39
+ walk(child);
40
+ }
41
+ }
42
+ walk(bodyNode);
43
+ return { hasLogging, hasRethrow, isEmpty: false };
44
+ }
45
+ /**
46
+ * Audits error handling patterns across AST
47
+ */
48
+ export async function auditErrorHandlingContracts(params) {
49
+ let tree = null;
50
+ try {
51
+ const targetPath = params.filePath || "in_memory.ts";
52
+ let content = params.code ?? params.content;
53
+ if (content === undefined) {
54
+ if (params.filePath && existsSync(params.filePath)) {
55
+ content = await fs.readFile(params.filePath, "utf-8");
56
+ }
57
+ else {
58
+ return {
59
+ success: false,
60
+ error: `File does not exist: ${params.filePath || "none"}`,
61
+ };
62
+ }
63
+ }
64
+ const ext = path.extname(targetPath).toLowerCase();
65
+ let registry = params.registry;
66
+ if (!registry) {
67
+ const engine = new CodeContextEngine();
68
+ await engine.init();
69
+ registry = new ParserRegistry(engine);
70
+ await registry.init();
71
+ }
72
+ const parser = registry.getParser(ext === ".py" ? ".py" : ".ts");
73
+ if (!parser) {
74
+ return {
75
+ success: false,
76
+ error: `No parser available for extension: ${ext}`,
77
+ };
78
+ }
79
+ tree = parser.parse(content);
80
+ const lines = content.split("\n");
81
+ const findings = [];
82
+ let totalCatches = 0;
83
+ function walkAST(n) {
84
+ // TypeScript / JS / PHP: catch_clause
85
+ if (n.type === "catch_clause") {
86
+ totalCatches++;
87
+ const param = n.childForFieldName("parameter")?.text;
88
+ const body = n.childForFieldName("body") || n.namedChild(n.namedChildCount - 1);
89
+ if (body) {
90
+ const { hasLogging, hasRethrow, isEmpty } = inspectCatchBody(body);
91
+ if (isEmpty) {
92
+ findings.push({
93
+ line: n.startPosition.row + 1,
94
+ column: n.startPosition.column,
95
+ caughtType: param,
96
+ findingType: "EMPTY_CATCH",
97
+ severity: "CRITICAL",
98
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
99
+ recommendation: "Never leave catch blocks empty. Add structured logging or rethrow.",
100
+ });
101
+ }
102
+ else if (!hasRethrow && !hasLogging) {
103
+ findings.push({
104
+ line: n.startPosition.row + 1,
105
+ column: n.startPosition.column,
106
+ caughtType: param,
107
+ findingType: "GENERIC_SWALLOW",
108
+ severity: "HIGH",
109
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
110
+ recommendation: "Swallowing caught exception without logging or rethrowing damages system observability.",
111
+ });
112
+ }
113
+ }
114
+ }
115
+ // Python: except_clause
116
+ if (n.type === "except_clause") {
117
+ totalCatches++;
118
+ const exceptText = n.text;
119
+ const parentTry = n.parent;
120
+ const body = parentTry?.childForFieldName("body") || n.nextNamedSibling;
121
+ if (n.text.includes("BaseException") || n.text.includes("KeyboardInterrupt") || n.text.includes("SystemExit")) {
122
+ findings.push({
123
+ line: n.startPosition.row + 1,
124
+ column: n.startPosition.column,
125
+ caughtType: exceptText,
126
+ findingType: "SUPPRESSED_CRITICAL",
127
+ severity: "CRITICAL",
128
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
129
+ recommendation: "Do not intercept KeyboardInterrupt or SystemExit; it prevents graceful process termination.",
130
+ });
131
+ }
132
+ // Check the block following except
133
+ const nextSibling = n.nextNamedSibling;
134
+ if (nextSibling && (nextSibling.type === "block" || nextSibling.type === "statement_block")) {
135
+ const { hasLogging, hasRethrow, isEmpty } = inspectCatchBody(nextSibling);
136
+ if (isEmpty) {
137
+ findings.push({
138
+ line: n.startPosition.row + 1,
139
+ column: n.startPosition.column,
140
+ caughtType: exceptText,
141
+ findingType: "EMPTY_CATCH",
142
+ severity: "CRITICAL",
143
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
144
+ recommendation: "Empty 'except: pass' silently hides catastrophic runtime failures.",
145
+ });
146
+ }
147
+ else if (!hasRethrow && !hasLogging) {
148
+ findings.push({
149
+ line: n.startPosition.row + 1,
150
+ column: n.startPosition.column,
151
+ caughtType: exceptText,
152
+ findingType: "GENERIC_SWALLOW",
153
+ severity: "HIGH",
154
+ snippet: lines[n.startPosition.row]?.trim() || n.text,
155
+ recommendation: "Add logger.exception() or re-raise with 'raise'.",
156
+ });
157
+ }
158
+ }
159
+ }
160
+ for (let i = 0; i < n.namedChildCount; i++) {
161
+ const child = n.namedChild(i);
162
+ if (child)
163
+ walkAST(child);
164
+ }
165
+ }
166
+ walkAST(tree.rootNode);
167
+ const riskyCount = findings.length;
168
+ const cleanCount = Math.max(0, totalCatches - riskyCount);
169
+ const resilienceScore = totalCatches > 0 ? Math.round((cleanCount / totalCatches) * 100) : 100;
170
+ const report = {
171
+ filePath: params.filePath,
172
+ totalCatchBlocks: totalCatches,
173
+ cleanCatchBlocks: cleanCount,
174
+ riskyCatchBlocks: riskyCount,
175
+ resilienceScore,
176
+ findings,
177
+ summary: `Audited ${totalCatches} catch/except clauses. Clean: ${cleanCount}, Risky: ${riskyCount}. Error Resilience Score: ${resilienceScore}/100.`,
178
+ };
179
+ return {
180
+ success: true,
181
+ content: JSON.stringify(report, null, 2),
182
+ };
183
+ }
184
+ catch (error) {
185
+ return {
186
+ success: false,
187
+ error: `audit_error_handling_contracts failed: ${error instanceof Error ? error.message : String(error)}`,
188
+ };
189
+ }
190
+ finally {
191
+ if (tree) {
192
+ try {
193
+ tree.delete();
194
+ }
195
+ catch {
196
+ // ignore
197
+ }
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=errorAudit.js.map