Local-first personalization layer for Claude CLI — learns how you work and injects that context into every session
Project description
Claude is powerful out of the box. But it doesn't know you. It doesn't know your preferred stack, your coding style, or that you always want root-cause analysis before a fix. Every session, you're a stranger.
agent-persona changes that. It reads your Claude session logs, the files you edit, and your shell history — builds a global profile of your persona on this machine — and silently injects that context into every Claude session from then on. Claude stops being a generic assistant and starts behaving like one that knows how you work.
No configuration. No manual writing. It learns from what you do. And when you want to set something explicitly — run agent-persona customize.
Install
pipx install agent-persona
agent-persona install
From the next session on, it's building your persona.
How your persona is built
agent-persona reads your behavior — not your demographics — and personalizes Claude to how you actually work. It's a closed loop: it personalizes, Claude acts, you react, it learns, it personalizes better next time.
Everything below is free and automatic (no LLM, no cost), learned from your session logs, edited files, and shell history:
- Stack — languages, frameworks, tools you actually use, frequency-weighted
- Coding style — indent and test-frequency, sampled from files you edit
- Request patterns — recurring follow-up habits across sessions (e.g. after a bug fix you usually ask why it happened) — behavioral, thresholded, never one-off
- What you correct — when you redirect Claude ("revert that", "too complex", "don't add that yet"), recurring corrections become injected guidance ("prefer the simplest solution", "do only what's asked"). This is the strongest signal: what you reject is clearer than what you ask for
Plus a manual layer — agent-persona customize lets you state preferences in
your own words (always injected first, never overwritten).
A rule engine decays stale signals, drops low-confidence ones, ranks and caps what's injected — so Claude gets the right context, not a dump.
Note: agent-persona does not mine preferences from your prose with regex — that proved unreliable ("is this a preference or just a sentence?" is a semantic judgment regex can't make). Preferences come from your behavior, your corrections, and your own words.
Everything is stored in ~/.agent-persona/profile.json — plain JSON, readable, portable, yours.
Or set it yourself
Run agent-persona customize for an interactive menu — like ChatGPT Custom Instructions, but stored locally and injected into every Claude session:
❯ What would you like to do?
Add — what Claude should know about you
Add — how you want Claude to respond
──────────────────────────────────────
View my manual preferences
Remove a preference
──────────────────────────────────────
Done
Manual preferences are stored with full confidence and always injected first, before anything auto-learned. They're never overwritten by the automatic pipeline.
How it gets into Claude
Three hooks wire into ~/.claude/settings.json:
SessionStart— injects your compiled persona as hidden context before you type a word.Stop— when a session ends, runs the analysis pipeline, updatesprofile.json, and regenerates the injected context.PostToolUse— logs each file edit asynchronously in the background. Never blocks your session.
Your profile, globally
The profile lives at ~/.agent-persona/ — not inside any project. It spans every Claude session on this machine, regardless of what you're working on.
~/.agent-persona/
├── profile.json # your persona — single source of truth
├── state.json # tracks which sessions have been processed
├── history/
│ └── files_edited.jsonl # rolling 90-day log of edited files
└── generated/
└── context.md # compiled persona injected at session start
profile.json is plain JSON — readable, portable, auditable:
{
"version": 1,
"stack": {
"languages": { "python": 45, "typescript": 30 },
"frameworks": { "fastapi": 20, "pytest": 18 },
"tools": { "docker": 15, "git": 50 }
},
"preferences": [
{ "text": "I work in fintech, keep examples relevant", "confidence": 1.0, "source": "manual" }
],
"corrections": [
{ "kind": "simplify", "count": 4, "confidence": 0.85 }
],
"coding_style": { "indent": "spaces", "indent_size": 4, "test_frequency": "high" },
"sessions_processed": 47
}
Commands
| Command | What it does |
|---|---|
agent-persona install |
Register hooks, create ~/.agent-persona/ |
agent-persona uninstall |
Remove hooks, leave profile intact |
agent-persona customize |
Interactively set what Claude should know about you and how to respond |
agent-persona status |
Show your current persona: stack, preferences, sessions processed |
agent-persona analyze |
Re-run analysis on demand |
agent-persona apply [--dry-run] |
Write persona into ~/.claude/CLAUDE.md as a static fallback |
agent-persona export [path] |
Export your profile to take to another machine |
agent-persona import [path] |
Merge an exported profile into this machine's profile |
agent-persona reset --confirm |
Wipe profile and start fresh |
agent-persona doctor |
Check install health |
Taking your persona to a new machine
# old machine
agent-persona export ~/persona.json
# new machine
agent-persona install
agent-persona import ~/persona.json
The profiles merge — nothing is lost from either machine.
Design decisions
Rule-based analysis is pure Python — fast, deterministic, free. No API calls, no network. Any future LLM enrichment is opt-in and runs on your own Claude credentials.
Preferences decay. Each preference carries a last_seen timestamp. Old ones fade: score × 0.9 ^ (days_since_seen / 30). What you get stays relevant to how you work now.
Crash-safe writes. Every write is atomic (write to .tmp → rename). A crashed Stop hook is caught up automatically on the next clean session.
Non-destructive CLAUDE.md injection. The apply command writes between AGENT-PERSONA:START and AGENT-PERSONA:END markers. Everything outside is untouched.
Sensitive data never stored. API keys, tokens, and passwords are stripped before anything reaches profile.json. Only file metadata is logged — never file contents.
What it doesn't do
- No cloud — your persona never leaves this machine unless you export it
- No per-project profiles in v1 — one global persona across all work
- No Fish shell history yet
Requirements
- Python 3.11+
- Claude CLI installed and authenticated
- macOS, Linux, or Windows
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_persona-0.3.1.tar.gz.
File metadata
- Download URL: agent_persona-0.3.1.tar.gz
- Upload date:
- Size: 53.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2b4999c5f255631ca6047281f306e18ed8b0e5d599aeacd7ebee812f97b6e0b
|
|
| MD5 |
acaa39d4d55f0c3d97b078b0b10bf256
|
|
| BLAKE2b-256 |
749620cd6cab7336e5d225fae3c0795de2bf03d06763f5727f2c9721e2c4dbba
|
Provenance
The following attestation bundles were made for agent_persona-0.3.1.tar.gz:
Publisher:
python-publish.yml on MaansiBisht/agent-persona
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_persona-0.3.1.tar.gz -
Subject digest:
d2b4999c5f255631ca6047281f306e18ed8b0e5d599aeacd7ebee812f97b6e0b - Sigstore transparency entry: 2096507196
- Sigstore integration time:
-
Permalink:
MaansiBisht/agent-persona@99249fc8947f790631978adc5f4bca5b786745b3 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/MaansiBisht
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@99249fc8947f790631978adc5f4bca5b786745b3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file agent_persona-0.3.1-py3-none-any.whl.
File metadata
- Download URL: agent_persona-0.3.1-py3-none-any.whl
- Upload date:
- Size: 37.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d51bb677f4f6414d7c58a339b3e0951d1ebe11adbf0db63d802bbd337ad5cce
|
|
| MD5 |
763e8bab3e1d3484c5746287c271d009
|
|
| BLAKE2b-256 |
0d7651f8846c7b04e28a9312fd77f5cdee1d262f5c10c1e132f8cd5070fb0bc1
|
Provenance
The following attestation bundles were made for agent_persona-0.3.1-py3-none-any.whl:
Publisher:
python-publish.yml on MaansiBisht/agent-persona
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_persona-0.3.1-py3-none-any.whl -
Subject digest:
7d51bb677f4f6414d7c58a339b3e0951d1ebe11adbf0db63d802bbd337ad5cce - Sigstore transparency entry: 2096507411
- Sigstore integration time:
-
Permalink:
MaansiBisht/agent-persona@99249fc8947f790631978adc5f4bca5b786745b3 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/MaansiBisht
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@99249fc8947f790631978adc5f4bca5b786745b3 -
Trigger Event:
release
-
Statement type: