Generate a Claude Code Digital ID of yourself — written from Claude's point of view — by scanning all of your past Claude Code sessions.
The output is a self-portrait that captures your voice, working style, collaboration preferences, strengths, frictions, and current obsessions across every project you've worked on with Claude Code.
Scope: As shipped, this project reads from the Claude Code ecosystem specifically —
~/.claude/projects/*.jsonl,~/.claude/usage-data/, per-projectmemory/dirs, and the globalCLAUDE.md. It won't work out of the box against ChatGPT exports, Cursor history, Gemini CLI sessions, or any other LLM tool, because the data shapes and file locations are different.But the architecture is portable. Only
prepare.pyis Claude Code-specific — the scanner that walks the jsonl files and extracts user turns. Everything else (render.py, the 13-block schema, the profile.json contract, the 8 view modes, the placeholder fallbacks) is LLM-agnostic. If you want to build a ChatGPT Digital ID or a Gemini CLI Digital ID, fork this repo, rewriteprepare.pyfor your tool's data format, and the rest of the pipeline works unchanged. The only rule that needs to carry over is the core idea: the LLM in the chat writesprofile.jsonby hand, no API calls anywhere.
The document is built to do two things at once:
1. A mirror — discover yourself through Claude's eyes. After months of working together, Claude has a view of you that no other tool does: how you phrase things, how you push back, when you're frustrated vs. satisfied, what you keep starting, what keeps slowing you down. This project turns that view into a document you can actually read. It's the candid-colleague description you'd never write about yourself — affectionate, honest, a little blunt, and surprisingly accurate. The included "Roast" block is optional and can be toggled off, but exists for the same reason: seeing yourself described by someone who's been paying attention is genuinely clarifying.
2. A memory — give future-Claude a context anchor.
Every new session starts with Claude knowing nothing about you beyond your global CLAUDE.md. The Digital ID closes that gap. You have three ways to feed it back in, from lightest to heaviest:
- Paste
output/for-claude.mdonce, ever. It opens with an instruction block telling Claude to save each section to the correct memory type under~/.claude/memory/and to deduplicate against existing memory. After that one paste, every future session auto-loads the rules. This is the recommended workflow. - Reference
output/id.mdfrom a session (read output/id.md) when you want Claude to pull in the full directive half on demand, without costing tokens in sessions that do not need it. - Paste the Capsule block (block 1) into a one-off session as a lightweight system-prompt addendum.
The HTML viewer also exposes a dedicated FOR CLAUDE view mode with a COPY ALL button for the first workflow — see the Preview section.
Same document, two reading modes. You read it for insight; future-Claude reads it for context.
Screenshots below use a fictional sample profile (examples/sample-profile.json) of an invented engineer named "Sam Rivera." No real user data is shown. The same HTML supports 9 live view modes — click the buttons in the header to switch, or press m to cycle.
FOR CLAUDE — the mode that closes the memory loop. Transforms the whole document into for-claude.md with a one-time initialization block at the top, a COPY ALL button (red/orange pill), and the full content ready to paste into a new Claude session. Claude reads it once, saves each section to the correct memory type under ~/.claude/memory/, deduplicates against existing memories, and responds with a single confirmation line. After that one paste, every future session auto-loads the rules.
| Full | Card |
|---|---|
| Compact | Grid |
|---|---|
| Timeline | Terminal |
|---|---|
See examples/sample-profile.json for a reference implementation of the 13-block schema — useful if you're forking the project to adapt it to another LLM tool.
To regenerate the preview HTML locally (e.g., after tweaking render.py):
for MODE in full compact grid card timeline terminal for-claude; do
python render.py \
--profile examples/sample-profile.json \
--stats examples/sample-stats.json \
--out-md examples/preview/id.md \
--out-html examples/preview/id-$MODE.html \
--out-for-claude examples/preview/for-claude.md \
--default-mode $MODE
doneA three-phase pipeline, fully local, no API keys, no network calls:
-
prepare.py— deterministic Python. Walks your~/.claude/directory and reads:- Your global
CLAUDE.mdandmemory/files - Per-project
memory/dirs under~/.claude/projects/*/memory/ - All
CLAUDE.mdfiles in your repos directory (optional) - All pre-computed session facets and metadata under
~/.claude/usage-data/ - A stratified sample of your actual user turns from raw
.jsonlconversations - Interrupts (where you cut Claude off) and satisfaction signals (where you praised Claude)
It emits a compact
context/bundle.md(~150 KB) plus a structuredcontext/stats.json. - Your global
-
You ask Claude in-session to "refresh the ID" — Claude reads
bundle.mdandstats.jsonand writesoutput/profile.jsonby hand, filling in every block of the Digital ID with two voices: a directive voice (for future-you's Claude to follow) and a descriptive voice (for you to read).There is no Anthropic API call anywhere in this project. Claude-in-the-chat is the LLM in the loop. That's intentional: no cost, no keys, and you stay in full control of what the final text says.
-
render.py— deterministic templating. Readsprofile.json+stats.jsonand produces:output/id.md— primary markdown, directive voice, designed as context to paste into future Claude sessionsoutput/id.html— styled single-file HTML with a sidebar TOC, scroll-spy, keyboard shortcuts (1–9to jump to blocks,0for top), and 8 live view modes (full, compact, grid, card, timeline, focus, terminal, presentation) switched via a button bar — pressmto cycle.
Requires Python 3.10+. No third-party dependencies — only the standard library.
git clone <this-repo> claude-pov
cd claude-povcp config.example.json config.jsonEdit config.json:
{
"claude_root": "~/.claude",
"repos_dir": null,
"stratified_target": 200,
"turn_char_cap": 300,
"week_bucket_days": 7
}-
claude_root— where Claude Code stores your data. On Linux, macOS, and Windows this is~/.claudeby default. Only change it if you've moved your Claude Code data elsewhere. -
repos_dir— optional. Root folder containing your personal code repos (e.g.,~/dev/repos). If set,prepare.pyscans each subdirectory for aCLAUDE.mdfile and includes it in the bundle — this is how your per-project rules and conventions make it into the Digital ID. Leave asnullto skip entirely. -
stratified_target— how many of your past messages to sample for voice analysis. The scanner walks every user turn in every session, then picks a balanced subset stratified across (week × project).200is the default — enough to capture tone, phrasing, and recurring patterns without bloating the bundle that Claude has to read in-session.- Lower (e.g., 100) — faster, smaller bundle, thinner voice analysis.
- Higher (e.g., 400) — richer voice, larger bundle. Bump this if the first Digital ID feels too generic.
- Note: interrupts (moments you cut Claude off) and satisfaction signals (short praise messages) are collected in addition to this cap and are never truncated, because they're the highest-signal data.
-
turn_char_cap— max characters per sampled message. Long rants get truncated at this limit so no single message dominates the sample.300captures the tone and gist of most messages. Raise to500for richer quotes, lower to200for a leaner bundle. -
week_bucket_days— bucket size for stratified sampling. Default7means "one bucket per week." The scanner picks roughlystratified_target / (weeks × projects)messages from each bucket, ensuring every week of your history is represented evenly. A busy week doesn't drown out quieter ones. You rarely need to touch this.
Trade-off in one sentence: bigger sampling values produce a richer Digital ID but make bundle.md larger, which costs more of Claude's context when you ask for a refresh. The defaults are tuned for ~5–12 weeks of moderate Claude Code use.
-
Scan the data:
python prepare.py
This produces
context/bundle.mdandcontext/stats.json. -
Open a Claude Code session in this project and say:
refresh the ID
Claude will read
context/bundle.md+context/stats.jsonand writeoutput/profile.json. -
Render the outputs:
python render.py
This produces
output/id.mdandoutput/id.html. -
View: open
output/id.htmlin a browser. For the "initialize Claude's memory" workflow, pasteoutput/for-claude.md(or use theFOR CLAUDEview in the HTML and clickCOPY ALL) into a Claude Code session once.
Same three steps:
python prepare.py # 1. rescan latest data
# then in a Claude Code session: "refresh the ID"
python render.py # 3. re-renderprepare.py is cheap to re-run. The voice-writing step (Claude re-reading the bundle in chat) is where the real value gets regenerated — that's the whole point: it's you asking Claude to look at you again with fresh eyes.
The Digital ID has 13 blocks, defined by the schema contract in docs/SCHEMA.md:
- Capsule — one-paragraph persona, pasteable as a system-prompt addendum
- Operating Manual — explicit rules for Claude when working with you
- Voice & Writing Style — how you write, signature phrases, typo fingerprint, register signals
- Collaboration Preferences — session rhythm, plan-vs-execute, ping-pong discipline
- Identity & Role — who you are professionally
- Technical Fingerprint — languages, tools, stack (deterministic from session-meta)
- Strengths & Wins — patterns of things you do well
- Friction Patterns — recurring struggles + what Claude should do instead, with
resolved_bytags on frictions already mitigated - Current Obsessions — active projects, last N weeks
- Working Style & Rhythms — hour × day heatmap, session length distribution, totals
- Tools Already Built — inventory of custom skills, plugins, workflows, and memory files you've shipped to reduce friction
- Tools to Build — concrete proposals for new tools that would address unresolved frictions, cross-checked against block 11
- Roast — affectionate, evidence-anchored ribbing from the candid-colleague voice (opt-in, can be disabled)
Blocks without enough data become placeholders with encouraging "keep working, this block will fill itself in" text instead of being dropped. The schema enforces the full 13-block structure on every refresh.
This project generates deeply personal content. The outputs contain your name, your projects, quotes from your conversations, your collaboration style, and observations Claude has made about you.
All personal data stays local:
context/bundle.md— gitignoredcontext/stats.json— gitignoredoutput/profile.json— gitignoredoutput/id.md— gitignoredoutput/id.html— gitignoredconfig.json— gitignored (contains your machine paths)
Only the source code (prepare.py, render.py, config.example.json, CLAUDE.md, docs/SCHEMA.md, README.md, LICENSE, .gitignore) is meant to be committed. Everything your Digital ID contains is yours — keep it local, or share deliberately.
- No LLM SDK integration by design. The final "voice" layer is written by Claude in your chat session, not by an API call. This keeps the project free, keyless, and keeps you in the loop on every refresh.
profile.jsonis the stable contract between the Claude-in-session phase and the renderers. If you change the schema, update bothrender_md()andrender_html()inrender.py.- Stats and voice are kept separate. Deterministic numbers (heatmap, top languages, totals) live in
stats.jsonand are rendered directly. Narrative paragraphs live inprofile.jsonand are written by Claude. The renderers merge them at the last step. - Sampling is capped deliberately.
prepare.pynever dumps full conversation bodies intobundle.md. It reads every user turn, stratifies by (week × project), and truncates each sample to a fixed char cap. Interrupts and satisfaction signals are collected separately and uncapped because they're high-signal.
Claude Code's built-in /INSIGHTS is a 30-day workflow check-in that produces a performance report with CLAUDE.md improvement suggestions. claude-pov is a lifetime-scoped persona document written in Claude's voice, designed to be fed back into future sessions as context — the two are complementary, run both.
This project was designed and built collaboratively with Claude Opus 4.6 in Claude Code. Unusually for a Claude Code project, Claude is also the runtime: every narrative block of your generated Digital ID — the Capsule, Operating Manual, Voice & Writing Style, Friction Patterns, Roast, all of it — is written by Claude in your chat session. No API calls, no SDK, no third-party LLM. The project is both about Claude reading you and made by Claude writing itself. Credit where it's due.
MIT. Do whatever you want with the code. Your generated Digital ID is yours.