Add transcript backup tracking system and pre-compact hook improvements
- pre-compact-backup.sh: derive transcript path from session_id+cwd (no longer relies on transcript_path field that Claude Code stopped providing); register each backup in tracking.json after saving - extract-transcripts.py: new script managing tracking.json — register, list, extract conversation text, mark-processed modes - list-transcripts-here.sh: thin wrapper for extract-transcripts --list using $(pwd); needed because SKILL.md bang commands reject $() substitution - install-hooks.sh: now also symlinks skill-helper scripts into ~/.claude/scripts/ via a curated SKILL_HELPERS list - Memory docs: new script-extract-transcripts.md, script-list-transcripts-here.md; updated skill-log.md, script-install-hooks.md, MEMORY.md index Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
41
memory/script-extract-transcripts.md
Normal file
41
memory/script-extract-transcripts.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# script: extract-transcripts
|
||||
|
||||
**Location:** `claude-foundations/scripts/extract-transcripts.py`
|
||||
**Symlinked to:** `~/.claude/scripts/extract-transcripts.py`
|
||||
|
||||
## Purpose
|
||||
|
||||
Manages the transcript backup tracking system. Registers pre-compaction JSONL backups, lists unprocessed ones per project, extracts readable conversation text for analysis, and marks entries as processed after a log is written.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Register a new backup (called by pre-compact-backup.sh hook)
|
||||
python3 ~/.claude/scripts/extract-transcripts.py \
|
||||
--register BACKUP_NAME --session-id SESSION_ID --cwd PROJECT_CWD
|
||||
|
||||
# List unprocessed transcripts for a project (used by /log skill)
|
||||
python3 ~/.claude/scripts/extract-transcripts.py --list /home/paul/dev/claude/projects/foo
|
||||
# → compact JSON array of {backup, session_id, saved_at, path, exists}
|
||||
|
||||
# Extract readable conversation from one backup (used by /log Sonnet subagent)
|
||||
python3 ~/.claude/scripts/extract-transcripts.py --extract BACKUP_NAME
|
||||
|
||||
# Mark all unprocessed backups for a project as done
|
||||
python3 ~/.claude/scripts/extract-transcripts.py \
|
||||
--mark-all-processed /home/paul/dev/claude/projects/foo --log-file memory/log/YYYY-MM-DD.HHMMSS-transcripts.md
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
- Tracking state lives in `~/.claude/transcript-backups/tracking.json`, keyed by backup filename
|
||||
- Each entry: `{session_id, cwd, saved_at, processed, log_file, processed_at}`
|
||||
- `--list` filters by `cwd == project_cwd` and `processed == false` — output is metadata only (no content), safe for skill pre-gathering
|
||||
- `--extract` reads the JSONL, skips sidechain entries, extracts `user`/`assistant` message text, truncates per-message at 3000 chars
|
||||
- Tool use blocks are summarised as `[tool: ToolName(key=...)]` rather than shown in full
|
||||
|
||||
## Gotchas
|
||||
|
||||
- `sys.exit(0)` inside a bare `except: pass` block is caught as SystemExit — always use specific exception types or `break` when early exit is needed inside exception handlers
|
||||
- The JSONL entries for `type: "user"` without a `message` field (e.g., file-history snapshots) are skipped silently
|
||||
- Old backups with `-auto` suffix (from before this system) are not in tracking.json and will never appear in `--list`
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
Symlinks all hook scripts from `claude-foundations/hooks/` into `~/.claude/hooks/` and prints the `settings.json` configuration to add.
|
||||
Symlinks all hook scripts from `claude-foundations/hooks/` into `~/.claude/hooks/`, and symlinks skill-helper scripts from `claude-foundations/scripts/` into `~/.claude/scripts/`. Also prints the `settings.json` configuration to add.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -13,15 +13,27 @@ cd ~/dev/claude/projects/claude-foundations
|
||||
scripts/install-hooks.sh
|
||||
```
|
||||
|
||||
One-time setup. Re-run after adding new hooks.
|
||||
One-time setup. Re-run after adding new hooks or skill-helper scripts.
|
||||
|
||||
## How it works
|
||||
|
||||
1. Iterates over `hooks/*.sh`
|
||||
2. Creates symlinks in `~/.claude/hooks/` (force-overwrites existing)
|
||||
1. Iterates over `hooks/*.sh`, creates symlinks in `~/.claude/hooks/` (force-overwrites)
|
||||
2. Iterates over a curated list of skill-helper scripts, creates symlinks in `~/.claude/scripts/`
|
||||
3. Prints the JSON config for `~/.claude/settings.json` covering PreCompact, PostToolUse, and PreToolUse matchers
|
||||
|
||||
## Skill-helper scripts vs regular scripts
|
||||
|
||||
Not all `claude-foundations/scripts/` go into `~/.claude/scripts/`. Only scripts that skills reference via `~/.claude/scripts/` are installed there. The `SKILL_HELPERS` array in `install-hooks.sh` is the authoritative list. Currently: `extract-transcripts.py`, `list-transcripts-here.sh`.
|
||||
|
||||
Regular scripts (`statusline.sh`, `set-topic.sh`, etc.) are accessed via their full path in `claude-foundations/scripts/`.
|
||||
|
||||
## Profile notes
|
||||
|
||||
- Hooks: `~/.claude/hooks/` is referenced in all profile `settings.json` files — install once, works everywhere
|
||||
- Scripts: `~/.claude/scripts/` is the only location skills reference — no per-profile script dirs needed
|
||||
|
||||
## Gotchas
|
||||
|
||||
- The printed JSON must be manually added to `settings.json` — the script doesn't edit it automatically.
|
||||
- Symlinks mean the hook code stays in the repo; updates take effect immediately without re-running the script.
|
||||
- Symlinks mean the hook/script code stays in the repo; updates take effect immediately without re-running the script.
|
||||
- Adding a new skill-helper script requires updating the `SKILL_HELPERS` array in `install-hooks.sh` and re-running it.
|
||||
|
||||
26
memory/script-list-transcripts-here.md
Normal file
26
memory/script-list-transcripts-here.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# script: list-transcripts-here
|
||||
|
||||
**Location:** `claude-foundations/scripts/list-transcripts-here.sh`
|
||||
**Symlinked to:** `~/.claude/scripts/list-transcripts-here.sh`
|
||||
|
||||
## Purpose
|
||||
|
||||
Thin wrapper around `extract-transcripts.py --list "$(pwd)"`. Exists because SKILL.md bang commands (`!`command``) cannot use `$()` substitution — the Claude Code permission checker rejects it. The wrapper runs the substitution internally (in bash, where it's fine) and outputs the result.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# From within a project directory
|
||||
bash ~/.claude/scripts/list-transcripts-here.sh
|
||||
# → JSON array of unprocessed transcript backups for the current cwd
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
Single line: `python3 "$HOME/.claude/scripts/extract-transcripts.py" --list "$(pwd)"`
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Must be called with `bash list-transcripts-here.sh` (not `python3`) — it's a shell wrapper, not a Python script
|
||||
- Output is the same as `extract-transcripts.py --list`, so check that script's docs for the JSON format
|
||||
- The `$()` substitution is the entire reason this wrapper exists; if that restriction is ever lifted from SKILL.md bang commands, this wrapper can be removed
|
||||
@@ -12,22 +12,31 @@ End-of-session logging. Captures key decisions, gotchas, open questions, and pro
|
||||
/log
|
||||
```
|
||||
|
||||
No arguments. Reviews the full conversation history automatically.
|
||||
No arguments. Reviews the full conversation history and any pre-compaction transcript backups automatically.
|
||||
|
||||
## How it works
|
||||
|
||||
1. Creates `memory/log/` if needed
|
||||
2. Reviews the conversation and extracts: Summary, Decisions, Gotchas (tagged with `[topic]`), Open Questions, Key Context, Process Notes
|
||||
3. Writes a structured log file — empty sections are omitted
|
||||
4. Prunes old logs: deletes reflected logs older than `retention_days` (default 7), warns about unreflected logs older than `warn_unreflected_days` (default 14)
|
||||
3. Writes a structured in-context log — empty sections are omitted
|
||||
4. **Transcript analysis (when backups exist):** Checks `~/.claude/transcript-backups/tracking.json` for unprocessed pre-compaction snapshots for the current project. If found, spawns a **Sonnet** subagent to read the JSONL backups (via `extract-transcripts.py --extract`) and write a companion log `HHMMSS-transcripts.md`. The subagent then marks backups as processed in `tracking.json`. Sonnet is used (not Haiku) because gotcha detection requires judgment about backtracking and failed attempts.
|
||||
5. Prunes old logs: deletes reflected logs older than `retention_days` (default 7), warns about unreflected logs older than `warn_unreflected_days` (default 14)
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `~/.claude/scripts/list-transcripts-here.sh` — pre-gathers unprocessed transcript metadata (small JSON, no context overflow)
|
||||
- `~/.claude/scripts/extract-transcripts.py` — reads JSONL backups and manages tracking.json (used by the Sonnet subagent)
|
||||
- Both scripts live in `claude-foundations/scripts/`, symlinked into `~/.claude/scripts/`
|
||||
|
||||
## Part of the knowledge pipeline
|
||||
|
||||
`/log` → `/reflect-logs` → `/distill-best-practices`
|
||||
|
||||
Raw session logs are input for `/reflect-logs`, which routes entries into topic memory files.
|
||||
Raw session logs (and transcript companion logs) are input for `/reflect-logs`, which routes entries into topic memory files.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Trivial sessions can be skipped — the skill says so if nothing worth logging happened
|
||||
- `[topic]` tags on gotchas should match existing memory file topics for routing by `/reflect-logs`
|
||||
- The Sonnet subagent writes to the project's absolute `memory/log/` path; if it uses a relative path from the wrong cwd, the file ends up in the wrong place — verify on first real run
|
||||
- Pre-compaction backups from before the tracking system existed (files with `-auto` in the name) are not in `tracking.json` and won't be processed; they'll be pruned by the 30-day cleanup in the hook
|
||||
|
||||
Reference in New Issue
Block a user