diff --git a/skills/log/SKILL.md b/skills/log/SKILL.md index 85ceba5..1f60cdf 100644 --- a/skills/log/SKILL.md +++ b/skills/log/SKILL.md @@ -4,7 +4,7 @@ description: > End-of-session logging. Captures key decisions, gotchas, open questions, and discussion points into memory/log/ for later reflection. Run before ending a session to preserve context. Fast and low-friction -- just run /log. -allowed-tools: Read, Write, Glob, Bash(date *), Bash(ls *), Bash(cat *), Bash(find *), Bash(rm *), Bash(mkdir *) +allowed-tools: Read, Write, Glob, Agent, Bash(date *), Bash(pwd), Bash(ls *), Bash(cat *), Bash(find *), Bash(rm *), Bash(mkdir *), Bash(python3 *), Bash(bash *) --- # Session Log Skill @@ -17,6 +17,9 @@ You are capturing key points from the current session into a structured log file !`date +%Y-%m-%d` !`date +%Y%m%d-%H%M%S` +### Current project directory +!`pwd` + ### Existing log files !`ls -1 memory/log/ 2>/dev/null || echo "No log directory yet"` @@ -29,16 +32,19 @@ You are capturing key points from the current session into a structured log file ### Current MEMORY.md index !`cat MEMORY.md 2>/dev/null || echo "No MEMORY.md found"` +### Unprocessed transcript backups for this project (metadata only) +!`bash ~/.claude/scripts/list-transcripts-here.sh 2>/dev/null || echo "[]"` + ## Instructions -Review the **full conversation history** in your context window and extract the key points worth preserving. Not every session needs a log — if the session was trivial (a typo fix, a quick question), say so and skip. +Review the **full conversation history** in your context window and extract key points worth preserving. Not every session needs a log — if the session was trivial (a typo fix, a quick question), say so and skip. -### Step 1: Create the log directory if needed +The "Unprocessed transcript backups" above shows metadata (filenames, timestamps) for any pre-compaction snapshots not yet captured in a log. **Do NOT read the transcript content yourself** — that is handled by a subagent in Step 2 to avoid context overflow. + +### Step 1: Create the log directory and write the in-context log If `memory/log/` does not exist, create it with `mkdir -p memory/log/`. -### Step 2: Write the log file - Generate the filename as `memory/log/YYYY-MM-DD..md` using the pre-gathered date and timestamp values. Write the file using this format: @@ -72,9 +78,82 @@ Write the file using this format: **Guidelines:** - Omit empty sections entirely rather than leaving them blank -- The `[topic]` tag on gotchas should match existing memory topic names where possible (e.g., `[k8s]`, `[cilium]`, `[ansible]`, `[sops]`, `[helm]`). Use new tags for new topics. +- The `[topic]` tag on gotchas should match existing memory topic names where possible (e.g., `[k8s]`, `[cilium]`, `[ansible]`, `[sops]`, `[helm]`) - Keep entries concise — this is raw material for `/reflect-logs`, not a polished document -- Include enough context that each entry makes sense on its own without the full conversation +- Include enough context that each entry makes sense without the full conversation + +### Step 2: Dispatch transcript analysis subagent (if unprocessed transcripts exist) + +If the pre-gathered transcript list is non-empty and contains backup files that `exists: true`: + +Spawn a **Sonnet** subagent (model: sonnet) with the following prompt. Sonnet is used (not Haiku) because gotcha detection requires judgment about backtracking, failed attempts, and domain-specific failure modes — Haiku tends to miss these. Fill in the bracketed values from the pre-gathered data: + +--- +**Subagent prompt template:** + +You are processing pre-compaction transcript backups into a structured session log. + +**Project directory:** [CWD from pre-gathered context] +**Log directory:** memory/log/ (relative to project dir — write files there using absolute path) +**Log filename:** [SAME HHMMSS timestamp as Step 1, but with suffix -transcripts, e.g. memory/log/YYYY-MM-DD.HHMMSS-transcripts.md] +**Transcripts to process:** [paste the JSON array from the pre-gathered list] + +## Your task + +For each backup file listed above (where `exists: true`): + +1. Extract the conversation using: + ``` + python3 ~/.claude/scripts/extract-transcripts.py --extract + ``` + Run this as a Bash command and read the output. + +2. If the transcript has >40 turns, process it in two passes: + - First half of turns in one read + - Second half in a second run (re-run --extract and skip to turn N) + Note: the --extract command outputs all turns; read the full output but focus analysis on substance. + +3. After reading all transcripts, write a single log file at the absolute path: + `[PROJECT_ABS_PATH]/memory/log/YYYY-MM-DD.HHMMSS-transcripts.md` + + Use this format: + ```markdown + # Transcript Log — YYYY-MM-DD (pre-compaction backups) + + ## Sources + - (session , saved ) + + ## Summary + + + ## Decisions + - Decision: — Rationale: + + ## Gotchas Discovered + - **[topic]** Symptom: — Fix: + + ## Open Questions + - + + ## Key Context + - + + ## Process Notes + - + ``` + +4. After writing the log, mark all processed transcripts: + ``` + python3 ~/.claude/scripts/extract-transcripts.py --mark-all-processed "[CWD]" --log-file "memory/log/YYYY-MM-DD.HHMMSS-transcripts.md" + ``` + +5. Report: transcript(s) processed, log file written, any issues encountered. + +**Allowed tools for the subagent:** Read, Write, Bash(python3 *), Bash(mkdir *) + +--- + +Spawn this subagent with `model: sonnet` and wait for it to complete before continuing. ### Step 3: Prune old logs @@ -91,6 +170,6 @@ After writing the log file, check for old logs that should be pruned: ### Step 4: Summary Print a brief summary: -- Log file created (with path) -- Number of entries by section +- In-context log file created (with path) +- Whether a transcript analysis subagent was dispatched (and which backups it processed) - Any files pruned or warnings issued diff --git a/skills/switch-mode/SKILL.md b/skills/switch-mode/SKILL.md new file mode 100644 index 0000000..7e31c3c --- /dev/null +++ b/skills/switch-mode/SKILL.md @@ -0,0 +1,128 @@ +--- +name: switch-mode +description: > + Change engagement mode mid-session. Updates active-mode.env and last-mode so + the next session launches in the new mode. Injects the new mode's workflow + stance into the current conversation so it takes effect immediately (driver + model cannot change without a relaunch). +allowed-tools: Read, Write, Glob, Bash(ls *), Bash(cat *) +--- + +# Switch Mode Skill + +You are helping the user change their engagement mode. + +## Pre-gathered context + +### Available modes +!`ls ~/dev/claude/small-scripts/data/claude-profile/modes/` + +### Current active-mode.env +!`cat ~/.claude-oreillyit/active-mode.env` + +### Current last-mode +!`cat ~/.claude-oreillyit/last-mode` + +## Instructions + +The user wants to switch engagement mode. Follow these steps exactly. + +### Step 1: Build the mode menu + +Read each `.md` file in `/home/paul/dev/claude/small-scripts/data/claude-profile/modes/` using the Read tool. +From each file's frontmatter, extract: +- `name` — the mode identifier +- `tag` — display tag (same as name usually) +- `driver` — the driver model +- `escalates_to` — escalation model (or "none") + +From the body, read the `## Purpose` section to get a one-line description. + +Present a numbered menu like this (order: quick, deep, hybrid, orch, chat): + +``` +Available modes: + +1. quick [Sonnet] One small focused job — get in, get out +2. deep [Sonnet -> Opus] Hard design/debug, plan-first, spec-driven +3. hybrid [Haiku -> Opus] Long sessions, cheap driver, escalate on demand +4. orch [Sonnet] Parallel container agents, orchestration focus +5. chat [Haiku] No project, just conversation +``` + +Mark the current mode (from `active-mode.env`'s `CLAUDE_MODE`) with `(current)`. + +If `$ARGUMENTS` is non-empty and matches a mode name, skip the menu and go directly to Step 2 with that mode. + +### Step 2: Confirm selection + +Ask the user which mode number (or name) they want to switch to. +Wait for their response. If they already specified a mode in `$ARGUMENTS` or the menu was skipped, confirm it: "Switching to `` mode — confirm? (y/n)" + +### Step 3: Read the target mode file + +Use the Read tool to read the full content of `/home/paul/dev/claude/small-scripts/data/claude-profile/modes/.md`. + +Extract all frontmatter fields: +- `name` +- `tag` +- `driver` +- `async_ok` +- `autoloop` +- `plan_mode_auto` +- `spec_driven` +- `escalates_to` + +Compute the full mode file path: `/home/paul/dev/claude/small-scripts/data/claude-profile/modes/.md` + +### Step 4: Write active-mode.env + +Write `/home/paul/.claude-oreillyit/active-mode.env` with this exact format (substitute the values from the frontmatter): + +``` +CLAUDE_MODE= +CLAUDE_MODE_TAG= +CLAUDE_DRIVER= +CLAUDE_ESCALATES_TO= +CLAUDE_PROJECT= +CLAUDE_TIME_HORIZON=2 +CLAUDE_ASYNC_OK= +CLAUDE_AUTOLOOP= +CLAUDE_PLAN_MODE_AUTO= +CLAUDE_SPEC_DRIVEN= +CLAUDE_MODE_FILE=/home/paul/dev/claude/small-scripts/data/claude-profile/modes/.md +``` + +For `CLAUDE_PROJECT=` — leave the value empty (no project context is carried across a mode switch initiated mid-session; the user will set it at relaunch). + +### Step 5: Write last-mode + +Write `/home/paul/.claude-oreillyit/last-mode` with just the mode name and a trailing newline: + +``` + +``` + +### Step 6: Adopt the new workflow stance + +Read the full body of the new mode's `.md` file (everything after the closing `---` of the frontmatter). This is the mode's instructions to Claude. + +Tell the user: + +> Mode updated to ``. The new mode will be fully active after `/clear` + relaunch (driver model `` cannot change mid-session). +> +> In this session, the following changes are active immediately: +> - **Workflow stance**: [summarise the key stance change in 1-2 sentences based on the mode body] +> - **Subagent policy**: [summarise from the Subagent policy section] +> - **Async policy**: [enabled / disabled based on async_ok] +> - **Plan mode**: [auto / manual / never, from plan_mode_auto] +> +> Adopting new stance now. + +Then behave according to the new mode's body prose for the remainder of the session. The driver model (``) is fixed — acknowledge this if the new mode's driver differs. + +### Error handling + +- If `$ARGUMENTS` is set but does not match any mode name: say "Unknown mode: ``. Available modes: quick, deep, hybrid, orch, chat." and show the menu. +- If the user picks their current mode: say "You are already in `` mode. No change made." and stop. +- If a file write fails: report the error and tell the user to check permissions on `/home/paul/.claude-oreillyit/`.