| name | autopsy |
| description | Diagnose runtime errors using the autopsy library. Invoke when the user hits an error, wants to understand a crash, asks "why did this fail", or wants to install global error hooks. Covers explain(), install(), and visualize(). |
Autopsy
"The error is not the end of the story — it is the first line of the investigation."
Autopsy turns broken stackframes into intelligent, Elm-style error explanations. A headless Flue agent reads the source around the crash site, gathers context from imports, git history, and Entire sessions, then returns a structured diagnosis with root cause, confidence, fix suggestion, and step-by-step reasoning.
When to use this skill
- The user hits a runtime error and wants more than a stacktrace
- The user asks "why did this crash" or "what does this error mean"
- The user wants to install automatic error diagnosis in their project
- The user wants an interactive HTML visualization of a diagnosis
Install
npm install autopsy
Core API
explain(error, config?) — diagnose an error
import { explain } from "autopsy";
const diagnosis = await explain(error, {
cwd: process.cwd(),
model: "anthropic/claude-haiku-4-5",
radius: 1,
tokenBudget: 6000,
gitContext: true,
entireContext: true,
});
Returns a Diagnosis object:
interface Diagnosis {
rootCause: string;
confidence: "high" | "medium" | "low";
fixSuggestion: string;
contextSufficient: boolean;
relevantFiles: Array<{ path, lineRange, snippet, relevance }>;
steps?: Array<{ title, description }>;
}
install(config?) / uninstall() — global error hooks
import { install, uninstall } from "autopsy";
install({
model: "anthropic/claude-haiku-4-5",
ignorePatterns: [/ECONNRESET/, /ETIMEDOUT/],
rateLimit: { max: 3, windowMs: 60_000 },
alwaysLogOriginal: true,
onDiagnosis: (d, err) => {
sendToSlack(d);
},
});
uninstall();
Safety rails: rate limiting, ignore patterns, always logs the original error, agent failures fall through gracefully.
visualize(error, diagnosis, config?) — interactive HTML
import { visualize } from "autopsy";
const filepath = await visualize(error, diagnosis, {
cwd: process.cwd(),
contextFiles,
});
Configuration
| Option | Type | Default | Description |
|---|
model | string | "anthropic/claude-sonnet-4-6" | Flue model identifier |
radius | 0-3 | 1 | Import hops from error site |
tokenBudget | number | 6000 | Max context tokens |
cwd | string | process.cwd() | Working directory |
gitContext | boolean | true | Include git log/diff/blame |
entireContext | boolean | true | Include Entire.io sessions |
ignorePatterns | RegExp[] | [] | Skip matching errors (hook only) |
rateLimit | {max, windowMs} | {3, 60000} | Rate limit for hook |
alwaysLogOriginal | boolean | true | Always print raw error |
onDiagnosis | function | pretty-print | Custom diagnosis handler |
cache | DiagnosisCache | shared instance | Custom cache for isolation |
contextSources | ContextSource[] | [] | Custom context gatherers |
File config: autopsy.config.json or .autopsy.json in the project root.
Custom context sources
import type { ContextSource } from "autopsy";
const mySource: ContextSource = {
name: "sentry",
async gather(errorSite, frames, { cwd, tokenBudget }) {
const events = await fetchSentryEvents(errorSite.file);
return events.map(e => ({
path: `sentry:${e.id}`,
lineRange: [1, 1],
content: JSON.stringify(e),
relevance: "custom" as const,
}));
},
};
const diagnosis = await explain(error, { contextSources: [mySource] });
Architecture
Error → parseStack() → findErrorSite()
↓
gatherContext() ← reads source files, follows imports
↓
gatherExtraContext() ← git, Entire, custom sources
↓
callFlueAgent() ← createFlueContext → init(BashFactory) → prompt()
↓
Diagnosis (cached) ← LRU cache keyed on error signature
Constraints
- Only use public Flue SDK APIs (
@flue/sdk/client, @mariozechner/pi-ai). Never import from @flue/sdk/internal.
- The Flue agent must be able to read the project's source files (uses
just-bash with the project's cwd).
- The
prompt() method in @flue/sdk ^0.3.x uses result (not schema — that's a main-branch rename).
just-bash Bash instances must be passed as BashFactory functions to ctx.init({ sandbox: factory }), never as raw instances.