← Docs hub

Configuration

Every tuning knob in llmwiki, explained.

Config file

Copy the default config and edit it:

cp examples/sessions_config.json config.json

config.json is gitignored so your settings stay local. The converter auto-loads it if present.

Minimal config:

{
  "redaction": {
    "real_username": "your-unix-username",
    "replacement_username": "USER"
  }
}

Replace your-unix-username with the output of whoami. The converter uses it to scrub paths like /Users/<name>/… or /home/<name>/… before writing to raw/.

Full schema

{
  "filters": {
    // Skip sessions with a record younger than this many minutes.
    // Prevents the converter from reading a .jsonl mid-write.
    "live_session_minutes": 60,

    // If non-empty, only convert projects whose slug matches one of these.
    "include_projects": [],

    // Skip projects whose slug contains one of these substrings.
    "exclude_projects": [],

    // Record types to drop entirely (noise / hook progress / queue ops)
    "drop_record_types": [
      "queue-operation",
      "file-history-snapshot",
      "progress"
    ],

    // Skip automated / headless agent launches (default on). Claude: SDK
    // entrypoint / promptSource; Cursor Agent CLI: subagentInfo or
    // approvalMode=auto-review; OpenClaw: never skipped. Applies at ingest
    // and synthesis. See docs/multi-agent-setup.md § automated.
    "exclude_headless": true,

    // Skip sessions whose cwd is a throwaway temp dir (/tmp, /var/folders,
    // …). Default OFF: a git worktree under /tmp is often real work, so we
    // don't silently drop it. Turn on only if your temp dirs hold nothing
    // but e2e/scratch junk.
    "exclude_temp_cwd": false

    // Optional shared sync lookback as absolute YYYY-MM-DD (#192).
    // Omit (default) = unlimited history. Per-adapter override:
    // adapters.<name>.since as YYYY-MM-DD, or "all" for no date gate.
    // CLI --since overrides both for one run. See configuration-reference.md.
    // "since": "2026-07-31"
  },

  "redaction": {
    // Your OS username. Paths like /Users/<you>/ become /Users/USER/.
    // Auto-detected from $USER if left empty.
    "real_username": "",

    // What to replace real_username with.
    "replacement_username": "USER",

    // Additional regexes to redact (Python re syntax).
    // Anything matching → "<REDACTED>".
    "extra_patterns": [
      "(?i)(api[_-]?key|secret|token|bearer|password)[\"'\\s:=]+[\\w\\-\\.]{8,}",
      "sk-[A-Za-z0-9]{20,}",
      "[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+"
    ]
  },

  "truncation": {
    // Max chars per tool result before truncation.
    "tool_result_chars": 500,

    // Max lines from a Bash stdout before truncation.
    "bash_stdout_lines": 5,

    // Max lines from a Write tool content preview.
    "write_content_preview_lines": 5,

    // Max chars per user prompt.
    "user_prompt_chars": 4000,

    // Max chars of assistant text rendered in the markdown body.
    "assistant_text_chars": 8000
  },

  // Drop <thinking> blocks from assistant messages entirely.
  // These are verbose and often redundant with the visible response.
  "drop_thinking_blocks": true,

  // Per-adapter config. Optional since: YYYY-MM-DD override or "all" (no date gate).
  "adapters": {
    "obsidian": {
      "vault_paths": ["~/Documents/Obsidian Vault"],
      "exclude_folders": [".obsidian", "Templates", "_templates", ".trash"],
      "min_content_chars": 50
    }
  }
}

Synthesis backend

llmwiki synth turns each raw session/document into a wiki/sources/ page. Which LLM (if any) writes those pages is picked by synthesis.backend in config.json. Per-engine settings live in nested blocks (synthesis.claude, synthesis.cursor_cli, synthesis.ollama); legacy flat claude_* / Ollama keys still work as fallbacks. Override the backend for one run with llmwiki synth --backend <name> (does not write config.json).

{
  "synthesis": {
    // "dummy" (default) | "ollama" | "claude" | "cursor_cli"
    "backend": "cursor_cli",
    "cursor_cli": { "model": "composer-2.5", "timeout": 180 },
    "claude": { "model": "sonnet", "lean": true },
    "ollama": { "model": "llama3.1:8b" }
  }
}
Backend What it does Needs
dummy Canned stub page: metadata summary, one [[ProjectEntity]] link, plain-text ## Raw Mentions. For previews/tests. nothing
ollama Local LLM over the Ollama HTTP API. Configure synthesis.ollama.{model,base_url,timeout,max_retries} (flat legacy keys still work). running ollama serve
claude Synchronous claude -p CLI calls (#16). Prefer nested synthesis.claude.{model,path,timeout,lean,effort}; flat claude_* keys remain as fallbacks. Default model sonnet. claude on $PATH (or synthesis.claude.path / claude_path)
cursor_cli Synchronous Cursor Agent CLI (agent -p / cursor-agent) (#230). Nested synthesis.cursor_cli.{model,timeout} only (default model composer-2.5). Binary from $PATH — no path key. Lean flags: -p, --mode ask, --sandbox enabled, --allowed-tools truncated_tool_call (shrinks tool schemas; still no empty system-prompt / empty-MCP switch). agent or cursor-agent on $PATH, authenticated

Not the same as session ingest. synthesis.backend: cursor_cli is the generator that writes wiki pages. The contrib adapters cursor_cli (Agent CLI chats under ~/.cursor/chats/) and cursor_ide (IDE Composer / state.vscdb) only ingest transcripts into raw/ — configuring one does not select the other.

Claude calls run in lean mode by default: tool schemas, MCP servers, skills, CLAUDE.md, and the agent system prompt are stripped from each invocation, since a synthesis call only reads stdout and can't use any of them. That is ~9x cheaper per page, measured — see reference/synthesis-cost.md for the numbers and for why the Claude default model is sonnet rather than a cheaper model. Set "lean": false under synthesis.claude (or flat "claude_lean": false) to opt out. Cursor's lean set is ask + sandbox plus a tiny --allowed-tools allowlist (~25–30% less prompt than the full tool catalog on Composer); the agent system prompt still cannot be emptied for normal accounts.

The old agent / agent_delegate backend (pending-prompt files + --list-pending / --complete) was removed in v1.4.0 — use claude or cursor_cli instead.

Sanity-check what's active and what a run would cost:

llmwiki synth --check                    # prints the resolved backend + availability
llmwiki synth --estimate                 # cached-vs-fresh token + dollar estimate (+ candidate backlog)
llmwiki synth --backend cursor_cli --estimate   # one-run backend overlay (no config write)
llmwiki synth --sessions-only            # pending sessions only (skip docs)
llmwiki synth --docs-only                # pending docs only (skip sessions)

Synthesis is incremental. <vault>/llmwiki-state.json (synth.files) records an mtime per raw file; a nightly sync/synthesize only processes files that are new or changed since the last run — the daily LLM bill is proportional to new content, not to corpus size. --force re-runs everything (use after switching backends, e.g. to replace dummy-stub pages with real ones — pages with only stub links produce a topic graph with no edges).

Downgrade protection: dummy is the resolved default when synthesis.backend is unset (or a typo — unknown values warn and fall back), so a --force run in that state used to overwrite every real page with link-free stubs and silently empty the knowledge graph. The pipeline now refuses that downgrade: stub output is never written over a real page, even under --force — such pages are reported as protected in the run summary. To deliberately re-synthesize a real page, delete it first. (An unavailable backend does not fall back — the run aborts with an error.)

Environment variables

Variable What it does
LLMWIKI_CONFIG Override the config file path. Defaults to ./config.json then examples/sessions_config.json.

Vault content root is vault.default_path in config.json (not an env var). The removed LLMWIKI_ROOT env var is no longer read.

CLI flags

llmwiki sync

python3 -m llmwiki sync [options]

--adapter <name...>       Only run the named adapter(s); default: all available
--since YYYY-MM-DD        One-run lookback (overrides filters.since / adapters.*.since)
--project <substring>     Only sync projects whose slug contains this substring
--include-current         Don't skip live (<60 min) sessions
--force                   Ignore the state file; reconvert everything
--fail-on-errors          Exit 1 if any file fails to convert
--vault PATH              Write into an external vault (also sets active state file)
--status                  Show last-sync + counters + quarantine (no sync)

Per-file conversion errors do not fail the run by default: each one is counted in the summary, recorded in llmwiki-state.json quarantine entries, and visible via llmwiki sync --status, while the rest of the corpus still converts. Pass --fail-on-errors for a hard gate (CI, scripted pipelines that must not proceed past a partial sync).

There is no sync --dry-run — use add --dry-run for document intake previews, or inspect with sync --status / synth --estimate.

Durable lookback (optional): set filters.since to an absolute YYYY-MM-DD in config.json, or adapters.<name>.since to a date / "all" (no date gate for that source). Unset = unlimited history. llmwiki configure-sources asks the shared date first (default today−30) and shows Sessions · Earliest · In last 30 days per source before Enable. See configuration-reference.md — Sync lookback.

llmwiki build

python3 -m llmwiki build [options]

--out <dir>               Output directory; default: ./site
--synthesize              Call the `claude` CLI once to generate an Overview
--claude <path>           Path to the claude binary; default: /usr/local/bin/claude
--local-root <path>       Value shown in place of a session's stored home directory;
                          default: this machine's home directory

llmwiki init

No options. Scaffolds raw/, wiki/, site/ and seeds wiki/index.md, wiki/log.md, wiki/overview.md.

llmwiki adapters

No options. Lists every registered adapter and whether its session store is present on the current machine.

.llmwikiignore

Gitignore-style file at the repo root. One pattern per line. Sessions matching any pattern are skipped during sync.

Example:

# Skip a whole project
confidential-client/*

# Skip anything before a date
*2025-11-*

# Skip a specific session
ai-newsletter/2026-04-04-*secret*

Adapter configuration

Claude Code

Default session store: ~/.claude/projects/

Override via the adapter config block (above).

Obsidian

Default vault locations checked:

  1. ~/Documents/Obsidian Vault
  2. ~/Obsidian

Override in config.json:

{
  "adapters": {
    "obsidian": {
      "vault_paths": [
        "~/Documents/Obsidian Vault",
        "~/work/second-vault"
      ],
      "exclude_folders": [".obsidian", "Templates"],
      "min_content_chars": 100
    }
  }
}

Files smaller than min_content_chars are skipped (mostly empty notes).

Codex CLI

Production core adapter. Default roots: ~/.codex/sessions and ~/.codex/projects. Override with adapters.codex_cli.roots. Included on a bare llmwiki sync when a root exists. Full detail: adapters/codex-cli.md.

Which agents + what “automated” means

Support map, core vs contrib (--adapter opt-in), Cursor Agent CLI vs IDE, and per-source headless rules: multi-agent-setup.md.

Changing the theme

Theme colours live in llmwiki/build.py inside the CSS string constant, under the :root block. The main tokens:

--accent: #7C3AED;     /* primary accent (purple) */
--accent-light: #a78bfa;
--accent-bg: #f5f3ff;

Change these and rebuild. The dark-mode variants auto-derive unless you override them too.

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date