Institutional knowledge on your filesystem.
lore manages personal knowledge vaults and shared team libraries backed by markdown and git. It handles the plumbing — subscriptions, publishing, search, graph traversal, and agent-driven maintenance — so your editor and your LLM agent can focus on the content.
A persistent daemon indexes your vault and libraries into SQLite (FTS5 for BM25-ranked search, typed graph edges for relationship traversal). Query from the CLI, a terminal UI, or let your agent use it as a knowledge backend.
go install github.com/gregbuehler/lore@latestOr build from source:
git clone https://github.com/gregbuehler/lore.git
cd lore
go install ./...lore vault init ~/vault
cd ~/vaultThis creates a personal vault with .lore/config.yaml and the default directory structure. If you already have an Obsidian vault or markdown directory:
lore vault init --adopt ~/my-existing-vaultlore subscribe git@git.example.com:team/services.gitOr subscribe to a local directory:
lore subscribe /path/to/library --localIf the lore content lives inside a normal project repository, subscribe with an explicit root:
lore subscribe git@github.com:gregbuehler/citizen.git --root docsexport LORE_VAULT=~/vault
lore daemon startThe daemon watches your vault and libraries, maintains a SQLite FTS5 index, and serves queries over a Unix socket. It auto-starts on first query if LORE_VAULT is set.
To auto-start at login:
lore daemon install # macOS launchd or Linux systemd --userlore query "gateway mTLS" # BM25 full-text search
lore query --graph Wiki/Services/gateway # outgoing graph edges
lore query --backlinks Wiki/Services/gateway # incoming references
lore context Wiki/Services/gateway --brief # assembled LLM context
lore ui # terminal UIlore vault contextThis writes .lore/LORE.md with your library subscriptions, skills, and workflows, and imports it into .claude/CLAUDE.md so Claude Code sees everything on session start.
For Codex-based vaults, the same generated .lore/LORE.md is imported from AGENTS.md.
lore vault status # see what you're subscribed to
lore search "authx mTLS" # raw grep-style markdown search
lore library skills # list available skillsVaults are personal. Your notes, daily logs, drafts, and context. A vault is a directory of markdown files with .lore/config.yaml. Your agent works here.
Libraries are shared. Team knowledge bases that anyone can subscribe to. Each library is a git repo (or local directory) containing Wiki pages, skills, and a library.yaml schema. Subscribing clones it locally; your agent reads it as local markdown alongside your vault. By default the library root is the repository root; use --root docs when the lore content lives in a subdirectory of a larger project repo.
Skills are procedural knowledge curated in libraries. They encode retrieval paths — not facts, but how to find out. When a library has a skill like deployed-versions, any agent with access to that library knows how to answer "what versions are deployed on staging?" without re-deriving the answer path.
Excerpts are self-descriptions that libraries publish. Each library generates an excerpt.md summarizing its pages, skills, and sources. lore vault context assembles these excerpts into your vault's agent context — so libraries own their own descriptions and the vault doesn't need to parse library internals.
See docs/commands.md, generated from the Cobra command tree. Refresh it with:
lore docs commands docs/commands.mdThe lore daemon is a lightweight background process that provides fast search and graph queries:
┌─────────────┐ Unix socket ┌──────────────────────┐
│ lore query │ ───────────────────── │ lore daemon │
│ lore ui │ length-prefixed JSON │ │
│ agent │ │ fsnotify watcher │
└─────────────┘ │ SQLite FTS5 index │
│ typed graph edges │
└──────────────────────┘
- Index: SQLite with FTS5 virtual table for BM25-ranked full-text search
- Graph:
edgestable storing typed relationships (owner, depends_on, deployed_in, mentions) extracted from wikilinks in section context - Watcher: fsnotify-based recursive file watching with 500ms debounce
- Resolver: Obsidian-style shortest-path wikilink resolution (folder expansion, proximity ranking, ancestor walking)
- Protocol: Length-prefixed JSON over Unix socket (
~/.local/share/lore/daemon.sock, orLORE_SOCKET)
The daemon auto-starts on first query when LORE_VAULT is set. All CLI commands fall back to direct SQLite access if the daemon is unavailable.
my-library/
library.yaml # schema, tone rules, TTLs, sources, skills
CLAUDE.md # agent instructions for this library
excerpt.md # self-description (generated by lore library index)
Wiki/
index.md # navigation index (generated)
Services/ # entity pages grouped by type
gateway.md
storage.md
skills/
deployed-versions.md # procedural knowledge
sources/
incoming/ # contributor drop zone
log.md # activity log
name: "services"
description: "Platform service knowledge"
publishing: pr-required
tone:
voice: third-person
prohibited:
- personal characterizations
required:
- factual sourcing
default_ttl:
service: 90d
environment-config: 14d
skills:
- name: deployed-versions
file: skills/deployed-versions.md
description: Look up deployed software versions
sources:
- repo: git.example.com/myorg/deployment
local: ~/src/git.example.com/myorg/deployment
watch:
- path: deployments/{entity}/**
maps_to: environmentA skill is a markdown file in skills/ with frontmatter and a step-by-step procedure:
---
name: deployed-versions
description: Look up deployed software versions
trigger: "what versions are deployed on {environment}"
inputs:
- name: environment
required: true
---
# Deployed Versions
## Fast Path: Service Catalog
...
## Detailed Path: Source Repos
...Skills teach agents how to answer questions, not what the answer is. The library's CLAUDE.md references skills so agents discover them automatically.
lore's maintenance system turns raw evidence into synthesized library knowledge:
Daily Logs ──→ lore library review ──→ surface new evidence
→ lore library maintain ──→ agent synthesizes into pages
Source Repos ──→ lore library watch ──→ agent updates pages from IaC changes
Sync ──→ lore sync ──→ pull all libraries + reindex
Push ──→ lore publish ──→ commit+push pending changes to library repos
- Scans daily log files for entity mentions newer than each page's
last_updated - Matches mentions using entity names and aliases (word-boundary-aware)
- Assembles a context package: current page + new evidence + tone rules + format rules
- Invokes the configured agent to rewrite the page
- Cleans up the context package and rebuilds indexes
- Reads
sources:fromlibrary.yaml— repos and path patterns to track - Maps entities to repo directories using
{entity}placeholders and inventory data - Runs
git log --since=<last_updated>to find relevant commits - Assembles a context package with commits, authors, file lists, and instructions
- Invokes the agent to synthesize changes into the page
Maintenance commands use agent.provider to decide how agent work is executed. Shared defaults live in .lore/config.yaml; machine-local preferences can live in .lore/local.yaml, so the same synced vault can use Codex at home and Claude at work without editing the shared config.
| Provider | Behavior |
|---|---|
claude |
Run Claude non-interactively with claude -p <prompt>. |
codex |
Run Codex non-interactively with codex exec, send the prompt on stdin, and pass --cd <workdir>. Sandbox and approval settings are configurable. |
custom |
Run a user-supplied command for sites that wrap or proxy an agent. Requires an explicit agent.command. |
none |
Do not invoke an agent; commands stop before synthesis. |
Dangerous permission bypass is always opt-in. When enabled, lore maps it to the provider-specific dangerous flag, such as Claude's --dangerously-skip-permissions or Codex's equivalent unsafe bypass flag. Leave it disabled for normal local or CI maintenance.
Agent selection precedence is:
- Command flag, for example
lore maintain services --agent codex - Environment, for example
LORE_AGENT_PROVIDER=codex - Machine-local
.lore/local.yaml - Shared
.lore/config.yaml - Backward-compatible default: Claude
Example .lore/local.yaml for a Codex machine:
agent:
provider: codex
command: codex
sandbox: workspace-write
approval: neverGenerate those local overrides with:
lore agent local codex
lore agent local claude
lore agent local none
lore agent local statuslore agent local only generates built-in provider configs. For custom,
edit .lore/local.yaml manually and include agent.command plus optional
agent.args.
When a library is a git repo, maintenance runs as GitHub Actions:
on:
schedule:
- cron: '0 6 * * 1'
workflow_dispatch:
jobs:
maintain:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: lore library watch my-library
- run: lore library lint my-library --fix
- run: lore library index my-library
- uses: peter-evans/create-pull-request@v6lore vault lint checks vault pages. lore library lint checks library pages with additional rules:
| Check | Vault | Library | Fixable |
|---|---|---|---|
| Missing frontmatter | yes | yes | yes |
| Empty files | yes | yes | no |
| Missing entity_type | yes | no | |
| Stale pages (TTL) | yes | no | |
| Stale index | yes | no | |
| Local filesystem paths | yes | yes | |
| Section names | yes | yes | |
| Change log format | yes | yes | |
| Required sections | yes | no | |
| Frontmatter field order | yes | no |
lore generates context so your agent understands the knowledge system:
.lore/LORE.md ← generated library/skills discovery
.claude/CLAUDE.md ← Claude vault operating manual
@../.lore/LORE.md ← import: generated context
AGENTS.md ← Codex vault operating manual
@.lore/LORE.md ← import: generated context
Library CLAUDE.md ← per-library agent instructions
excerpt.md ← per-library self-description
Run lore vault context after subscribing to new libraries or adding skills. It regenerates .lore/LORE.md and wires imports idempotently. By default, it updates existing provider context files (.claude/CLAUDE.md and/or AGENTS.md); if none exist, it falls back to the effective agent provider. Use --agent claude, --agent codex, --agent all, or --agent none to be explicit.