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 @@
1
+ {"version":3,"file":"CheckerQueries.js","sourceRoot":"","sources":["../../../../src/analysis/ts/program/CheckerQueries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import ts from 'typescript';
2
+ import type { SnapshotResolver } from '../../../session/SnapshotResolver.js';
3
+ /**
4
+ * Manages a cached TypeScript Program for semantic queries.
5
+ *
6
+ * This is NOT a replacement for the LSP server — it's a focused semantic
7
+ * accelerator for questions that AST analysis alone cannot answer reliably:
8
+ * enum member enumeration, type compatibility, exhaustiveness, param signatures.
9
+ *
10
+ * Integrates with the Phase 2A SnapshotResolver so the program operates on
11
+ * live (unsaved) buffer content when overlays are present.
12
+ */
13
+ export declare class ProgramManager {
14
+ private cache;
15
+ /**
16
+ * Get or build a TypeScript Program for a workspace root.
17
+ *
18
+ * @param workspaceRoot - Absolute path to the workspace root.
19
+ * @param resolver - Optional Phase 2A snapshot resolver for overlay awareness.
20
+ * Different resolver states produce separate cached programs — overlay and
21
+ * disk programs never share a cache entry.
22
+ */
23
+ getOrBuild(workspaceRoot: string, resolver?: SnapshotResolver): ts.Program;
24
+ /** Invalidate all cached programs for a workspace root. */
25
+ invalidate(workspaceRoot: string): void;
26
+ }
27
+ export declare const programManager: ProgramManager;
@@ -0,0 +1,147 @@
1
+ import ts from 'typescript';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import * as crypto from 'crypto';
5
+ /**
6
+ * Manages a cached TypeScript Program for semantic queries.
7
+ *
8
+ * This is NOT a replacement for the LSP server — it's a focused semantic
9
+ * accelerator for questions that AST analysis alone cannot answer reliably:
10
+ * enum member enumeration, type compatibility, exhaustiveness, param signatures.
11
+ *
12
+ * Integrates with the Phase 2A SnapshotResolver so the program operates on
13
+ * live (unsaved) buffer content when overlays are present.
14
+ */
15
+ export class ProgramManager {
16
+ // Keyed by full cache key (workspaceRoot + tsconfig hash + dirty files signature)
17
+ // so different overlay states produce independent program instances.
18
+ cache = new Map();
19
+ /**
20
+ * Get or build a TypeScript Program for a workspace root.
21
+ *
22
+ * @param workspaceRoot - Absolute path to the workspace root.
23
+ * @param resolver - Optional Phase 2A snapshot resolver for overlay awareness.
24
+ * Different resolver states produce separate cached programs — overlay and
25
+ * disk programs never share a cache entry.
26
+ */
27
+ getOrBuild(workspaceRoot, resolver) {
28
+ const cacheKey = buildCacheKey(workspaceRoot, resolver);
29
+ const cached = this.cache.get(cacheKey);
30
+ if (cached)
31
+ return cached;
32
+ const program = buildProgram(workspaceRoot, resolver);
33
+ this.cache.set(cacheKey, program);
34
+ return program;
35
+ }
36
+ /** Invalidate all cached programs for a workspace root. */
37
+ invalidate(workspaceRoot) {
38
+ for (const key of this.cache.keys()) {
39
+ if (key.startsWith(workspaceRoot + ':'))
40
+ this.cache.delete(key);
41
+ }
42
+ }
43
+ }
44
+ // Module-level singleton — one manager per process.
45
+ export const programManager = new ProgramManager();
46
+ // ---------------------------------------------------------------------------
47
+ // Internal helpers
48
+ // ---------------------------------------------------------------------------
49
+ function buildCacheKey(workspaceRoot, resolver) {
50
+ const tsConfigPath = findTsConfig(workspaceRoot);
51
+ const tsConfigHash = tsConfigPath ? hashFile(tsConfigPath) : 'no-tsconfig';
52
+ const dirtyKey = resolver ? resolver.getDirtyFiles().sort().join('|') : '';
53
+ return `${workspaceRoot}:${tsConfigHash}:${dirtyKey}`;
54
+ }
55
+ function buildProgram(workspaceRoot, resolver) {
56
+ const tsConfigPath = findTsConfig(workspaceRoot);
57
+ let compilerOptions = {
58
+ target: ts.ScriptTarget.ES2020,
59
+ module: ts.ModuleKind.CommonJS,
60
+ strict: false,
61
+ noEmit: true,
62
+ allowJs: true,
63
+ skipLibCheck: true,
64
+ skipDefaultLibCheck: true,
65
+ };
66
+ let rootNames = [];
67
+ if (tsConfigPath) {
68
+ try {
69
+ const { config, error } = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
70
+ if (!error) {
71
+ const parsed = ts.parseJsonConfigFileContent(config, ts.sys, path.dirname(tsConfigPath), {}, tsConfigPath);
72
+ compilerOptions = { ...parsed.options, noEmit: true, skipLibCheck: true, skipDefaultLibCheck: true };
73
+ rootNames = parsed.fileNames;
74
+ }
75
+ }
76
+ catch {
77
+ // Fall back to defaults
78
+ }
79
+ }
80
+ // If no files from tsconfig, collect manually
81
+ if (rootNames.length === 0) {
82
+ rootNames = collectTsFiles(workspaceRoot);
83
+ }
84
+ const host = createSnapshotHost(compilerOptions, resolver);
85
+ return ts.createProgram(rootNames, compilerOptions, host);
86
+ }
87
+ /**
88
+ * Create a CompilerHost that respects the SnapshotResolver for overlay content.
89
+ */
90
+ function createSnapshotHost(options, resolver) {
91
+ const defaultHost = ts.createCompilerHost(options);
92
+ return {
93
+ ...defaultHost,
94
+ getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
95
+ // Use overlay text if available (Phase 2A integration)
96
+ const overlayText = resolver?.getText(path.normalize(fileName));
97
+ if (overlayText !== undefined) {
98
+ return ts.createSourceFile(fileName, overlayText, languageVersion, true);
99
+ }
100
+ return defaultHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
101
+ },
102
+ fileExists(fileName) {
103
+ // Overlay files exist even if not on disk
104
+ if (resolver?.hasOverlay(path.normalize(fileName)))
105
+ return true;
106
+ return defaultHost.fileExists(fileName);
107
+ },
108
+ readFile(fileName) {
109
+ const overlayText = resolver?.getText(path.normalize(fileName));
110
+ if (overlayText !== undefined)
111
+ return overlayText;
112
+ return defaultHost.readFile(fileName);
113
+ },
114
+ };
115
+ }
116
+ function findTsConfig(workspaceRoot) {
117
+ return ts.findConfigFile(workspaceRoot, ts.sys.fileExists, 'tsconfig.json') ?? undefined;
118
+ }
119
+ function collectTsFiles(dir, depth = 0) {
120
+ if (depth > 6)
121
+ return [];
122
+ const files = [];
123
+ try {
124
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
125
+ if (entry.isDirectory()) {
126
+ const skip = ['node_modules', 'dist', 'build', '.git', 'coverage'];
127
+ if (entry.name.startsWith('.') || skip.includes(entry.name))
128
+ continue;
129
+ files.push(...collectTsFiles(path.join(dir, entry.name), depth + 1));
130
+ }
131
+ else if (/\.(ts|tsx)$/.test(entry.name) && !entry.name.endsWith('.d.ts')) {
132
+ files.push(path.join(dir, entry.name));
133
+ }
134
+ }
135
+ }
136
+ catch { }
137
+ return files;
138
+ }
139
+ function hashFile(filePath) {
140
+ try {
141
+ return crypto.createHash('sha1').update(fs.readFileSync(filePath)).digest('hex').slice(0, 8);
142
+ }
143
+ catch {
144
+ return 'unreadable';
145
+ }
146
+ }
147
+ //# sourceMappingURL=ProgramManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgramManager.js","sourceRoot":"","sources":["../../../../src/analysis/ts/program/ProgramManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { CheckerQueries } from './CheckerQueries.js';
2
+ /**
3
+ * Higher-level semantic facts derived from CheckerQueries.
4
+ * These answer the kinds of questions that make the engine "obviously smarter":
5
+ *
6
+ * - "If I add this enum member, which switches break?"
7
+ * - "Which places narrow this union and will now be wrong?"
8
+ * - "If I make this parameter required, what calls become invalid?"
9
+ */
10
+ export interface EnumMemberFact {
11
+ enumName: string;
12
+ filePath: string;
13
+ members: string[];
14
+ isStringEnum: boolean;
15
+ }
16
+ /**
17
+ * Get semantic facts about an enum, including all its current members.
18
+ */
19
+ export declare function getEnumFacts(queries: CheckerQueries, filePath: string, enumName: string): EnumMemberFact | null;
20
+ export interface ParamCompatibilityFact {
21
+ funcName: string;
22
+ filePath: string;
23
+ params: Array<{
24
+ name: string;
25
+ typeText: string;
26
+ optional: boolean;
27
+ rest: boolean;
28
+ }>;
29
+ /** Whether any required parameters exist */
30
+ hasRequiredParams: boolean;
31
+ /** Minimum number of arguments required */
32
+ minArity: number;
33
+ /** Maximum arity (Infinity if rest param present) */
34
+ maxArity: number;
35
+ }
36
+ /**
37
+ * Get parameter compatibility facts for a function.
38
+ * Used to answer "what callers would break if this param became required?"
39
+ */
40
+ export declare function getParamFacts(queries: CheckerQueries, filePath: string, funcName: string): ParamCompatibilityFact | null;
41
+ export interface SwitchExhaustivenessFact {
42
+ enumName: string;
43
+ handledMembers: string[];
44
+ missingMembers: string[];
45
+ isExhaustive: boolean;
46
+ /**
47
+ * Files where the enum is used in a switch that would be non-exhaustive
48
+ * if a new member were added.
49
+ */
50
+ affectedFiles: string[];
51
+ }
52
+ /**
53
+ * For a given enum, check all files in the program for switch statements
54
+ * that use it, and determine which would break if a new member is added.
55
+ *
56
+ * This is a preview of Phase 2D exhaustiveness intelligence.
57
+ */
58
+ export declare function getSwitchExhaustivenessAcrossFiles(queries: CheckerQueries, enumFilePath: string, enumName: string): SwitchExhaustivenessFact | null;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Get semantic facts about an enum, including all its current members.
3
+ */
4
+ export function getEnumFacts(queries, filePath, enumName) {
5
+ const members = queries.getEnumMembers(filePath, enumName);
6
+ if (!members)
7
+ return null;
8
+ // Heuristic: string enum if members have string initializers
9
+ // (CheckerQueries.getEnumMembers already returns the member names — we use type as a fact)
10
+ return {
11
+ enumName,
12
+ filePath,
13
+ members,
14
+ isStringEnum: true, // TypeScript string enums are most common; refine in Phase 2D
15
+ };
16
+ }
17
+ /**
18
+ * Get parameter compatibility facts for a function.
19
+ * Used to answer "what callers would break if this param became required?"
20
+ */
21
+ export function getParamFacts(queries, filePath, funcName) {
22
+ const params = queries.getFunctionParams(filePath, funcName);
23
+ if (!params)
24
+ return null;
25
+ const required = params.filter((p) => !p.optional && !p.rest);
26
+ const hasRest = params.some((p) => p.rest);
27
+ return {
28
+ funcName,
29
+ filePath,
30
+ params,
31
+ hasRequiredParams: required.length > 0,
32
+ minArity: required.length,
33
+ maxArity: hasRest ? Infinity : params.length,
34
+ };
35
+ }
36
+ /**
37
+ * For a given enum, check all files in the program for switch statements
38
+ * that use it, and determine which would break if a new member is added.
39
+ *
40
+ * This is a preview of Phase 2D exhaustiveness intelligence.
41
+ */
42
+ export function getSwitchExhaustivenessAcrossFiles(queries, enumFilePath, enumName) {
43
+ const allMembers = queries.getEnumMembers(enumFilePath, enumName);
44
+ if (!allMembers)
45
+ return null;
46
+ const affectedFiles = [];
47
+ let allHandled = new Set();
48
+ let allMissing = new Set(allMembers);
49
+ for (const filePath of queries.getProgramFiles()) {
50
+ const result = queries.getSwitchExhaustiveness(filePath, enumFilePath, enumName);
51
+ if (!result)
52
+ continue;
53
+ if (result.handled.length > 0) {
54
+ affectedFiles.push(filePath);
55
+ result.handled.forEach((m) => allHandled.add(m));
56
+ result.missing.forEach((m) => allMissing.add(m));
57
+ }
58
+ }
59
+ const missing = allMembers.filter((m) => !allHandled.has(m));
60
+ return {
61
+ enumName,
62
+ handledMembers: [...allHandled],
63
+ missingMembers: missing,
64
+ isExhaustive: missing.length === 0,
65
+ affectedFiles,
66
+ };
67
+ }
68
+ //# sourceMappingURL=TypeFacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeFacts.js","sourceRoot":"","sources":["../../../../src/analysis/ts/program/TypeFacts.ts"],"names":[],"mappings":"AAuBA;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAuB,EACvB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,6DAA6D;IAC7D,2FAA2F;IAC3F,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,YAAY,EAAE,IAAI,EAAE,8DAA8D;KACnF,CAAC;AACJ,CAAC;AAuBD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAuB,EACvB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE3C,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,MAAM;QACN,iBAAiB,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC;QACtC,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;KAC7C,CAAC;AACJ,CAAC;AAkBD;;;;;GAKG;AACH,MAAM,UAAU,kCAAkC,CAChD,OAAuB,EACvB,YAAoB,EACpB,QAAgB;IAEhB,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAClE,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,IAAI,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,IAAI,UAAU,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAErC,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;QACjF,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,OAAO;QACL,QAAQ;QACR,cAAc,EAAE,CAAC,GAAG,UAAU,CAAC;QAC/B,cAAc,EAAE,OAAO;QACvB,YAAY,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;QAClC,aAAa;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,46 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Phase 2D — Type-state and narrowing intelligence.
4
+ *
5
+ * Finds places in the code that depend on the specific shape of a type:
6
+ * type guards, discriminant checks, narrowing expressions.
7
+ *
8
+ * Answers: "Which places narrow this union and will be wrong if I change it?"
9
+ */
10
+ export type NarrowingKind = 'typeof-check' | 'instanceof-check' | 'discriminant-check' | 'user-defined-guard' | 'nullish-check' | 'truthiness-check';
11
+ export interface TypeNarrowingUsage {
12
+ filePath: string;
13
+ line: number;
14
+ narrowingKind: NarrowingKind;
15
+ /** The symbol being narrowed */
16
+ symbolName: string;
17
+ /** The type/value being checked against */
18
+ checkValue: string;
19
+ }
20
+ export interface TypeGuardFunction {
21
+ filePath: string;
22
+ line: number;
23
+ funcName: string;
24
+ /** The type being guarded: x is T */
25
+ guardedType: string;
26
+ }
27
+ /**
28
+ * Find all type narrowing usages for a given type name across the program.
29
+ * Used to identify code that depends on the specific shape of a discriminated union.
30
+ */
31
+ export declare function findTypeNarrowingUsages(program: ts.Program, typeName: string): TypeNarrowingUsage[];
32
+ /**
33
+ * Find all user-defined type guards that check for a specific type.
34
+ * e.g., `function isFoo(x: unknown): x is Foo`
35
+ */
36
+ export declare function findTypeGuardFunctions(program: ts.Program, typeName: string): TypeGuardFunction[];
37
+ /**
38
+ * Find all usages of a discriminant field (e.g., `.kind`, `.type`, `.tag`)
39
+ * that compare against specific string values.
40
+ * Used to identify switch/if exhaustiveness over discriminated unions.
41
+ */
42
+ export declare function findDiscriminantUsages(program: ts.Program, discriminantField: string): Array<{
43
+ filePath: string;
44
+ line: number;
45
+ checkedValue: string;
46
+ }>;
@@ -0,0 +1,108 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Find all type narrowing usages for a given type name across the program.
4
+ * Used to identify code that depends on the specific shape of a discriminated union.
5
+ */
6
+ export function findTypeNarrowingUsages(program, typeName) {
7
+ const results = [];
8
+ for (const sf of program.getSourceFiles()) {
9
+ if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
10
+ continue;
11
+ ts.forEachChild(sf, function visitNode(node) {
12
+ // Discriminant checks: x.kind === 'foo', x.type === 'bar'
13
+ if (ts.isBinaryExpression(node) &&
14
+ (node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken ||
15
+ node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken)) {
16
+ const lhsName = extractPropertyAccessBase(node.left);
17
+ if (lhsName && looksLikeTypeName(lhsName, typeName)) {
18
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
19
+ const checkValue = node.right.getText(sf);
20
+ results.push({ filePath: sf.fileName, line, narrowingKind: 'discriminant-check', symbolName: lhsName, checkValue });
21
+ }
22
+ }
23
+ // typeof checks: typeof x === 'string'
24
+ if (ts.isTypeOfExpression(node)) {
25
+ const parent = node.parent;
26
+ if (parent && ts.isBinaryExpression(parent)) {
27
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
28
+ const sym = node.expression.getText(sf);
29
+ if (sym.includes(typeName)) {
30
+ results.push({ filePath: sf.fileName, line, narrowingKind: 'typeof-check', symbolName: sym, checkValue: parent.right.getText(sf) });
31
+ }
32
+ }
33
+ }
34
+ // instanceof checks: x instanceof Foo
35
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword) {
36
+ const rhs = node.right.getText(sf);
37
+ if (rhs === typeName) {
38
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
39
+ results.push({ filePath: sf.fileName, line, narrowingKind: 'instanceof-check', symbolName: node.left.getText(sf), checkValue: rhs });
40
+ }
41
+ }
42
+ ts.forEachChild(node, visitNode);
43
+ });
44
+ }
45
+ return results;
46
+ }
47
+ /**
48
+ * Find all user-defined type guards that check for a specific type.
49
+ * e.g., `function isFoo(x: unknown): x is Foo`
50
+ */
51
+ export function findTypeGuardFunctions(program, typeName) {
52
+ const results = [];
53
+ for (const sf of program.getSourceFiles()) {
54
+ if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
55
+ continue;
56
+ ts.forEachChild(sf, (node) => {
57
+ if ((ts.isFunctionDeclaration(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&
58
+ node.type && ts.isTypePredicateNode(node.type)) {
59
+ const predicate = node.type;
60
+ const guardedTypeName = predicate.type?.getText(sf) ?? '';
61
+ if (guardedTypeName === typeName || guardedTypeName.includes(typeName)) {
62
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
63
+ const funcName = ts.isFunctionDeclaration(node) && node.name ? node.name.text : '<anonymous>';
64
+ results.push({ filePath: sf.fileName, line, funcName, guardedType: guardedTypeName });
65
+ }
66
+ }
67
+ });
68
+ }
69
+ return results;
70
+ }
71
+ /**
72
+ * Find all usages of a discriminant field (e.g., `.kind`, `.type`, `.tag`)
73
+ * that compare against specific string values.
74
+ * Used to identify switch/if exhaustiveness over discriminated unions.
75
+ */
76
+ export function findDiscriminantUsages(program, discriminantField) {
77
+ const results = [];
78
+ for (const sf of program.getSourceFiles()) {
79
+ if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
80
+ continue;
81
+ ts.forEachChild(sf, function visitNode(node) {
82
+ if (ts.isBinaryExpression(node) &&
83
+ node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken &&
84
+ ts.isPropertyAccessExpression(node.left) &&
85
+ node.left.name.text === discriminantField) {
86
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
87
+ const checkedValue = node.right.getText(sf).replace(/['"]/g, '');
88
+ results.push({ filePath: sf.fileName, line, checkedValue });
89
+ }
90
+ ts.forEachChild(node, visitNode);
91
+ });
92
+ }
93
+ return results;
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // Internal helpers
97
+ // ---------------------------------------------------------------------------
98
+ function extractPropertyAccessBase(expr) {
99
+ if (ts.isPropertyAccessExpression(expr)) {
100
+ return expr.expression.getText();
101
+ }
102
+ return null;
103
+ }
104
+ function looksLikeTypeName(symbolName, typeName) {
105
+ // Heuristic: the base variable name contains the type name (case-insensitive)
106
+ return symbolName.toLowerCase().includes(typeName.toLowerCase());
107
+ }
108
+ //# sourceMappingURL=typeState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeState.js","sourceRoot":"","sources":["../../../src/analysis/ts/typeState.ts"],"names":[],"mappings":"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"}
@@ -88,27 +88,41 @@ function compareDeclarations(base, current) {
88
88
  }
89
89
  // Interface member comparison
90
90
  if (base.declarationKind === 'interface' && current.declarationKind === 'interface') {
91
- const baseMembers = new Set(base.members ?? []);
92
- const currentMembers = new Set(current.members ?? []);
93
- for (const m of baseMembers) {
94
- if (!currentMembers.has(m)) {
91
+ // Build name optional maps (members may carry "?" suffix from extractBlockMembersFromLines)
92
+ const baseByName = new Map((base.members ?? []).map((m) => [m.replace('?', ''), m.endsWith('?')]));
93
+ const currentByName = new Map((current.members ?? []).map((m) => [m.replace('?', ''), m.endsWith('?')]));
94
+ for (const [name] of baseByName) {
95
+ if (!currentByName.has(name)) {
95
96
  changes.push({
96
97
  kind: 'interface_shape_changed',
97
98
  risk: 'breaking',
98
- reason: `Interface property "${m}" removed`,
99
- diffs: [`- ${m}`],
99
+ reason: `Interface property "${name}" removed`,
100
+ diffs: [`- ${name}`],
100
101
  });
101
102
  }
102
103
  }
103
- for (const m of currentMembers) {
104
- if (!baseMembers.has(m)) {
104
+ for (const [name, isOptional] of currentByName) {
105
+ if (!baseByName.has(name)) {
105
106
  changes.push({
106
107
  kind: 'interface_shape_changed',
107
- risk: 'risky',
108
- reason: `Interface property "${m}" added`,
109
- diffs: [`+ ${m}`],
108
+ risk: isOptional ? 'risky' : 'breaking',
109
+ reason: isOptional
110
+ ? `Optional interface property "${name}" added`
111
+ : `Required interface property "${name}" added — breaking for existing implementations`,
112
+ diffs: [`+ ${isOptional ? name + '?' : name}`],
110
113
  });
111
114
  }
115
+ else {
116
+ const wasOptional = baseByName.get(name);
117
+ if (wasOptional && !isOptional) {
118
+ changes.push({
119
+ kind: 'interface_shape_changed',
120
+ risk: 'breaking',
121
+ reason: `Interface property "${name}" became required (was optional)`,
122
+ diffs: [`~ ${name}? → ${name}`],
123
+ });
124
+ }
125
+ }
112
126
  }
113
127
  return changes;
114
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"diffDeclarationShapes.js","sourceRoot":"","sources":["../../src/ast/diffDeclarationShapes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diffDeclarationShapes.js","sourceRoot":"","sources":["../../src/ast/diffDeclarationShapes.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,9 @@ function extractWithAst(root, source) {
17
17
  // Find all exported declarations using ast-grep patterns
18
18
  const patterns = [
19
19
  { pattern: 'export function $NAME($$$) { $$$ }', kind: 'function' },
20
+ { pattern: 'export function $NAME($$$): $RTYPE { $$$ }', kind: 'function' },
20
21
  { pattern: 'export async function $NAME($$$) { $$$ }', kind: 'function' },
22
+ { pattern: 'export async function $NAME($$$): $RTYPE { $$$ }', kind: 'function' },
21
23
  { pattern: 'export const $NAME = $$$', kind: 'const' },
22
24
  { pattern: 'export let $NAME = $$$', kind: 'variable' },
23
25
  { pattern: 'export interface $NAME { $$$ }', kind: 'interface' },
@@ -26,6 +28,7 @@ function extractWithAst(root, source) {
26
28
  { pattern: 'export class $NAME { $$$ }', kind: 'class' },
27
29
  { pattern: 'export abstract class $NAME { $$$ }', kind: 'class' },
28
30
  { pattern: 'export default function $NAME($$$) { $$$ }', kind: 'function' },
31
+ { pattern: 'export default function $NAME($$$): $RTYPE { $$$ }', kind: 'function' },
29
32
  ];
30
33
  for (const { pattern, kind } of patterns) {
31
34
  try {
@@ -197,9 +200,11 @@ function extractBlockMembersFromLines(lines, startLine) {
197
200
  if (lines[i].includes('}'))
198
201
  braceCount--;
199
202
  if (started && braceCount > 0) {
200
- const memberMatch = lines[i].trim().match(/^(\w+)\s*[?:=,]/);
201
- if (memberMatch && memberMatch[1] !== 'export')
202
- members.push(memberMatch[1]);
203
+ // Capture optional marker: `name?: Type` → "name?", `name: Type` → "name"
204
+ const memberMatch = lines[i].trim().match(/^(\w+)(\?)?\s*[:=,]/);
205
+ if (memberMatch && memberMatch[1] !== 'export') {
206
+ members.push(memberMatch[2] ? `${memberMatch[1]}?` : memberMatch[1]);
207
+ }
203
208
  }
204
209
  if (started && braceCount === 0)
205
210
  break;