diff --git a/docs/plans/2024-12-29-pa-agent-mode-implementation.md b/docs/plans/2024-12-29-pa-agent-mode-implementation.md new file mode 100644 index 0000000..600c0e5 --- /dev/null +++ b/docs/plans/2024-12-29-pa-agent-mode-implementation.md @@ -0,0 +1,470 @@ +# PA Agent Mode Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Create a persistent Claude Code environment with tmux, full autonomy, and long-term memory. + +**Architecture:** Shell scripts manage tmux session lifecycle. Memory stored as JSON files. Hyprland keybind launches via existing `omarchy-launch-tui` pattern. PA agent instructions updated to load memory on startup. + +**Tech Stack:** Bash, tmux, JSON, Hyprland config + +--- + +## Task 1: Create Directory Structure + +**Files:** +- Create: `~/.claude/state/personal-assistant/history/` +- Create: `~/.claude/state/personal-assistant/memory/` + +**Step 1: Create directories** + +```bash +mkdir -p ~/.claude/state/personal-assistant/history +mkdir -p ~/.claude/state/personal-assistant/memory +``` + +Run: `mkdir -p ~/.claude/state/personal-assistant/history ~/.claude/state/personal-assistant/memory` + +**Step 2: Verify directories exist** + +Run: `ls -la ~/.claude/state/personal-assistant/` +Expected: `history` and `memory` directories listed + +**Step 3: Commit** + +```bash +# No git commit - these are runtime directories, not tracked +``` + +--- + +## Task 2: Create History Index File + +**Files:** +- Create: `~/.claude/state/personal-assistant/history/index.json` + +**Step 1: Create index.json with empty sessions array** + +```json +{ + "version": "1.0", + "sessions": [] +} +``` + +Write to: `~/.claude/state/personal-assistant/history/index.json` + +**Step 2: Verify file is valid JSON** + +Run: `cat ~/.claude/state/personal-assistant/history/index.json | jq .` +Expected: Pretty-printed JSON with empty sessions array + +--- + +## Task 3: Create Memory Category Files + +**Files:** +- Create: `~/.claude/state/personal-assistant/memory/decisions.json` +- Create: `~/.claude/state/personal-assistant/memory/preferences.json` +- Create: `~/.claude/state/personal-assistant/memory/projects.json` +- Create: `~/.claude/state/personal-assistant/memory/facts.json` +- Create: `~/.claude/state/personal-assistant/memory/meta.json` + +**Step 1: Create decisions.json** + +```json +{ + "version": "1.0", + "description": "Decisions made with rationale", + "items": [] +} +``` + +**Step 2: Create preferences.json** + +```json +{ + "version": "1.0", + "description": "User preferences learned over time", + "items": [] +} +``` + +**Step 3: Create projects.json** + +```json +{ + "version": "1.0", + "description": "Active and recent project context", + "items": [] +} +``` + +**Step 4: Create facts.json** + +```json +{ + "version": "1.0", + "description": "Factual knowledge about the environment", + "items": [] +} +``` + +**Step 5: Create meta.json** + +```json +{ + "version": "1.0", + "last_summarized": null, + "total_sessions": 0, + "total_items": { + "decisions": 0, + "preferences": 0, + "projects": 0, + "facts": 0 + } +} +``` + +**Step 6: Verify all files are valid JSON** + +Run: `for f in ~/.claude/state/personal-assistant/memory/*.json; do echo "=== $f ===" && jq . "$f"; done` +Expected: All 5 files display as valid JSON + +--- + +## Task 4: Create pa-mode Launch Script + +**Files:** +- Create: `~/.claude/automation/pa-mode` + +**Step 1: Write the pa-mode script** + +```bash +#!/usr/bin/env bash +# PA Agent Mode - Launch/attach to persistent PA tmux session +set -euo pipefail + +SESSION_NAME="pa" +HISTORY_DIR="$HOME/.claude/state/personal-assistant/history" +INDEX_FILE="$HISTORY_DIR/index.json" + +usage() { + echo "Usage: pa-mode [command]" + echo "" + echo "Commands:" + echo " (none) Attach to existing session or create new one" + echo " new Force new session (detaches existing if any)" + echo " kill Terminate the PA session" + echo " status Show session status" + echo "" +} + +get_session_id() { + date +"%Y-%m-%d_%H-%M-%S" +} + +create_session() { + local session_id + session_id=$(get_session_id) + local history_file="$HISTORY_DIR/${session_id}.jsonl" + + # Record session start in index + local tmp_file + tmp_file=$(mktemp) + jq --arg id "$session_id" --arg started "$(date -Iseconds)" \ + '.sessions += [{"id": $id, "started": $started, "ended": null, "summarized": false, "topics": []}]' \ + "$INDEX_FILE" > "$tmp_file" && mv "$tmp_file" "$INDEX_FILE" + + # Create tmux session with claude in PA mode + # Using HISTFILE-like approach: set env var for history location + tmux new-session -d -s "$SESSION_NAME" -c "$HOME" \ + "PA_SESSION_ID='$session_id' PA_HISTORY_FILE='$history_file' claude --dangerously-skip-permissions --agent personal-assistant" + + echo "Created new PA session: $session_id" +} + +attach_session() { + if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then + tmux attach-session -t "$SESSION_NAME" + else + create_session + tmux attach-session -t "$SESSION_NAME" + fi +} + +case "${1:-}" in + "") + attach_session + ;; + new) + if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then + echo "Killing existing session..." + tmux kill-session -t "$SESSION_NAME" + fi + create_session + tmux attach-session -t "$SESSION_NAME" + ;; + kill) + if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then + tmux kill-session -t "$SESSION_NAME" + echo "PA session terminated" + else + echo "No PA session running" + fi + ;; + status) + if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then + echo "PA session is running" + tmux list-sessions -F "#{session_name}: #{session_created} (#{session_attached} attached)" | grep "^$SESSION_NAME:" + else + echo "PA session is not running" + fi + ;; + -h|--help|help) + usage + ;; + *) + echo "Unknown command: $1" + usage + exit 1 + ;; +esac +``` + +**Step 2: Make script executable** + +Run: `chmod +x ~/.claude/automation/pa-mode` + +**Step 3: Verify script syntax** + +Run: `bash -n ~/.claude/automation/pa-mode && echo "Syntax OK"` +Expected: "Syntax OK" + +**Step 4: Test help output** + +Run: `~/.claude/automation/pa-mode --help` +Expected: Usage information displayed + +**Step 5: Commit** + +```bash +cd ~/.claude && git add automation/pa-mode && git commit -m "feat: add pa-mode launch script" +``` + +--- + +## Task 5: Create pa-summarize Hook Script + +**Files:** +- Create: `~/.claude/automation/pa-summarize` + +**Step 1: Write the pa-summarize script** + +```bash +#!/usr/bin/env bash +# PA Summarize - Extract session summary before shutdown +set -euo pipefail + +MEMORY_DIR="$HOME/.claude/state/personal-assistant/memory" +INDEX_FILE="$HOME/.claude/state/personal-assistant/history/index.json" + +# This script is called by tmux hook or manually +# It sends a summarization request to the running claude session + +SESSION_NAME="pa" + +if ! tmux has-session -t "$SESSION_NAME" 2>/dev/null; then + echo "No PA session running" + exit 1 +fi + +# Send summarization prompt to the tmux pane +# The PA agent will handle extracting and saving to memory files +tmux send-keys -t "$SESSION_NAME" \ + "Please summarize this session for long-term memory. Extract key decisions, preferences learned, project context, and facts into the appropriate memory files in ~/.claude/state/personal-assistant/memory/. Then mark this session as summarized in the history index." \ + Enter + +echo "Summarization request sent to PA session" +``` + +**Step 2: Make script executable** + +Run: `chmod +x ~/.claude/automation/pa-summarize` + +**Step 3: Verify script syntax** + +Run: `bash -n ~/.claude/automation/pa-summarize && echo "Syntax OK"` +Expected: "Syntax OK" + +**Step 4: Commit** + +```bash +cd ~/.claude && git add automation/pa-summarize && git commit -m "feat: add pa-summarize hook script" +``` + +--- + +## Task 6: Update Hyprland Keybind + +**Files:** +- Modify: `~/.config/hypr/bindings.conf` + +**Step 1: Update the SUPER SHIFT C binding** + +Find line: +```conf +bindd = SUPER SHIFT, C, Claude Code, exec, omarchy-launch-tui tmux new-session -A -s claude-code claude +``` + +Replace with: +```conf +bindd = SUPER SHIFT, C, PA Agent Mode, exec, omarchy-launch-tui /home/will/.claude/automation/pa-mode +``` + +**Step 2: Reload Hyprland config** + +Run: `hyprctl reload` +Expected: No errors + +**Step 3: Verify binding registered** + +Run: `hyprctl binds | grep -i "PA Agent"` +Expected: Shows the PA Agent Mode binding + +--- + +## Task 7: Update PA Agent Instructions + +**Files:** +- Modify: `~/.claude/agents/personal-assistant.md` + +**Step 1: Add memory loading to initialization section** + +Find the initialization section after line 14 and add memory files to the list. Update the code block: + +```markdown +**Read these state files before executing tasks:** + +``` +~/.claude/state/system-instructions.json # Process definitions +~/.claude/state/future-considerations.json # Deferred features +~/.claude/state/model-policy.json # Model selection rules +~/.claude/state/autonomy-levels.json # Autonomy definitions +~/.claude/state/personal-assistant-preferences.json # PA persistent config +~/.claude/state/personal-assistant/session-context.json # Session context override +~/.claude/state/personal-assistant/general-instructions.json # User memory +~/.claude/state/personal-assistant/memory/decisions.json # Decisions with rationale +~/.claude/state/personal-assistant/memory/preferences.json # Learned preferences +~/.claude/state/personal-assistant/memory/projects.json # Project context +~/.claude/state/personal-assistant/memory/facts.json # Environment facts +``` +``` + +**Step 2: Add PA Agent Mode section before Notes** + +Insert before the "## Notes" section (around line 235): + +```markdown +## PA Agent Mode + +When running in PA Agent Mode (tmux session "pa" with `--dangerously-skip-permissions`): + +### Memory System + +**On startup:** +1. Read all memory files from `~/.claude/state/personal-assistant/memory/` +2. Check `history/index.json` for unsummarized sessions +3. If unsummarized sessions exist, offer: "Last session wasn't summarized. Review it now?" + +**During session:** +- Respond to `/pa --summarize` or "summarize this session" by extracting: + - Decisions → `memory/decisions.json` + - Preferences learned → `memory/preferences.json` + - Project context → `memory/projects.json` + - Facts → `memory/facts.json` +- Update `memory/meta.json` timestamps +- Mark session as summarized in `history/index.json` + +**Memory item format:** +```json +{ + "id": "uuid", + "date": "YYYY-MM-DD", + "content": "description of item", + "context": "optional additional context", + "session": "session-id" +} +``` + +### History Search + +When asked about past conversations: +1. Search `history/index.json` for relevant session IDs by topic +2. Read the corresponding `.jsonl` files +3. Provide relevant context from historical sessions +``` + +**Step 3: Commit** + +```bash +cd ~/.claude && git add agents/personal-assistant.md && git commit -m "feat: add PA Agent Mode memory instructions" +``` + +--- + +## Task 8: End-to-End Test + +**Step 1: Verify pa-mode creates session** + +Run: `~/.claude/automation/pa-mode status` +Expected: "PA session is not running" + +Run: `~/.claude/automation/pa-mode new &` then `sleep 2 && tmux has-session -t pa && echo "Session created"` +Expected: "Session created" + +**Step 2: Verify index was updated** + +Run: `cat ~/.claude/state/personal-assistant/history/index.json | jq '.sessions | length'` +Expected: `1` + +**Step 3: Kill test session** + +Run: `~/.claude/automation/pa-mode kill` +Expected: "PA session terminated" + +**Step 4: Test keybind (manual)** + +Press Super+Shift+C +Expected: Alacritty opens with PA session attached + +--- + +## Task 9: Final Commit + +**Step 1: Check git status** + +Run: `cd ~/.claude && git status` +Expected: All changes committed, working tree clean + +**Step 2: Tag release** + +```bash +cd ~/.claude && git tag -a v1.0.0-pa-mode -m "PA Agent Mode implementation" +``` + +--- + +## Summary + +| Task | Description | Files | +|------|-------------|-------| +| 1 | Create directories | history/, memory/ | +| 2 | Create history index | history/index.json | +| 3 | Create memory files | memory/*.json (5 files) | +| 4 | Create pa-mode script | automation/pa-mode | +| 5 | Create pa-summarize script | automation/pa-summarize | +| 6 | Update Hyprland keybind | ~/.config/hypr/bindings.conf | +| 7 | Update PA agent instructions | agents/personal-assistant.md | +| 8 | End-to-end test | (verification) | +| 9 | Final commit + tag | (git) |