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.
- package/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +11 -0
- package/CLAUDE.md +75 -0
- package/README.md +15 -38
- package/dist/adapters/express/index.d.ts +9 -0
- package/dist/adapters/express/index.js +46 -0
- package/dist/adapters/express/index.js.map +1 -0
- package/dist/adapters/next/index.d.ts +10 -0
- package/dist/adapters/next/index.js +67 -0
- package/dist/adapters/next/index.js.map +1 -0
- package/dist/adapters/react/index.d.ts +11 -0
- package/dist/adapters/react/index.js +133 -0
- package/dist/adapters/react/index.js.map +1 -0
- package/dist/adapters/registry.d.ts +22 -0
- package/dist/adapters/registry.js +101 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/types.d.ts +97 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/analysis/ts/applyVirtualEdit.d.ts +27 -0
- package/dist/analysis/ts/applyVirtualEdit.js +235 -0
- package/dist/analysis/ts/applyVirtualEdit.js.map +1 -0
- package/dist/analysis/ts/changeRecipes.d.ts +52 -0
- package/dist/analysis/ts/changeRecipes.js +14 -0
- package/dist/analysis/ts/changeRecipes.js.map +1 -0
- package/dist/analysis/ts/compatibility.d.ts +54 -0
- package/dist/analysis/ts/compatibility.js +113 -0
- package/dist/analysis/ts/compatibility.js.map +1 -0
- package/dist/analysis/ts/diffDeclarationShape.d.ts +26 -0
- package/dist/analysis/ts/diffDeclarationShape.js +114 -0
- package/dist/analysis/ts/diffDeclarationShape.js.map +1 -0
- package/dist/analysis/ts/exhaustiveness.d.ts +49 -0
- package/dist/analysis/ts/exhaustiveness.js +158 -0
- package/dist/analysis/ts/exhaustiveness.js.map +1 -0
- package/dist/analysis/ts/extractDeclarationShape.d.ts +30 -0
- package/dist/analysis/ts/extractDeclarationShape.js +127 -0
- package/dist/analysis/ts/extractDeclarationShape.js.map +1 -0
- package/dist/analysis/ts/extractExports.d.ts +19 -0
- package/dist/analysis/ts/extractExports.js +178 -0
- package/dist/analysis/ts/extractExports.js.map +1 -0
- package/dist/analysis/ts/extractRoutes.d.ts +12 -0
- package/dist/analysis/ts/extractRoutes.js +165 -0
- package/dist/analysis/ts/extractRoutes.js.map +1 -0
- package/dist/analysis/ts/parseSourceFile.d.ts +5 -1
- package/dist/analysis/ts/parseSourceFile.js +6 -2
- package/dist/analysis/ts/parseSourceFile.js.map +1 -1
- package/dist/analysis/ts/program/CheckerQueries.d.ts +56 -0
- package/dist/analysis/ts/program/CheckerQueries.js +187 -0
- package/dist/analysis/ts/program/CheckerQueries.js.map +1 -0
- package/dist/analysis/ts/program/ProgramManager.d.ts +27 -0
- package/dist/analysis/ts/program/ProgramManager.js +147 -0
- package/dist/analysis/ts/program/ProgramManager.js.map +1 -0
- package/dist/analysis/ts/program/TypeFacts.d.ts +58 -0
- package/dist/analysis/ts/program/TypeFacts.js +68 -0
- package/dist/analysis/ts/program/TypeFacts.js.map +1 -0
- package/dist/analysis/ts/typeState.d.ts +46 -0
- package/dist/analysis/ts/typeState.js +108 -0
- package/dist/analysis/ts/typeState.js.map +1 -0
- package/dist/ast/diffDeclarationShapes.js +25 -11
- package/dist/ast/diffDeclarationShapes.js.map +1 -1
- package/dist/ast/extractExportDeclarations.js +8 -3
- package/dist/ast/extractExportDeclarations.js.map +1 -1
- package/dist/cache/CacheSchema.d.ts +30 -0
- package/dist/cache/CacheSchema.js +9 -0
- package/dist/cache/CacheSchema.js.map +1 -0
- package/dist/cache/CacheStore.d.ts +22 -0
- package/dist/cache/CacheStore.js +111 -0
- package/dist/cache/CacheStore.js.map +1 -0
- package/dist/cache/SemanticCache.d.ts +38 -0
- package/dist/cache/SemanticCache.js +87 -0
- package/dist/cache/SemanticCache.js.map +1 -0
- package/dist/cache/SnapshotFingerprint.d.ts +17 -0
- package/dist/cache/SnapshotFingerprint.js +14 -0
- package/dist/cache/SnapshotFingerprint.js.map +1 -0
- package/dist/engine/DocumentManager.d.ts +16 -0
- package/dist/engine/DocumentManager.js +32 -0
- package/dist/engine/DocumentManager.js.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/search/adapters/http.d.ts +9 -3
- package/dist/search/adapters/http.js +7 -52
- package/dist/search/adapters/http.js.map +1 -1
- package/dist/search/adapters/react.d.ts +8 -8
- package/dist/search/adapters/react.js +3 -88
- package/dist/search/adapters/react.js.map +1 -1
- package/dist/search/adapters/registry.d.ts +7 -4
- package/dist/search/adapters/registry.js +7 -17
- package/dist/search/adapters/registry.js.map +1 -1
- package/dist/search/expand/graphExpansion.js +47 -14
- package/dist/search/expand/graphExpansion.js.map +1 -1
- package/dist/search/index/declarationIndex.d.ts +3 -1
- package/dist/search/index/declarationIndex.js +4 -2
- package/dist/search/index/declarationIndex.js.map +1 -1
- package/dist/search/index/routeIndex.d.ts +6 -0
- package/dist/search/index/routeIndex.js +19 -0
- package/dist/search/index/routeIndex.js.map +1 -0
- package/dist/search/index/usageIndex.d.ts +3 -1
- package/dist/search/index/usageIndex.js +4 -2
- package/dist/search/index/usageIndex.js.map +1 -1
- package/dist/search/index/workspaceIndex.d.ts +7 -1
- package/dist/search/index/workspaceIndex.js +54 -14
- package/dist/search/index/workspaceIndex.js.map +1 -1
- package/dist/search/query/compileEffectiveSearchSpec.js +9 -0
- package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -1
- package/dist/search/query/parseQuery.js +5 -1
- package/dist/search/query/parseQuery.js.map +1 -1
- package/dist/search/query/planQuery.js +14 -4
- package/dist/search/query/planQuery.js.map +1 -1
- package/dist/search/ranking/mergeCandidates.d.ts +1 -0
- package/dist/search/ranking/mergeCandidates.js +16 -0
- package/dist/search/ranking/mergeCandidates.js.map +1 -1
- package/dist/search/retrievers/routeRetriever.d.ts +7 -0
- package/dist/search/retrievers/routeRetriever.js +64 -0
- package/dist/search/retrievers/routeRetriever.js.map +1 -0
- package/dist/search/types.d.ts +16 -4
- package/dist/session/OverlayStore.d.ts +15 -0
- package/dist/session/OverlayStore.js +46 -0
- package/dist/session/OverlayStore.js.map +1 -0
- package/dist/session/SnapshotResolver.d.ts +31 -0
- package/dist/session/SnapshotResolver.js +50 -0
- package/dist/session/SnapshotResolver.js.map +1 -0
- package/dist/session/WorkspaceSnapshot.d.ts +21 -0
- package/dist/session/WorkspaceSnapshot.js +2 -0
- package/dist/session/WorkspaceSnapshot.js.map +1 -0
- package/dist/tools/composites/apiGuard.d.ts +4 -0
- package/dist/tools/composites/apiGuard.js +158 -24
- package/dist/tools/composites/apiGuard.js.map +1 -1
- package/dist/tools/composites/findCode.js +12 -2
- package/dist/tools/composites/findCode.js.map +1 -1
- package/dist/tools/composites/rootCauseTrace.js +89 -13
- package/dist/tools/composites/rootCauseTrace.js.map +1 -1
- package/dist/workflows/simulateChange.d.ts +44 -0
- package/dist/workflows/simulateChange.js +194 -0
- package/dist/workflows/simulateChange.js.map +1 -0
- package/dist/workflows/verifyChangeSet.d.ts +58 -0
- package/dist/workflows/verifyChangeSet.js +300 -0
- package/dist/workflows/verifyChangeSet.js.map +1 -0
- package/hooks/hooks.json +25 -0
- package/hooks/post-edit-check.sh +23 -0
- package/package.json +20 -4
- package/scripts/launch.mjs +29 -0
- package/skills/api-check/SKILL.md +34 -0
- package/skills/check/SKILL.md +25 -0
- package/skills/context/SKILL.md +24 -0
- package/skills/diff/SKILL.md +27 -0
- package/skills/find/SKILL.md +63 -0
- package/skills/impact/SKILL.md +21 -0
- package/skills/verify/SKILL.md +54 -0
- package/skills/why/SKILL.md +31 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface SimulationResult {
|
|
2
|
+
recipe: string;
|
|
3
|
+
targetFile: string;
|
|
4
|
+
targetSymbol: string;
|
|
5
|
+
/** Human-readable description of the virtual edit */
|
|
6
|
+
editDescription: string;
|
|
7
|
+
/** Diff of the signature (original → new) */
|
|
8
|
+
signatureDiff: {
|
|
9
|
+
original: string;
|
|
10
|
+
modified: string;
|
|
11
|
+
};
|
|
12
|
+
/** Callers that would break */
|
|
13
|
+
breakingCallers: Array<{
|
|
14
|
+
filePath: string;
|
|
15
|
+
relativePath: string;
|
|
16
|
+
line: number;
|
|
17
|
+
issue: string;
|
|
18
|
+
}>;
|
|
19
|
+
/** Callers that remain compatible */
|
|
20
|
+
compatibleCallerCount: number;
|
|
21
|
+
/** API contract impact */
|
|
22
|
+
contractImpact: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
kind: string;
|
|
25
|
+
risk: string;
|
|
26
|
+
reason: string;
|
|
27
|
+
}>;
|
|
28
|
+
/** For enum changes: switches that become non-exhaustive */
|
|
29
|
+
exhaustivenessImpact: Array<{
|
|
30
|
+
filePath: string;
|
|
31
|
+
relativePath: string;
|
|
32
|
+
line: number;
|
|
33
|
+
missingMembers: string[];
|
|
34
|
+
}>;
|
|
35
|
+
/** Semantic diagnostics in the virtual program (errors from the overlay) */
|
|
36
|
+
diagnosticsDelta: {
|
|
37
|
+
newErrors: number;
|
|
38
|
+
sample: string[];
|
|
39
|
+
};
|
|
40
|
+
/** One-sentence verdict */
|
|
41
|
+
summary: string;
|
|
42
|
+
warnings: string[];
|
|
43
|
+
}
|
|
44
|
+
export declare const simulateChange: import("../tools/registry.js").ToolDef;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { defineTool } from '../tools/registry.js';
|
|
5
|
+
import { relativePath } from '../engine/positions.js';
|
|
6
|
+
import { applyVirtualEdit } from '../analysis/ts/applyVirtualEdit.js';
|
|
7
|
+
import { programManager } from '../analysis/ts/program/ProgramManager.js';
|
|
8
|
+
import { CheckerQueries } from '../analysis/ts/program/CheckerQueries.js';
|
|
9
|
+
import { analyzeCallSiteCompatibility } from '../analysis/ts/compatibility.js';
|
|
10
|
+
import { findNonExhaustiveSwitches, predictAddedMemberImpact } from '../analysis/ts/exhaustiveness.js';
|
|
11
|
+
import { diffExportSets } from '../analysis/ts/diffDeclarationShape.js';
|
|
12
|
+
import { extractExports } from '../analysis/ts/extractExports.js';
|
|
13
|
+
import { extractDeclarationShape } from '../analysis/ts/extractDeclarationShape.js';
|
|
14
|
+
import { parseSourceContent } from '../analysis/ts/parseSourceFile.js';
|
|
15
|
+
import { buildStaticSnapshotResolver } from '../session/SnapshotResolver.js';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// MCP tool definition
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
export const simulateChange = defineTool({
|
|
20
|
+
name: 'simulate_change',
|
|
21
|
+
description: 'Speculative change simulation (Phase 3B): predict what breaks if you apply a change WITHOUT touching disk. ' +
|
|
22
|
+
'Creates an in-memory overlay of the modified file, rebuilds the TypeScript program over it, and reports: ' +
|
|
23
|
+
'breaking callers, exhaustiveness impact, and API contract delta. ' +
|
|
24
|
+
'Currently supported recipes: add_required_param, add_optional_param, remove_param, add_enum_member, remove_enum_member.',
|
|
25
|
+
schema: z.object({
|
|
26
|
+
file_path: z.string().describe('File containing the symbol to change (absolute or workspace-relative)'),
|
|
27
|
+
recipe: z.enum([
|
|
28
|
+
'add_required_param',
|
|
29
|
+
'add_optional_param',
|
|
30
|
+
'remove_param',
|
|
31
|
+
'add_enum_member',
|
|
32
|
+
'remove_enum_member',
|
|
33
|
+
]).describe('Kind of change to simulate'),
|
|
34
|
+
symbol: z.string().describe('Function name (for param recipes) or enum name (for enum recipes)'),
|
|
35
|
+
param_name: z.string().optional().describe('Parameter name (required for param recipes)'),
|
|
36
|
+
param_type: z.string().default('unknown').describe('Parameter type annotation (for add_param recipes)'),
|
|
37
|
+
member_name: z.string().optional().describe('Enum member name (required for enum recipes)'),
|
|
38
|
+
member_value: z.string().optional().describe('Enum member value (optional for add_enum_member)'),
|
|
39
|
+
}),
|
|
40
|
+
async handler(params, engine) {
|
|
41
|
+
const warnings = [];
|
|
42
|
+
// Resolve file path
|
|
43
|
+
const filePath = path.isAbsolute(params.file_path)
|
|
44
|
+
? params.file_path
|
|
45
|
+
: path.join(engine.workspaceRoot, params.file_path);
|
|
46
|
+
if (!fs.existsSync(filePath)) {
|
|
47
|
+
return { summary: `File not found: ${params.file_path}`, warnings: [`File not found: ${filePath}`] };
|
|
48
|
+
}
|
|
49
|
+
// Build the recipe
|
|
50
|
+
const recipe = buildRecipe(params, filePath);
|
|
51
|
+
if (!recipe) {
|
|
52
|
+
return { summary: 'Could not build recipe — check param_name or member_name', warnings };
|
|
53
|
+
}
|
|
54
|
+
// Step 1: Apply the virtual edit
|
|
55
|
+
const source = fs.readFileSync(filePath, 'utf-8');
|
|
56
|
+
const editResult = applyVirtualEdit(source, filePath, recipe);
|
|
57
|
+
if (!editResult) {
|
|
58
|
+
return {
|
|
59
|
+
summary: `Could not apply recipe — symbol "${params.symbol}" not found in ${params.file_path}`,
|
|
60
|
+
warnings: [`Symbol "${params.symbol}" not found in ${filePath}`],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Step 2: Build overlay program with the virtual edit
|
|
64
|
+
const resolver = buildStaticSnapshotResolver({ [filePath]: editResult.modifiedSource });
|
|
65
|
+
const overlayProgram = programManager.getOrBuild(engine.workspaceRoot, resolver);
|
|
66
|
+
const overlayQueries = new CheckerQueries(overlayProgram);
|
|
67
|
+
// Step 3: Analyze breaking callers (for param changes)
|
|
68
|
+
const breakingCallers = [];
|
|
69
|
+
let compatibleCallerCount = 0;
|
|
70
|
+
if (recipe.kind === 'add_required_param' || recipe.kind === 'add_optional_param' || recipe.kind === 'remove_param') {
|
|
71
|
+
const funcParams = overlayQueries.getFunctionParams(filePath, params.symbol);
|
|
72
|
+
if (funcParams) {
|
|
73
|
+
const required = funcParams.filter((p) => !p.optional && !p.rest).length;
|
|
74
|
+
const max = funcParams.length;
|
|
75
|
+
const report = analyzeCallSiteCompatibility(overlayProgram, filePath, params.symbol, required, max);
|
|
76
|
+
compatibleCallerCount = report.compatibleCallers.length;
|
|
77
|
+
for (const c of report.breakingCallers) {
|
|
78
|
+
breakingCallers.push({
|
|
79
|
+
filePath: c.filePath,
|
|
80
|
+
relativePath: relativePath(c.filePath, engine.workspaceRoot),
|
|
81
|
+
line: c.line,
|
|
82
|
+
issue: c.issue ?? 'incompatible call',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Step 4: Exhaustiveness impact (for enum changes)
|
|
88
|
+
const exhaustivenessImpact = [];
|
|
89
|
+
if (recipe.kind === 'add_enum_member' && params.member_name) {
|
|
90
|
+
const impact = predictAddedMemberImpact(overlayProgram, filePath, params.symbol, params.member_name);
|
|
91
|
+
for (const s of impact.affectedSwitches) {
|
|
92
|
+
exhaustivenessImpact.push({
|
|
93
|
+
filePath: s.filePath,
|
|
94
|
+
relativePath: relativePath(s.filePath, engine.workspaceRoot),
|
|
95
|
+
line: s.line,
|
|
96
|
+
missingMembers: [s.missingMember],
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (recipe.kind === 'remove_enum_member') {
|
|
101
|
+
// After removal: find any switches that now reference the removed member (would produce TS2339)
|
|
102
|
+
const nonExhaustive = findNonExhaustiveSwitches(overlayProgram, filePath, params.symbol);
|
|
103
|
+
for (const s of nonExhaustive) {
|
|
104
|
+
exhaustivenessImpact.push({
|
|
105
|
+
filePath: s.filePath,
|
|
106
|
+
relativePath: relativePath(s.filePath, engine.workspaceRoot),
|
|
107
|
+
line: s.line,
|
|
108
|
+
missingMembers: s.missingMembers,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Step 5: API contract delta — diff the overlay shape vs the current shape
|
|
113
|
+
const contractImpact = [];
|
|
114
|
+
try {
|
|
115
|
+
const baseSf = parseSourceContent(source, filePath);
|
|
116
|
+
const overlayContent = editResult.modifiedSource;
|
|
117
|
+
const overlaySf = parseSourceContent(overlayContent, filePath);
|
|
118
|
+
const baseShapes = extractExports(baseSf).map((e) => extractDeclarationShape(baseSf, e));
|
|
119
|
+
const overlayShapes = extractExports(overlaySf).map((e) => extractDeclarationShape(overlaySf, e));
|
|
120
|
+
const diffs = diffExportSets(baseShapes, overlayShapes);
|
|
121
|
+
for (const d of diffs) {
|
|
122
|
+
const reason = d.diffs.map((dd) => dd.reason).join('; ');
|
|
123
|
+
contractImpact.push({ name: d.name, kind: d.diffs[0]?.kind ?? d.status, risk: d.risk, reason });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
warnings.push(`Contract diff failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
128
|
+
}
|
|
129
|
+
// Step 6: Semantic diagnostics delta
|
|
130
|
+
const diagnosticsDelta = { newErrors: 0, sample: [] };
|
|
131
|
+
try {
|
|
132
|
+
const diagnostics = overlayQueries.getSemanticDiagnostics(filePath);
|
|
133
|
+
diagnosticsDelta.newErrors = diagnostics.filter((d) => d.category === 1).length;
|
|
134
|
+
diagnosticsDelta.sample = diagnostics
|
|
135
|
+
.filter((d) => d.category === 1)
|
|
136
|
+
.slice(0, 3)
|
|
137
|
+
.map((d) => `TS${d.code}: ${typeof d.messageText === 'string' ? d.messageText : d.messageText.messageText}`);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// Diagnostics are best-effort
|
|
141
|
+
}
|
|
142
|
+
// Step 7: Build summary
|
|
143
|
+
const breakCount = breakingCallers.length;
|
|
144
|
+
const exhaustCount = exhaustivenessImpact.length;
|
|
145
|
+
const contractCount = contractImpact.filter((c) => c.risk === 'breaking' || c.risk === 'risky').length;
|
|
146
|
+
let summary;
|
|
147
|
+
if (breakCount === 0 && exhaustCount === 0 && contractCount === 0) {
|
|
148
|
+
summary = `Simulated "${recipe.kind}" on "${params.symbol}" — no breaking impact found.`;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const parts = [];
|
|
152
|
+
if (breakCount > 0)
|
|
153
|
+
parts.push(`${breakCount} breaking caller(s)`);
|
|
154
|
+
if (exhaustCount > 0)
|
|
155
|
+
parts.push(`${exhaustCount} non-exhaustive switch(es)`);
|
|
156
|
+
if (contractCount > 0)
|
|
157
|
+
parts.push(`${contractCount} breaking contract change(s)`);
|
|
158
|
+
summary = `Simulated "${recipe.kind}" on "${params.symbol}" — would cause: ${parts.join(', ')}.`;
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
recipe: recipe.kind,
|
|
162
|
+
targetFile: relativePath(filePath, engine.workspaceRoot),
|
|
163
|
+
targetSymbol: params.symbol,
|
|
164
|
+
editDescription: `${editResult.originalSignature} → ${editResult.newSignature}`,
|
|
165
|
+
signatureDiff: { original: editResult.originalSignature, modified: editResult.newSignature },
|
|
166
|
+
breakingCallers,
|
|
167
|
+
compatibleCallerCount,
|
|
168
|
+
contractImpact,
|
|
169
|
+
exhaustivenessImpact,
|
|
170
|
+
diagnosticsDelta,
|
|
171
|
+
summary,
|
|
172
|
+
warnings,
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// Helpers
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
function buildRecipe(params, filePath) {
|
|
180
|
+
switch (params.recipe) {
|
|
181
|
+
case 'add_required_param':
|
|
182
|
+
case 'add_optional_param':
|
|
183
|
+
return { kind: params.recipe, funcName: params.symbol, filePath, paramName: params.param_name ?? 'newParam', paramType: params.param_type ?? 'unknown' };
|
|
184
|
+
case 'remove_param':
|
|
185
|
+
return { kind: 'remove_param', funcName: params.symbol, filePath, paramName: params.param_name ?? '' };
|
|
186
|
+
case 'add_enum_member':
|
|
187
|
+
return { kind: 'add_enum_member', enumName: params.symbol, filePath, memberName: params.member_name ?? 'NewMember', memberValue: params.member_value };
|
|
188
|
+
case 'remove_enum_member':
|
|
189
|
+
return { kind: 'remove_enum_member', enumName: params.symbol, filePath, memberName: params.member_name ?? '' };
|
|
190
|
+
default:
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=simulateChange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulateChange.js","sourceRoot":"","sources":["../../src/workflows/simulateChange.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
interface DiagnosticSummary {
|
|
2
|
+
filePath: string;
|
|
3
|
+
errorCount: number;
|
|
4
|
+
errors: Array<{
|
|
5
|
+
line: number;
|
|
6
|
+
message: string;
|
|
7
|
+
code?: string;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
interface ApiSummary {
|
|
11
|
+
semver: string;
|
|
12
|
+
breaking: number;
|
|
13
|
+
risky: number;
|
|
14
|
+
safe: number;
|
|
15
|
+
entries: any[];
|
|
16
|
+
}
|
|
17
|
+
interface TestGap {
|
|
18
|
+
symbol: string;
|
|
19
|
+
filePath: string;
|
|
20
|
+
hasTests: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface TypeRisks {
|
|
23
|
+
/** Switches that are no longer exhaustive due to changed enums */
|
|
24
|
+
nonExhaustiveSwitches: Array<{
|
|
25
|
+
filePath: string;
|
|
26
|
+
line: number;
|
|
27
|
+
missingMembers: string[];
|
|
28
|
+
enumName: string;
|
|
29
|
+
}>;
|
|
30
|
+
/** Exports whose type changed in a potentially incompatible way */
|
|
31
|
+
signatureChanges: Array<{
|
|
32
|
+
symbol: string;
|
|
33
|
+
filePath: string;
|
|
34
|
+
changeKind: string;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
export interface VerifyResult {
|
|
38
|
+
base: string | undefined;
|
|
39
|
+
changedFiles: string[];
|
|
40
|
+
diagnostics: DiagnosticSummary[];
|
|
41
|
+
totalErrors: number;
|
|
42
|
+
api: ApiSummary | null;
|
|
43
|
+
testGaps: TestGap[];
|
|
44
|
+
/** Phase 3A: type-state risks found in changed files */
|
|
45
|
+
typeRisks: TypeRisks;
|
|
46
|
+
/** Phase 3A: shell commands the developer should run next */
|
|
47
|
+
suggestedCommands: string[];
|
|
48
|
+
/** Phase 3A: ordered list of what to check or fix */
|
|
49
|
+
nextSteps: string[];
|
|
50
|
+
/** Phase 3A: clear verdict */
|
|
51
|
+
verdict: 'safe' | 'needs-attention' | 'has-errors';
|
|
52
|
+
/** Phase 3A: one sentence explaining the verdict */
|
|
53
|
+
verdictReason: string;
|
|
54
|
+
warnings: string[];
|
|
55
|
+
elapsedMs: number;
|
|
56
|
+
}
|
|
57
|
+
export declare const verifyChangeSet: import("../tools/registry.js").ToolDef;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { defineTool } from '../tools/registry.js';
|
|
3
|
+
import { getMergeBase } from '../git/getMergeBase.js';
|
|
4
|
+
import { getChangedFiles } from '../git/getChangedFiles.js';
|
|
5
|
+
import { apiGuard } from '../tools/composites/apiGuard.js';
|
|
6
|
+
import { findTestFiles } from '../tools/composites/findTestFiles.js';
|
|
7
|
+
import { pathToUri, relativePath } from '../engine/positions.js';
|
|
8
|
+
import { waitForDiagnostics } from '../engine/waitForDiagnostics.js';
|
|
9
|
+
import { programManager } from '../analysis/ts/program/ProgramManager.js';
|
|
10
|
+
import { CheckerQueries } from '../analysis/ts/program/CheckerQueries.js';
|
|
11
|
+
import { findNonExhaustiveSwitches } from '../analysis/ts/exhaustiveness.js';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import { parseSourceContent } from '../analysis/ts/parseSourceFile.js';
|
|
14
|
+
import { extractExports } from '../analysis/ts/extractExports.js';
|
|
15
|
+
import { getBaseFileContent } from '../git/getBaseFileContent.js';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Tool
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
export const verifyChangeSet = defineTool({
|
|
20
|
+
name: 'verify_changes',
|
|
21
|
+
description: 'Full pre-merge verification: diagnostics on changed files, API contract check, type-state risks (exhaustiveness, compatibility), test coverage gaps. ' +
|
|
22
|
+
'Returns a structured verdict with specific next steps and suggested commands.',
|
|
23
|
+
schema: z.object({
|
|
24
|
+
base: z.string().optional().describe('Git base branch (auto-detected if omitted)'),
|
|
25
|
+
paths: z.array(z.string()).optional().describe('Limit to specific paths'),
|
|
26
|
+
}),
|
|
27
|
+
async handler(params, engine) {
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
const warnings = [];
|
|
30
|
+
// Step 1: Determine changed files
|
|
31
|
+
const base = engine.gitAvailable ? getMergeBase(engine.workspaceRoot, params.base) : undefined;
|
|
32
|
+
if (!base) {
|
|
33
|
+
return earlyReturn(startTime, { verdict: 'needs-attention', verdictReason: 'Git not available — run with base branch or from a git repository', warnings: ['Could not determine git base'] });
|
|
34
|
+
}
|
|
35
|
+
let changedFiles = getChangedFiles(engine.workspaceRoot, base);
|
|
36
|
+
if (params.paths?.length) {
|
|
37
|
+
changedFiles = changedFiles.filter((f) => params.paths.some((p) => f.includes(p)));
|
|
38
|
+
}
|
|
39
|
+
if (changedFiles.length === 0) {
|
|
40
|
+
return earlyReturn(startTime, { verdict: 'safe', verdictReason: 'No changed files — nothing to verify', warnings: ['No changed files found'] });
|
|
41
|
+
}
|
|
42
|
+
// Step 2: Diagnostics on changed files (using cached diagnostics from LSP push)
|
|
43
|
+
const diagnostics = [];
|
|
44
|
+
let totalErrors = 0;
|
|
45
|
+
for (const filePath of changedFiles) {
|
|
46
|
+
try {
|
|
47
|
+
const uri = pathToUri(filePath);
|
|
48
|
+
await engine.prepareFile(filePath);
|
|
49
|
+
await waitForDiagnostics(engine.docManager, uri, 1500);
|
|
50
|
+
const fileDiags = engine.docManager.getCachedDiagnostics(uri);
|
|
51
|
+
const errors = fileDiags
|
|
52
|
+
.filter((d) => d.severity === 1)
|
|
53
|
+
.map((d) => ({
|
|
54
|
+
line: (d.range?.start?.line ?? 0) + 1,
|
|
55
|
+
message: d.message ?? 'Unknown error',
|
|
56
|
+
code: d.code != null ? `TS${d.code}` : undefined,
|
|
57
|
+
}));
|
|
58
|
+
if (errors.length > 0) {
|
|
59
|
+
diagnostics.push({ filePath: relativePath(filePath, engine.workspaceRoot), errorCount: errors.length, errors });
|
|
60
|
+
totalErrors += errors.length;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Skip files that can't be diagnosed
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Step 3: API contract guard
|
|
68
|
+
let api = null;
|
|
69
|
+
const hasExportFiles = changedFiles.some((f) => /\.(ts|tsx|js|jsx)$/.test(f));
|
|
70
|
+
if (hasExportFiles) {
|
|
71
|
+
try {
|
|
72
|
+
const guardResult = await apiGuard.handler({ scope: 'changed', base: params.base }, engine);
|
|
73
|
+
api = {
|
|
74
|
+
semver: guardResult.summary?.recommendedSemver ?? 'patch',
|
|
75
|
+
breaking: guardResult.summary?.breaking ?? 0,
|
|
76
|
+
risky: guardResult.summary?.risky ?? 0,
|
|
77
|
+
safe: guardResult.summary?.safe ?? 0,
|
|
78
|
+
entries: guardResult.entries ?? [],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
warnings.push(`api_guard failed: ${err?.message ?? 'unknown'}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Step 4: Phase 3A — Type-state risks via Phase 2D (exhaustiveness + compatibility)
|
|
86
|
+
const typeRisks = { nonExhaustiveSwitches: [], signatureChanges: [] };
|
|
87
|
+
try {
|
|
88
|
+
const tsProgram = programManager.getOrBuild(engine.workspaceRoot);
|
|
89
|
+
const queries = new CheckerQueries(tsProgram);
|
|
90
|
+
for (const filePath of changedFiles) {
|
|
91
|
+
try {
|
|
92
|
+
const baseContent = getBaseFileContent(filePath, base, engine.workspaceRoot);
|
|
93
|
+
if (!baseContent)
|
|
94
|
+
continue;
|
|
95
|
+
const currentContent = fs.readFileSync(filePath, 'utf-8');
|
|
96
|
+
const baseSf = parseSourceContent(baseContent, filePath);
|
|
97
|
+
const currentSf = parseSourceContent(currentContent, filePath);
|
|
98
|
+
const baseExports = extractExports(baseSf);
|
|
99
|
+
const currentExports = extractExports(currentSf);
|
|
100
|
+
// Find changed enums and check exhaustiveness impact
|
|
101
|
+
const baseEnums = new Map(baseExports.filter(e => e.kind === 'enum').map(e => [e.name, e]));
|
|
102
|
+
const currentEnums = new Map(currentExports.filter(e => e.kind === 'enum').map(e => [e.name, e]));
|
|
103
|
+
for (const [enumName] of currentEnums) {
|
|
104
|
+
if (baseEnums.has(enumName)) {
|
|
105
|
+
// Enum existed before — check if members changed
|
|
106
|
+
const baseMembers = queries.getEnumMembers(filePath, enumName) ?? [];
|
|
107
|
+
// Members in current version (use AST directly)
|
|
108
|
+
const currentSfEnum = currentSf.statements.find((s) => s.kind !== undefined &&
|
|
109
|
+
s.name?.text === enumName &&
|
|
110
|
+
s.members !== undefined);
|
|
111
|
+
if (currentSfEnum) {
|
|
112
|
+
// Use addedMemberImpact for each new member to find affected switches
|
|
113
|
+
const nonExhaustive = findNonExhaustiveSwitches(tsProgram, filePath, enumName);
|
|
114
|
+
for (const sw of nonExhaustive) {
|
|
115
|
+
typeRisks.nonExhaustiveSwitches.push({
|
|
116
|
+
filePath: relativePath(sw.filePath, engine.workspaceRoot),
|
|
117
|
+
line: sw.line,
|
|
118
|
+
missingMembers: sw.missingMembers,
|
|
119
|
+
enumName,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Collect signature changes from api entries if available
|
|
126
|
+
if (api) {
|
|
127
|
+
for (const entry of api.entries) {
|
|
128
|
+
if (entry.risk !== 'safe' && (entry.kind === 'param_required' || entry.kind === 'return_type_changed' || entry.kind === 'param_removed')) {
|
|
129
|
+
typeRisks.signatureChanges.push({
|
|
130
|
+
symbol: entry.exportName,
|
|
131
|
+
filePath: relativePath(entry.filePath, engine.workspaceRoot),
|
|
132
|
+
changeKind: entry.kind,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Best-effort per file
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
warnings.push(`Type-risk analysis failed: ${err?.message ?? 'unknown'}`);
|
|
145
|
+
}
|
|
146
|
+
// Step 5: Test coverage gaps for high-risk changed symbols
|
|
147
|
+
const testGaps = [];
|
|
148
|
+
if (api?.entries) {
|
|
149
|
+
const breaking = api.entries.filter((e) => e.risk === 'breaking').slice(0, 5);
|
|
150
|
+
for (const entry of breaking) {
|
|
151
|
+
try {
|
|
152
|
+
const testResult = await findTestFiles.handler({ symbol: entry.exportName }, engine);
|
|
153
|
+
const hasTests = !testResult.includes('No test files') && !testResult.includes('No references');
|
|
154
|
+
testGaps.push({ symbol: entry.exportName, filePath: entry.filePath, hasTests });
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
testGaps.push({ symbol: entry.exportName, filePath: entry.filePath, hasTests: false });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Step 6: Phase 3A — Build verdict, next steps, and suggested commands
|
|
162
|
+
const { verdict, verdictReason, nextSteps, suggestedCommands } = buildVerdict({
|
|
163
|
+
totalErrors,
|
|
164
|
+
api,
|
|
165
|
+
typeRisks,
|
|
166
|
+
testGaps,
|
|
167
|
+
changedFiles: changedFiles.map((f) => relativePath(f, engine.workspaceRoot)),
|
|
168
|
+
workspaceRoot: engine.workspaceRoot,
|
|
169
|
+
});
|
|
170
|
+
return {
|
|
171
|
+
base,
|
|
172
|
+
changedFiles: changedFiles.map((f) => relativePath(f, engine.workspaceRoot)),
|
|
173
|
+
diagnostics,
|
|
174
|
+
totalErrors,
|
|
175
|
+
api,
|
|
176
|
+
testGaps,
|
|
177
|
+
typeRisks,
|
|
178
|
+
suggestedCommands,
|
|
179
|
+
nextSteps,
|
|
180
|
+
verdict,
|
|
181
|
+
verdictReason,
|
|
182
|
+
warnings,
|
|
183
|
+
elapsedMs: Date.now() - startTime,
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
function buildVerdict(input) {
|
|
188
|
+
const { totalErrors, api, typeRisks, testGaps, changedFiles } = input;
|
|
189
|
+
const nextSteps = [];
|
|
190
|
+
const suggestedCommands = [];
|
|
191
|
+
// Hard errors first
|
|
192
|
+
if (totalErrors > 0) {
|
|
193
|
+
nextSteps.push(`Fix ${totalErrors} TypeScript error(s) in changed files before merging`);
|
|
194
|
+
suggestedCommands.push('npx tsc --noEmit');
|
|
195
|
+
for (const entry of (api?.entries ?? []).filter((e) => e.risk === 'breaking').slice(0, 3)) {
|
|
196
|
+
for (const step of (entry.migrationSteps ?? []))
|
|
197
|
+
nextSteps.push(step);
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
verdict: 'has-errors',
|
|
201
|
+
verdictReason: `${totalErrors} TypeScript error(s) found in changed files`,
|
|
202
|
+
nextSteps,
|
|
203
|
+
suggestedCommands,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// Breaking API changes
|
|
207
|
+
const breaking = api?.breaking ?? 0;
|
|
208
|
+
const switchIssues = typeRisks.nonExhaustiveSwitches.length;
|
|
209
|
+
const sigChanges = typeRisks.signatureChanges.length;
|
|
210
|
+
if (breaking > 0 || switchIssues > 0 || sigChanges > 0) {
|
|
211
|
+
if (breaking > 0) {
|
|
212
|
+
nextSteps.push(`${breaking} breaking API change(s) — update consumers before merging`);
|
|
213
|
+
for (const entry of (api?.entries ?? []).filter((e) => e.risk === 'breaking').slice(0, 3)) {
|
|
214
|
+
for (const step of (entry.migrationSteps ?? []))
|
|
215
|
+
nextSteps.push(step);
|
|
216
|
+
if (entry.filesToInspect?.length) {
|
|
217
|
+
suggestedCommands.push(`# Check consumers of ${entry.exportName}:`);
|
|
218
|
+
suggestedCommands.push(`grep -r '${entry.exportName}' --include='*.ts' src/`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (switchIssues > 0) {
|
|
223
|
+
nextSteps.push(`${switchIssues} non-exhaustive switch statement(s) — add cases for new enum members`);
|
|
224
|
+
const affected = [...new Set(typeRisks.nonExhaustiveSwitches.map(s => s.filePath))].slice(0, 2);
|
|
225
|
+
suggestedCommands.push(`# Fix exhaustiveness in: ${affected.join(', ')}`);
|
|
226
|
+
}
|
|
227
|
+
if (sigChanges > 0) {
|
|
228
|
+
nextSteps.push(`${sigChanges} signature change(s) — verify all callers pass the correct arguments`);
|
|
229
|
+
for (const sc of typeRisks.signatureChanges.slice(0, 3)) {
|
|
230
|
+
suggestedCommands.push(`grep -r '${sc.symbol}(' --include='*.ts' src/`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Test gaps
|
|
234
|
+
const untested = testGaps.filter((g) => !g.hasTests);
|
|
235
|
+
if (untested.length > 0) {
|
|
236
|
+
nextSteps.push(`${untested.length} breaking export(s) lack test coverage`);
|
|
237
|
+
}
|
|
238
|
+
const reasons = [];
|
|
239
|
+
if (breaking > 0)
|
|
240
|
+
reasons.push(`${breaking} breaking API change(s)`);
|
|
241
|
+
if (switchIssues > 0)
|
|
242
|
+
reasons.push(`${switchIssues} exhaustiveness issue(s)`);
|
|
243
|
+
if (sigChanges > 0)
|
|
244
|
+
reasons.push(`${sigChanges} signature change(s)`);
|
|
245
|
+
return {
|
|
246
|
+
verdict: 'needs-attention',
|
|
247
|
+
verdictReason: reasons.join(', '),
|
|
248
|
+
nextSteps,
|
|
249
|
+
suggestedCommands,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
// Risky-only changes
|
|
253
|
+
const risky = api?.risky ?? 0;
|
|
254
|
+
if (risky > 0) {
|
|
255
|
+
nextSteps.push(`${risky} risky (non-breaking) API change(s) — review before release`);
|
|
256
|
+
if (api?.semver === 'minor') {
|
|
257
|
+
nextSteps.push('Bump the minor version when releasing (new functionality added)');
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
verdict: 'needs-attention',
|
|
261
|
+
verdictReason: `${risky} risky change(s) — recommend review before release`,
|
|
262
|
+
nextSteps,
|
|
263
|
+
suggestedCommands,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// Safe
|
|
267
|
+
nextSteps.push('All checks passed — safe to merge');
|
|
268
|
+
if (changedFiles.length > 0) {
|
|
269
|
+
const ext = changedFiles[0].endsWith('.ts') ? 'ts' : 'js';
|
|
270
|
+
suggestedCommands.push('npm test');
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
verdict: 'safe',
|
|
274
|
+
verdictReason: 'No errors, no breaking changes, no type risks detected',
|
|
275
|
+
nextSteps,
|
|
276
|
+
suggestedCommands,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
// Early return helper
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
282
|
+
function earlyReturn(startTime, overrides) {
|
|
283
|
+
return {
|
|
284
|
+
base: undefined,
|
|
285
|
+
changedFiles: [],
|
|
286
|
+
diagnostics: [],
|
|
287
|
+
totalErrors: 0,
|
|
288
|
+
api: null,
|
|
289
|
+
testGaps: [],
|
|
290
|
+
typeRisks: { nonExhaustiveSwitches: [], signatureChanges: [] },
|
|
291
|
+
suggestedCommands: [],
|
|
292
|
+
nextSteps: [],
|
|
293
|
+
verdict: 'safe',
|
|
294
|
+
verdictReason: '',
|
|
295
|
+
warnings: [],
|
|
296
|
+
elapsedMs: Date.now() - startTime,
|
|
297
|
+
...overrides,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=verifyChangeSet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyChangeSet.js","sourceRoot":"","sources":["../../src/workflows/verifyChangeSet.ts"],"names":[],"mappings":"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"}
|