Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cad0p/pi-napkin/llms.txt

Use this file to discover all available pages before exploring further.

Auto-distill is pi-napkin’s core feature. It runs silently in the background, periodically forking your pi session and asking a model to extract structured knowledge into your vault — no prompting, no interruption to your work. Over time, your vault accumulates a curated record of decisions, patterns, and discoveries from every conversation, captured automatically as you work.

How it works

1

Session start: timer armed

When you open a pi session in a vault with distill.enabled: true, the extension arms a timer set to intervalMinutes (default: 60 minutes). It also sweeps any stale distill worktrees left behind by crashed pi instances.
2

Timer tick: worktree created and subprocess forked

On each tick, the extension creates a per-distill git worktree under $XDG_CACHE_HOME/napkin-distill/<vault-hash>/<branch-suffix>/ (typically ~/.cache/napkin-distill/…). The current session is forked into the worktree’s .napkin/distill/ directory.
3

Detached subprocess spawned

A detached pi -p subprocess is launched with the distill prompt as its task. It runs entirely in the background — the wrapper uses bash with detached: true and unref() so it survives parent exit. NAPKIN_DISTILL_NO_RECURSE=1 is exported into the subprocess environment to prevent recursive distill spawning.
4

Agent distills, merges, squashes, and pushes

The distill agent runs the 9 steps of the distill prompt: it learns the vault structure, identifies what’s worth capturing, creates or appends notes, updates the daily note, then merges its distill branch into the default branch, squashes the result, and pushes to origin if configured.
5

JS-side polling and overlap notices

The JS side polls every 2 seconds for the worktree directory to disappear (which signals completion). On completion, if the agent wrote to files you’ve also touched in this session, pi-napkin posts an overlap notice into the conversation:
⚠️ Background napkin distill is editing files you've also touched: notes/foo.md.
Recent writes to these files may be overwritten or merged automatically at distill
completion; consider re-reading before further edits.
6

Session shutdown: final distill

When onShutdown: true (the default), the extension runs one final distill at session shutdown to capture anything the interval timer missed. The shutdown handler guards against double-spawning: if a distill is already in flight for this session size, it skips.

Enable auto-distill

napkin --vault ~/path/to/vault config set --key distill.enabled --value true

Config reference

KeyDefaultDescription
distill.enabledfalseMaster switch. Nothing auto-distill related runs when false.
distill.intervalMinutes60How often to fire a distill (in minutes).
distill.maxDurationMinutes10Hard wall-clock cap for each distill subprocess. Values ≤ 0 or non-finite fall back to 10 minutes.
distill.onShutdowntrueRun a final distill at session shutdown.
distill.model.provider"anthropic"Model provider for the distill subprocess.
distill.model.id"claude-sonnet-4-6"Model ID. Prefer a cheap, fast model — distill is automated, not interactive.

Status bar

While auto-distill is configured, the status bar shows live feedback:
StateStatus bar
Idle, counting downdistill: XmYYs (e.g. distill: 4m32s); seconds are zero-padded to two digits when minutes > 0, or just Xs when under a minute
Distill running● distill (with elapsed seconds updating every 2s)
Completed successfully✓ distill Xs
Completed with warning (local-only, no content)⚠ distill: local-only / ⚠ distill: no content
Error or timeout✗ distill: <reason>
Auto-distill paused for this sessiondistill: off (session)

What the distill agent does

The agent follows the 9-step prompt in extensions/distill/distill-prompt.md, covering knowledge capture (steps 1–6) and git integration (steps 7–9). The wrapper post-validates the result and cleans up the worktree after the agent exits.
1

Learn vault structure

Runs napkin overview and reads _about.md files to understand what each folder is for and what kinds of notes belong there.
2

Read templates

Runs napkin template list and napkin template read to learn the note formats used in this vault.
3

Identify what's worth capturing

Decides selectively what from the conversation deserves a note. Meta-discussion, raw tool output, and chatter are skipped — only knowledge useful to someone working on this project later is captured.
4

Search, create, or append notes

For each candidate note, runs napkin search for the topic. If an existing note already covers it, appends to that note instead of creating a duplicate. Creates new notes with napkin create (following the vault’s templates and folder structure). Adds [[wikilinks]] to related notes.
5

Update today's daily note

Appends a brief summary of key activities and decisions to today’s daily note in the relevant namespace (e.g. {namespace}/daily/YYYY-MM-DD.md), following existing patterns. Creates it if it doesn’t exist.
6

Add supersedes frontmatter

When a new note replaces an older one, adds supersedes: ["path/to/old.md"] frontmatter. A future janitor will archive the superseded note.
7

Merge default branch into distill branch

From the worktree, runs git -C <worktree> merge --no-edit <default>. If conflicts arise, the agent resolves them in place using the conversation history as context, then commits.
8

Squash to default branch

Squash-merges the distill branch into the vault’s default branch (git -C <vault> merge --squash <branch>) — one clean commit per distill, keeping history linear and easy to revert.
9

Push to origin

If origin/<default> is configured, pushes. On non-fast-forward failures, recovers via git pull --no-rebase origin <default> then re-pushes. Never uses --force or --force-with-lease. After the agent exits, the wrapper post-validates (no conflict markers, HEAD on default branch) and writes an outcome sidecar to <vault>/.napkin/distill/errors/ before removing the worktree.

Auto-init on first use

When distill.enabled: true is set on a vault that has no .git/ directory, pi-napkin automatically initializes git on the next session start:
  1. Runs git init
  2. Installs a managed .gitignore block (excludes .napkin/distill/ and Obsidian workspace files)
  3. Commits everything as napkin: initial vault commit (auto-distill setup)
  4. Notifies you once with the file count, an undo command (rm -rf <vault>/.git), and an opt-out hint (distill.enabled: false)
Auto-init is idempotent — re-running it on an already-initialized vault is safe and will only repair any drift in the managed .gitignore block.

Pausing for a session

To pause auto-distill for the current session only (for example, if you’re drafting sensitive content you don’t want captured):
/distill-auto-this-session off
Turn it back on with:
/distill-auto-this-session on
The pause state persists across pi restarts of the same session — if you close and reopen pi on the same session file, the suppression is remembered.
Auto-distill requires the subdir vault layout — the .napkin/ config directory must be a subdirectory of your vault root (distinct from the content root). If your vault uses the legacy embedded layout (config at <vault>/config.json with no .napkin/ subdir), you’ll see a migration notification at session start and auto-distill will be disabled for that session. Manual /distill continues to work on any layout. See vault migration for the migration steps.
The environment variable NAPKIN_DISTILL_NO_RECURSE=1 is exported into every distill subprocess by the wrapper. This prevents a distill agent from accidentally triggering another auto-distill recursively. If you find this variable set in your shell environment by accident, unset it and re-run — the wrapper falls back to normal behavior automatically.

Build docs developers (and LLMs) love