Skip to content

ohadellis/claude-pov

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

claude-pov

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-project memory/ dirs, and the global CLAUDE.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.py is 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, rewrite prepare.py for 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 writes profile.json by hand, no API calls anywhere.

Two purposes

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.md once, 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.md from 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.

Preview

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.

The one that matters most

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.

FOR CLAUDE mode — COPY ALL button, one-time init instructions, memory-type mapping, full content ready to paste

The other eight modes

Full Card
Full mode — sidebar TOC, 13-block card stack, refresh bar, mode switcher Card mode — one-page trading-card summary with top strengths, frictions, projects, voice
Compact Grid
Compact mode — collapsed block titles, click to expand Grid mode — 3-column dashboard tile overview
Timeline Terminal
Timeline mode — vertical spine with block dots Terminal mode — green-on-black monospace retro aesthetic

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
done

What it is

A three-phase pipeline, fully local, no API keys, no network calls:

  1. prepare.py — deterministic Python. Walks your ~/.claude/ directory and reads:

    • Your global CLAUDE.md and memory/ files
    • Per-project memory/ dirs under ~/.claude/projects/*/memory/
    • All CLAUDE.md files 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 .jsonl conversations
    • Interrupts (where you cut Claude off) and satisfaction signals (where you praised Claude)

    It emits a compact context/bundle.md (~150 KB) plus a structured context/stats.json.

  2. You ask Claude in-session to "refresh the ID" — Claude reads bundle.md and stats.json and writes output/profile.json by 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.

  3. render.py — deterministic templating. Reads profile.json + stats.json and produces:

    • output/id.md — primary markdown, directive voice, designed as context to paste into future Claude sessions
    • output/id.html — styled single-file HTML with a sidebar TOC, scroll-spy, keyboard shortcuts (19 to jump to blocks, 0 for top), and 8 live view modes (full, compact, grid, card, timeline, focus, terminal, presentation) switched via a button bar — press m to cycle.

Install

Requires Python 3.10+. No third-party dependencies — only the standard library.

git clone <this-repo> claude-pov
cd claude-pov

Configure

cp config.example.json config.json

Edit 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 ~/.claude by default. Only change it if you've moved your Claude Code data elsewhere.

  • repos_diroptional. Root folder containing your personal code repos (e.g., ~/dev/repos). If set, prepare.py scans each subdirectory for a CLAUDE.md file and includes it in the bundle — this is how your per-project rules and conventions make it into the Digital ID. Leave as null to skip entirely.

  • stratified_targethow 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). 200 is 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_capmax characters per sampled message. Long rants get truncated at this limit so no single message dominates the sample. 300 captures the tone and gist of most messages. Raise to 500 for richer quotes, lower to 200 for a leaner bundle.

  • week_bucket_daysbucket size for stratified sampling. Default 7 means "one bucket per week." The scanner picks roughly stratified_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.

Run — first time

  1. Scan the data:

    python prepare.py

    This produces context/bundle.md and context/stats.json.

  2. Open a Claude Code session in this project and say:

    refresh the ID

    Claude will read context/bundle.md + context/stats.json and write output/profile.json.

  3. Render the outputs:

    python render.py

    This produces output/id.md and output/id.html.

  4. View: open output/id.html in a browser. For the "initialize Claude's memory" workflow, paste output/for-claude.md (or use the FOR CLAUDE view in the HTML and click COPY ALL) into a Claude Code session once.

Refresh later

Same three steps:

python prepare.py          # 1. rescan latest data
# then in a Claude Code session: "refresh the ID"
python render.py           # 3. re-render

prepare.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.

Output structure

The Digital ID has 13 blocks, defined by the schema contract in docs/SCHEMA.md:

  1. Capsule — one-paragraph persona, pasteable as a system-prompt addendum
  2. Operating Manual — explicit rules for Claude when working with you
  3. Voice & Writing Style — how you write, signature phrases, typo fingerprint, register signals
  4. Collaboration Preferences — session rhythm, plan-vs-execute, ping-pong discipline
  5. Identity & Role — who you are professionally
  6. Technical Fingerprint — languages, tools, stack (deterministic from session-meta)
  7. Strengths & Wins — patterns of things you do well
  8. Friction Patterns — recurring struggles + what Claude should do instead, with resolved_by tags on frictions already mitigated
  9. Current Obsessions — active projects, last N weeks
  10. Working Style & Rhythms — hour × day heatmap, session length distribution, totals
  11. Tools Already Built — inventory of custom skills, plugins, workflows, and memory files you've shipped to reduce friction
  12. Tools to Build — concrete proposals for new tools that would address unresolved frictions, cross-checked against block 11
  13. 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.

Privacy

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 — gitignored
  • context/stats.json — gitignored
  • output/profile.json — gitignored
  • output/id.md — gitignored
  • output/id.html — gitignored
  • config.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.

Design notes

  • 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.json is the stable contract between the Claude-in-session phase and the renderers. If you change the schema, update both render_md() and render_html() in render.py.
  • Stats and voice are kept separate. Deterministic numbers (heatmap, top languages, totals) live in stats.json and are rendered directly. Narrative paragraphs live in profile.json and are written by Claude. The renderers merge them at the last step.
  • Sampling is capped deliberately. prepare.py never dumps full conversation bodies into bundle.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.

How it differs from /INSIGHTS

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.

Built with Claude

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.

License

MIT. Do whatever you want with the code. Your generated Digital ID is yours.

About

Generate a Claude Code Digital ID of yourself — written from Claude's point of view by scanning your session history. No API calls, fully local.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages