
Security News
upm Launches as a Fast, Tiny Package Manager Written in TypeScript
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.
@shipispec/tsfix
Advanced tools
Reusable TypeScript error-recovery agent. Validates LLM-generated TS code, auto-fixes deterministic error classes via the TS Language Service, and exposes hooks for LLM-driven repair.
Headless TypeScript error recovery — auto-resolve
TS2304,TS2305,TS2551,TS2552,TS2724before they reach a human.
@shipispec/tsfix borrows the same TypeScript Language Service that powers VS Code's "Quick Fix" lightbulb and runs it as a CLI. Point it at a workspace, it fixes typos, missing imports, and did-you-mean errors deterministically — no LLM, no calls home, no config.
Built for the case where you've just generated a few hundred files of TypeScript with an LLM and tsc --noEmit is screaming at you.
$ tsc --noEmit
src/api.ts:5:2 - error TS2552: Cannot find name 'consol'. Did you mean 'console'?
src/api.ts:8:5 - error TS2305: Module '"react"' has no exported member 'ueState'.
src/api.ts:12:14 - error TS2551: Property 'lenght' does not exist on type 'string[]'. Did you mean 'length'?
Found 3 errors in 1 file.
$ npx @shipispec/tsfix --workspace .
[ts-lsp-fixer] applied 3 fixes across 1 file
$ tsc --noEmit
$ # 0 errors
cd your-broken-project
npx @shipispec/tsfix --workspace .
No config file. Exit code conventions:
| Code | Meaning |
|---|---|
| 0 | Workspace is clean |
| 1 | Errors remain (printed to stderr) |
| 2 | Bad arguments / harness error |
Preview what would change without writing to disk:
npx @shipispec/tsfix --workspace . --dry-run
Machine-readable output for piping into other tools:
npx @shipispec/tsfix --workspace . --json
| Flag | Meaning |
|---|---|
--workspace <path> | Required. Directory containing your tsconfig.json. |
--dry-run | Run the fixer in memory, report counts, write nothing. |
--no-lsp | Validate only — skip auto-fix. |
--files <a.ts,b.ts> | Restrict fixing to a comma-separated list. |
--json | Machine-readable output. |
--verbose | Per-fix logging. |
--help | Print usage. |
| TS code | Meaning | What tsfix does |
|---|---|---|
TS2304 | Cannot find name | Auto-imports |
TS2305 | Module has no exported member | Did-you-mean rename |
TS2551 | Property does not exist on T, did you mean Y | Spelling fix |
TS2552 | Cannot find name, did you mean Y | Spelling fix |
TS2724 | Module member did-you-mean | Import rename |
Against a 14-fixture benchmark spanning typos, did-you-mean cases, multi-file ripples, and 4 API-drift scenarios: 14/14 fixtures pass and 14/25 errors are auto-fixed (56%). The remaining errors are intentionally outside Layer 0's scope (see below).
By design, tsfix only applies fixes that are deterministic and non-structural. It will refuse to:
await insertions, async propagation)The internal allowlist is two-layered: error codes (SAFE_FIXABLE_CODES) and Quick Fix names (SAFE_FIX_NAMES = ['import', 'fixImport', 'spelling', 'fixSpelling']). When the language service offers anything outside that allowlist, tsfix abstains and surfaces the error in the result so a higher layer (LLM, human) can pick it up.
tsfix is Layer 0–1 of a larger error-recovery stack. The other layers are LLM-driven and live elsewhere (in your own code, or in companion packages):
Layer 0 — Prevention (prompt rules, exported-API injection — your problem)
Layer 1 — tsfix (this package: deterministic auto-fix)
─────────────────────────────────────────────────────────────────────────
Layer 2 — Single-file LLM mend (architect + editor split)
Layer 3 — Multi-file LLM mend (blast-radius search/replace)
Layer 4 — Stub-and-continue (escape hatch)
The bet: roughly half of TypeScript errors in LLM output are deterministically fixable. By catching them in Layer 1, you dodge the LLM tax (latency, cost, nondeterminism) on the easy half.
import { runValidationLoop } from '@shipispec/tsfix';
const result = runValidationLoop({
workspaceRoot: '/path/to/your/project',
// Optional:
// targetFiles: ['src/api.ts'],
// dryRun: true,
// logger: { info: console.log, warn: console.warn, error: console.error },
});
result.errorsBefore; // number
result.errorsAfter; // number
result.lspFixer.fixesApplied; // number
result.lspFixer.filesEdited; // string[]
result.passed; // boolean — true if errorsAfter === 0
Other exports:
runInProcessTsc(opts) — validation only, no fixer. Returns structured diagnostics.runLSPFixerPass(opts) — Layer 0 fixer alone, no validation loop wrapper.discoverTsFiles(workspaceRoot) — file-walking helper. Skips node_modules, .next, dist, build, out, coverage, .git.tsfix loads typescript from your workspace's node_modules — it does not bundle its own. This is intentional: it ensures the fixer behaves identically to the tsc your project actually compiles with.
Run tsfix only on workspaces you trust. Loading
typescriptfrom an attacker-controllednode_modulesis equivalent to runningnode_modules/.bin/tscagainst it.
Other surface:
--workspace.>=20.9.0>=5.0.0 (peer dep — must be installed in your workspace)If your workspace has no node_modules/typescript, tsfix will fail with a clear error:
error: this workspace has no TypeScript installed.
run: npm install --save-dev typescript
The contract for adding a fix:
fixtures/<descriptive-name>/ with an expected.json declaring errorsBefore, errorsAfterMax, lspFixesAppliedMin/Max, and mustPass.npm run benchmark -- --fixture <name> and inspect what the language service offers (the fix.fixName field).fixName is unsafe (fixMissingFunctionDeclaration, addMissingPropertyAndOptional, etc.), document why we don't trust it. Otherwise, add the error code to SAFE_FIXABLE_CODES and the fix name to SAFE_FIX_NAMES in src/tsLanguageServiceFixer.ts.npm run benchmark). Open a PR.Each new code/fix-name pair gets its own fixture. We don't trust the language service blindly — we trust it under specific, pinned conditions.
npm run matrix runs the same package against 6 distinct project shapes (Next.js, Vite + React, plain nodenext, plain bundler, plain CommonJS, monorepo with project references). It builds the local tarball and exercises it cold; pre-publish gate.
MIT.
CHANGELOG.md — release notes per version.ARCHITECTURE.md — internal design rationale (the four-layer model, the workspace lib-path workaround).STATUS.md — current snapshot, gaps, and roadmap state.tsc-defense-roadmap.md — phased plan.docs/internal-orientation.md — the original SpecToShip-context README, kept for contributors who want the design history.FAQs
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.
The npm package @shipispec/tsfix receives a total of 5 weekly downloads. As such, @shipispec/tsfix popularity was classified as not popular.
We found that @shipispec/tsfix demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.