# Hooks for Autocoder Memory System

This folder contains the hooks that integrate with Claude Code to capture session data and trigger memory extraction.

## Components

| File | Purpose |
|------|---------|
| `state.py` | Chunk state management (tracks task boundaries) |
| `user_prompt_submit.py` | Hook triggered when user submits prompt |
| `stop.py` | Hook triggered when Claude finishes (triggers triage) |
| `jsonl_parser.py` | Parse Claude Code JSONL transcript files |
| `triage.py` | Spawn triage sessions and store learnings |
| `config.py` | Configuration (server URL, thresholds, etc.) |
| `test_hooks.py` | Test script for all components |

## How It Works

```
┌─────────────────────────────────────────────────────────────────┐
│                        HOOK FLOW                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  User submits prompt                                             │
│       │                                                          │
│       ▼                                                          │
│  [UserPromptSubmit Hook]                                         │
│       │                                                          │
│       └── Save chunk_state.json with:                            │
│           - timestamp (chunk start)                              │
│           - session_id                                           │
│           - user_prompt                                          │
│           - jsonl_path                                           │
│                                                                  │
│  Claude works... (messages saved to JSONL by Claude Code)        │
│                                                                  │
│  Claude finishes                                                 │
│       │                                                          │
│       ▼                                                          │
│  [Stop Hook]                                                     │
│       │                                                          │
│       ├── Load chunk_state.json                                  │
│       ├── Read JSONL from chunk_start to end                     │
│       ├── Format as transcript                                   │
│       ├── Spawn Claude Code for triage                           │
│       ├── Parse XML output                                       │
│       ├── Store in codecontext                                  │
│       └── Clear state                                            │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

## Quick Start

### Test the System

```powershell
cd hooks
python test_hooks.py
```

### Manual Testing

```powershell
# 1. Simulate UserPromptSubmit
python user_prompt_submit.py --prompt "Add authentication" --session-id test123

# 2. Check state was created
type $env:USERPROFILE\.autocoder\memory\chunk_state.json

# 3. Test JSONL parsing (with a real JSONL file)
python jsonl_parser.py path\to\session.jsonl --chunks

# 4. Test triage with mock data
python triage.py --test
```

## Integration with Claude Code

### Option 1: Claude Code Settings (settings.json)

Add to `~/.claude/settings.json`:

```json
{
  "hooks": {
    "UserPromptSubmit": ["python", "C:/path/to/hooks/user_prompt_submit.py"],
    "Stop": ["python", "C:/path/to/hooks/stop.py"]
  }
}
```

### Option 2: Autocoder SDK Integration

If using Autocoder with Claude Agent SDK:

```python
from hooks import on_user_prompt_submit, on_stop

# In your agent loop
@agent.on("UserPromptSubmit")
def handle_prompt(event):
    on_user_prompt_submit(event)

@agent.on("Stop")
def handle_stop(event):
    on_stop(event)
```

### Option 3: Manual Invocation

Call hooks programmatically:

```python
from hooks import on_user_prompt_submit, on_stop

# When task starts
on_user_prompt_submit({
    "session_id": session.id,
    "prompt": user_message,
    "cwd": project_path
})

# When task ends
on_stop({
    "session_id": session.id,
    "reason": "completed"
})
```

## State File

Location: `~/.autocoder/memory/chunk_state.json`

```json
{
  "chunk_start_timestamp": "2026-01-14T10:30:00.000000",
  "session_id": "b3280872-6bb1-4728-9b2e-c66391cb4f0c",
  "project_path": "C:\\Users\\Sam\\project",
  "user_prompt": "Add authentication",
  "jsonl_path": "C:\\Users\\Sam\\.claude\\projects\\...\\session.jsonl"
}
```

## Headless Mode

Triage uses Claude CLI with headless flags to prevent permission popups:

```bash
claude --print --dangerously-skip-permissions --model haiku -p "prompt"
```

| Flag | Purpose |
|------|---------|
| `--print` | Output response directly (no interactive mode) |
| `--dangerously-skip-permissions` | Skip all permission prompts |
| `--model haiku` | Use Haiku for faster, cheaper extraction |
| `-p` | Pass prompt as argument |

This allows hooks to run Claude CLI from background processes without user interaction, using the cost-effective Haiku model for structured XML extraction.

## Dependencies

The hooks use only Python standard library except for storage:

```powershell
# For storage (codecontext)
pip install lancedb sentence-transformers pyarrow
```

## Troubleshooting

### "Claude Code CLI not found"

Install Claude Code CLI:
```powershell
npm install -g @anthropic/claude-code
```

### "JSONL not found"

Claude Code saves JSONL to: `~/.claude/projects/{encoded-path}/{session-id}.jsonl`

Check that:
1. Claude Code has been used in this project
2. The session ID is correct
3. The project path encoding matches

### "No chunk state found"

The UserPromptSubmit hook needs to run before Stop. Make sure both hooks are registered.

### Triage timeout

Triage has a 120-second timeout. For very long sessions, consider:
1. Truncating the transcript
2. Increasing the timeout in `triage.py`

## Extraction Quality

Triage uses strict stance criteria to ensure high-quality memory extraction:

| Extract | Skip |
|---------|------|
| Specific bug fixes with code | Generic questions/discussions |
| Concrete implementation details | Explanations without changes |
| Architecture decisions with rationale | Research without conclusions |
| Project-specific discoveries | Common programming knowledge |

The extraction prompt requests XML output only (no markdown, no explanations) for reliable parsing.
