A self-improving layer for Claude Code: it learns from your sessions, retains knowledge in a vault, and proposes skills/automations from recurring patterns. This repo holds the machinery (hooks, distill prompt + runner, dashboard, install config).
What's inside
FAQ
recall is a Claude Code plugin with hand-picked skills for automation work, indexed on Flowy. Install it with the command on its page. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
A self-improving layer for Claude Code: it learns from your sessions, retains knowledge in a vault, and proposes skills/automations from recurring patterns.
This repo holds the machinery (hooks, distill prompt + runner, dashboard, install config). The knowledge lives in a separate vault directory, partitioned by project โ kept out of this repo entirely.
capture (Stop hook) โโโถ vault/sessions โโโถ distill (nightly) โโโถ vault/knowledge
โ
retrieve (SessionStart hook) โโโโโโโโโโโโโโโโโโ
โโโโถ inbox/proposals.md โโโถ you approve โโโถ skills
hooks/capture-session.sh, wired to Claude Code's Stop hook.
On each session end it writes a raw dump (cwd, project, git diff stat,
transcript pointer) to the vault. Pure shell + jq, ~zero tokens, never blocks.distill/run-distill.sh, a nightly launchd job. Thins each new
transcript, runs a headless Claude pass to update knowledge/, refreshes the
indexes, and appends pattern observations to inbox/proposals.md. Skips (costs
$0) when there's nothing new.hooks/inject-knowledge.sh, wired to the SessionStart hook.
Injects the global + per-project knowledge indexes as background context so
they survive /clear and auto-compact.inbox/proposals.md. Nothing
auto-promotes to a skill until you approve it.dashboard/recall.sh (status CLI) and build-dashboard.sh
(self-contained HTML). recall.sh open rebuilds and opens it.date/stat).claude CLI on your PATH.brew install bash (system /bin/bash is 3.2 and lacks mapfile).jq via brew install jq; git/perl ship with macOS.Clone the repo anywhere you like โ ~/Sites/recall below is just an example;
~/dev/recall, ~/code/recall, etc. are all fine. The installer locates itself,
so the repo path is never hardcoded.
git clone <this-repo> ~/Sites/recall # or wherever you prefer
cd ~/Sites/recall
./install/install.sh # interactive
The installer is interactive and will ask:
recall/ subfolder, syncing alongside your notes) or let it create one;~/.claude/CLAUDE.md โ a short, idempotent
note telling Claude the vault is auto-injected and read-only in sessions.It then checks dependencies, scaffolds the vault, merges the two hooks into
~/.claude/settings.json without disturbing existing hooks (backup written to
settings.json.recall-bak), and loads the launchd job. Safe to re-run.
Non-interactive / scripted installs:
./install/install.sh -y # accept all defaults, no prompts
./install/install.sh --vault ~/notes/recall --time 22:30
./install/install.sh --no-git --no-launchd
| Flag | Effect |
|---|---|
-y, --yes | No prompts; accept defaults. |
--vault DIR | Set the recall data dir explicitly (skips the vault question). |
--time HH:MM | Nightly distill time, 24h. |
--no-git | Never git init the vault. |
--no-launchd | Skip the scheduler (run distill by hand). |
--no-claude-md | Don't add the recall block to ~/.claude/CLAUDE.md. |
For knowledge to sync across machines the vault needs a git
originremote (the nightly job commits + pushes) โ or let the obsidian-git plugin handle sync. Without either, distilled knowledge is still saved locally.
All optional โ sensible defaults apply.
| Variable | Default | What |
|---|---|---|
RECALL_VAULT | ~/Documents/Vault/recall | Vault data dir (sessions, knowledge, inbox). |
RECALL_DISTILL_THRESHOLD | 1 | Min undistilled sessions before a nightly run does work. |
RECALL_DISTILL_MODEL | sonnet | Model for the distill pass. |
RECALL_DISTILL_BUDGET | 1.50 | Max USD per distill run. |
RECALL_DISTILL_STALE_MIN | 30 | Skip sessions touched within this many minutes (still active). |
RECALL_INJECT_MAX_LINES | 200 | Cap on lines of knowledge injected per session (mirrors Claude Code memory). |
RECALL_INJECT_MAX_BYTES | 25600 | Cap on bytes injected per session; overflow is truncated with a visible marker. |
The installer bakes RECALL_VAULT into the launchd plist, so a custom --vault
is respected by the nightly job. For the hooks/CLI to use a custom vault in your
interactive shell, export RECALL_VAULT in your shell profile.
dashboard/recall.sh # overall health (default)
dashboard/recall.sh sessions # per-project session breakdown
dashboard/recall.sh knowledge # notes by area + recent additions
dashboard/recall.sh proposals # pending + implemented proposals
dashboard/recall.sh distill # recent runs (cost, duration, outcome)
dashboard/recall.sh open # rebuild + open the HTML dashboard
dashboard/recall.sh update # self-update (git pull + re-apply install)
dashboard/recall.sh all # everything
distill/run-distill.sh # run a distill pass now (instead of waiting for 7pm)
recall runs in place from the clone, so updating is just pulling the latest code and re-applying the install (to pick up any changed hook/launchd templates):
dashboard/recall.sh update
This does git pull --ff-only then re-runs install.sh non-interactively using
the settings saved at install time (<vault>/.recall-install). The installed
version is shown by recall.sh status and in the dashboard footer; when your
clone is behind its remote, both surface an "update available" hint (the nightly
distill refreshes that check).
<RECALL_VAULT>/ default: ~/Documents/Vault/recall
sessions/ raw dumps, tagged by project
knowledge/
global/ <topic>.md cross-project
projects/<proj>/<topic>.md project-specific
inbox/proposals.md skill/automation candidates (you approve)
dashboard.html generated dashboard
Knowledge and skills land at the narrowest scope that fits, and promote to global only when a pattern generalizes.
<proj>/.claude/skills/)~/.claude/skills/)| Decision | Choice | Why |
|---|---|---|
| Knowledge store | Hybrid | Tiny always-on index โ on-demand vault reads. Flat per-session token cost as knowledge grows. |
| Capture | Auto Stop hook, raw dump | Pure shell, no LLM call (~zero tokens), never forgets. Summarizing deferred to distill. |
| Automation gate | Human-approval | Distill only proposes into an inbox. Nothing auto-promotes until trusted. |
| Project identity | git repo root, else launch dir | Subdirs of one repo = same project; loose folders scoped to launch dir. |
launchctl unload ~/Library/LaunchAgents/com.recall.distill.plist
rm ~/Library/LaunchAgents/com.recall.distill.plist
# then remove the two recall entries from ~/.claude/settings.json
# (restore ~/.claude/settings.json.recall-bak if you want the pre-install state)
The vault is never touched by uninstall โ delete ~/Documents/Vault/recall
yourself if you want the captured data gone.
recall was inspired by Andrej Karpathy's LLM Wiki: the idea that instead of re-deriving answers from raw sources every time, an LLM should incrementally maintain a persistent, compounding markdown knowledge base โ cross-referenced notes that build up over time, with the tedious bookkeeping left to the model.
recall applies that loop to Claude Code, with the same three layers Karpathy describes โ raw sources โ wiki โ schema:
sessions/)[[...]]) knowledge vault (knowledge/)The nightly distill pass is what does the bookkeeping: reading the day's raw sessions and folding them into the wiki so each new session starts from accumulated knowledge rather than cold.
.gitignore dashboard/ build-dashboard.sh recall.sh distill/ distill-prompt.md run-distill.sh thin-transcript.sh hooks/ capture-session.sh inject-knowledge.sh install/ com.recall.distill.plist.template install.sh recall-hooks.json.template README.md
ยฉ 2026 Flowy ยท Free and open source
Built for Claude Code ยท Not affiliated with Anthropic