Metadata-Version: 2.4
Name: agent-persona
Version: 0.1.0
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.

---

## 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 watches four things:

| Source | What it captures |
|---|---|
| **Claude session logs** | Parsed from `~/.claude/` after each session ends |
| **Files you edit** | Every `Write` / `Edit` in Claude CLI is logged asynchronously |
| **Shell history** | Read from `~/.zsh_history` or `~/.bash_history` at analysis time |
| **Your own words** | Phrases like `"I prefer..."`, `"always use..."`, `"never do..."` extracted from your side of every conversation |

From those sources, it builds a profile across five dimensions:

- **Languages** — which languages you actually use, weighted by frequency across sessions
- **Frameworks** — inferred from imports, file extensions, and install commands
- **Tools** — CLI tools, build systems, databases that appear repeatedly in your workflow
- **Preferences** — explicit things you've told Claude, confidence-scored and time-decayed so stale preferences fade out
- **Coding style** — indent preference from your actual files; test frequency from how often you write tests

Everything is stored in `~/.agent-persona/profile.json` — plain JSON, readable, portable, yours.

---

## 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. Claude already knows how you work.

**`Stop` (×2)** — when a session ends:
- A command hook runs the full rule-based pipeline, updates `profile.json`, regenerates `context.md`
- A prompt hook gives the already-running Claude instance a free richer pass — no extra API calls, no extra cost

**`PostToolUse`** — every file edit is logged 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": "root-cause analysis before fixes", "confidence": 0.9,  "source": "rule" },
    { "text": "always include tradeoffs",          "confidence": 0.95, "source": "llm"  }
  ],
  "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

**No LLM API calls from Python.** All rule-based analysis runs in pure Python — fast, deterministic, free. The richer LLM extraction piggybacks on the Claude session that's already ending via a `type: "prompt"` Stop hook. Zero extra cost.

**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
