lsp-intelligence 0.2.1 → 0.3.2

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 (149) hide show
  1. package/.claude-plugin/marketplace.json +18 -0
  2. package/.claude-plugin/plugin.json +11 -0
  3. package/CLAUDE.md +75 -0
  4. package/README.md +15 -38
  5. package/dist/adapters/express/index.d.ts +9 -0
  6. package/dist/adapters/express/index.js +46 -0
  7. package/dist/adapters/express/index.js.map +1 -0
  8. package/dist/adapters/next/index.d.ts +10 -0
  9. package/dist/adapters/next/index.js +67 -0
  10. package/dist/adapters/next/index.js.map +1 -0
  11. package/dist/adapters/react/index.d.ts +11 -0
  12. package/dist/adapters/react/index.js +133 -0
  13. package/dist/adapters/react/index.js.map +1 -0
  14. package/dist/adapters/registry.d.ts +22 -0
  15. package/dist/adapters/registry.js +101 -0
  16. package/dist/adapters/registry.js.map +1 -0
  17. package/dist/adapters/types.d.ts +97 -0
  18. package/dist/adapters/types.js +2 -0
  19. package/dist/adapters/types.js.map +1 -0
  20. package/dist/analysis/ts/applyVirtualEdit.d.ts +27 -0
  21. package/dist/analysis/ts/applyVirtualEdit.js +235 -0
  22. package/dist/analysis/ts/applyVirtualEdit.js.map +1 -0
  23. package/dist/analysis/ts/changeRecipes.d.ts +52 -0
  24. package/dist/analysis/ts/changeRecipes.js +14 -0
  25. package/dist/analysis/ts/changeRecipes.js.map +1 -0
  26. package/dist/analysis/ts/compatibility.d.ts +54 -0
  27. package/dist/analysis/ts/compatibility.js +113 -0
  28. package/dist/analysis/ts/compatibility.js.map +1 -0
  29. package/dist/analysis/ts/diffDeclarationShape.d.ts +26 -0
  30. package/dist/analysis/ts/diffDeclarationShape.js +114 -0
  31. package/dist/analysis/ts/diffDeclarationShape.js.map +1 -0
  32. package/dist/analysis/ts/exhaustiveness.d.ts +49 -0
  33. package/dist/analysis/ts/exhaustiveness.js +158 -0
  34. package/dist/analysis/ts/exhaustiveness.js.map +1 -0
  35. package/dist/analysis/ts/extractDeclarationShape.d.ts +30 -0
  36. package/dist/analysis/ts/extractDeclarationShape.js +127 -0
  37. package/dist/analysis/ts/extractDeclarationShape.js.map +1 -0
  38. package/dist/analysis/ts/extractExports.d.ts +19 -0
  39. package/dist/analysis/ts/extractExports.js +178 -0
  40. package/dist/analysis/ts/extractExports.js.map +1 -0
  41. package/dist/analysis/ts/extractRoutes.d.ts +12 -0
  42. package/dist/analysis/ts/extractRoutes.js +165 -0
  43. package/dist/analysis/ts/extractRoutes.js.map +1 -0
  44. package/dist/analysis/ts/parseSourceFile.d.ts +5 -1
  45. package/dist/analysis/ts/parseSourceFile.js +6 -2
  46. package/dist/analysis/ts/parseSourceFile.js.map +1 -1
  47. package/dist/analysis/ts/program/CheckerQueries.d.ts +56 -0
  48. package/dist/analysis/ts/program/CheckerQueries.js +187 -0
  49. package/dist/analysis/ts/program/CheckerQueries.js.map +1 -0
  50. package/dist/analysis/ts/program/ProgramManager.d.ts +27 -0
  51. package/dist/analysis/ts/program/ProgramManager.js +147 -0
  52. package/dist/analysis/ts/program/ProgramManager.js.map +1 -0
  53. package/dist/analysis/ts/program/TypeFacts.d.ts +58 -0
  54. package/dist/analysis/ts/program/TypeFacts.js +68 -0
  55. package/dist/analysis/ts/program/TypeFacts.js.map +1 -0
  56. package/dist/analysis/ts/typeState.d.ts +46 -0
  57. package/dist/analysis/ts/typeState.js +108 -0
  58. package/dist/analysis/ts/typeState.js.map +1 -0
  59. package/dist/ast/diffDeclarationShapes.js +25 -11
  60. package/dist/ast/diffDeclarationShapes.js.map +1 -1
  61. package/dist/ast/extractExportDeclarations.js +8 -3
  62. package/dist/ast/extractExportDeclarations.js.map +1 -1
  63. package/dist/cache/CacheSchema.d.ts +30 -0
  64. package/dist/cache/CacheSchema.js +9 -0
  65. package/dist/cache/CacheSchema.js.map +1 -0
  66. package/dist/cache/CacheStore.d.ts +22 -0
  67. package/dist/cache/CacheStore.js +111 -0
  68. package/dist/cache/CacheStore.js.map +1 -0
  69. package/dist/cache/SemanticCache.d.ts +38 -0
  70. package/dist/cache/SemanticCache.js +87 -0
  71. package/dist/cache/SemanticCache.js.map +1 -0
  72. package/dist/cache/SnapshotFingerprint.d.ts +17 -0
  73. package/dist/cache/SnapshotFingerprint.js +14 -0
  74. package/dist/cache/SnapshotFingerprint.js.map +1 -0
  75. package/dist/engine/DocumentManager.d.ts +16 -0
  76. package/dist/engine/DocumentManager.js +32 -0
  77. package/dist/engine/DocumentManager.js.map +1 -1
  78. package/dist/index.js +6 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/search/adapters/http.d.ts +9 -3
  81. package/dist/search/adapters/http.js +7 -52
  82. package/dist/search/adapters/http.js.map +1 -1
  83. package/dist/search/adapters/react.d.ts +8 -8
  84. package/dist/search/adapters/react.js +3 -88
  85. package/dist/search/adapters/react.js.map +1 -1
  86. package/dist/search/adapters/registry.d.ts +7 -4
  87. package/dist/search/adapters/registry.js +7 -17
  88. package/dist/search/adapters/registry.js.map +1 -1
  89. package/dist/search/expand/graphExpansion.js +47 -14
  90. package/dist/search/expand/graphExpansion.js.map +1 -1
  91. package/dist/search/index/declarationIndex.d.ts +3 -1
  92. package/dist/search/index/declarationIndex.js +4 -2
  93. package/dist/search/index/declarationIndex.js.map +1 -1
  94. package/dist/search/index/routeIndex.d.ts +6 -0
  95. package/dist/search/index/routeIndex.js +19 -0
  96. package/dist/search/index/routeIndex.js.map +1 -0
  97. package/dist/search/index/usageIndex.d.ts +3 -1
  98. package/dist/search/index/usageIndex.js +4 -2
  99. package/dist/search/index/usageIndex.js.map +1 -1
  100. package/dist/search/index/workspaceIndex.d.ts +7 -1
  101. package/dist/search/index/workspaceIndex.js +54 -14
  102. package/dist/search/index/workspaceIndex.js.map +1 -1
  103. package/dist/search/query/compileEffectiveSearchSpec.js +9 -0
  104. package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -1
  105. package/dist/search/query/parseQuery.js +5 -1
  106. package/dist/search/query/parseQuery.js.map +1 -1
  107. package/dist/search/query/planQuery.js +14 -4
  108. package/dist/search/query/planQuery.js.map +1 -1
  109. package/dist/search/ranking/mergeCandidates.d.ts +1 -0
  110. package/dist/search/ranking/mergeCandidates.js +16 -0
  111. package/dist/search/ranking/mergeCandidates.js.map +1 -1
  112. package/dist/search/retrievers/routeRetriever.d.ts +7 -0
  113. package/dist/search/retrievers/routeRetriever.js +64 -0
  114. package/dist/search/retrievers/routeRetriever.js.map +1 -0
  115. package/dist/search/types.d.ts +16 -4
  116. package/dist/session/OverlayStore.d.ts +15 -0
  117. package/dist/session/OverlayStore.js +46 -0
  118. package/dist/session/OverlayStore.js.map +1 -0
  119. package/dist/session/SnapshotResolver.d.ts +31 -0
  120. package/dist/session/SnapshotResolver.js +50 -0
  121. package/dist/session/SnapshotResolver.js.map +1 -0
  122. package/dist/session/WorkspaceSnapshot.d.ts +21 -0
  123. package/dist/session/WorkspaceSnapshot.js +2 -0
  124. package/dist/session/WorkspaceSnapshot.js.map +1 -0
  125. package/dist/tools/composites/apiGuard.d.ts +4 -0
  126. package/dist/tools/composites/apiGuard.js +158 -24
  127. package/dist/tools/composites/apiGuard.js.map +1 -1
  128. package/dist/tools/composites/findCode.js +12 -2
  129. package/dist/tools/composites/findCode.js.map +1 -1
  130. package/dist/tools/composites/rootCauseTrace.js +89 -13
  131. package/dist/tools/composites/rootCauseTrace.js.map +1 -1
  132. package/dist/workflows/simulateChange.d.ts +44 -0
  133. package/dist/workflows/simulateChange.js +194 -0
  134. package/dist/workflows/simulateChange.js.map +1 -0
  135. package/dist/workflows/verifyChangeSet.d.ts +58 -0
  136. package/dist/workflows/verifyChangeSet.js +300 -0
  137. package/dist/workflows/verifyChangeSet.js.map +1 -0
  138. package/hooks/hooks.json +25 -0
  139. package/hooks/post-edit-check.sh +23 -0
  140. package/package.json +20 -4
  141. package/scripts/launch.mjs +29 -0
  142. package/skills/api-check/SKILL.md +34 -0
  143. package/skills/check/SKILL.md +25 -0
  144. package/skills/context/SKILL.md +24 -0
  145. package/skills/diff/SKILL.md +27 -0
  146. package/skills/find/SKILL.md +63 -0
  147. package/skills/impact/SKILL.md +21 -0
  148. package/skills/verify/SKILL.md +54 -0
  149. package/skills/why/SKILL.md +31 -0
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Diff two declaration shapes and return a list of changes.
3
+ */
4
+ export function diffDeclarationShapes(base, current) {
5
+ const diffs = [];
6
+ // Name changed
7
+ if (base.name !== current.name) {
8
+ diffs.push({ kind: 'renamed', risk: 'breaking', reason: `Renamed from "${base.name}" to "${current.name}"`, details: [`base: ${base.name}`, `current: ${current.name}`] });
9
+ }
10
+ // Params changed (functions)
11
+ if (base.params && current.params) {
12
+ // New params (required or optional)
13
+ for (const cp of current.params) {
14
+ const bp = base.params.find((p) => p.name === cp.name);
15
+ if (!bp && !cp.optional) {
16
+ diffs.push({ kind: 'param_required', risk: 'breaking', reason: `New required parameter "${cp.name}"`, details: [`param: ${cp.name}`, `type: ${cp.typeText ?? 'unknown'}`] });
17
+ }
18
+ else if (!bp && cp.optional) {
19
+ diffs.push({ kind: 'param_added', risk: 'safe', reason: `New optional parameter "${cp.name}"`, details: [`param: ${cp.name}`, `type: ${cp.typeText ?? 'unknown'}`] });
20
+ }
21
+ }
22
+ // Removed params
23
+ for (const bp of base.params) {
24
+ if (!current.params.find((p) => p.name === bp.name)) {
25
+ diffs.push({ kind: 'param_removed', risk: 'breaking', reason: `Parameter "${bp.name}" removed`, details: [`param: ${bp.name}`] });
26
+ }
27
+ }
28
+ // Optional → required
29
+ for (const cp of current.params) {
30
+ const bp = base.params.find((p) => p.name === cp.name);
31
+ if (bp && bp.optional && !cp.optional) {
32
+ diffs.push({ kind: 'param_required', risk: 'breaking', reason: `Parameter "${cp.name}" became required (was optional)`, details: [`param: ${cp.name}`] });
33
+ }
34
+ }
35
+ }
36
+ // Return type changed
37
+ if (base.returnTypeText && current.returnTypeText && base.returnTypeText !== current.returnTypeText) {
38
+ diffs.push({ kind: 'return_type_changed', risk: 'risky', reason: `Return type changed from "${base.returnTypeText}" to "${current.returnTypeText}"`, details: [`base: ${base.returnTypeText}`, `current: ${current.returnTypeText}`] });
39
+ }
40
+ // Interface members changed
41
+ if (base.members && current.members) {
42
+ const baseByName = new Map(base.members.map((m) => [m.name, m]));
43
+ const currentByName = new Map(current.members.map((m) => [m.name, m]));
44
+ for (const [name, cm] of currentByName) {
45
+ const bm = baseByName.get(name);
46
+ if (!bm) {
47
+ if (!cm.optional) {
48
+ diffs.push({ kind: 'interface_shape_changed', risk: 'breaking', reason: `Required interface property "${name}" added — breaking for existing implementations`, details: [`property: ${name}`, `type: ${cm.typeText ?? 'unknown'}`] });
49
+ }
50
+ else {
51
+ diffs.push({ kind: 'interface_shape_changed', risk: 'risky', reason: `Optional interface property "${name}" added`, details: [`property: ${name}`] });
52
+ }
53
+ }
54
+ else if (bm.optional && !cm.optional) {
55
+ diffs.push({ kind: 'interface_shape_changed', risk: 'breaking', reason: `Interface property "${name}" became required (was optional)`, details: [`property: ${name}`] });
56
+ }
57
+ }
58
+ for (const [name] of baseByName) {
59
+ if (!currentByName.has(name)) {
60
+ diffs.push({ kind: 'interface_shape_changed', risk: 'breaking', reason: `Interface property "${name}" removed`, details: [`property: ${name}`] });
61
+ }
62
+ }
63
+ }
64
+ // Enum members changed
65
+ if (base.enumMembers && current.enumMembers) {
66
+ const added = current.enumMembers.filter((m) => !base.enumMembers.includes(m));
67
+ const removed = base.enumMembers.filter((m) => !current.enumMembers.includes(m));
68
+ for (const m of added) {
69
+ diffs.push({ kind: 'enum_member_added', risk: 'risky', reason: `Enum member "${m}" added — exhaustive handling may be incomplete`, details: [m] });
70
+ }
71
+ for (const m of removed) {
72
+ diffs.push({ kind: 'enum_member_removed', risk: 'breaking', reason: `Enum member "${m}" removed`, details: [m] });
73
+ }
74
+ }
75
+ // Signature text changed (catch-all)
76
+ if (diffs.length === 0 && base.signatureText !== current.signatureText) {
77
+ diffs.push({ kind: 'signature_changed', risk: 'risky', reason: 'Declaration signature changed', details: [`base: ${base.signatureText}`, `current: ${current.signatureText}`] });
78
+ }
79
+ return diffs;
80
+ }
81
+ const RISK_ORDER = { breaking: 2, risky: 1, safe: 0 };
82
+ function worstRisk(diffs) {
83
+ return diffs.reduce((worst, d) => RISK_ORDER[d.risk] > RISK_ORDER[worst] ? d.risk : worst, 'safe');
84
+ }
85
+ /**
86
+ * Diff two sets of exports: find added, removed, and changed declarations.
87
+ * Each result includes risk, the originating shapes, and per-change diffs.
88
+ */
89
+ export function diffExportSets(baseShapes, currentShapes) {
90
+ const results = [];
91
+ const baseByName = new Map(baseShapes.map((s) => [s.name, s]));
92
+ const currentByName = new Map(currentShapes.map((s) => [s.name, s]));
93
+ for (const [name, baseShape] of baseByName) {
94
+ if (!currentByName.has(name)) {
95
+ results.push({ name, status: 'removed', risk: 'breaking', diffs: [{ kind: 'removed', risk: 'breaking', reason: `Export "${name}" (${baseShape.kind}) was removed`, details: [] }], baseShape });
96
+ }
97
+ }
98
+ for (const [name, currentShape] of currentByName) {
99
+ if (!baseByName.has(name)) {
100
+ results.push({ name, status: 'added', risk: 'safe', diffs: [{ kind: 'added', risk: 'safe', reason: `New export "${name}" (${currentShape.kind})`, details: [] }], currentShape });
101
+ }
102
+ }
103
+ for (const [name, currentShape] of currentByName) {
104
+ const baseShape = baseByName.get(name);
105
+ if (baseShape) {
106
+ const diffs = diffDeclarationShapes(baseShape, currentShape);
107
+ if (diffs.length > 0) {
108
+ results.push({ name, status: 'changed', risk: worstRisk(diffs), diffs, baseShape, currentShape });
109
+ }
110
+ }
111
+ }
112
+ return results;
113
+ }
114
+ //# sourceMappingURL=diffDeclarationShape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diffDeclarationShape.js","sourceRoot":"","sources":["../../../src/analysis/ts/diffDeclarationShape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Phase 2D — Switch exhaustiveness intelligence.
4
+ *
5
+ * Answers questions that a graph product cannot answer from structure alone:
6
+ * - "Which switches break if I add/remove this enum member?"
7
+ * - "Is this switch exhaustive over its enum?"
8
+ *
9
+ * Builds on the TypeScript checker (Phase 2C) for accurate type information.
10
+ */
11
+ export interface SwitchExhaustivenessResult {
12
+ filePath: string;
13
+ /** 1-indexed line number of the switch keyword */
14
+ line: number;
15
+ /** Enum members that are explicitly handled in this switch */
16
+ handledMembers: string[];
17
+ /** Enum members NOT handled (and no default case covers them) */
18
+ missingMembers: string[];
19
+ /** True if there is a default case (covers missing members at runtime) */
20
+ hasDefaultCase: boolean;
21
+ /** Whether the switch is exhaustive — all members covered OR has default */
22
+ isExhaustive: boolean;
23
+ }
24
+ /**
25
+ * Find all non-exhaustive switch statements for a given enum across the program.
26
+ * "Non-exhaustive" means: missing at least one enum member AND no default case.
27
+ *
28
+ * This is the core "smarter than a graph" query: the TypeScript checker knows
29
+ * which type is being switched on, and we can verify coverage precisely.
30
+ */
31
+ export declare function findNonExhaustiveSwitches(program: ts.Program, enumFilePath: string, enumName: string): SwitchExhaustivenessResult[];
32
+ /**
33
+ * Predict the exhaustiveness impact of adding a new enum member.
34
+ * Returns which switches would become non-exhaustive — i.e., they currently
35
+ * handle all members but would miss the new one.
36
+ */
37
+ export declare function predictAddedMemberImpact(program: ts.Program, enumFilePath: string, enumName: string, newMemberName: string): {
38
+ affectedSwitches: Array<{
39
+ filePath: string;
40
+ line: number;
41
+ missingMember: string;
42
+ }>;
43
+ safeCount: number;
44
+ };
45
+ /**
46
+ * Get all switch exhaustiveness results for an enum, including exhaustive ones.
47
+ * Useful for a full picture: which files use this enum in a switch.
48
+ */
49
+ export declare function getAllSwitchResults(program: ts.Program, enumFilePath: string, enumName: string): SwitchExhaustivenessResult[];
@@ -0,0 +1,158 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Find all non-exhaustive switch statements for a given enum across the program.
4
+ * "Non-exhaustive" means: missing at least one enum member AND no default case.
5
+ *
6
+ * This is the core "smarter than a graph" query: the TypeScript checker knows
7
+ * which type is being switched on, and we can verify coverage precisely.
8
+ */
9
+ export function findNonExhaustiveSwitches(program, enumFilePath, enumName) {
10
+ const checker = program.getTypeChecker();
11
+ const allMembers = getEnumMembers(program, enumFilePath, enumName);
12
+ if (!allMembers)
13
+ return [];
14
+ const results = [];
15
+ for (const sf of program.getSourceFiles()) {
16
+ if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
17
+ continue;
18
+ ts.forEachChild(sf, function visitNode(node) {
19
+ if (ts.isSwitchStatement(node)) {
20
+ const result = analyzeSwitchForEnum(node, sf, checker, enumName, allMembers);
21
+ if (result)
22
+ results.push({ filePath: sf.fileName, ...result });
23
+ }
24
+ ts.forEachChild(node, visitNode);
25
+ });
26
+ }
27
+ return results.filter((r) => !r.isExhaustive);
28
+ }
29
+ /**
30
+ * Predict the exhaustiveness impact of adding a new enum member.
31
+ * Returns which switches would become non-exhaustive — i.e., they currently
32
+ * handle all members but would miss the new one.
33
+ */
34
+ export function predictAddedMemberImpact(program, enumFilePath, enumName, newMemberName) {
35
+ const checker = program.getTypeChecker();
36
+ const currentMembers = getEnumMembers(program, enumFilePath, enumName);
37
+ if (!currentMembers)
38
+ return { affectedSwitches: [], safeCount: 0 };
39
+ const affectedSwitches = [];
40
+ let safeCount = 0;
41
+ for (const sf of program.getSourceFiles()) {
42
+ if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
43
+ continue;
44
+ ts.forEachChild(sf, function visitNode(node) {
45
+ if (ts.isSwitchStatement(node)) {
46
+ const result = analyzeSwitchForEnum(node, sf, checker, enumName, currentMembers);
47
+ if (result && result.handledMembers.length > 0) {
48
+ // This switch uses the enum
49
+ if (!result.hasDefaultCase) {
50
+ // No default — adding a new member would make it non-exhaustive
51
+ affectedSwitches.push({ filePath: sf.fileName, line: result.line, missingMember: newMemberName });
52
+ }
53
+ else {
54
+ safeCount++;
55
+ }
56
+ }
57
+ }
58
+ ts.forEachChild(node, visitNode);
59
+ });
60
+ }
61
+ return { affectedSwitches, safeCount };
62
+ }
63
+ /**
64
+ * Get all switch exhaustiveness results for an enum, including exhaustive ones.
65
+ * Useful for a full picture: which files use this enum in a switch.
66
+ */
67
+ export function getAllSwitchResults(program, enumFilePath, enumName) {
68
+ const checker = program.getTypeChecker();
69
+ const allMembers = getEnumMembers(program, enumFilePath, enumName);
70
+ if (!allMembers)
71
+ return [];
72
+ const results = [];
73
+ for (const sf of program.getSourceFiles()) {
74
+ if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
75
+ continue;
76
+ ts.forEachChild(sf, function visitNode(node) {
77
+ if (ts.isSwitchStatement(node)) {
78
+ const result = analyzeSwitchForEnum(node, sf, checker, enumName, allMembers);
79
+ if (result)
80
+ results.push({ filePath: sf.fileName, ...result });
81
+ }
82
+ ts.forEachChild(node, visitNode);
83
+ });
84
+ }
85
+ return results;
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // Internal helpers
89
+ // ---------------------------------------------------------------------------
90
+ function getEnumMembers(program, filePath, enumName) {
91
+ const sf = program.getSourceFile(filePath);
92
+ if (!sf)
93
+ return null;
94
+ let members = null;
95
+ ts.forEachChild(sf, (node) => {
96
+ if (ts.isEnumDeclaration(node) && node.name.text === enumName) {
97
+ members = node.members.map((m) => (ts.isIdentifier(m.name) ? m.name.text : m.name.getText(sf)));
98
+ }
99
+ });
100
+ return members;
101
+ }
102
+ function analyzeSwitchForEnum(node, sf, checker, enumName, allMembers) {
103
+ // Check if the switch expression uses the enum type
104
+ const switchType = checker.getTypeAtLocation(node.expression);
105
+ const typeSym = switchType.getSymbol() ?? switchType.aliasSymbol;
106
+ const typeStr = checker.typeToString(switchType);
107
+ const usesEnum = typeSym?.name === enumName || typeStr === enumName;
108
+ if (!usesEnum) {
109
+ // Also check if any case clause uses EnumName.Member pattern
110
+ const hasMemberAccess = hasCaseWithEnumAccess(node, enumName, allMembers, sf);
111
+ if (!hasMemberAccess)
112
+ return null;
113
+ }
114
+ const handled = new Set();
115
+ let hasDefaultCase = false;
116
+ for (const clause of node.caseBlock.clauses) {
117
+ if (ts.isDefaultClause(clause)) {
118
+ hasDefaultCase = true;
119
+ }
120
+ else if (ts.isCaseClause(clause)) {
121
+ const memberName = extractEnumMemberFromExpr(clause.expression, enumName, sf);
122
+ if (memberName && allMembers.includes(memberName)) {
123
+ handled.add(memberName);
124
+ }
125
+ }
126
+ }
127
+ if (handled.size === 0 && !hasDefaultCase)
128
+ return null; // Not actually using this enum
129
+ const missingMembers = allMembers.filter((m) => !handled.has(m));
130
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
131
+ return {
132
+ line,
133
+ handledMembers: [...handled],
134
+ missingMembers,
135
+ hasDefaultCase,
136
+ isExhaustive: missingMembers.length === 0 || hasDefaultCase,
137
+ };
138
+ }
139
+ function extractEnumMemberFromExpr(expr, enumName, sf) {
140
+ if (ts.isPropertyAccessExpression(expr)) {
141
+ const obj = expr.expression;
142
+ if (ts.isIdentifier(obj) && obj.text === enumName) {
143
+ return expr.name.text;
144
+ }
145
+ }
146
+ return null;
147
+ }
148
+ function hasCaseWithEnumAccess(node, enumName, members, sf) {
149
+ for (const clause of node.caseBlock.clauses) {
150
+ if (ts.isCaseClause(clause)) {
151
+ const m = extractEnumMemberFromExpr(clause.expression, enumName, sf);
152
+ if (m && members.includes(m))
153
+ return true;
154
+ }
155
+ }
156
+ return false;
157
+ }
158
+ //# sourceMappingURL=exhaustiveness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exhaustiveness.js","sourceRoot":"","sources":["../../../src/analysis/ts/exhaustiveness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import ts from 'typescript';
2
+ import type { ExportedDeclaration } from './extractExports.js';
3
+ export interface ParamShape {
4
+ name: string;
5
+ optional: boolean;
6
+ rest: boolean;
7
+ typeText?: string;
8
+ }
9
+ export interface MemberShape {
10
+ name: string;
11
+ optional?: boolean;
12
+ typeText?: string;
13
+ }
14
+ export interface DeclarationShape {
15
+ name: string;
16
+ kind: ExportedDeclaration['kind'];
17
+ line: number;
18
+ signatureText: string;
19
+ params?: ParamShape[];
20
+ returnTypeText?: string;
21
+ members?: MemberShape[];
22
+ enumMembers?: string[];
23
+ exportedAs?: string[];
24
+ moduleSpecifier?: string;
25
+ }
26
+ /**
27
+ * Extract the shape of an exported declaration for diffing.
28
+ * Works on the TS AST node near the export's line.
29
+ */
30
+ export declare function extractDeclarationShape(sf: ts.SourceFile, exp: ExportedDeclaration): DeclarationShape;
@@ -0,0 +1,127 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Extract the shape of an exported declaration for diffing.
4
+ * Works on the TS AST node near the export's line.
5
+ */
6
+ export function extractDeclarationShape(sf, exp) {
7
+ const base = {
8
+ name: exp.name,
9
+ kind: exp.kind,
10
+ line: exp.line,
11
+ signatureText: '',
12
+ exportedAs: exp.exportedAs,
13
+ moduleSpecifier: exp.moduleSpecifier,
14
+ };
15
+ // Find the node at the export's line
16
+ const node = findNodeAtLine(sf, exp.line - 1);
17
+ if (!node)
18
+ return { ...base, signatureText: `${exp.kind} ${exp.name}` };
19
+ // Function
20
+ if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {
21
+ base.params = extractParams(node);
22
+ base.returnTypeText = node.type ? node.type.getText(sf) : undefined;
23
+ base.signatureText = `function ${exp.name}(${formatParams(base.params)}): ${base.returnTypeText ?? 'unknown'}`;
24
+ return base;
25
+ }
26
+ // Method (inside class)
27
+ if (ts.isMethodDeclaration(node)) {
28
+ base.params = extractParams(node);
29
+ base.returnTypeText = node.type ? node.type.getText(sf) : undefined;
30
+ base.signatureText = `method ${exp.name}(${formatParams(base.params)})`;
31
+ return base;
32
+ }
33
+ // Interface
34
+ if (ts.isInterfaceDeclaration(node)) {
35
+ base.members = extractMembers(node, sf);
36
+ base.signatureText = `interface ${exp.name} { ${base.members.map((m) => m.name).join(', ')} }`;
37
+ return base;
38
+ }
39
+ // Type alias
40
+ if (ts.isTypeAliasDeclaration(node)) {
41
+ base.signatureText = `type ${exp.name} = ${node.type.getText(sf).substring(0, 100)}`;
42
+ return base;
43
+ }
44
+ // Enum
45
+ if (ts.isEnumDeclaration(node)) {
46
+ base.enumMembers = node.members.map((m) => ts.isIdentifier(m.name) ? m.name.text : m.name.getText(sf));
47
+ base.signatureText = `enum ${exp.name} { ${base.enumMembers.join(', ')} }`;
48
+ return base;
49
+ }
50
+ // Variable
51
+ if (ts.isVariableStatement(node)) {
52
+ for (const decl of node.declarationList.declarations) {
53
+ if (ts.isIdentifier(decl.name) && decl.name.text === exp.name) {
54
+ if (decl.initializer && (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))) {
55
+ base.params = extractParams(decl.initializer);
56
+ base.returnTypeText = decl.initializer.type ? decl.initializer.type.getText(sf) : undefined;
57
+ base.signatureText = `const ${exp.name} = (${formatParams(base.params)}) => ${base.returnTypeText ?? '...'}`;
58
+ }
59
+ else {
60
+ base.signatureText = `const ${exp.name}: ${decl.type?.getText(sf) ?? 'unknown'}`;
61
+ }
62
+ return base;
63
+ }
64
+ }
65
+ }
66
+ // Class
67
+ if (ts.isClassDeclaration(node)) {
68
+ base.members = [];
69
+ for (const member of node.members) {
70
+ if (ts.isMethodDeclaration(member) && ts.isIdentifier(member.name)) {
71
+ base.members.push({ name: member.name.text });
72
+ }
73
+ else if (ts.isPropertyDeclaration(member) && ts.isIdentifier(member.name)) {
74
+ base.members.push({
75
+ name: member.name.text,
76
+ optional: !!member.questionToken,
77
+ typeText: member.type?.getText(sf),
78
+ });
79
+ }
80
+ }
81
+ base.signatureText = `class ${exp.name} { ${base.members.map((m) => m.name).join(', ')} }`;
82
+ return base;
83
+ }
84
+ base.signatureText = `${exp.kind} ${exp.name}`;
85
+ return base;
86
+ }
87
+ function extractParams(node) {
88
+ return node.parameters.map((p) => ({
89
+ name: ts.isIdentifier(p.name) ? p.name.text : p.name.getText(),
90
+ optional: !!p.questionToken || !!p.initializer,
91
+ rest: !!p.dotDotDotToken,
92
+ typeText: p.type?.getText() ?? undefined,
93
+ }));
94
+ }
95
+ function extractMembers(node, sf) {
96
+ return node.members
97
+ .filter((m) => ts.isPropertySignature(m))
98
+ .map((m) => ({
99
+ name: ts.isIdentifier(m.name) ? m.name.text : m.name.getText(sf),
100
+ optional: !!m.questionToken,
101
+ typeText: m.type?.getText(sf),
102
+ }));
103
+ }
104
+ function formatParams(params) {
105
+ return params.map((p) => `${p.rest ? '...' : ''}${p.name}${p.optional ? '?' : ''}`).join(', ');
106
+ }
107
+ function findNodeAtLine(sf, line0) {
108
+ let found;
109
+ function visit(node) {
110
+ if (found)
111
+ return;
112
+ const nodeLine = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line;
113
+ if (nodeLine === line0 || nodeLine === line0 + 1 || nodeLine === line0 - 1) {
114
+ // Prefer specific declaration types
115
+ if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) ||
116
+ ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) ||
117
+ ts.isEnumDeclaration(node) || ts.isVariableStatement(node)) {
118
+ found = node;
119
+ return;
120
+ }
121
+ }
122
+ ts.forEachChild(node, visit);
123
+ }
124
+ visit(sf);
125
+ return found;
126
+ }
127
+ //# sourceMappingURL=extractDeclarationShape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractDeclarationShape.js","sourceRoot":"","sources":["../../../src/analysis/ts/extractDeclarationShape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Exported declaration — the shared type used by api_guard and root_cause_trace.
4
+ */
5
+ export interface ExportedDeclaration {
6
+ name: string;
7
+ exportedAs: string[];
8
+ kind: 'function' | 'class' | 'interface' | 'type' | 'enum' | 'const' | 'var' | 'default' | 'reexport' | 'cjs' | 'unknown';
9
+ filePath: string;
10
+ line: number;
11
+ isTypeOnly?: boolean;
12
+ moduleSpecifier?: string;
13
+ }
14
+ /**
15
+ * Extract all exports from a TypeScript/JavaScript source file using the TS AST.
16
+ * Supports ESM (export function, export const, export { }, export * from, export default)
17
+ * and basic CJS (module.exports, exports.foo).
18
+ */
19
+ export declare function extractExports(sf: ts.SourceFile): ExportedDeclaration[];