🩺 CodeScalpel
Surgical AI error fixer for TypeScript & JavaScript — verified by your real linter before it ever shows you a change.
CodeScalpel reads a single error reported by the TypeScript / JavaScript
language service, asks an LLM to propose a fix, applies the fix
invisibly to the in-memory buffer, and then waits for the language
server to re-evaluate the file. If the original error is gone AND no new
errors appeared near the edit, you get a clean diff to review. Otherwise
the buffer is rolled back and you see a clear CANNOT_FIX: <reason>.
It's the only AI fixer that never lies about a fix being correct —
because a real linter is always the final judge.
✨ Features
- Surgical — never rewrites whole files. The LLM is forced to output a
1–5 line unified diff, or to admit
CANNOT_FIX.
- Verified — every candidate fix is round-tripped through the real
TypeScript / JavaScript LSP. No "trust me, it works".
- Multi-provider — works with Groq (free Llama 3.1 70B), Anthropic
Claude 3.5 Haiku, and any local Ollama model.
- Private — Ollama runs entirely on your machine. For cloud providers
the only data that leaves is the ~10-line error snippet.
- Surgical rollback — failed verifications are silently undone with
the editor's built-in
undo.
- Honest — when it can't fix something, it says so with a one-sentence
reason instead of pretending.
🚀 Quick start
- Install CodeScalpel from the VS Code Marketplace.
- Open a TypeScript or JavaScript file with an error.
- Run CodeScalpel: Fix This Error from the command palette
(or click the
⚡ Groq / 🧠 Anthropic / 🏠 Ollama item in the
status bar to switch providers first).
- Add your API key: CodeScalpel: Set API Key.
- Review the verified diff. Click Apply to keep it, Skip to
discard, or Retry with more context for a second attempt.
Free tier: 30 verified fixes per calendar month. Upgrade to Pro for
unlimited fixes via CodeScalpel: Enter Pro License Key.
🛠️ Configuration
| Setting |
Default |
Description |
codescalpel.provider |
groq |
LLM backend: groq, anthropic, or ollama |
codescalpel.autoApply |
false |
Apply verified fixes immediately, no review panel |
codescalpel.maxContextLines |
5 |
Lines of code sent to the LLM on each side of the error (3–20) |
codescalpel.groqModel |
llama-3.1-70b-versatile |
Model name to use with Groq |
codescalpel.anthropicModel |
claude-3-5-haiku-20241022 |
Model name to use with Anthropic |
codescalpel.ollamaEndpoint |
http://localhost:11434 |
Base URL of local Ollama daemon |
codescalpel.ollamaModel |
qwen2.5-coder:7b |
Model name to use with Ollama |
codescalpel.telemetryEnabled |
true |
Anonymous, aggregate-only usage stats (no code, no filenames) |
codescalpel.freeQuotaPerMonth |
30 |
Free fixes per UTC month |
codescalpel.verifyTimeoutMs |
2000 |
How long to wait for the LSP to re-evaluate |
codescalpel.verifyDebounceMs |
750 |
Debounce before reading diagnostic updates |
🔐 API keys & license keys
All secrets are stored with VS Code's SecretStorage, which on
macOS / Windows / most Linux desktops is backed by the OS keychain.
They never touch settings.json, disk in plain text, or any server.
📊 Telemetry
When codescalpel.telemetryEnabled is true (the default) we send
aggregate counters to a Cloudflare worker:
fix_attempt, fix_success, fix_failed, command. No code, no
file names, no error messages are ever transmitted. The identifier is
vscode.env.machineId — a stable, anonymous per-installation token.
Disable at any time via the setting above.
🧪 Supported errors
CodeScalpel only attempts to fix errors whose codes are in a small
whitelist of "small change, big win" patterns:
| TS code |
Meaning |
2304 |
Cannot find name |
2322 / 2345 |
Type / argument is not assignable |
2339 |
Property does not exist on type |
2531, 18047, 18048 |
Object is possibly null / undefined |
2554 |
Expected N arguments, got M |
2740 / 2741 |
Missing properties from type |
7006 |
Parameter implicitly has any type |
Errors we intentionally ignore: module-not-found, tsconfig issues, and
anything that would require editing another file.
🏗️ Architecture
src/
├── extension.ts # main activation, commands, status bar
├── diagnostics.ts # error capture + context extraction
├── llm/
│ ├── provider.ts # interface (LLMProvider, FixContext, LlmResult)
│ ├── anthropic.ts # Claude 3.5 Haiku implementation
│ ├── groq.ts # Llama 3.1 70B (default)
│ ├── ollama.ts # local Ollama implementation
│ ├── prompts.ts # strict system prompt + few-shot
│ └── index.ts # factory
├── diffUtils.ts # unified-diff → TextEdit[]
├── verification.ts # INVISIBLE LSP verification state machine
├── diffUI.ts # side-by-side webview diff panel
├── licensing.ts # free counter + license cache
├── config.ts # settings + SecretStorage
├── logger.ts # output channel
└── telemetry.ts # opt-out anonymous analytics
The verification engine is the core moat. Its job is to apply the
LLM's diff to the live buffer, wait for onDidChangeDiagnostics,
compare the before/after sets, and either keep the edit (and show the
diff) or silently undo it.
🧰 Development
npm install
npm run watch # tsc --watch
# In VS Code: F5 launches the extension in a new Extension Host window.
Tests
npm test
Pure unit tests for the diff parser, the LLM response parser, and the
verification comparator. They run in plain Node (no VS Code required).
Build a .vsix
npm install -g @vscode/vsce
vsce package
📜 License
MIT — see LICENSE.