@codeledger/cli 0.6.7 → 0.6.9

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 (175) hide show
  1. package/dist/architecture-graph/dependency-scanner.d.ts +16 -0
  2. package/dist/architecture-graph/dependency-scanner.d.ts.map +1 -0
  3. package/dist/architecture-graph/dependency-scanner.js +96 -0
  4. package/dist/architecture-graph/dependency-scanner.js.map +1 -0
  5. package/dist/architecture-graph/graph-builder.d.ts +70 -0
  6. package/dist/architecture-graph/graph-builder.d.ts.map +1 -0
  7. package/dist/architecture-graph/graph-builder.js +231 -0
  8. package/dist/architecture-graph/graph-builder.js.map +1 -0
  9. package/dist/architecture-graph/index.d.ts +4 -0
  10. package/dist/architecture-graph/index.d.ts.map +1 -0
  11. package/dist/architecture-graph/index.js +7 -0
  12. package/dist/architecture-graph/index.js.map +1 -0
  13. package/dist/architecture-graph/service-scanner.d.ts +22 -0
  14. package/dist/architecture-graph/service-scanner.d.ts.map +1 -0
  15. package/dist/architecture-graph/service-scanner.js +181 -0
  16. package/dist/architecture-graph/service-scanner.js.map +1 -0
  17. package/dist/commands/activate.d.ts.map +1 -1
  18. package/dist/commands/activate.js +16 -1
  19. package/dist/commands/activate.js.map +1 -1
  20. package/dist/commands/audit-export.d.ts +8 -0
  21. package/dist/commands/audit-export.d.ts.map +1 -0
  22. package/dist/commands/audit-export.js +190 -0
  23. package/dist/commands/audit-export.js.map +1 -0
  24. package/dist/commands/commit-msg.d.ts +58 -0
  25. package/dist/commands/commit-msg.d.ts.map +1 -0
  26. package/dist/commands/commit-msg.js +461 -0
  27. package/dist/commands/commit-msg.js.map +1 -0
  28. package/dist/commands/fix.d.ts +7 -0
  29. package/dist/commands/fix.d.ts.map +1 -0
  30. package/dist/commands/fix.js +107 -0
  31. package/dist/commands/fix.js.map +1 -0
  32. package/dist/commands/graph.d.ts +8 -0
  33. package/dist/commands/graph.d.ts.map +1 -0
  34. package/dist/commands/graph.js +29 -0
  35. package/dist/commands/graph.js.map +1 -0
  36. package/dist/commands/init.d.ts.map +1 -1
  37. package/dist/commands/init.js +14 -0
  38. package/dist/commands/init.js.map +1 -1
  39. package/dist/commands/intent.d.ts +3 -1
  40. package/dist/commands/intent.d.ts.map +1 -1
  41. package/dist/commands/intent.js +68 -2
  42. package/dist/commands/intent.js.map +1 -1
  43. package/dist/commands/learn.d.ts +8 -0
  44. package/dist/commands/learn.d.ts.map +1 -0
  45. package/dist/commands/learn.js +33 -0
  46. package/dist/commands/learn.js.map +1 -0
  47. package/dist/commands/pack.d.ts +12 -0
  48. package/dist/commands/pack.d.ts.map +1 -0
  49. package/dist/commands/pack.js +75 -0
  50. package/dist/commands/pack.js.map +1 -0
  51. package/dist/commands/pr-summary.d.ts +59 -0
  52. package/dist/commands/pr-summary.d.ts.map +1 -0
  53. package/dist/commands/pr-summary.js +524 -0
  54. package/dist/commands/pr-summary.js.map +1 -0
  55. package/dist/commands/serve.d.ts +13 -0
  56. package/dist/commands/serve.d.ts.map +1 -0
  57. package/dist/commands/serve.js +179 -0
  58. package/dist/commands/serve.js.map +1 -0
  59. package/dist/commands/session-cleanup.js +1 -0
  60. package/dist/commands/session-cleanup.js.map +1 -1
  61. package/dist/commands/session-summary.d.ts.map +1 -1
  62. package/dist/commands/session-summary.js +135 -3
  63. package/dist/commands/session-summary.js.map +1 -1
  64. package/dist/commands/setup-ci.d.ts +6 -4
  65. package/dist/commands/setup-ci.d.ts.map +1 -1
  66. package/dist/commands/setup-ci.js +228 -23
  67. package/dist/commands/setup-ci.js.map +1 -1
  68. package/dist/commands/verify.d.ts.map +1 -1
  69. package/dist/commands/verify.js +35 -3
  70. package/dist/commands/verify.js.map +1 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +127 -4
  73. package/dist/index.js.map +1 -1
  74. package/dist/intent/extractor.d.ts +15 -0
  75. package/dist/intent/extractor.d.ts.map +1 -0
  76. package/dist/intent/extractor.js +149 -0
  77. package/dist/intent/extractor.js.map +1 -0
  78. package/dist/intent/fetcher.d.ts +33 -0
  79. package/dist/intent/fetcher.d.ts.map +1 -0
  80. package/dist/intent/fetcher.js +364 -0
  81. package/dist/intent/fetcher.js.map +1 -0
  82. package/dist/intent/loader.d.ts +26 -0
  83. package/dist/intent/loader.d.ts.map +1 -0
  84. package/dist/intent/loader.js +80 -0
  85. package/dist/intent/loader.js.map +1 -0
  86. package/dist/intent/types.d.ts +33 -0
  87. package/dist/intent/types.d.ts.map +1 -0
  88. package/dist/intent/types.js +9 -0
  89. package/dist/intent/types.js.map +1 -0
  90. package/dist/project-config.d.ts +38 -0
  91. package/dist/project-config.d.ts.map +1 -0
  92. package/dist/project-config.js +206 -0
  93. package/dist/project-config.js.map +1 -0
  94. package/dist/review-intelligence/detectors/architecture-graph.d.ts +18 -0
  95. package/dist/review-intelligence/detectors/architecture-graph.d.ts.map +1 -0
  96. package/dist/review-intelligence/detectors/architecture-graph.js +73 -0
  97. package/dist/review-intelligence/detectors/architecture-graph.js.map +1 -0
  98. package/dist/review-intelligence/detectors/cjs-named-import.d.ts +13 -0
  99. package/dist/review-intelligence/detectors/cjs-named-import.d.ts.map +1 -0
  100. package/dist/review-intelligence/detectors/cjs-named-import.js +134 -0
  101. package/dist/review-intelligence/detectors/cjs-named-import.js.map +1 -0
  102. package/dist/review-intelligence/detectors/exact-count-assertion.d.ts +17 -0
  103. package/dist/review-intelligence/detectors/exact-count-assertion.d.ts.map +1 -0
  104. package/dist/review-intelligence/detectors/exact-count-assertion.js +93 -0
  105. package/dist/review-intelligence/detectors/exact-count-assertion.js.map +1 -0
  106. package/dist/review-intelligence/detectors/exports-map-missing.d.ts +14 -0
  107. package/dist/review-intelligence/detectors/exports-map-missing.d.ts.map +1 -0
  108. package/dist/review-intelligence/detectors/exports-map-missing.js +131 -0
  109. package/dist/review-intelligence/detectors/exports-map-missing.js.map +1 -0
  110. package/dist/review-intelligence/detectors/fixture-keyword-drift.d.ts +12 -0
  111. package/dist/review-intelligence/detectors/fixture-keyword-drift.d.ts.map +1 -0
  112. package/dist/review-intelligence/detectors/fixture-keyword-drift.js +82 -0
  113. package/dist/review-intelligence/detectors/fixture-keyword-drift.js.map +1 -0
  114. package/dist/review-intelligence/detectors/optional-infra-crash.d.ts +12 -0
  115. package/dist/review-intelligence/detectors/optional-infra-crash.d.ts.map +1 -0
  116. package/dist/review-intelligence/detectors/optional-infra-crash.js +97 -0
  117. package/dist/review-intelligence/detectors/optional-infra-crash.js.map +1 -0
  118. package/dist/review-intelligence/detectors/pack-rules.d.ts +16 -0
  119. package/dist/review-intelligence/detectors/pack-rules.d.ts.map +1 -0
  120. package/dist/review-intelligence/detectors/pack-rules.js +107 -0
  121. package/dist/review-intelligence/detectors/pack-rules.js.map +1 -0
  122. package/dist/review-intelligence/detectors/undeclared-dependency.d.ts +11 -0
  123. package/dist/review-intelligence/detectors/undeclared-dependency.d.ts.map +1 -0
  124. package/dist/review-intelligence/detectors/undeclared-dependency.js +100 -0
  125. package/dist/review-intelligence/detectors/undeclared-dependency.js.map +1 -0
  126. package/dist/review-intelligence/engine/ast-parser.d.ts +90 -0
  127. package/dist/review-intelligence/engine/ast-parser.d.ts.map +1 -0
  128. package/dist/review-intelligence/engine/ast-parser.js +266 -0
  129. package/dist/review-intelligence/engine/ast-parser.js.map +1 -0
  130. package/dist/review-intelligence/engine/dataflow.d.ts +34 -0
  131. package/dist/review-intelligence/engine/dataflow.d.ts.map +1 -0
  132. package/dist/review-intelligence/engine/dataflow.js +115 -0
  133. package/dist/review-intelligence/engine/dataflow.js.map +1 -0
  134. package/dist/review-intelligence/engine/index.d.ts +7 -0
  135. package/dist/review-intelligence/engine/index.d.ts.map +1 -0
  136. package/dist/review-intelligence/engine/index.js +7 -0
  137. package/dist/review-intelligence/engine/index.js.map +1 -0
  138. package/dist/review-intelligence/engine/symbol-resolver.d.ts +34 -0
  139. package/dist/review-intelligence/engine/symbol-resolver.d.ts.map +1 -0
  140. package/dist/review-intelligence/engine/symbol-resolver.js +106 -0
  141. package/dist/review-intelligence/engine/symbol-resolver.js.map +1 -0
  142. package/dist/review-intelligence/fixes/index.d.ts +54 -0
  143. package/dist/review-intelligence/fixes/index.d.ts.map +1 -0
  144. package/dist/review-intelligence/fixes/index.js +346 -0
  145. package/dist/review-intelligence/fixes/index.js.map +1 -0
  146. package/dist/review-intelligence/index.d.ts +4 -1
  147. package/dist/review-intelligence/index.d.ts.map +1 -1
  148. package/dist/review-intelligence/index.js +22 -3
  149. package/dist/review-intelligence/index.js.map +1 -1
  150. package/dist/review-intelligence/invariants.d.ts +15 -0
  151. package/dist/review-intelligence/invariants.d.ts.map +1 -1
  152. package/dist/review-intelligence/invariants.js +48 -4
  153. package/dist/review-intelligence/invariants.js.map +1 -1
  154. package/dist/review-intelligence/learning/index.d.ts +39 -0
  155. package/dist/review-intelligence/learning/index.d.ts.map +1 -0
  156. package/dist/review-intelligence/learning/index.js +265 -0
  157. package/dist/review-intelligence/learning/index.js.map +1 -0
  158. package/dist/review-intelligence/packs/index.d.ts +69 -0
  159. package/dist/review-intelligence/packs/index.d.ts.map +1 -0
  160. package/dist/review-intelligence/packs/index.js +168 -0
  161. package/dist/review-intelligence/packs/index.js.map +1 -0
  162. package/dist/review-intelligence/repair-guidance.d.ts.map +1 -1
  163. package/dist/review-intelligence/repair-guidance.js +46 -0
  164. package/dist/review-intelligence/repair-guidance.js.map +1 -1
  165. package/dist/review-intelligence/types.d.ts +18 -9
  166. package/dist/review-intelligence/types.d.ts.map +1 -1
  167. package/dist/review-intelligence/types.js +9 -1
  168. package/dist/review-intelligence/types.js.map +1 -1
  169. package/dist/templates/claude-md.d.ts.map +1 -1
  170. package/dist/templates/claude-md.js +23 -128
  171. package/dist/templates/claude-md.js.map +1 -1
  172. package/dist/templates/hooks.d.ts.map +1 -1
  173. package/dist/templates/hooks.js +39 -0
  174. package/dist/templates/hooks.js.map +1 -1
  175. package/package.json +9 -9
@@ -0,0 +1,16 @@
1
+ import type { InvariantDetector } from '../types.js';
2
+ import type { PackRule } from '../packs/index.js';
3
+ /**
4
+ * INVARIANT — pack_rules (dynamic)
5
+ *
6
+ * Enforces enabled invariant pack rules. Each PackRule has:
7
+ * - trigger_pattern: regex that matches raw callsites
8
+ * - helper: the sanctioned wrapper/helper name that should be used
9
+ * - kind: required_wrapper | required_helper | forbidden_pattern | required_pattern
10
+ *
11
+ * This detector is parameterized at construction time with the active pack
12
+ * rules. It is NOT registered as a static built-in — instead it is created
13
+ * on-the-fly by the engine when enabled packs have rules.
14
+ */
15
+ export declare function createPackRulesDetector(rules: PackRule[]): InvariantDetector;
16
+ //# sourceMappingURL=pack-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-rules.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/pack-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CA6B5E"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * INVARIANT — pack_rules (dynamic)
3
+ *
4
+ * Enforces enabled invariant pack rules. Each PackRule has:
5
+ * - trigger_pattern: regex that matches raw callsites
6
+ * - helper: the sanctioned wrapper/helper name that should be used
7
+ * - kind: required_wrapper | required_helper | forbidden_pattern | required_pattern
8
+ *
9
+ * This detector is parameterized at construction time with the active pack
10
+ * rules. It is NOT registered as a static built-in — instead it is created
11
+ * on-the-fly by the engine when enabled packs have rules.
12
+ */
13
+ export function createPackRulesDetector(rules) {
14
+ return {
15
+ name: 'pack_rules',
16
+ analyze(ctx) {
17
+ const findings = [];
18
+ if (rules.length === 0)
19
+ return findings;
20
+ for (const filePath of ctx.files) {
21
+ const content = ctx.fileContents.get(filePath);
22
+ if (!content)
23
+ continue;
24
+ if (!isAnalyzableFile(filePath))
25
+ continue;
26
+ const lines = content.split('\n');
27
+ for (const rule of rules) {
28
+ if (rule.kind === 'forbidden_pattern') {
29
+ analyzeForbiddenPattern(rule, filePath, lines, findings);
30
+ }
31
+ else if (rule.kind === 'required_wrapper' || rule.kind === 'required_helper') {
32
+ analyzeRequiredWrapper(rule, filePath, content, lines, findings);
33
+ }
34
+ // required_pattern rules are structural — handled by built-in detectors
35
+ }
36
+ }
37
+ return findings;
38
+ },
39
+ };
40
+ }
41
+ function analyzeForbiddenPattern(rule, filePath, lines, findings) {
42
+ if (!rule.trigger_pattern)
43
+ return;
44
+ const triggerRe = new RegExp(rule.trigger_pattern, 'g');
45
+ for (let i = 0; i < lines.length; i++) {
46
+ const line = lines[i];
47
+ const trimmed = line.trim();
48
+ if (trimmed.startsWith('//') || trimmed.startsWith('*'))
49
+ continue;
50
+ triggerRe.lastIndex = 0;
51
+ if (triggerRe.test(trimmed)) {
52
+ findings.push({
53
+ rule_id: rule.rule_id,
54
+ title: rule.description,
55
+ severity: rule.severity,
56
+ category: 'pack_rules',
57
+ file: filePath,
58
+ line: i + 1,
59
+ trigger: trimmed.slice(0, 80),
60
+ missing_companions: ['Remove or replace the forbidden pattern'],
61
+ why_it_matters: rule.description,
62
+ confidence: 'high',
63
+ fixable: false,
64
+ });
65
+ }
66
+ }
67
+ }
68
+ function analyzeRequiredWrapper(rule, filePath, content, lines, findings) {
69
+ if (!rule.trigger_pattern || !rule.helper)
70
+ return;
71
+ // Check if the file uses the sanctioned helper
72
+ const helperUsed = content.includes(rule.helper);
73
+ if (helperUsed)
74
+ return; // File already uses the helper
75
+ const triggerRe = new RegExp(rule.trigger_pattern, 'g');
76
+ for (let i = 0; i < lines.length; i++) {
77
+ const line = lines[i];
78
+ const trimmed = line.trim();
79
+ if (trimmed.startsWith('//') || trimmed.startsWith('*'))
80
+ continue;
81
+ if (trimmed.startsWith('import '))
82
+ continue;
83
+ triggerRe.lastIndex = 0;
84
+ if (triggerRe.test(trimmed)) {
85
+ findings.push({
86
+ rule_id: rule.rule_id,
87
+ title: rule.description,
88
+ severity: rule.severity,
89
+ category: 'pack_rules',
90
+ file: filePath,
91
+ line: i + 1,
92
+ trigger: trimmed.slice(0, 80),
93
+ missing_companions: [`Use ${rule.helper} instead`],
94
+ why_it_matters: `Repository convention: ${rule.description}. ` +
95
+ `The sanctioned helper \`${rule.helper}\` should be used instead of raw calls.`,
96
+ confidence: 'high',
97
+ fixable: true,
98
+ });
99
+ // Only report first violation per file per rule to avoid noise
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ function isAnalyzableFile(filePath) {
105
+ return /\.(?:ts|tsx|js|jsx|mts|mjs)$/.test(filePath);
106
+ }
107
+ //# sourceMappingURL=pack-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-rules.js","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/pack-rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { InvariantDetector } from '../types.js';
2
+ /**
3
+ * INVARIANT — undeclared_dependency
4
+ *
5
+ * Detect imports of external packages that are not declared in the
6
+ * nearest package.json's dependencies or devDependencies.
7
+ *
8
+ * Severity: P1 (can cause runtime failures in production/Docker builds)
9
+ */
10
+ export declare const undeclaredDependencyDetector: InvariantDetector;
11
+ //# sourceMappingURL=undeclared-dependency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"undeclared-dependency.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/undeclared-dependency.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,aAAa,CAAC;AAIrB;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAgD1C,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { parseImports } from '../engine/ast-parser.js';
4
+ import { resolveModule } from '../engine/symbol-resolver.js';
5
+ /**
6
+ * INVARIANT — undeclared_dependency
7
+ *
8
+ * Detect imports of external packages that are not declared in the
9
+ * nearest package.json's dependencies or devDependencies.
10
+ *
11
+ * Severity: P1 (can cause runtime failures in production/Docker builds)
12
+ */
13
+ export const undeclaredDependencyDetector = {
14
+ name: 'build_runtime',
15
+ analyze(ctx) {
16
+ const findings = [];
17
+ const pkgJsonCache = new Map();
18
+ for (const filePath of ctx.files) {
19
+ const content = ctx.fileContents.get(filePath);
20
+ if (!content)
21
+ continue;
22
+ if (!isAnalyzableFile(filePath))
23
+ continue;
24
+ const imports = parseImports(content);
25
+ const declaredDeps = findDeclaredDependencies(ctx.cwd, filePath, pkgJsonCache);
26
+ if (!declaredDeps)
27
+ continue; // No package.json found
28
+ for (const imp of imports) {
29
+ if (imp.isTypeOnly)
30
+ continue; // Type-only imports don't need runtime deps
31
+ const resolved = resolveModule(imp.source);
32
+ if (resolved.kind !== 'external')
33
+ continue;
34
+ if (!resolved.packageName)
35
+ continue;
36
+ // Skip workspace packages (handled separately)
37
+ if (resolved.packageName.startsWith('@codeledger/'))
38
+ continue;
39
+ if (!declaredDeps.has(resolved.packageName)) {
40
+ findings.push({
41
+ rule_id: 'RI-UD-001',
42
+ title: 'Undeclared dependency',
43
+ severity: 'P1',
44
+ category: 'build_runtime',
45
+ file: filePath,
46
+ line: imp.line,
47
+ trigger: `import from '${imp.source}'`,
48
+ missing_companions: [`Add '${resolved.packageName}' to package.json dependencies`],
49
+ why_it_matters: `Package '${resolved.packageName}' is imported but not declared in package.json. ` +
50
+ 'This may work locally due to hoisting but will fail in Docker builds, ' +
51
+ 'CI environments, or after clean installs.',
52
+ confidence: 'high',
53
+ });
54
+ }
55
+ }
56
+ }
57
+ return findings;
58
+ },
59
+ };
60
+ /**
61
+ * Find the declared dependencies for a file by walking up to the nearest package.json.
62
+ */
63
+ function findDeclaredDependencies(cwd, filePath, cache) {
64
+ const fullPath = join(cwd, filePath);
65
+ let dir = dirname(fullPath);
66
+ while (dir.startsWith(cwd)) {
67
+ const pkgJsonPath = join(dir, 'package.json');
68
+ const cached = cache.get(pkgJsonPath);
69
+ if (cached)
70
+ return cached;
71
+ if (existsSync(pkgJsonPath)) {
72
+ try {
73
+ const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
74
+ const deps = new Set();
75
+ for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
76
+ const section = pkg[field];
77
+ if (section && typeof section === 'object') {
78
+ for (const name of Object.keys(section)) {
79
+ deps.add(name);
80
+ }
81
+ }
82
+ }
83
+ cache.set(pkgJsonPath, deps);
84
+ return deps;
85
+ }
86
+ catch {
87
+ return undefined;
88
+ }
89
+ }
90
+ const parent = dirname(dir);
91
+ if (parent === dir)
92
+ break;
93
+ dir = parent;
94
+ }
95
+ return undefined;
96
+ }
97
+ function isAnalyzableFile(filePath) {
98
+ return /\.(?:ts|tsx|js|jsx|mts|mjs)$/.test(filePath);
99
+ }
100
+ //# sourceMappingURL=undeclared-dependency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"undeclared-dependency.js","sourceRoot":"","sources":["../../../src/review-intelligence/detectors/undeclared-dependency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /** Represents a detected import declaration */
2
+ export interface ImportInfo {
3
+ /** The module specifier (e.g. 'node:fs', './utils.js', 'lodash') */
4
+ source: string;
5
+ /** Named imports (e.g. ['readFileSync', 'writeFileSync']) */
6
+ namedImports: string[];
7
+ /** Default import name, if any */
8
+ defaultImport?: string;
9
+ /** Namespace import name (import * as X), if any */
10
+ namespaceImport?: string;
11
+ /** Whether this is a type-only import */
12
+ isTypeOnly: boolean;
13
+ /** Line number (1-based) */
14
+ line: number;
15
+ /** Whether this is a dynamic import() */
16
+ isDynamic: boolean;
17
+ }
18
+ /** Represents a detected function/method call */
19
+ export interface CallExpressionInfo {
20
+ /** The callee expression (e.g. 'fetch', 'reply.status', 'z.object') */
21
+ callee: string;
22
+ /** The object part if a member expression (e.g. 'reply' from 'reply.status') */
23
+ object?: string;
24
+ /** The method part if a member expression (e.g. 'status' from 'reply.status') */
25
+ method?: string;
26
+ /** Line number (1-based) */
27
+ line: number;
28
+ /** Raw matched text */
29
+ rawText: string;
30
+ /** Whether this call has generic type arguments */
31
+ hasGenerics: boolean;
32
+ }
33
+ /** Represents a detected generic type usage */
34
+ export interface GenericInfo {
35
+ /** The base type/function name */
36
+ name: string;
37
+ /** The generic type arguments as raw text */
38
+ typeArgs: string;
39
+ /** Line number (1-based) */
40
+ line: number;
41
+ }
42
+ /** Represents an exported symbol */
43
+ export interface ExportInfo {
44
+ /** The exported name */
45
+ name: string;
46
+ /** The kind of export */
47
+ kind: 'function' | 'const' | 'class' | 'type' | 'interface' | 'enum' | 'reexport';
48
+ /** Whether it's a default export */
49
+ isDefault: boolean;
50
+ /** Line number (1-based) */
51
+ line: number;
52
+ }
53
+ /** Full AST analysis result for a file */
54
+ export interface FileAnalysis {
55
+ /** All import declarations */
56
+ imports: ImportInfo[];
57
+ /** All call expressions detected */
58
+ calls: CallExpressionInfo[];
59
+ /** All generic type usages */
60
+ generics: GenericInfo[];
61
+ /** All exports */
62
+ exports: ExportInfo[];
63
+ /** Whether the file is analyzable (TS/JS) */
64
+ analyzable: boolean;
65
+ }
66
+ /**
67
+ * Check if a file path is analyzable by the AST engine.
68
+ */
69
+ export declare function isAnalyzableFile(filePath: string): boolean;
70
+ /**
71
+ * Parse all import declarations from TypeScript/JavaScript source.
72
+ */
73
+ export declare function parseImports(content: string): ImportInfo[];
74
+ /**
75
+ * Parse call expressions from source code.
76
+ */
77
+ export declare function parseCallExpressions(content: string): CallExpressionInfo[];
78
+ /**
79
+ * Parse generic type usages from source code.
80
+ */
81
+ export declare function parseGenerics(content: string): GenericInfo[];
82
+ /**
83
+ * Parse all exports from source code.
84
+ */
85
+ export declare function parseExports(content: string): ExportInfo[];
86
+ /**
87
+ * Perform full file analysis: imports, calls, generics, exports.
88
+ */
89
+ export declare function analyzeFile(filePath: string, content: string): FileAnalysis;
90
+ //# sourceMappingURL=ast-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-parser.d.ts","sourceRoot":"","sources":["../../../src/review-intelligence/engine/ast-parser.ts"],"names":[],"mappings":"AAWA,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kCAAkC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,UAAU,EAAE,OAAO,CAAC;IACpB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;IAClF,oCAAoC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IAC3B,8BAA8B;IAC9B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,oCAAoC;IACpC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,8BAA8B;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,kBAAkB;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,6CAA6C;IAC7C,UAAU,EAAE,OAAO,CAAC;CACrB;AAID;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAoG1D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAgD1E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CA0B5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAyD1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAkB3E"}
@@ -0,0 +1,266 @@
1
+ // ─── AST Parser ─────────────────────────────────────────────────────────────
2
+ //
3
+ // Lightweight TypeScript AST analysis using regex-based pattern matching
4
+ // with structural awareness. Provides the foundation for detecting
5
+ // call expressions, import declarations, generics, and variable references
6
+ // without requiring ts-morph or the full TypeScript compiler API as a
7
+ // runtime dependency.
8
+ //
9
+ // For non-TS files (Dockerfiles, YAML, JSON, shell), use the regex-based
10
+ // detectors directly.
11
+ const ANALYZABLE_EXTENSIONS = /\.(?:ts|tsx|js|jsx|mts|mjs|cts|cjs)$/;
12
+ /**
13
+ * Check if a file path is analyzable by the AST engine.
14
+ */
15
+ export function isAnalyzableFile(filePath) {
16
+ return ANALYZABLE_EXTENSIONS.test(filePath);
17
+ }
18
+ /**
19
+ * Parse all import declarations from TypeScript/JavaScript source.
20
+ */
21
+ export function parseImports(content) {
22
+ const imports = [];
23
+ const lines = content.split('\n');
24
+ for (let i = 0; i < lines.length; i++) {
25
+ const line = lines[i];
26
+ const trimmed = line.trim();
27
+ // Skip comments
28
+ if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) {
29
+ continue;
30
+ }
31
+ // Static imports: import { x } from 'y'; import x from 'y'; import * as x from 'y'
32
+ const staticImportMatch = /^import\s+(type\s+)?(.+?)\s+from\s+['"]([^'"]+)['"]/
33
+ .exec(trimmed);
34
+ if (staticImportMatch) {
35
+ const isTypeOnly = !!staticImportMatch[1];
36
+ const importClause = staticImportMatch[2];
37
+ const source = staticImportMatch[3];
38
+ const info = {
39
+ source,
40
+ namedImports: [],
41
+ isTypeOnly,
42
+ line: i + 1,
43
+ isDynamic: false,
44
+ };
45
+ // Namespace import: import * as X from '...'
46
+ const nsMatch = /^\*\s+as\s+(\w+)$/.exec(importClause);
47
+ if (nsMatch) {
48
+ info.namespaceImport = nsMatch[1];
49
+ }
50
+ // Named imports: import { a, b } from '...'
51
+ else if (importClause.includes('{')) {
52
+ const namedMatch = /\{([^}]+)\}/.exec(importClause);
53
+ if (namedMatch) {
54
+ info.namedImports = namedMatch[1]
55
+ .split(',')
56
+ .map((n) => n.trim().replace(/\s+as\s+\w+/, '').replace(/^type\s+/, ''))
57
+ .filter((n) => n.length > 0);
58
+ }
59
+ // Also check for default import before the braces: import X, { a, b } from '...'
60
+ const defaultBeforeBrace = /^(\w+)\s*,\s*\{/.exec(importClause);
61
+ if (defaultBeforeBrace) {
62
+ info.defaultImport = defaultBeforeBrace[1];
63
+ }
64
+ }
65
+ // Default import: import X from '...'
66
+ else {
67
+ const defaultMatch = /^(\w+)$/.exec(importClause.trim());
68
+ if (defaultMatch) {
69
+ info.defaultImport = defaultMatch[1];
70
+ }
71
+ }
72
+ imports.push(info);
73
+ continue;
74
+ }
75
+ // Side-effect imports: import 'module'
76
+ const sideEffectMatch = /^import\s+['"]([^'"]+)['"]/.exec(trimmed);
77
+ if (sideEffectMatch) {
78
+ imports.push({
79
+ source: sideEffectMatch[1],
80
+ namedImports: [],
81
+ isTypeOnly: false,
82
+ line: i + 1,
83
+ isDynamic: false,
84
+ });
85
+ continue;
86
+ }
87
+ // Dynamic imports: import('module') or await import('module')
88
+ const dynamicMatch = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/.exec(trimmed);
89
+ if (dynamicMatch && !trimmed.startsWith('import ')) {
90
+ imports.push({
91
+ source: dynamicMatch[1],
92
+ namedImports: [],
93
+ isTypeOnly: false,
94
+ line: i + 1,
95
+ isDynamic: true,
96
+ });
97
+ }
98
+ // require() calls
99
+ const requireMatch = /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/.exec(trimmed);
100
+ if (requireMatch) {
101
+ imports.push({
102
+ source: requireMatch[1],
103
+ namedImports: [],
104
+ isTypeOnly: false,
105
+ line: i + 1,
106
+ isDynamic: true,
107
+ });
108
+ }
109
+ }
110
+ return imports;
111
+ }
112
+ /**
113
+ * Parse call expressions from source code.
114
+ */
115
+ export function parseCallExpressions(content) {
116
+ const calls = [];
117
+ const lines = content.split('\n');
118
+ for (let i = 0; i < lines.length; i++) {
119
+ const line = lines[i];
120
+ const trimmed = line.trim();
121
+ // Skip comments and imports
122
+ if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*'))
123
+ continue;
124
+ if (trimmed.startsWith('import '))
125
+ continue;
126
+ // Member calls
127
+ const memberPattern = /\b(\w+)\s*\.\s*(\w+)\s*(<[^>]*>)?\s*\(/g;
128
+ let match;
129
+ while ((match = memberPattern.exec(line)) !== null) {
130
+ const obj = match[1];
131
+ const method = match[2];
132
+ // Skip common non-calls
133
+ if (['if', 'for', 'while', 'switch', 'catch', 'return', 'typeof', 'class'].includes(obj))
134
+ continue;
135
+ calls.push({
136
+ callee: `${obj}.${method}`,
137
+ object: obj,
138
+ method,
139
+ line: i + 1,
140
+ rawText: match[0],
141
+ hasGenerics: !!match[3],
142
+ });
143
+ }
144
+ // Standalone function calls (not already captured as member calls)
145
+ const standalonePattern = /(?:^|[^.\w])(\w+)\s*(<[^>]*>)?\s*\(/g;
146
+ while ((match = standalonePattern.exec(line)) !== null) {
147
+ const name = match[1];
148
+ // Skip keywords and common false positives
149
+ if (['if', 'for', 'while', 'switch', 'catch', 'return', 'typeof', 'class', 'new', 'function', 'import', 'export', 'const', 'let', 'var', 'async', 'await'].includes(name))
150
+ continue;
151
+ calls.push({
152
+ callee: name,
153
+ line: i + 1,
154
+ rawText: match[0],
155
+ hasGenerics: !!match[2],
156
+ });
157
+ }
158
+ }
159
+ return calls;
160
+ }
161
+ /**
162
+ * Parse generic type usages from source code.
163
+ */
164
+ export function parseGenerics(content) {
165
+ const generics = [];
166
+ const lines = content.split('\n');
167
+ const genericPattern = /\b(\w+)\s*<([^>]+)>/g;
168
+ for (let i = 0; i < lines.length; i++) {
169
+ const line = lines[i];
170
+ const trimmed = line.trim();
171
+ if (trimmed.startsWith('//') || trimmed.startsWith('*'))
172
+ continue;
173
+ let match;
174
+ while ((match = genericPattern.exec(line)) !== null) {
175
+ const name = match[1];
176
+ // Skip common HTML-like tags and comparison operators
177
+ if (['return', 'const', 'let', 'var'].includes(name))
178
+ continue;
179
+ generics.push({
180
+ name,
181
+ typeArgs: match[2].trim(),
182
+ line: i + 1,
183
+ });
184
+ }
185
+ }
186
+ return generics;
187
+ }
188
+ /**
189
+ * Parse all exports from source code.
190
+ */
191
+ export function parseExports(content) {
192
+ const exports = [];
193
+ const lines = content.split('\n');
194
+ for (let i = 0; i < lines.length; i++) {
195
+ const line = lines[i];
196
+ const trimmed = line.trim();
197
+ // export default
198
+ if (/^export\s+default\s+/.test(trimmed)) {
199
+ const kindMatch = /^export\s+default\s+(?:async\s+)?(\w+)/.exec(trimmed);
200
+ const kind = kindMatch?.[1];
201
+ let exportKind = 'const';
202
+ if (kind === 'function')
203
+ exportKind = 'function';
204
+ else if (kind === 'class')
205
+ exportKind = 'class';
206
+ exports.push({
207
+ name: 'default',
208
+ kind: exportKind,
209
+ isDefault: true,
210
+ line: i + 1,
211
+ });
212
+ continue;
213
+ }
214
+ // export function/const/class/type/interface/enum
215
+ const namedExportMatch = /^export\s+(?:async\s+)?(function|const|let|class|type|interface|enum)\s+(\w+)/.exec(trimmed);
216
+ if (namedExportMatch) {
217
+ const rawKind = namedExportMatch[1];
218
+ const kind = rawKind === 'let' ? 'const' : rawKind;
219
+ exports.push({
220
+ name: namedExportMatch[2],
221
+ kind,
222
+ isDefault: false,
223
+ line: i + 1,
224
+ });
225
+ continue;
226
+ }
227
+ // export { a, b, c }
228
+ const reExportMatch = /^export\s*\{([^}]+)\}/.exec(trimmed);
229
+ if (reExportMatch) {
230
+ const names = reExportMatch[1].split(',').map((n) => n.trim().split(/\s+as\s+/).pop().trim());
231
+ for (const name of names) {
232
+ if (name) {
233
+ exports.push({
234
+ name,
235
+ kind: 'reexport',
236
+ isDefault: false,
237
+ line: i + 1,
238
+ });
239
+ }
240
+ }
241
+ }
242
+ }
243
+ return exports;
244
+ }
245
+ /**
246
+ * Perform full file analysis: imports, calls, generics, exports.
247
+ */
248
+ export function analyzeFile(filePath, content) {
249
+ if (!isAnalyzableFile(filePath)) {
250
+ return {
251
+ imports: [],
252
+ calls: [],
253
+ generics: [],
254
+ exports: [],
255
+ analyzable: false,
256
+ };
257
+ }
258
+ return {
259
+ imports: parseImports(content),
260
+ calls: parseCallExpressions(content),
261
+ generics: parseGenerics(content),
262
+ exports: parseExports(content),
263
+ analyzable: true,
264
+ };
265
+ }
266
+ //# sourceMappingURL=ast-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-parser.js","sourceRoot":"","sources":["../../../src/review-intelligence/engine/ast-parser.ts"],"names":[],"mappings":"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"}