Local AI session capture and search for Claude Code.
Ghost non-blockingly records Claude Code sessions as markdown, attaches them to commits via git notes, and indexes them into QMD for semantic search. The agent can query its own history, learn from past mistakes, and start every session warm.
Ghost installs as a set of Claude Code hooks. During a session, hooks fire on prompt submit, file write, and turn completion — each exits in under 100ms so you never notice them. They append to a markdown file in .ai-sessions/active/ that captures everything: your prompts, which files were modified, and when each turn finished.
When the session ends, Ghost moves the file to .ai-sessions/completed/, redacts secrets, and forks a background process. That process calls claude -p to summarize the session, extracts decisions and mistakes into their own ledgers, attaches a git note to HEAD, and indexes the session into QMD for search. All of this happens after your terminal is free.
On the next session start, Ghost checks for a recent session on the same branch. If it finds one, it injects context — what you were working on, open items, key decisions, and known pitfalls — so the agent picks up where you left off. Mistakes and decisions are scored by file overlap with your current changes, so you only see what's relevant.
Multiple concurrent sessions are supported. Each Claude Code session is tracked independently via a session map, so two sessions in the same repo write to separate files without interfering.
Everything is stored locally in .ai-sessions/ (gitignored by default):
active/— in-progress session files (one per running session)completed/— finalized session markdown with summariesmistakes.md— mistake ledger, auto-extracted from sessions or added manuallydecisions.md— decision log with context and reasoningknowledge.md— auto-generated project knowledge basetags.json— tag-to-session index for filtering
Git notes live on refs/notes/ai-sessions. QMD collections are named ghost-<repo-name>. No data leaves your machine.
- Bun >= 1.0
- Claude Code (for AI summarization)
- QMD (for semantic search, optional)
- macOS:
brew install sqlite(required by QMD)
bun install -g github:notkurt/ghost#mainOr clone and link:
git clone https://github.com/notkurt/ghost.git
cd ghost
bun install
bun linkghost updateThis auto-detects your install method (git clone or global bun package) and updates accordingly. Check your version with ghost --version.
Enable ghost in any git repository:
cd your-project
ghost enableThis creates the .ai-sessions/ directory, configures Claude Code hooks in .claude/settings.json, sets up git notes, and optionally creates a QMD collection for search.
To auto-install missing dependencies (QMD, sqlite):
ghost enable -fTo build an initial knowledge base from your codebase before any sessions:
ghost enable --genesisTo remove hooks (session files are preserved):
ghost disableEvery Claude Code session automatically produces a markdown file like this:
---
session: 2026-02-13-k8f2m9x1
branch: feature/cart-fees
base_commit: a1b2c3d4
started: 2026-02-13T09:30:00Z
ended: 2026-02-13T10:15:00Z
tags: [area:cart, fees, type:refactor]
---
## Prompt 1
> Refactor the cart to use percentage-based fees
- Modified: src/cart/fees.ts
- Modified: src/cart/types.ts
---
_turn completed: 2026-02-13T09:35:12Z_
## Prompt 2
> The fee calculation is wrong for orders over $500
- Modified: src/cart/fees.ts
- Modified: src/cart/__tests__/fees.test.ts
---
_turn completed: 2026-02-13T09:41:30Z_
## Summary
### Intent
Migrate cart fee system from fixed amounts to percentage-based with a cap.
### Changes
- src/cart/fees.ts: Replaced fixed fee lookup with percentage calc, added $50 cap
- src/cart/types.ts: Added FeeStrategy type
### Decisions
**Percentage with hard cap**: Client wanted flexible fees -> chose percentage
with $50 cap (simpler, client preferred)
### Mistakes
_None this session._
### Open Items
- Update metafield sync to include fee strategy
- Tax interaction with percentage fees untested
### Tags
area:cart, fees, type:refactor| Command | Description |
|---|---|
ghost enable |
Set up hooks, directories, git notes, QMD collection |
ghost enable -f |
Same, but auto-install missing dependencies |
ghost enable --genesis |
Same, plus build initial knowledge base from codebase |
ghost disable |
Remove hooks (keeps session files) |
ghost reset |
Clear all session data, git notes, and QMD collection (keeps hooks) |
ghost status |
Show current session, counts, dependency status |
ghost update |
Update ghost to latest version |
ghost version |
Show current version (also --version, -v) |
| Command | Description |
|---|---|
ghost search <query> |
Semantic search across sessions via QMD |
ghost search --tag <tag> <query> |
Search filtered by tag |
ghost log |
List recent sessions |
ghost show <commit> |
Show session note attached to a commit |
| Command | Description |
|---|---|
ghost knowledge build |
Rebuild knowledge base from all sessions |
ghost knowledge inject |
Append knowledge base to CLAUDE.md |
ghost knowledge show |
Print current knowledge base |
ghost knowledge diff |
Show current knowledge base (rebuild to update) |
ghost absorb |
Distill CLAUDE.md into Ghost knowledge files |
ghost absorb --dry-run |
Preview extraction without writing files |
ghost edit knowledge |
Open knowledge base for manual editing |
ghost edit mistakes |
Open mistake ledger for manual editing |
ghost edit decisions |
Open decision log for manual editing |
| Command | Description |
|---|---|
ghost tag <session-id> <tags...> |
Add tags to a session |
ghost tag --last <tags...> |
Tag the most recent session |
| Command | Description |
|---|---|
ghost resume [session-id] |
Context handoff from a previous session |
ghost brief "<description>" |
Generate scoped context brief for upcoming work |
ghost mistake "<description>" |
Add entry to mistake ledger |
ghost decisions |
Show decision log |
| Command | Description |
|---|---|
ghost heatmap |
File modification frequency across sessions |
ghost heatmap --tag <tag> |
Heatmap filtered by tag |
ghost stats |
Session metrics and trends |
ghost stats --json |
Structured output |
ghost stats --since <date> |
Filter by date |
ghost validate |
Check session files for formatting errors |
ghost validate -f |
Auto-fix fixable formatting issues |
ghost reindex |
Rebuild QMD collection from all completed sessions |
Ghost registers these Claude Code hooks (all called automatically):
| Hook | Event | What It Does |
|---|---|---|
ghost session-start |
SessionStart | Creates session file, injects warm resume context |
ghost session-end |
SessionEnd | Finalizes session, forks background processing |
ghost prompt |
UserPromptSubmit | Records user prompt |
ghost stop |
Stop | Records turn completion with timestamp |
ghost post-write |
PostToolUse(Write/Edit) | Records file modification |
ghost post-task |
PostToolUse(Task) | Records subtask completion |
ghost checkpoint |
post-commit (git hook) | Attaches session as git note to HEAD |
When you start a new session on the same branch within 24 hours, Ghost automatically injects context from the previous session: what you were doing, where you left off, which files were involved, key decisions made, and known pitfalls. No manual "continue where we left off" needed.
After every N sessions (default 5), Ghost can rebuild a project knowledge base that captures architecture, conventions, decisions, gotchas, and patterns that work. This is CLAUDE.md that writes itself.
ghost knowledge build # Rebuild now
ghost knowledge inject # Append to CLAUDE.md so the agent sees itCLAUDE.md files tend to grow massive over time with verbose examples, architecture docs, and embedded knowledge. ghost absorb reads your CLAUDE.md, uses Claude to extract and categorize the content, moves knowledge into Ghost's structured files (decisions.md, mistakes.md, knowledge.md), and writes back a slim CLAUDE.md with just the essential rules.
ghost absorb --dry-run # Preview what would be extracted
ghost absorb # Extract and write (backs up to CLAUDE.md.pre-absorb)Ghost tracks things that went wrong. Auto-extracted from session summaries, or added manually:
ghost mistake "Don't use cart.js API for bundles -- it drops line properties over 250 chars"On session start, known pitfalls are injected into context so the agent avoids repeating past mistakes.
Significant technical decisions are auto-extracted from sessions and logged with context and reasoning. Query them later:
ghost decisions
ghost decisions --tag "area:checkout"Before starting work, generate a context brief that pulls relevant sessions, decisions, known issues, and frequently modified files:
ghost brief "add a new payment method to checkout"Session data is attached to commits via refs/notes/ai-sessions. View them with:
git log --show-notes=ai-sessions
ghost show <commit-sha>Push notes to a remote:
git push origin refs/notes/ai-sessionsWhen QMD is installed, Ghost configures an MCP server so Claude Code can search past sessions directly during a conversation. The agent can ask things like "what did we decide about fee calculation?" and get answers from its own history.
Sessions not being captured
- Run
ghost statusto verify hooks are configured - Check
.claude/settings.jsonhas Ghost hooks in thehookssection - Re-run
ghost enableto reinstall hooks
No summaries appearing
- Ensure
claudeCLI is installed and on your PATH (which claude) - Run
ghost logsto check for background process errors - Summaries run in the background after session end — check
ghost statusfor background process state
Search returns no results
- Verify QMD is installed:
which qmd - Check collection exists:
ghost status(look for QMD line) - Rebuild the index:
ghost reindex
MCP server not working
- Confirm
ghost-sessionsis in.claude/settings.jsonundermcpServers - Re-run
ghost enableto regenerate the config - Try
qmd -c <collection-name> search "test"to verify QMD works directly
Background process seems stuck
- Check
ghost status— if it shows "running" for a long time, the PID file may be stale - Run
ghost logsto see what happened - Delete
.ai-sessions/.background.pidto reset the state
- Runtime: Bun (starts in ~6ms, critical for hook latency)
- Sessions: Markdown with YAML frontmatter in
.ai-sessions/ - Git integration: Notes on
refs/notes/ai-sessions - Search: QMD with project-scoped collections (
ghost-<repo-name>) - Summarization:
claude -pvia Claude Code CLI - Hooks: Registered in
.claude/settings.json
All data is local. No SaaS, no external services. Everything is scoped to the individual repo.
bun src/index.ts <command> # Run from source
bun test # Run all tests
bun run typecheck # TypeScript type checking
bun run format # Auto-format with Biome
bun run lint # Biome linting + format check
bun run check # Run all checks (typecheck + lint + test)
bun link # Install globally as 'ghost'MIT