Metadata-Version: 2.4
Name: agent-persona
Version: 0.3.1
Summary: Local-first personalization layer for Claude CLI — learns how you work and injects that context into every session
License: MIT
Requires-Python: >=3.11
Requires-Dist: click>=8.1
Requires-Dist: filelock>=3.12
Requires-Dist: questionary>=2.0
Requires-Dist: rich>=13.0
Provides-Extra: dev
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

<div align="center">

<img src="assets/logo.svg" width="100" alt="agent-persona logo" />

# agent-persona

*Personalise your Claude CLI to your persona — learned from how you actually work.*

[![PyPI](https://img.shields.io/pypi/v/agent-persona?color=blue&label=pypi)](https://pypi.org/project/agent-persona/)
[![Python](https://img.shields.io/badge/python-3.11+-blue)](#)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](#)
[![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey)](#)

</div>

---

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

```bash
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, updates `profile.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:

```json
{
  "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

```bash
# 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](https://claude.ai/code) installed and authenticated
- macOS, Linux, or Windows

---

## License

MIT
