lore
Wrapped for your coding agents: a local recap of your Claude Code, Codex, Gemini CLI and other agent history.
Quick start • Privacy • What it reads • Usage • Development
Quick start
npx -y lore-wrapped
-y skips npx's "Ok to proceed?" question. Needs Node 22.13+. Reads the agent history already on your machine and opens your report on 127.0.0.1. No account, and no model calls unless you ask.
npx.cmd lore-wrapped # Windows PowerShell (its default policy blocks npx.ps1)
bunx lore-wrapped # or: pnpm dlx lore-wrapped
npx github:julianramey/lore-wrapped # straight from GitHub, built on your machine
To read the code first: git clone https://github.com/julianramey/lore-wrapped && cd lore-wrapped && npm install && npm start.
What you get
- Your card: one of 14 in the lore deck, dealt from how you work, with a four-letter code.
- Your twin: the builder whose way of working points the same way as yours.
- Since your last run: new prompts, new projects, and whether your card changed.
- Share cards: posts and stories with counts and your card. No code, quotes or project names.
- The year: every day as a contribution graph, by agent.
- The records: longest streak and session, busiest day, latest night, and rock bottom.
- The branches: your projects as a git graph.
- Your models: the models that did the most work, what each cost, and how often you redirected it.
- The bill: what your tokens would cost at API prices, next to what your plans cost. You guess first.
- In your words: your most repeated prompt, your most used word, and the swear jar.
- Where you rank: your Claude Code spend per day against Anthropic's published numbers, then the lore index.
- The lore: moments you forgot, from the first prompt of every project to the file that wouldn't die.
- The deep dive: seven spectra, agent hours, lines, languages and commands, each with its definition.
- Versus a friend: swap short codes and see how in sync you are. No server involved.
- The data: every number behind the report, and a calendar reminder for the 1st of the month.
Privacy
| What | Where it goes |
|---|
| Your history: prompts, replies, code, paths, project names | Stays on your machine, except what the optional story sends when you click it and the sessions you tick and send (below). Parsed copies are cached in ~/.lore, readable only by you. The report runs on 127.0.0.1 and opens from a one-time link. |
| Anonymous counts (every field below) | Sent to lore's collector when you run lore. Running it again the same month doesn't send again. Nothing runs in the background. |
| Run counts | Each run that opens a report sends up to three one-line pings to lore's collector: {"v":"0.5.1","os":"darwin","stage":"start"} when it starts, then the same with "scanned" when the scan finishes and "report" when the page opens. That's the whole body: lore's version, your OS family and how far the run got. No id. The collector only adds one to a count per day, version, OS and stage. --json and the subcommands don't send it, and everything below that turns stats off turns this off too. |
| Repo stats (off unless you turn them on) | Only after npx lore-wrapped stats repos on: counts across the repos your agents edited, with no names, paths, URLs or authors. |
| The public index | Downloaded from lore's collector (GET /v1/index) when the report opens, to rank you on your machine. Nothing about you is sent. It still happens with stats off; --offline skips it. |
| The optional written story | Only when you click for it, through your own Claude or Codex CLI on your own plan. It gets lore's numbers, your top project names, and up to 8 short prompt excerpts and 5 phrases you repeat, with secrets, emails, URLs and paths redacted. For Codex, lore also reads your plan's rate-limit window before and after (via codex app-server) to show what the call cost. |
| Checking your sessions | Nothing runs until you click Check my sessions and give your email. lore then finds, on your machine, the sessions where you corrected an agent and it can rebuild your code before and after, and keeps them in ~/.lore/episodes. Your email goes to lore's collector with a few totals and no code or names: how many sessions you have, how many count, how many repos of each kind, and their size. A random token stays on your machine so only it can update those totals; the collector keeps its sha256. |
| Sessions you choose to send, including code | Only the sessions you tick, after you tick the consent box and click Send: your prompts and corrections (redacted), the agent's replies, the commands that ran, and your repo's code at each correction and after, as a git bundle of trimmed states with no history or authors. A session from a public repo goes as its URL and commits instead, without code. Each carries a consent record bound to the sha256 of its exact bytes. lore won't license or sell any of it without contacting you first. Work and shared repos are never offered, and sessions where a password or key survived redaction stay on your machine. or deletes them. |
Why the counts: they rank you (the report downloads the public index and compares on your machine) and build the public lore index. No account or install id, no IP kept, and raw rows are never published or sold.
The server: you can't inspect a server from your machine, so its code is public. collector/ is exactly what runs at api.lore-wrapped.com, a Cloudflare Worker (src/index.ts). It stores each payload with the month it arrived (raw rows kept 13 months) and counters. A run count is only ever a counter: one more for that day, version, OS and stage. Every 10 minutes it rebuilds the index from the counters, published only from 25+ runs, with a new snapshot only after 25+ new runs. A refused payload isn't kept: it only adds one to a count of refusals by month and the first field that failed. No IPs or user agents are stored, and no raw row is ever published or sold. Sessions you send land in their own bucket; the collector checks every byte against the sha256 you approved, sweeps them again for secrets and emails, and keeps the contributor's email in its own table, never joined to the stats. Tests are in collector/test.
Turn it off:
npx lore-wrapped stats # print this run's exact payload
npx lore-wrapped stats off # stop sending stats and run counts, on every run (stats on to resume)
npx lore-wrapped --offline # nothing leaves the machine: no stats, no index, no model calls, no emails or sessions
Also off with --no-stats, DO_NOT_TRACK=1, LORE_NO_STATS=1, or Claude Code's DISABLE_TELEMETRY and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC. CI never sends, and neither do piped runs, unless a coding agent is running lore for you (Claude Code, Codex, Gemini CLI, Qwen Code, OpenCode and Kilo mark the commands they run).
Every field: the collector rejects anything not on this list. node scripts/readme-fields.ts writes this table from src/pipeline/indexAgg.ts, and a test fails if the code sends a field that isn't here.
| Field | What it is |
|---|
schema | which version of this list the payload follows |
client | the lore version that sent it |
sources | which agents you use (Claude Code, Codex, …), no versions or accounts |
history_months | how many months of history lore could read |
threads | how many conversations |
prompts | how many prompts you sent |
active_days | how many days you used agents |
projects | how many projects (just the number, no names) |
median_prompt_words | how many words a typical prompt runs |
steer_rate | the share of your follow-ups that redirect the agent |
approval_rate | the share of your follow-ups that are short approvals (“yes”, “go”) |
interrupts_per_100 | how often you stop an agent mid-turn, per 100 prompts |
night_share | the share of prompts sent between 10pm and 4am |
weekend_share | the share of prompts sent on weekends |
model_share | which model families did your work, as rounded shares |
steer_themes | what your redirects are about, from a fixed list (“it’s broken”, “simplify”…) |
steer_by_model | how often each model family gets redirected |
intents | what opening prompts ask for, from a fixed list (fix, build, explain…) |
archetype | your card in the lore deck |
type_code | your four-letter code |
agent_hours | hours agents worked for you, as timed in your history |
lines_added | lines agents wrote |
high_effort_share | the share of agent turns at the highest effort setting |
Audit us: paste this into Claude Code, Codex or any agent you trust.
Audit the npm package lore-wrapped before I run it. Assume it might be lying to me.
1. Get the code without running it: `npm pack lore-wrapped`, then unpack the .tgz into a scratch folder (or clone its GitHub repo).
2. Find every network call (fetch, http, https, net, dns, WebSocket, and any child process that could reach the network) and every file it reads or writes outside that folder.
3. For each one: what data, sent where, when, and what triggers it.
4. Compare that with the Privacy section of the package's README.md and flag anything it sends that isn't listed there. What the server does with it is in the GitHub repo's collector/ folder.
5. Run `npx lore-wrapped stats` and check that the printed payload is all the code would send.
6. Rate each finding none, low, medium or high risk, then give me a one-line verdict: is it safe to run, and what should I turn off?
What it reads
| Agent | Location | Notes |
|---|
| Claude Code | ~/.claude/projects/*/*.jsonl | SDK-driven sessions excluded; subagents/ read for token counts and time only |
| Claude Code prompt history | ~/.claude/history.jsonl | Never cleaned up, so sessions Claude deleted after 30 days come back as prompts-only threads, with no agent time on record (agent hours show as a floor, plus an estimate) |
| Claude Code stats | ~/.claude/stats-cache.json | Tokens by model and day, for days whose transcripts are gone |
| Claude plan | ~/.claude.json | Only the plan type and rate-limit tier, for the plan cost, and firstStartTime, for when you started |
| Claude Desktop Code | ~/Library/Application Support/Claude/claude-code-sessions | Joined to the CLI transcript by cliSessionId; Windows and Linux app data too |
| Codex (CLI, IDE, desktop) | ~/.codex/sessions, archived_sessions | Subagents read for token counts and task times only; exec/SDK runs excluded |
| Gemini CLI | ~/.gemini/tmp/*/chats/session-*.json[l], logs.json | Messages folded by id; deleted chats come back as prompts from logs.json |
| OpenCode | ~/.local/share/opencode/opencode*.db, storage/ | Read-only SQLite, plus the pre-1.2 JSON tree; child sessions for token counts only |
| Kilo CLI | ~/.local/share/kilo/kilo*.db | OpenCode's format |
| GitHub Copilot CLI | ~/.copilot/session-state/*/events.jsonl | Tokens from each session's running totals |
| Qwen Code | ~/.qwen/projects/*/chats/*.jsonl | Usage from assistant records only |
| Pi | ~/.pi/agent/sessions/*/*.jsonl | Branches and forks counted once by entry id |
| OpenClaw | ~/.openclaw (or ~/.clawdbot, ~/.moltbot): agents/*/agent/openclaw-agent.sqlite, |
Each path honors the agent's own override: CLAUDE_CONFIG_DIR, CODEX_HOME, GEMINI_CLI_HOME, OPENCODE_DATA_DIR, KILO_DB, COPILOT_HOME, QWEN_HOME, PI_CODING_AGENT_DIR, OPENCLAW_STATE_DIR, XDG_DATA_HOME.
On Windows lore also reads WSL distros, and inside WSL your Windows profile (--no-wsl skips both). Main threads only: hidden reasoning, tool output and injected context never enter the report, and forked history counts once.
Usage
npx lore-wrapped # scan, then open the report
npx lore-wrapped stats # print the exact anonymous payload
npx lore-wrapped stats off|on # stop or resume sending it, on every run
npx lore-wrapped stats repos on # also send repo counts (repos off to stop)
npx lore-wrapped manifesto # what lore is for
npx lore-wrapped episodes withdraw <id>|all # withdraw sessions you sent
npx lore-wrapped --json # the full report as JSON; nothing is sent
# Options
--offline # nothing leaves the machine: no stats, no index, no model calls, no emails or sessions
--no-stats # don't send stats this run
--no-ai # never call a model
--no-open # don't open a browser
--no-anim # plain output, no terminal animation
--port <n> # port for the local report (default: random)
--endpoint <url> # where stats go and the index comes from
--no-wsl # on Windows, don't look inside WSL distros
-v, --version
-h, --help
Installed globally (npm i -g lore-wrapped), the command is also lore. The link lore prints opens the report in one browser; run lore again for a fresh one. Over SSH, lore prints the link and an ssh -L line instead of opening a browser.
Why it's fast
21 GB of history in about 3 seconds, under a second once cached.
- Skips most bytes: files stream as raw bytes, and only the first 768 bytes of a line decide whether it gets parsed.
- Uses every core: files parse in a
worker_threads pool.
- Remembers: threads are cached by file size and mtime, so a second run rereads only what changed.
- Plain code: the analysis is rules over counts. No model runs unless you ask for the story.
Node API
import { scan, buildReport } from 'lore-wrapped'
const { report } = buildReport(await scan())
console.log(report.archetype.name, report.deep.work.agentHours)
The same local pipeline the CLI runs. Nothing in it sends data.
Development
git clone https://github.com/julianramey/lore-wrapped && cd lore-wrapped
npm install # installs and builds
npm test # node --test over the TypeScript sources
npm run typecheck
npm start # node dist/cli.js; npm start -- stats passes flags
node scripts/personas.ts # simulated users, every agent format
src/sources/ one adapter per agent, and where each keeps history
src/pipeline/ scan, classify, facts, deep, spend, deck, lore, stats
src/terminal.ts the live terminal pane
src/server/ the local report server
web/ the report UI (Preact)
scripts/ build, the README field table, simulated users
test/ node --test suites
collector/ the stats and sessions API at api.lore-wrapped.com, a Cloudflare Worker, and its tests
Coming next
Get paid when AI labs want tasks from your history. npx lore-wrapped manifesto has the plan.
License
MIT. Questions, or lore for your team: [email protected]