Show the full install prompt (one paste)
Set up a personal "second brain" markdown vault plus a session-memory layer for Claude Code. Work carefully and do every step. First run `echo $HOME` and use that real home path wherever you see ~ below (expand it to an absolute path for any Write tool call).
STEP 1 — Create folders:
mkdir -p ~/Documents/brain/raw/assets ~/Documents/brain/wiki/projects ~/Documents/brain/wiki/areas ~/Documents/brain/wiki/resources ~/Documents/brain/wiki/people ~/Documents/brain/wiki/archive ~/Documents/brain/daily ~/Documents/brain/.claude/commands ~/.claude/commands ~/.claude/hooks
STEP 2 — Write ~/Documents/brain/CLAUDE.md with EXACTLY the content between the markers (do not include the marker lines):
===SCHEMA_START===
# Brain — LLM Wiki Schema
This vault is a personal knowledge base that the AI maintains for you. It follows Andrej Karpathy's LLM-wiki pattern: a persistent, compounding wiki of markdown files that sits between raw sources and any question. The AI compiles knowledge once and keeps it current, instead of re-deriving it on every query.
The viewer (Obsidian, VS Code, anything) is the IDE. The AI is the programmer. The wiki is the codebase.
## Token discipline (read this first)
Do NOT read the whole wiki on every task. Reading the entire vault wastes tokens and degrades answers. The savings come from loading a tiny cache and pulling detail on demand.
1. For most coding or chat tasks, answer normally without touching the wiki.
2. When a task needs personal or project context, read in this order and STOP as soon as you have enough: SESSION.md then hot.md then index.md then the specific page(s) the index points to, following [[wikilinks]] only if the answer requires it.
3. Never read the entire wiki/ tree. Use the index as the map.
## Architecture
- raw/ — immutable source documents you drop in. The AI READS these and NEVER modifies or deletes them. Source of truth. Images go in raw/assets/.
- wiki/ — markdown files the AI owns entirely. PARA plus entities:
- wiki/projects/ — active efforts with a goal and a finish line
- wiki/areas/ — ongoing responsibilities with no end date
- wiki/resources/ — topics and reference material
- wiki/people/ — one page per person
- wiki/archive/ — inactive things; keep for history, do not surface by default
- daily/ — your daily notes (daily/YYYY-MM-DD.md). Reflection space. Input for /graduate.
- SESSION.md — lean "where we left off" handoff. Refreshed by /tldr. Auto-loaded each session.
- hot.md — about 500 words of current strategic context. Refreshed during ingest and graduate passes.
- log.md — append-only history. Rich /tldr entries land here. Each starts with: ## [YYYY-MM-DD ...] <op> | <title>
- sessions.md — append-only ledger auto-written by the SessionEnd/PreCompact hooks. One line per session so nothing is lost even if /tldr was skipped; recover any session with /recall.
- index.md — a catalog of every wiki page, one line each, grouped by category. The map.
- CLAUDE.md — this schema. Co-evolve it as conventions change.
## Page conventions
Every wiki page starts with YAML frontmatter:
```yaml
---
title: <Page Title>
type: project | area | resource | person | concept | tool | synthesis
tags: [tag1, tag2]
created: YYYY-MM-DD
updated: YYYY-MM-DD
sources: [raw/file-a.md]
---
```
- Link generously with [[Page Name]] wikilinks. Cross-references are the point.
- Prefer many small interlinked pages over a few giant ones.
- When new data contradicts a claim, do not silently overwrite. Note the contradiction inline and update.
- Cite the raw/ file a claim came from.
## Operations
- /ingest — process a source dropped in raw/: read it, write or update a wiki page, update index.md, add two-way [[links]], append a line to log.md.
- /query — answer a question from the wiki, synthesize with citations, then FILE the answer back as a page so it compounds.
- /graduate — scan recent daily/ notes for ideas that never became notes; create standalone notes and wire them in.
- /lint — health check: contradictions, stale claims, orphan pages, missing links, gaps.
- /context — deep warm-start: read hot.md, index.md, the active projects/ and areas/ pages, and recent daily/ notes.
- /tldr (global) — save where we left off: refresh SESSION.md (lean, auto-loaded) AND append a detailed, timestamped entry to log.md (kept forever, read on demand).
- /recall (global) — pull verbatim detail from a past session's raw transcript, on demand, when you need exact words.
- /map (global) — refresh a one-line-per-folder map of the workspace into map.md (top level only, on demand; not a full file index).
## Cross-agent
This vault is portable plain markdown. Any agent can use it: point it here and tell it to read SESSION.md, hot.md, and index.md first. It is also a git repo if you run git init here.
## Scale note
This index-based approach replaces embedding search well up to a few hundred pages. Beyond that, add a local markdown search tool. Most vaults never get close.
===SCHEMA_END===
STEP 3 — Write ~/Documents/brain/SESSION.md with EXACTLY this content:
===SESSION_START===
# Session State — where we left off
> Auto-loaded into every new Claude session started under ~/Documents (SessionStart hook).
> Refreshed by /tldr at the end of a work session. Fast-moving "what was I just doing" handoff.
> Strategic context: hot.md. Full per-session detail: log.md. Verbatim recall: /recall.
**Last updated:** (set on first /tldr)
## Active focus
Brain installed. Nothing in progress yet.
## Where we left off
Just set up the second brain and the session-memory layer.
## Next steps / pick up here
- Drop a source file in brain/raw/ and run /ingest, or write a daily/ note and run /graduate.
- Run /tldr at the end of each chat to keep this file current.
## Open loops
- (none yet)
## Recently primed folders
- (none yet)
===SESSION_END===
STEP 4 — Write ~/Documents/brain/hot.md with EXACTLY this content:
===HOT_START===
# Hot cache
About 500 words of your most relevant current context. Read this first for routine context. Refreshed during ingest and graduate passes.
---
(empty for now: drop sources in raw/ and run /ingest, or write a daily/ note and run /graduate)
===HOT_END===
STEP 5 — Write ~/Documents/brain/index.md with EXACTLY this content:
===INDEX_START===
# Index
Content catalog of the wiki. Read this first to find the right page, then drill in. Empty for now; it fills in as you /ingest sources and the AI creates pages.
## Projects
(none yet)
## Areas
(none yet)
## Resources
(none yet)
## People
(none yet)
===INDEX_END===
STEP 6 — Write ~/Documents/brain/log.md with EXACTLY this content:
===LOG_START===
# Log
Append-only history. Rich /tldr entries land here. Each entry starts with: ## [YYYY-MM-DD HH:MM] <op> | <title>
===LOG_END===
STEP 7 — Write ~/Documents/brain/README.md with EXACTLY this content:
===README_START===
# Brain
A personal LLM-wiki second brain. Plain markdown that the AI maintains; you read it. Open it in any editor or in Obsidian (Open folder as vault).
- raw/ — your immutable sources. The AI reads, never edits. (raw/assets/ for images.)
- wiki/ — AI-owned, PARA-organized: projects/ areas/ resources/ people/ archive/.
- daily/ — your daily notes and reflections.
- SESSION.md — where we left off (auto-loaded). hot.md — current state. log.md — rich history. sessions.md — session ledger. index.md — the map.
- CLAUDE.md — the schema that governs all of it.
Daily use: open a chat under ~/Documents (it auto-loads SESSION.md + hot.md), work, then run /tldr to save. Use /recall to pull verbatim detail from any past session. Drop a file in raw/ and run /ingest to file it.
===README_END===
STEP 8 — Write these five vault command files. Each goes in ~/Documents/brain/.claude/commands/ and is a thin wrapper over the schema:
~/Documents/brain/.claude/commands/context.md:
===CONTEXT_START===
---
description: Deep warm-start from the vault
---
Follow the /context operation in this vault's CLAUDE.md: read hot.md, index.md, the active wiki/projects/ and wiki/areas/ pages, and the most recent daily/ notes. Then produce a tight situational brief of the current state.
===CONTEXT_END===
~/Documents/brain/.claude/commands/ingest.md:
===INGEST_START===
---
description: Process a source from raw/ into the wiki
argument-hint: [optional: path to the raw file]
---
Follow the /ingest operation in this vault's CLAUDE.md. Read the source in raw/ (the one named in $ARGUMENTS if given, else the newest), discuss key takeaways briefly, write or update the right wiki/ page, update index.md, add two-way [[wikilinks]] on related pages, and append a line to log.md.
===INGEST_END===
~/Documents/brain/.claude/commands/query.md:
===QUERY_START===
---
description: Ask the wiki a question; file the answer back
argument-hint: [your question]
---
Follow the /query operation in this vault's CLAUDE.md. Answer $ARGUMENTS using index.md to locate pages, drill in, synthesize with citations, then FILE the good answer back as a new page so it compounds. Append a query line to log.md.
===QUERY_END===
~/Documents/brain/.claude/commands/graduate.md:
===GRADUATE_START===
---
description: Promote buried ideas from daily notes into standalone notes
---
Follow the /graduate operation in this vault's CLAUDE.md. Scan recent daily/ notes for ideas that never became notes, present the best candidates, and for each one I approve, create a standalone note and wire it in with backlinks.
===GRADUATE_END===
~/Documents/brain/.claude/commands/lint.md:
===LINT_START===
---
description: Health-check the wiki
---
Follow the /lint operation in this vault's CLAUDE.md. Report contradictions, stale claims, orphan pages, important concepts missing their own page, missing cross-references, and data gaps. Do not auto-fix structural changes without asking.
===LINT_END===
STEP 9 — Write the SessionStart auto-load hook at ~/.claude/hooks/documents-brain-load.sh with EXACTLY this content, then run: chmod +x ~/.claude/hooks/documents-brain-load.sh
===LOADHOOK_START===
#!/bin/bash
# documents-brain-load.sh
# SessionStart hook: when a Claude session starts anywhere under ~/Documents, inject the brain's
# working state (SESSION.md) + strategic state (hot.md) + recent log/ledger breadcrumb so the new
# chat is warm. No-ops silently for any session outside ~/Documents.
DOCS="$HOME/Documents"
BRAIN="$DOCS/brain"
CWD="$(pwd)"
case "$CWD/" in
"$DOCS"/*|"$DOCS/") ;;
*) exit 0 ;;
esac
[ -d "$BRAIN" ] || exit 0
echo "=== BRAIN CONTINUITY (auto-loaded) ==="
echo "You started a session under ~/Documents. Below is the persistent working state and strategic"
echo "context from ~/Documents/brain. Pick up exactly where the last session left off."
echo "Do NOT crawl the full wiki to orient: this cache is the distilled 'everything'. Read"
echo "brain/index.md only as a map and drill into a page only when the task needs it."
echo "When you finish meaningful work, run /tldr to save the new state back here."
echo
if [ -f "$BRAIN/SESSION.md" ]; then
echo "----- WHERE WE LEFT OFF (brain/SESSION.md) -----"
cat "$BRAIN/SESSION.md"
echo
fi
if [ -f "$BRAIN/hot.md" ]; then
echo "----- STRATEGIC STATE (brain/hot.md) -----"
cat "$BRAIN/hot.md"
echo
fi
if [ -f "$BRAIN/log.md" ]; then
echo "----- RECENT /tldr ENTRIES (full detail in brain/log.md) -----"
grep '^## \[' "$BRAIN/log.md" | tail -5
echo
fi
if [ -f "$BRAIN/sessions.md" ]; then
N=$(grep -c '^- \[' "$BRAIN/sessions.md" 2>/dev/null || echo 0)
echo "Session ledger: $N logged sessions. Run /recall to pull verbatim detail from any past session."
echo
fi
echo "----- MAP -----"
echo "Full catalog of all pages: brain/index.md . Rich session log: brain/log.md . Perfect recall: /recall ."
echo "For a deep warm-start (active projects + recent dailies), run /context inside brain/."
exit 0
===LOADHOOK_END===
STEP 10 — Write the safety-net capture hook at ~/.claude/hooks/brain-session-capture.sh with EXACTLY this content, then run: chmod +x ~/.claude/hooks/brain-session-capture.sh
===CAPHOOK_START===
#!/bin/bash
# brain-session-capture.sh
# Handles BOTH SessionEnd and PreCompact hooks. Appends a one-line pointer to brain/sessions.md for
# every ending/compacting session so nothing is lost even if /tldr was never run (the raw transcript
# stays recoverable via /recall). For PreCompact it also injects a reminder to save state first.
# No-ops silently for any session whose cwd is outside ~/Documents.
INPUT="$(cat)"
DOCS="$HOME/Documents"
BRAIN="$DOCS/brain"
[ -d "$BRAIN" ] || exit 0
# Pass the hook JSON via env var (NOT stdin): the heredoc below is python's program on stdin.
INPUT="$INPUT" DOCS="$DOCS" BRAIN="$BRAIN" python3 - <<'PY'
import os, json, sys, datetime
try:
d = json.loads(os.environ.get("INPUT", "") or "{}")
except Exception:
sys.exit(0)
docs = os.environ["DOCS"]
brain = os.environ["BRAIN"]
cwd = d.get("cwd", "") or ""
if not (cwd == docs or cwd.startswith(docs + "/")):
sys.exit(0)
ledger = os.path.join(brain, "sessions.md")
ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
sid = (d.get("session_id") or "")[:8]
tp = d.get("transcript_path") or ""
ev = d.get("hook_event_name", "")
if ev == "PreCompact":
kind, reason = "precompact", (d.get("trigger") or "auto")
else:
kind, reason = "end", (d.get("reason") or "other")
if not os.path.exists(ledger):
with open(ledger, "w") as f:
f.write(
"# Sessions ledger\n\n"
"Auto-logged by the SessionEnd / PreCompact hooks. One line per event, newest at bottom.\n"
"Even if /tldr was skipped, the raw transcript is recoverable: run /recall <session-id>.\n\n"
)
with open(ledger, "a") as f:
f.write(f"- [{ts}] {kind} ({reason}) | session {sid} | {tp}\n")
if ev == "PreCompact":
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PreCompact",
"additionalContext": (
"Context is about to compact. Make sure the key state is captured in "
"~/Documents/brain/SESSION.md and log.md (run /tldr if not). The full pre-compaction "
"transcript remains at: " + tp
),
}
}))
PY
exit 0
===CAPHOOK_END===
STEP 11 — Register all hooks in ~/.claude/settings.json. If the file does not exist, create it with exactly this:
{
"cleanupPeriodDays": 3650,
"hooks": {
"SessionStart": [
{ "matcher": "startup", "hooks": [ { "type": "command", "command": "~/.claude/hooks/documents-brain-load.sh", "timeout": 15 } ] },
{ "matcher": "resume", "hooks": [ { "type": "command", "command": "~/.claude/hooks/documents-brain-load.sh", "timeout": 15 } ] },
{ "matcher": "clear", "hooks": [ { "type": "command", "command": "~/.claude/hooks/documents-brain-load.sh", "timeout": 15 } ] }
],
"SessionEnd": [
{ "hooks": [ { "type": "command", "command": "~/.claude/hooks/brain-session-capture.sh", "timeout": 15 } ] }
],
"PreCompact": [
{ "matcher": "auto", "hooks": [ { "type": "command", "command": "~/.claude/hooks/brain-session-capture.sh", "timeout": 15 } ] },
{ "matcher": "manual", "hooks": [ { "type": "command", "command": "~/.claude/hooks/brain-session-capture.sh", "timeout": 15 } ] }
]
}
}
If the file already exists, READ it first and merge: add the SessionStart, SessionEnd, and PreCompact arrays into the existing "hooks" object. Preserve every existing key and any existing hooks (for example a Stop hook) exactly. After editing, verify it is still valid JSON: python3 -c "import json; json.load(open('$HOME/.claude/settings.json')); print('valid')" . Also set a top-level "cleanupPeriodDays": 3650 (keeps Claude Code session transcripts about 10 years instead of the 30-day default, so /recall can reach far back).
STEP 12 — Write the global /tldr command at ~/.claude/commands/tldr.md with EXACTLY this content (the ~ paths inside expand to the home directory at run time):
===TLDR_START===
---
description: Save where we left off so the next chat picks up exactly here
allowed-tools: Read, Write, Edit, Bash
argument-hint: [optional: short title for this session]
---
# /tldr — save session state to the brain
Capture this conversation two ways: a LEAN handoff that auto-loads next session, and a RICH, append-only log entry kept forever for on-demand recall. The SessionStart hook auto-loads the lean handoff (SESSION.md); the rich log (log.md) is read only when a future session needs the specifics.
## Variables
- TITLE: $ARGUMENTS (if empty, infer a short title from the session)
- SESSION_FILE: ~/Documents/brain/SESSION.md
- LOG_FILE: ~/Documents/brain/log.md
## Workflow
1. Get the timestamp: run `date '+%Y-%m-%d %H:%M'` (use `date +%Y-%m-%d` where only the date is needed).
2. Review THIS conversation and extract two levels of detail:
- LEAN (for SESSION.md): active focus, where we left off, next steps, open loops, primed folders.
- RICH (for log.md): the same plus decisions WITH rationale, exact file:line references, short code or command snippets worth keeping, and any open questions or instructions verbatim.
3. OVERWRITE SESSION_FILE with the lean structure below, fully refreshed. Do not append; this file is always latest-only. Keep it under about 400 words.
# Session State — where we left off
> Auto-loaded into every new Claude session under ~/Documents (SessionStart hook).
> Refreshed by /tldr. Fast-moving working state. Strategic context: hot.md. Full detail: log.md.
**Last updated:** <date>
## Active focus
<one line>
## Where we left off
<specifics with file paths>
## Next steps / pick up here
- <step>
## Open loops
- <loop>
## Recently primed folders
- <folder>: <stack + key understanding>
4. APPEND a RICH entry to LOG_FILE (create it if missing). Do NOT overwrite. Keep the ## [...] header so the log stays grep-able:
## [<date> <time>] tldr | <TITLE>
**Focus:** <one line>
**What happened & decisions** (with rationale):
- <decision or change> -> <why>
**Files touched** (exact paths, file:line where relevant):
- <path:line> -> <what changed>
**Snippets worth keeping:**
- <short code or command, or "none">
**Open questions / verbatim notes:**
- <quote, or "none">
**Next:** <where to pick up>
Be detailed here; this is what lets a future session refer to specific things. It costs nothing at session start because it is not auto-loaded.
5. If durable, reusable knowledge emerged, suggest creating or updating a page under ~/Documents/brain/wiki/ , but ask before writing any wiki page.
6. Confirm in two or three lines what you wrote to SESSION.md and that the rich entry was appended to log.md.
===TLDR_END===
STEP 13 — Write the global /recall command at ~/.claude/commands/recall.md with EXACTLY this content:
===RECALL_START===
---
description: Perfect-recall search across past session transcripts (read on demand, token-cheap)
allowed-tools: Bash, Read
argument-hint: [search term | session-id | "list"]
---
# /recall — pull verbatim detail from past sessions
SESSION.md and log.md hold the distilled state. Use /recall when you need EXACT detail from a past conversation. This reads the raw session transcripts, which are token-cheap IF you filter first and only extract the matching slice. NEVER cat a whole transcript; they can be tens of MB.
## Where transcripts live
Claude Code stores one .jsonl per session under ~/.claude/projects/<cwd-slug>/, where the slug is the working directory with / replaced by -. All ~/Documents sessions live under dirs matching ~/.claude/projects/*Documents*/. Discover them with: ls -dt ~/.claude/projects/*Documents*/ 2>/dev/null . Each line is a JSON object; message text is usually at message.content (a string, or a list of blocks with a text field).
## ARG: $ARGUMENTS
## Workflow
1. ARG empty or "list": show `tail -n 15 ~/Documents/brain/sessions.md` and `grep '^## \[' ~/Documents/brain/log.md | tail -n 8`. Tell me I can run /recall <term> to search or /recall <session-id> to open one.
2. ARG looks like a session id (8+ hex) or a transcript path: find the file with `ls ~/.claude/projects/*Documents*/<id>*.jsonl` (or use the path). Write a short python snippet to walk the JSONL and print role: text per message (handle message.content as string or list of {type:text,text}). Pull the detail I asked about and summarize the session.
3. Otherwise treat ARG as a SEARCH TERM (ID-first, then fetch): find sessions without reading whole files via `grep -rli -- "$ARG" ~/.claude/projects/*Documents*/*.jsonl | head -20`; for the top matches show `grep -hi -m 3 -- "$ARG" <file>` and extract readable text with python; report which sessions discussed it (file mtime = date) with snippets; ask which to open in full, then read only that one.
4. After recalling, if worth keeping, offer to run /tldr or /ingest so I do not have to recall it again.
Keep it surgical: filter with grep to find the right session, then extract only the relevant messages.
===RECALL_END===
STEP 14 — Write the global /map command at ~/.claude/commands/map.md with EXACTLY this content:
===MAP_START===
---
description: Map the workspace top-level folders into the brain (on demand, bounded — not every file)
allowed-tools: Bash, Read, Write
---
# /map — index the workspace top-level into the brain
Build or refresh a one-line-per-folder map of ~/Documents so the brain knows WHERE things live, without indexing every file (that would be noise and would go stale instantly). Top level only.
## Variables
- MAP_FILE: ~/Documents/brain/map.md
- LOG_FILE: ~/Documents/brain/log.md
## Workflow
1. Get the date: run `date +%Y-%m-%d`.
2. If ~/Documents/INDEX.md exists, READ and condense it (it is the maintained source of truth for the folder layout; do not re-scan the tree). Otherwise list the top-level folders with `ls -d ~/Documents/*/` and give each a ONE-line description from its CLAUDE.md or README.md first heading/sentence if present, else infer from the name. Do not recurse; do not read file contents beyond those first lines.
3. OVERWRITE MAP_FILE with: a "# Workspace map" heading, a one-line note that it is top-level only and not a full index, a "**Last mapped:** <date>" line, then one "- **<folder>/** — <one-line description>" line per top-level folder.
4. APPEND to LOG_FILE: a line `## [<date>] map | workspace top-level mapped` plus a one-sentence summary.
5. Confirm what you wrote and where.
Keep it to top-level folders. The point is orientation (where to look), not a copy of the tree.
===MAP_END===
STEP 15 — Add a brain section to ~/Documents/CLAUDE.md so every session knows the system. If the file exists, APPEND the block below. If it does not exist, CREATE it with the block:
===DOCSMD_START===
## Brain (session memory)
`~/Documents/brain/` is an LLM-wiki second brain. A SessionStart hook auto-loads `brain/SESSION.md` (where we left off) and `brain/hot.md` (current state) into every session started anywhere under `~/Documents`, so you begin warm without being asked. That cache is the distilled state; do NOT crawl the full wiki to orient. Use `brain/index.md` as the map and drill into a page only when the task needs it.
At the end of meaningful work, run `/tldr` to save where you left off (it refreshes `brain/SESSION.md` and appends a detailed entry to `brain/log.md`). After scanning a folder, run `/tldr` so the understanding is stored. SessionEnd/PreCompact hooks log every session to `brain/sessions.md` as a safety net, so even a forgotten session is recoverable. To pull verbatim detail from any past session, run `/recall`.
===DOCSMD_END===
STEP 16 — Verify everything:
- ls -la ~/Documents/brain ; ls ~/Documents/brain/.claude/commands ; ls ~/.claude/commands/tldr.md ~/.claude/commands/recall.md
- python3 -c "import json; json.load(open('$HOME/.claude/settings.json')); print('settings.json valid')"
- bash ~/.claude/hooks/documents-brain-load.sh (run from inside ~/Documents; should print the brain context)
- echo '{"hook_event_name":"SessionEnd","cwd":"'$HOME'/Documents","session_id":"test1234","transcript_path":"/tmp/x.jsonl","reason":"clear"}' | bash ~/.claude/hooks/brain-session-capture.sh ; tail -1 ~/Documents/brain/sessions.md (should show the test line, then delete it from sessions.md)
When done, tell me: the brain is built, all hooks and commands are installed. Remind me that hooks and commands load at session start, so I must START A NEW Claude session inside ~/Documents to see the brain auto-load and to use /tldr and /recall.