@shipispec/tsfix 0.4.0 → 0.5.0
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/CHANGELOG.md +59 -0
- package/dist/cli.js +866 -26
- package/dist/index.d.ts +8 -0
- package/dist/index.js +281 -34717
- package/dist/types/index.d.ts +8 -0
- package/dist/types/runMendLoop.d.ts +16 -1
- package/dist/types/stubAndContinue.d.ts +68 -0
- package/package.json +2 -3
package/dist/types/index.d.ts
CHANGED
|
@@ -44,6 +44,12 @@
|
|
|
44
44
|
* - `mendSingleFile` — single-LLM-call repair via Vercel AI SDK
|
|
45
45
|
* - `runMendLoop` — bounded retry with no-progress / regression detection
|
|
46
46
|
* - `parseEditBlocks` / `applyEditBlocks` — Aider-style SEARCH/REPLACE applier
|
|
47
|
+
*
|
|
48
|
+
* ## Layer 4 escape hatch (v0.5.0+)
|
|
49
|
+
*
|
|
50
|
+
* - `stubAndContinue` — insert `// @ts-expect-error - tsfix: ...` above
|
|
51
|
+
* unresolved error sites so the workspace compiles. Opt-in: set
|
|
52
|
+
* `stubOnFailure: true` on `runMendLoop`, or call directly.
|
|
47
53
|
*/
|
|
48
54
|
export { runInProcessTsc, isInProcessTscEnabled, resetInProcessTscCache } from "./validatorInProcess.js";
|
|
49
55
|
export type { InProcessTscOptions, InProcessTscResult } from "./validatorInProcess.js";
|
|
@@ -186,3 +192,5 @@ export { mendSingleFile } from "./mendAgent.js";
|
|
|
186
192
|
export type { MendSingleFileOptions, MendSingleFileResult, LLMCall } from "./mendAgent.js";
|
|
187
193
|
export { runMendLoop } from "./runMendLoop.js";
|
|
188
194
|
export type { RunMendLoopOptions, RunMendLoopResult, MendLoopIteration, StopReason, } from "./runMendLoop.js";
|
|
195
|
+
export { stubAndContinue } from "./stubAndContinue.js";
|
|
196
|
+
export type { StubAndContinueOptions, StubAndContinueResult, AppliedStub, SkippedStub, } from "./stubAndContinue.js";
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import type { Diagnostic, MendContext } from "./index.js";
|
|
26
26
|
import { type LLMCall } from "./mendAgent.js";
|
|
27
|
+
import { type AppliedStub } from "./stubAndContinue.js";
|
|
27
28
|
export interface RunMendLoopOptions {
|
|
28
29
|
context: MendContext;
|
|
29
30
|
llm: {
|
|
@@ -35,6 +36,13 @@ export interface RunMendLoopOptions {
|
|
|
35
36
|
maxIterations?: number;
|
|
36
37
|
/** Single dry-run pass — call LLM, parse, but don't write to disk. Default false. */
|
|
37
38
|
dryRun?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* When the loop exits with leftover errors (stopReason !== "fixed"),
|
|
41
|
+
* apply Layer 4 stub-and-continue: insert `// @ts-expect-error - tsfix: ...`
|
|
42
|
+
* comments above each unresolved error site so tsc exits 0. Opt-in.
|
|
43
|
+
* Default false. Ignored when `dryRun: true`.
|
|
44
|
+
*/
|
|
45
|
+
stubOnFailure?: boolean;
|
|
38
46
|
/** @internal — LLM call override for tests. */
|
|
39
47
|
_callLLM?: LLMCall;
|
|
40
48
|
}
|
|
@@ -50,7 +58,7 @@ export interface MendLoopIteration {
|
|
|
50
58
|
/** Raw LLM response for this iteration — useful for debugging failed patches. */
|
|
51
59
|
rawResponse: string;
|
|
52
60
|
}
|
|
53
|
-
export type StopReason = "noErrors" | "fixed" | "noProgress" | "regressed" | "maxIterations";
|
|
61
|
+
export type StopReason = "noErrors" | "fixed" | "noProgress" | "regressed" | "maxIterations" | "stubbed";
|
|
54
62
|
export interface RunMendLoopResult {
|
|
55
63
|
iterations: MendLoopIteration[];
|
|
56
64
|
diagnosticsBefore: Diagnostic[];
|
|
@@ -60,5 +68,12 @@ export interface RunMendLoopResult {
|
|
|
60
68
|
totalInputTokens: number;
|
|
61
69
|
totalOutputTokens: number;
|
|
62
70
|
totalLatencyMs: number;
|
|
71
|
+
/**
|
|
72
|
+
* Layer 4 stubs applied after the LLM loop terminated with leftover
|
|
73
|
+
* errors. Present only when `stubOnFailure: true` was set. Empty array
|
|
74
|
+
* means stubOnFailure ran but nothing was eligible (e.g. all errors
|
|
75
|
+
* were in .d.ts files).
|
|
76
|
+
*/
|
|
77
|
+
stubs?: AppliedStub[];
|
|
63
78
|
}
|
|
64
79
|
export declare function runMendLoop(opts: RunMendLoopOptions): Promise<RunMendLoopResult>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 4 — stub-and-continue escape hatch.
|
|
3
|
+
*
|
|
4
|
+
* When Layer 0/1 abstains and Layer 2's `runMendLoop` returns with leftover
|
|
5
|
+
* diagnostics (stopReason `noProgress`, `regressed`, or `maxIterations`),
|
|
6
|
+
* Layer 4 inserts a `// @ts-expect-error` directive immediately above each
|
|
7
|
+
* unresolved error site so `tsc --noEmit` exits 0. Caller's pipeline
|
|
8
|
+
* unblocks; the developer reviews the directive at leisure.
|
|
9
|
+
*
|
|
10
|
+
* Why `@ts-expect-error` and not `@ts-ignore`:
|
|
11
|
+
* `@ts-expect-error` errors out if the next line has NO error — meaning
|
|
12
|
+
* stale directives self-destruct as soon as the underlying issue is
|
|
13
|
+
* fixed by other means. `@ts-ignore` is permissive and rots silently.
|
|
14
|
+
*
|
|
15
|
+
* Trust posture: Layer 4 is opt-in. The CLI default never reaches it.
|
|
16
|
+
* `runMendLoop` only invokes it when `stubOnFailure: true` is set.
|
|
17
|
+
*
|
|
18
|
+
* Idempotency: re-running on a workspace that already has stubs above the
|
|
19
|
+
* same error lines is a no-op. We detect the existing directive on the
|
|
20
|
+
* line above and skip.
|
|
21
|
+
*/
|
|
22
|
+
import type { Diagnostic } from "./index.js";
|
|
23
|
+
export interface StubAndContinueOptions {
|
|
24
|
+
/** Absolute path to the workspace (used for resolving / skipping node_modules). */
|
|
25
|
+
workspaceRoot: string;
|
|
26
|
+
/** Unresolved diagnostics (errors only — warnings/suggestions ignored). */
|
|
27
|
+
diagnostics: Diagnostic[];
|
|
28
|
+
/** Report what would be stubbed without writing. Default false. */
|
|
29
|
+
dryRun?: boolean;
|
|
30
|
+
logger?: {
|
|
31
|
+
info(msg: string): void;
|
|
32
|
+
warn(msg: string): void;
|
|
33
|
+
error(msg: string): void;
|
|
34
|
+
};
|
|
35
|
+
/** Override the comment marker (default: "tsfix"). */
|
|
36
|
+
stubMarker?: string;
|
|
37
|
+
/** Cap on message length included in the comment. Default 120. */
|
|
38
|
+
maxMessageLength?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface AppliedStub {
|
|
41
|
+
/** Absolute path of the file edited. */
|
|
42
|
+
file: string;
|
|
43
|
+
/**
|
|
44
|
+
* 1-based line number tsc originally reported the error on (pre-stub).
|
|
45
|
+
* In the file *after* stubbing, the error code lives at `errorLine + 1`
|
|
46
|
+
* and the `@ts-expect-error` comment lives at `errorLine`.
|
|
47
|
+
*/
|
|
48
|
+
errorLine: number;
|
|
49
|
+
/** All TS codes on the error line, deduplicated and sorted. */
|
|
50
|
+
codes: string[];
|
|
51
|
+
/** The comment text actually written (without leading whitespace). */
|
|
52
|
+
commentText: string;
|
|
53
|
+
}
|
|
54
|
+
export interface SkippedStub {
|
|
55
|
+
file: string;
|
|
56
|
+
line: number;
|
|
57
|
+
codes: string[];
|
|
58
|
+
reason: "node_modules" | "declaration_file" | "file_not_found" | "already_stubbed" | "file_too_short";
|
|
59
|
+
}
|
|
60
|
+
export interface StubAndContinueResult {
|
|
61
|
+
stubsApplied: AppliedStub[];
|
|
62
|
+
skipped: SkippedStub[];
|
|
63
|
+
filesEdited: string[];
|
|
64
|
+
diagnosticsBefore: number;
|
|
65
|
+
/** Diagnostics still on disk after stubs were applied (excludes the stubbed sites). */
|
|
66
|
+
diagnosticsAfter: number;
|
|
67
|
+
}
|
|
68
|
+
export declare function stubAndContinue(opts: StubAndContinueOptions): StubAndContinueResult;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipispec/tsfix",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "TypeScript error-recovery for LLM-generated code. Layer 0/1 deterministic auto-fix via the TS Language Service + Layer 2 LLM mend (Vercel AI SDK + Anthropic) in one package.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -52,8 +52,7 @@
|
|
|
52
52
|
"build": "node scripts/build.mjs",
|
|
53
53
|
"matrix": "node scripts/run-matrix.mjs",
|
|
54
54
|
"capture": "node scripts/capture-fixture.mjs",
|
|
55
|
-
"
|
|
56
|
-
"generate-fixtures": "node scripts/generate-fixtures.mjs",
|
|
55
|
+
"generate-fixtures": "tsx scripts/generate-fixtures.mjs",
|
|
57
56
|
"prepack": "npm run build",
|
|
58
57
|
"setup-fixtures": "node -e \"require('fs').existsSync('fixtures/_shared/node_modules')||require('child_process').execSync('npm install --prefix fixtures/_shared',{stdio:'inherit'})\"",
|
|
59
58
|
"prebenchmark": "npm run setup-fixtures",
|