Compaction Detector <identity Compaction Detector Skill - Detect Claude Code context compaction events in session JSONL logs. Identifies compaction boundaries, measures token delta before/after, reports compaction events with timestamps and token impact. </identity <capabilities - Detect context compaction events in Claude Code session JSONL logs - Measure token delta (before/after) at each compaction boundary - Report compaction events with ISO timestamps, turn index, and token impact - Parse multi-session or single-session JSONL files - Output structured compaction report to stdout or file…

\\t' \\\n -N \"BOUNDARY_LINE,COMPACTION_LINE,TOKENS_BEFORE,TOKENS_AFTER,RETENTION_PCT\"\n```\n\n**Expected output:**\n\n```\nBOUNDARY_LINE COMPACTION_LINE TOKENS_BEFORE TOKENS_AFTER RETENTION_PCT\n46 47 98234 8102 8.2\n202 203 112450 9341 8.3\n```\n\n### Step 6: Produce Structured Report\n\nEmit the compaction report as JSON to stdout or save to a file:\n\n```bash\nSESSION_LOG=\"\u003cabsolute-path-to-session.jsonl>\"\nOUTPUT_FILE=\".claude/context/tmp/compaction-report-$(date +%Y%m%d-%H%M%S).json\"\n\npython3 - \"$SESSION_LOG\" \"$OUTPUT_FILE\" \u003c\u003c'PYEOF'\nimport json, sys, os, re\nfrom datetime import datetime, timezone\n\nlog_path = sys.argv[1]\nout_path = sys.argv[2]\n\nlines = open(log_path).readlines()\nevents = []\nprev_tokens = None\nprev_ts = None\n\nfor i, raw in enumerate(lines):\n try:\n obj = json.loads(raw)\n except Exception:\n continue\n tokens = (obj.get(\"usage\") or {}).get(\"input_tokens\")\n ts = obj.get(\"timestamp\")\n if tokens is None:\n continue\n if prev_tokens is not None and tokens \u003c prev_tokens * 0.5:\n events.append({\n \"line_number\": i + 1,\n \"timestamp\": ts or \"unknown\",\n \"tokens_before\": prev_tokens,\n \"tokens_after\": tokens,\n \"delta\": prev_tokens - tokens,\n \"retention_pct\": round(tokens / prev_tokens * 100, 1)\n })\n prev_tokens = tokens\n prev_ts = ts\n\nreport = {\n \"session_log\": log_path,\n \"analyzed_at\": datetime.now(timezone.utc).isoformat(),\n \"total_lines\": len(lines),\n \"compaction_count\": len(events),\n \"events\": events\n}\n\nos.makedirs(os.path.dirname(out_path), exist_ok=True)\nwith open(out_path, \"w\") as f:\n json.dump(report, f, indent=2)\n\nprint(json.dumps(report, indent=2))\nPYEOF\n```\n\n**Expected output (stdout + file):**\n\n```json\n{\n \"session_log\": \"/home/user/.claude/projects/abc123/logs/session.jsonl\",\n \"analyzed_at\": \"2026-03-21T15:00:00.000Z\",\n \"total_lines\": 312,\n \"compaction_count\": 2,\n \"events\": [\n {\n \"line_number\": 47,\n \"timestamp\": \"2026-03-21T14:32:07.441Z\",\n \"tokens_before\": 98234,\n \"tokens_after\": 8102,\n \"delta\": 90132,\n \"retention_pct\": 8.2\n },\n {\n \"line_number\": 203,\n \"timestamp\": \"2026-03-21T14:58:33.117Z\",\n \"tokens_before\": 112450,\n \"tokens_after\": 9341,\n \"delta\": 103109,\n \"retention_pct\": 8.3\n }\n ]\n}\n```\n\n**Verify:** `compaction_count` matches the number of events in the `events` array.\n\n\u003c/execution_process>\n\n\u003cbest_practices>\n\n1. **Always use absolute paths** for `SESSION_LOG` — relative paths fail when the shell CWD differs.\n2. **Check file size before parsing** — files >10MB should be processed line-by-line (streaming), not loaded into memory.\n3. **Threshold tuning** — the default 50% drop threshold catches most compactions. Use 30% for aggressive detection or 70% for conservative (fewer false positives on large tool outputs).\n4. **Handle missing timestamps gracefully** — not all JSONL lines include `timestamp`; fall back to line number as the event identifier.\n5. **Use `python3` pipeline for production** — the awk pipeline is fast for quick checks; the Python script is more reliable for malformed JSON or multi-byte characters.\n\n\u003c/best_practices>\n\u003c/instructions>\n\n\u003cexamples>\n\u003cusage_example>\n**Quick check — does this session have any compactions?**\n\n```bash\nSESSION_LOG=\"$HOME/.claude/projects/$(ls -t ~/.claude/projects | head -1)/logs/session.jsonl\"\n\ngrep '\"input_tokens\"' \"$SESSION_LOG\" \\\n | grep -oP '\"input_tokens\"\\s*:\\s*\\K[0-9]+' \\\n | awk 'NR>1 && ($1/prev)\u003c0.5 {print \"Compaction found: \"prev\" -> \"$1} {prev=$1}'\n```\n\n**Full structured report:**\n\n```bash\nSkill({ skill: 'compaction-detector' })\n# Then supply the session log path when prompted\n```\n\n**Pipe report into jq for summary:**\n\n```bash\nnode .claude/skills/compaction-detector/scripts/main.cjs --log \"$SESSION_LOG\" \\\n | jq '{count: .compaction_count, events: [.events[] | {ts: .timestamp, delta: .delta}]}'\n```\n\n\u003c/usage_example>\n\u003c/examples>\n\n## Search Protocol\n\nFor code discovery and search tasks, follow this priority order:\n\n1. \\`pnpm search:code \"\u003cquery>\"\\` (Primary intent-based search).\n2. \\`ripgrep\\` (for exact keyword/regex matches).\n3. semantic/structural search via code tools if available.\n\n## Memory Protocol (MANDATORY)\n\n**Before starting:**\n\\`\\`\\`bash\ncat .claude/context/memory/learnings.md\ncat .claude/context/memory/decisions.md\n\\`\\`\\`\n\n**After completing:**\n\n- New pattern -> \\`.claude/context/memory/learnings.md\\`\n- Issue found -> \\`.claude/context/memory/issues.md\\`\n- Decision made -> \\`.claude/context/memory/decisions.md\\`\n\n> ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.\n---","attachment_filenames":["commands/compaction-detector.md","references/research-requirements.md","rules/compaction-detector.md","schemas/input.schema.json","schemas/output.schema.json","templates/implementation-template.md"],"attachments":[{"filename":"commands/compaction-detector.md","content":"---\ndisable-model-invocation: true\n---\n\nInvoke the compaction-detector skill and follow it exactly as presented to you\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":119,"content_sha256":"f7bd492260609ac86dff135b58ddef5055b0dad1717630899ad40220012ecd16"},{"filename":"references/research-requirements.md","content":"# Compaction Detector Research Requirements (2026)\n\n## Verified Tech Stack\n\n- **Monitoring**: Token budget tracking\n- **Detection**: Redundancy analysis\n- **Alerting**: Proactive warnings\n\n## Detection Patterns\n\n### Token Budget Analysis\n\n- Current usage percentage\n- Growth rate projection\n- Critical threshold proximity\n\n### Redundancy Detection\n\n- Duplicate content identification\n- Repeated context patterns\n- Stale content detection\n\n## Source References\n\n- Context management patterns in agent-studio\n- Token budget optimization strategies\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":546,"content_sha256":"90ddbd9035d1d67f4089f9d824d5247d29e0ca56e214bba4c10c0a642b373e13"},{"filename":"rules/compaction-detector.md","content":"# compaction-detector Rules\n\n## Purpose\n\nDetect context compaction risks before they occur, enabling proactive context management.\n\n## Best Practices\n\n- Monitor token budget consumption\n- Detect redundant context buildup\n- Identify compaction triggers early\n- Suggest proactive compression\n\n## Integration Points\n\nSee SKILL.md for complete documentation.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":355,"content_sha256":"30f8578f2d8e06e44f8a367de1c68875e79e5809150bcf34c5577383834b09e4"},{"filename":"schemas/input.schema.json","content":"{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"compactionDetectorInput\",\n \"description\": \"Input schema for compaction-detector skill\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"target\": {\n \"type\": \"string\",\n \"description\": \"Target session or context to analyze\"\n },\n \"options\": {\n \"type\": \"object\",\n \"description\": \"Detection options\",\n \"additionalProperties\": true\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":466,"content_sha256":"2e541ccb491f97aafac1170adf10676ba0de35e3c8cea924862ec4ecfd6c92ef"},{"filename":"schemas/output.schema.json","content":"{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"compactionDetectorOutput\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"ok\": {\n \"type\": \"boolean\"\n },\n \"summary\": {\n \"type\": \"string\"\n },\n \"compactionRisk\": {\n \"type\": \"number\"\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":316,"content_sha256":"23be484fa8b8b8edf83ec72810445acfa5d041b73aecbcd53763db25c1c42dc1"},{"filename":"templates/implementation-template.md","content":"# compaction-detector Implementation Template\n\n## Goal\n\n- Define target outcome and acceptance criteria.\n\n## TDD\n\n1. Red\n2. Green\n3. Refactor\n\n## Verification\n\n- lint\n- format\n- targeted tests\n\n## Compaction Detection Checks\n\n1. Token budget monitoring\n2. Redundancy detection\n3. Compaction trigger identification\n4. Proactive alert generation\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":344,"content_sha256":"7036a04f08b0af94b158080ebfd1fec8d8008e7bcc8bfea5eead8228f2668377"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Compaction Detector","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003cidentity> Compaction Detector Skill - Detect Claude Code context compaction events in session JSONL logs. Identifies compaction boundaries, measures token delta before/after, reports compaction events with timestamps and token impact. \u003c/identity>","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003ccapabilities>","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detect context compaction events in Claude Code session JSONL logs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Measure token delta (before/after) at each compaction boundary","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report compaction events with ISO timestamps, turn index, and token impact","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Parse multi-session or single-session JSONL files","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Output structured compaction report to stdout or file \u003c/capabilities>","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"\u003cinstructions> \u003cexecution_process>","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Locate the Session Log File","type":"text"}]},{"type":"paragraph","content":[{"text":"Claude Code session logs are stored as JSONL files. Find the target log:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Default log location (adjust path for your OS)\n# macOS / Linux\nls -lt ~/.claude/projects/*/logs/*.jsonl | head -5\n\n# Windows (Git Bash / WSL)\nls -lt \"/c/Users/$USER/.claude/projects/\"*/logs/*.jsonl 2>/dev/null | head -5\n\n# Or search by project path hash\nfind ~/.claude/projects -name \"*.jsonl\" -newer /tmp/sentinel 2>/dev/null","type":"text"}]},{"type":"paragraph","content":[{"text":"Expected output:","type":"text","marks":[{"type":"strong"}]},{"text":" One or more ","type":"text"},{"text":".jsonl","type":"text","marks":[{"type":"code_inline"}]},{"text":" file paths with modification timestamps. ","type":"text"},{"text":"Verify:","type":"text","marks":[{"type":"strong"}]},{"text":" File is non-empty — ","type":"text"},{"text":"wc -l \u003cpath>","type":"text","marks":[{"type":"code_inline"}]},{"text":" should return > 0.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Identify Compaction Boundary Lines","type":"text"}]},{"type":"paragraph","content":[{"text":"Each line in a Claude Code session JSONL is a JSON object. Compaction events are identified by a sharp drop in ","type":"text"},{"text":"usage.input_tokens","type":"text","marks":[{"type":"code_inline"}]},{"text":" between consecutive turns — the context was summarised and reset to a smaller window.","type":"text"}]},{"type":"paragraph","content":[{"text":"Command — extract token counts with line numbers:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"SESSION_LOG=\"\u003cabsolute-path-to-session.jsonl>\"\n\ngrep -n '\"input_tokens\"' \"$SESSION_LOG\" \\\n | awk -F'[\":,]' '{\n for(i=1;i\u003c=NF;i++) {\n if($i ~ /input_tokens/) { print NR, $(i+2); break }\n }\n }'","type":"text"}]},{"type":"paragraph","content":[{"text":"Simpler alternative using ","type":"text","marks":[{"type":"strong"}]},{"text":"jq","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" (if available):","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"jq -r 'select(.usage.input_tokens != null) | [.timestamp, .usage.input_tokens, .usage.output_tokens] | @tsv' \\\n \"$SESSION_LOG\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Expected output:","type":"text","marks":[{"type":"strong"}]},{"text":" Tab-separated rows: ","type":"text"},{"text":"\u003ctimestamp> \u003cinput_tokens> \u003coutput_tokens>","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Detect Token Drop Events","type":"text"}]},{"type":"paragraph","content":[{"text":"A compaction event occurs when ","type":"text"},{"text":"input_tokens[N] \u003c input_tokens[N-1] * 0.5","type":"text","marks":[{"type":"code_inline"}]},{"text":" (tokens dropped by more than 50%).","type":"text"}]},{"type":"paragraph","content":[{"text":"Command — detect drops with awk:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"SESSION_LOG=\"\u003cabsolute-path-to-session.jsonl>\"\n\ngrep '\"input_tokens\"' \"$SESSION_LOG\" \\\n | grep -oP '\"input_tokens\"\\s*:\\s*\\K[0-9]+' \\\n | awk '\n NR > 1 {\n pct = ($1 / prev) * 100\n if (pct \u003c 50) {\n printf \"COMPACTION at line %d: %d -> %d tokens (%.1f%% retained)\\n\", \\\n NR, prev, $1, pct\n }\n }\n { prev = $1 }\n '","type":"text"}]},{"type":"paragraph","content":[{"text":"Expected output:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"COMPACTION at line 47: 98234 -> 8102 tokens (8.2% retained)\nCOMPACTION at line 203: 112450 -> 9341 tokens (8.3% retained)","type":"text"}]},{"type":"paragraph","content":[{"text":"Verify:","type":"text","marks":[{"type":"strong"}]},{"text":" Each reported line number corresponds to a real turn boundary. Cross-check with ","type":"text"},{"text":"sed -n '\u003cline>p' \"$SESSION_LOG\" | jq .timestamp","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Extract Timestamps for Each Compaction","type":"text"}]},{"type":"paragraph","content":[{"text":"For each compaction line number identified in Step 3, extract the ISO timestamp:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"SESSION_LOG=\"\u003cabsolute-path-to-session.jsonl>\"\nCOMPACTION_LINE=47 # Replace with actual line number\n\n# Extract timestamp from that JSONL line\nsed -n \"${COMPACTION_LINE}p\" \"$SESSION_LOG\" \\\n | grep -oP '\"timestamp\"\\s*:\\s*\"\\K[^\"]+'","type":"text"}]},{"type":"paragraph","content":[{"text":"Alternative with jq:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"sed -n \"${COMPACTION_LINE}p\" \"$SESSION_LOG\" | jq -r '.timestamp // \"unknown\"'","type":"text"}]},{"type":"paragraph","content":[{"text":"Expected output:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"2026-03-21T14:32:07.441Z","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Compute Token Delta Per Compaction Event","type":"text"}]},{"type":"paragraph","content":[{"text":"For each compaction boundary, calculate:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"tokens_before","type":"text","marks":[{"type":"code_inline"}]},{"text":": input_tokens on the line immediately before the drop","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"tokens_after","type":"text","marks":[{"type":"code_inline"}]},{"text":": input_tokens on the compaction line","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delta","type":"text","marks":[{"type":"code_inline"}]},{"text":": tokens_before - tokens_after","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"retention_pct","type":"text","marks":[{"type":"code_inline"}]},{"text":": (tokens_after / tokens_before) * 100","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Full pipeline — produces structured TSV:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"SESSION_LOG=\"\u003cabsolute-path-to-session.jsonl>\"\n\npaste \\\n \u003c(grep -n '\"input_tokens\"' \"$SESSION_LOG\" | grep -oP '^\\d+') \\\n \u003c(grep '\"input_tokens\"' \"$SESSION_LOG\" | grep -oP '\"input_tokens\"\\s*:\\s*\\K[0-9]+') \\\n | awk '\n NR > 1 {\n delta = prev_tokens - $2\n pct = ($2 / prev_tokens) * 100\n if (pct \u003c 50) {\n printf \"%s\\t%d\\t%d\\t%d\\t%.1f\\n\", \\\n prev_line, $1, prev_tokens, $2, pct\n }\n }\n { prev_line = $1; prev_tokens = $2 }\n ' \\\n | column -t -s

Compaction Detector <identity Compaction Detector Skill - Detect Claude Code context compaction events in session JSONL logs. Identifies compaction boundaries, measures token delta before/after, reports compaction events with timestamps and token impact. </identity <capabilities - Detect context compaction events in Claude Code session JSONL logs - Measure token delta (before/after) at each compaction boundary - Report compaction events with ISO timestamps, turn index, and token impact - Parse multi-session or single-session JSONL files - Output structured compaction report to stdout or file…

\\t' \\\n -N \"BOUNDARY_LINE,COMPACTION_LINE,TOKENS_BEFORE,TOKENS_AFTER,RETENTION_PCT\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Expected output:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"BOUNDARY_LINE COMPACTION_LINE TOKENS_BEFORE TOKENS_AFTER RETENTION_PCT\n46 47 98234 8102 8.2\n202 203 112450 9341 8.3","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Produce Structured Report","type":"text"}]},{"type":"paragraph","content":[{"text":"Emit the compaction report as JSON to stdout or save to a file:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"SESSION_LOG=\"\u003cabsolute-path-to-session.jsonl>\"\nOUTPUT_FILE=\".claude/context/tmp/compaction-report-$(date +%Y%m%d-%H%M%S).json\"\n\npython3 - \"$SESSION_LOG\" \"$OUTPUT_FILE\" \u003c\u003c'PYEOF'\nimport json, sys, os, re\nfrom datetime import datetime, timezone\n\nlog_path = sys.argv[1]\nout_path = sys.argv[2]\n\nlines = open(log_path).readlines()\nevents = []\nprev_tokens = None\nprev_ts = None\n\nfor i, raw in enumerate(lines):\n try:\n obj = json.loads(raw)\n except Exception:\n continue\n tokens = (obj.get(\"usage\") or {}).get(\"input_tokens\")\n ts = obj.get(\"timestamp\")\n if tokens is None:\n continue\n if prev_tokens is not None and tokens \u003c prev_tokens * 0.5:\n events.append({\n \"line_number\": i + 1,\n \"timestamp\": ts or \"unknown\",\n \"tokens_before\": prev_tokens,\n \"tokens_after\": tokens,\n \"delta\": prev_tokens - tokens,\n \"retention_pct\": round(tokens / prev_tokens * 100, 1)\n })\n prev_tokens = tokens\n prev_ts = ts\n\nreport = {\n \"session_log\": log_path,\n \"analyzed_at\": datetime.now(timezone.utc).isoformat(),\n \"total_lines\": len(lines),\n \"compaction_count\": len(events),\n \"events\": events\n}\n\nos.makedirs(os.path.dirname(out_path), exist_ok=True)\nwith open(out_path, \"w\") as f:\n json.dump(report, f, indent=2)\n\nprint(json.dumps(report, indent=2))\nPYEOF","type":"text"}]},{"type":"paragraph","content":[{"text":"Expected output (stdout + file):","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"session_log\": \"/home/user/.claude/projects/abc123/logs/session.jsonl\",\n \"analyzed_at\": \"2026-03-21T15:00:00.000Z\",\n \"total_lines\": 312,\n \"compaction_count\": 2,\n \"events\": [\n {\n \"line_number\": 47,\n \"timestamp\": \"2026-03-21T14:32:07.441Z\",\n \"tokens_before\": 98234,\n \"tokens_after\": 8102,\n \"delta\": 90132,\n \"retention_pct\": 8.2\n },\n {\n \"line_number\": 203,\n \"timestamp\": \"2026-03-21T14:58:33.117Z\",\n \"tokens_before\": 112450,\n \"tokens_after\": 9341,\n \"delta\": 103109,\n \"retention_pct\": 8.3\n }\n ]\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Verify:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"compaction_count","type":"text","marks":[{"type":"code_inline"}]},{"text":" matches the number of events in the ","type":"text"},{"text":"events","type":"text","marks":[{"type":"code_inline"}]},{"text":" array.","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003c/execution_process>","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003cbest_practices>","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Always use absolute paths","type":"text","marks":[{"type":"strong"}]},{"text":" for ","type":"text"},{"text":"SESSION_LOG","type":"text","marks":[{"type":"code_inline"}]},{"text":" — relative paths fail when the shell CWD differs.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check file size before parsing","type":"text","marks":[{"type":"strong"}]},{"text":" — files >10MB should be processed line-by-line (streaming), not loaded into memory.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Threshold tuning","type":"text","marks":[{"type":"strong"}]},{"text":" — the default 50% drop threshold catches most compactions. Use 30% for aggressive detection or 70% for conservative (fewer false positives on large tool outputs).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Handle missing timestamps gracefully","type":"text","marks":[{"type":"strong"}]},{"text":" — not all JSONL lines include ","type":"text"},{"text":"timestamp","type":"text","marks":[{"type":"code_inline"}]},{"text":"; fall back to line number as the event identifier.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text","marks":[{"type":"strong"}]},{"text":"python3","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" pipeline for production","type":"text","marks":[{"type":"strong"}]},{"text":" — the awk pipeline is fast for quick checks; the Python script is more reliable for malformed JSON or multi-byte characters.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"\u003c/best_practices> \u003c/instructions>","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003cexamples> \u003cusage_example> ","type":"text"},{"text":"Quick check — does this session have any compactions?","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"SESSION_LOG=\"$HOME/.claude/projects/$(ls -t ~/.claude/projects | head -1)/logs/session.jsonl\"\n\ngrep '\"input_tokens\"' \"$SESSION_LOG\" \\\n | grep -oP '\"input_tokens\"\\s*:\\s*\\K[0-9]+' \\\n | awk 'NR>1 && ($1/prev)\u003c0.5 {print \"Compaction found: \"prev\" -> \"$1} {prev=$1}'","type":"text"}]},{"type":"paragraph","content":[{"text":"Full structured report:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"Skill({ skill: 'compaction-detector' })\n# Then supply the session log path when prompted","type":"text"}]},{"type":"paragraph","content":[{"text":"Pipe report into jq for summary:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"node .claude/skills/compaction-detector/scripts/main.cjs --log \"$SESSION_LOG\" \\\n | jq '{count: .compaction_count, events: [.events[] | {ts: .timestamp, delta: .delta}]}'","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003c/usage_example> \u003c/examples>","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Search Protocol","type":"text"}]},{"type":"paragraph","content":[{"text":"For code discovery and search tasks, follow this priority order:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"`pnpm search:code \"\u003cquery>\"` (Primary intent-based search).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"`ripgrep` (for exact keyword/regex matches).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"semantic/structural search via code tools if available.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Memory Protocol (MANDATORY)","type":"text"}]},{"type":"paragraph","content":[{"text":"Before starting:","type":"text","marks":[{"type":"strong"}]},{"text":" ```bash cat .claude/context/memory/learnings.md cat .claude/context/memory/decisions.md ```","type":"text"}]},{"type":"paragraph","content":[{"text":"After completing:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"New pattern -> `.claude/context/memory/learnings.md`","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Issue found -> `.claude/context/memory/issues.md`","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Decision made -> `.claude/context/memory/decisions.md`","type":"text"}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.","type":"text"}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"compaction-detector","model":"sonnet","tools":["Read","Bash","Grep","TaskUpdate"],"author":"@skillopedia","source":{"stars":29,"repo_name":"agent-studio","origin_url":"https://github.com/oimiragieo/agent-studio/blob/HEAD/.claude/skills/compaction-detector/SKILL.md","repo_owner":"oimiragieo","body_sha256":"d8733cd61cca3cec01e897d6cebccf133194bbf58a2f9d86178447a8eb6a3491","cluster_key":"3be1a93e7e010088c4a54889bbb3d1ef8c8af82b5b5b73bcce1df13cd9695087","clean_bundle":{"format":"clean-skill-bundle-v1","source":"oimiragieo/agent-studio/.claude/skills/compaction-detector/SKILL.md","attachments":[{"id":"439129d8-78f5-5f63-b2fb-de15073a8f17","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/439129d8-78f5-5f63-b2fb-de15073a8f17/attachment.md","path":"commands/compaction-detector.md","size":119,"sha256":"f7bd492260609ac86dff135b58ddef5055b0dad1717630899ad40220012ecd16","contentType":"text/markdown; charset=utf-8"},{"id":"5b0293ce-e1cc-5e3b-a616-47ada499108f","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5b0293ce-e1cc-5e3b-a616-47ada499108f/attachment.cjs","path":"hooks/post-execute.cjs","size":191,"sha256":"1b1a83b1fd83d19c69b968c86088cbeb5e3ac8b601186e24f6d4bdbbb5658420","contentType":"text/plain; charset=utf-8"},{"id":"296c78a9-903c-5a01-b5eb-c4caa9adb904","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/296c78a9-903c-5a01-b5eb-c4caa9adb904/attachment.cjs","path":"hooks/pre-execute.cjs","size":297,"sha256":"540f641044de31ce41a1fe6237e9665829b59a498096648db775090d739abb2d","contentType":"text/plain; charset=utf-8"},{"id":"da79b9a3-c8ef-5e3e-8b7e-c849a658c534","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/da79b9a3-c8ef-5e3e-8b7e-c849a658c534/attachment.md","path":"references/research-requirements.md","size":546,"sha256":"90ddbd9035d1d67f4089f9d824d5247d29e0ca56e214bba4c10c0a642b373e13","contentType":"text/markdown; charset=utf-8"},{"id":"dac91330-ac1b-526d-931b-ae372091644c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/dac91330-ac1b-526d-931b-ae372091644c/attachment.md","path":"rules/compaction-detector.md","size":355,"sha256":"30f8578f2d8e06e44f8a367de1c68875e79e5809150bcf34c5577383834b09e4","contentType":"text/markdown; charset=utf-8"},{"id":"6857e7c1-cda7-5fdd-a0c8-8b37cb5f7022","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6857e7c1-cda7-5fdd-a0c8-8b37cb5f7022/attachment.json","path":"schemas/input.schema.json","size":466,"sha256":"2e541ccb491f97aafac1170adf10676ba0de35e3c8cea924862ec4ecfd6c92ef","contentType":"application/json; charset=utf-8"},{"id":"57a00931-25fd-5859-a567-74a733176b00","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/57a00931-25fd-5859-a567-74a733176b00/attachment.json","path":"schemas/output.schema.json","size":316,"sha256":"23be484fa8b8b8edf83ec72810445acfa5d041b73aecbcd53763db25c1c42dc1","contentType":"application/json; charset=utf-8"},{"id":"7dde990c-7348-56e0-aec6-142148b67df5","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7dde990c-7348-56e0-aec6-142148b67df5/attachment.cjs","path":"scripts/main.cjs","size":626,"sha256":"9c383583cd400c664efaa05eba26b1570b6815e7ccb696612f34284c28c9b287","contentType":"text/plain; charset=utf-8"},{"id":"d8297942-a7af-5770-87f9-1a06b29af582","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d8297942-a7af-5770-87f9-1a06b29af582/attachment.md","path":"templates/implementation-template.md","size":344,"sha256":"7036a04f08b0af94b158080ebfd1fec8d8008e7bcc8bfea5eead8228f2668377","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"93b562f6331ad3258386684a4066c2bf4b45641b81fea0f34e24bc51cb6fcd0e","attachment_count":9,"text_attachments":9,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":".claude/skills/compaction-detector/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"software-engineering","category_label":"Engineering"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"software-engineering","verified":true,"streaming":"supported","import_tag":"clean-skills-v1","invoked_by":"both","description":"Detect Claude Code context compaction events in session JSONL logs. Identifies compaction boundaries, measures token delta before/after, reports compaction events with timestamps and token impact.","trust_score":100,"best_practices":["Follow existing project patterns","Document all outputs clearly","Handle errors gracefully"],"error_handling":"graceful","lastVerifiedAt":"2026-03-23T23:18:04.669Z","provenance_sha":"4d2a925398265bc8","user_invocable":true}},"renderedAt":1782979831618}

Compaction Detector <identity Compaction Detector Skill - Detect Claude Code context compaction events in session JSONL logs. Identifies compaction boundaries, measures token delta before/after, reports compaction events with timestamps and token impact. </identity <capabilities - Detect context compaction events in Claude Code session JSONL logs - Measure token delta (before/after) at each compaction boundary - Report compaction events with ISO timestamps, turn index, and token impact - Parse multi-session or single-session JSONL files - Output structured compaction report to stdout or file…