/reflect-solution — solution recap deck Produce a single-file HTML slide deck summarizing the outcome of a Claude Code session: what shipped, why, and how it was verified. Audience: someone who wants the elevator pitch, not the journey. Sibling to . Where looks at wrong turns , this skill looks at what was delivered . Tool-call churn, retries, dead-ends, and reversals are excluded unless they shaped a final decision. Self-contained. This skill ships its own working starter ( ) — fonts, CSS tokens, all six content blocks, IntersectionObserver, keyboard nav, theme toggle. The agent's job is to…

, text, re.M):\n quotes.append(m.group(1))\n # Dedup, preserve order\n seen, out = set(), []\n for q in quotes:\n k = q.strip().lower()\n if k not in seen:\n seen.add(k)\n out.append(q.strip())\n return out\n\n\ndef summarize_tool_input(name, inp):\n \"\"\"One-line summary of a tool call's salient args.\"\"\"\n if not isinstance(inp, dict):\n return \"\"\n keys = [\"file_path\", \"path\", \"command\", \"pattern\", \"url\", \"prompt\", \"description\", \"query\"]\n parts = []\n for k in keys:\n if k in inp and inp[k]:\n v = str(inp[k])\n parts.append(f\"{k}={squash(v, 120)}\")\n if len(parts) >= 2:\n break\n if not parts:\n # Fallback: dump first ~120 chars of the whole input\n try:\n parts.append(squash(json.dumps(inp, ensure_ascii=False), 120))\n except Exception:\n parts.append(\"?\")\n return \", \".join(parts)\n\n\ndef render_tool_result(tr):\n body = tr.get(\"content\", \"\")\n if isinstance(body, list):\n body = \" \".join(\n x.get(\"text\", \"\") if isinstance(x, dict) else str(x) for x in body\n )\n body = str(body)\n low = body.lower()\n if any(m in low for m in REJECTION_MARKERS):\n return f\" ← [REJECTED] {squash(body, 160)}\"\n if tr.get(\"is_error\"):\n return f\" ← [ERR] {squash(body, 160)}\"\n return f\" ← {squash(body, 120)}\"\n\n\ndef render_assistant_text(text):\n text = strip_system_reminders(text).strip()\n if not text:\n return \"\"\n # Collapse internal whitespace lightly but keep paragraph structure for readability.\n lines = [l.rstrip() for l in text.splitlines()]\n lines = [l for l in lines if l.strip()]\n joined = \"\\n\".join(lines)\n return squash(joined, 600)\n\n\ndef compress(events):\n # Meta\n cwd = \"\"\n session_id = \"\"\n for ev in events:\n if not cwd and ev.get(\"cwd\"):\n cwd = ev.get(\"cwd\", \"\")\n if not session_id and ev.get(\"sessionId\"):\n session_id = ev.get(\"sessionId\", \"\")\n if cwd and session_id:\n break\n\n lines = []\n lines.append(f\"# Session transcript (compressed)\")\n lines.append(f\"\")\n lines.append(f\"- session: `{session_id}`\")\n lines.append(f\"- cwd: `{cwd}`\")\n lines.append(f\"- events: {len(events)}\")\n lines.append(f\"\")\n lines.append(f\"Legend: `→` assistant tool call · `←` tool result · `[ERR]` failed · `[REJECTED]` user blocked it · `[COMPACTED]` auto-summary block · `[INTERRUPT]` user interrupted\")\n lines.append(f\"\")\n lines.append(f\"---\")\n lines.append(f\"\")\n\n turn = 0\n first_user_goal = None\n user_count = 0\n rejection_count = 0\n interrupt_count = 0\n compaction_count = 0\n\n for ev in events:\n t = ev.get(\"type\")\n msg = ev.get(\"message\", {}) or {}\n content = msg.get(\"content\")\n\n if t == \"user\":\n turn += 1\n # Distinguish: tool_result-only message vs real user text\n if isinstance(content, list) and content and all(\n isinstance(b, dict) and b.get(\"type\") == \"tool_result\" for b in content\n ):\n for tr in content:\n line = render_tool_result(tr)\n if \"[REJECTED]\" in line:\n rejection_count += 1\n if \"[INTERRUPT\" in line.upper() or \"interrupted by user\" in line.lower():\n interrupt_count += 1\n lines.append(line)\n continue\n\n # Real user message (string or list with text blocks)\n if isinstance(content, str):\n raw = content\n elif isinstance(content, list):\n raw = \"\\n\".join(\n b.get(\"text\", \"\") for b in content if isinstance(b, dict) and b.get(\"type\") == \"text\"\n )\n else:\n raw = \"\"\n\n cleaned = strip_system_reminders(raw)\n\n if not cleaned or is_pure_boilerplate(cleaned):\n continue\n\n if is_compaction(cleaned):\n compaction_count += 1\n quotes = extract_compaction_quotes(cleaned)\n lines.append(f\"## T{turn} · USER [COMPACTED]\")\n lines.append(f\"\")\n lines.append(f\"_(auto-summary block — embedded user quotes extracted below)_\")\n if quotes:\n lines.append(f\"\")\n for q in quotes[:25]:\n lines.append(f\"- > {squash(q, 280)}\")\n lines.append(f\"\")\n continue\n\n user_count += 1\n if first_user_goal is None:\n first_user_goal = squash(cleaned, 300)\n\n lines.append(f\"## T{turn} · USER\")\n lines.append(f\"\")\n lines.append(squash(cleaned, 1200))\n lines.append(f\"\")\n\n elif t == \"assistant\":\n turn += 1\n if not isinstance(content, list):\n continue\n text_blocks = [b.get(\"text\", \"\") for b in content if isinstance(b, dict) and b.get(\"type\") == \"text\"]\n tool_uses = [b for b in content if isinstance(b, dict) and b.get(\"type\") == \"tool_use\"]\n\n text = \"\\n\".join(text_blocks).strip()\n rendered_text = render_assistant_text(text) if text else \"\"\n\n if not rendered_text and not tool_uses:\n continue\n\n header = f\"## T{turn} · ASSISTANT\"\n lines.append(header)\n if rendered_text:\n lines.append(f\"\")\n lines.append(rendered_text)\n for tu in tool_uses:\n name = tu.get(\"name\", \"?\")\n args = summarize_tool_input(name, tu.get(\"input\", {}))\n lines.append(f\"\")\n lines.append(f\"→ {name}({args})\")\n lines.append(f\"\")\n\n # Trailer with cheap structural summary (no classification — just counts)\n lines.append(f\"---\")\n lines.append(f\"\")\n lines.append(f\"## Structural summary\")\n lines.append(f\"\")\n lines.append(f\"- real user turns (after stripping system reminders): {user_count}\")\n lines.append(f\"- compaction blocks: {compaction_count}\")\n lines.append(f\"- tool rejections: {rejection_count}\")\n lines.append(f\"- explicit interrupts: {interrupt_count}\")\n if first_user_goal:\n lines.append(f\"- first user goal: {first_user_goal}\")\n lines.append(f\"\")\n lines.append(f\"_Analyze this transcript yourself: identify wrong-turn moments (corrections, retries, reversals, dead-ends, drift) by reading the user/assistant flow. Do not rely on counts alone._\")\n lines.append(f\"\")\n lines.append(f\"_This transcript is **lossy by design** — tool args, results, and long user messages are truncated. When an incident hinges on detail not visible here (exact rejected input, full error body, diff content), read the source JSONL directly with `Read` (scoped via `offset`/`limit`). The compressed view is an index; the JSONL is the source of truth._\")\n\n return \"\\n\".join(lines)\n\n\ndef main():\n if len(sys.argv) \u003c 2:\n print(\"usage: analyze_session.py \u003cjsonl>\", file=sys.stderr)\n sys.exit(2)\n path = Path(sys.argv[1])\n events = load_events(path)\n sys.stdout.write(compress(events))\n sys.stdout.write(\"\\n\")\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":10687,"content_sha256":"4445739247e297d9bd45e3c22d3825bbea4d7e7817ca6553096c88aea975e5ab"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"/reflect-solution — solution recap deck","type":"text"}]},{"type":"paragraph","content":[{"text":"Produce a single-file HTML slide deck summarizing the ","type":"text"},{"text":"outcome","type":"text","marks":[{"type":"strong"}]},{"text":" of a Claude Code session: what shipped, why, and how it was verified. Audience: someone who wants the elevator pitch, not the journey.","type":"text"}]},{"type":"paragraph","content":[{"text":"Sibling to ","type":"text"},{"text":"/reflect","type":"text","marks":[{"type":"code_inline"}]},{"text":". Where ","type":"text"},{"text":"/reflect","type":"text","marks":[{"type":"code_inline"}]},{"text":" looks at ","type":"text"},{"text":"wrong turns","type":"text","marks":[{"type":"em"}]},{"text":", this skill looks at ","type":"text"},{"text":"what was delivered","type":"text","marks":[{"type":"em"}]},{"text":". Tool-call churn, retries, dead-ends, and reversals are excluded unless they shaped a final decision.","type":"text"}]},{"type":"paragraph","content":[{"text":"Self-contained.","type":"text","marks":[{"type":"strong"}]},{"text":" This skill ships its own working starter (","type":"text"},{"text":"assets/template.html","type":"text","marks":[{"type":"code_inline"}]},{"text":") — fonts, CSS tokens, all six content blocks, IntersectionObserver, keyboard nav, theme toggle. The agent's job is to ","type":"text"},{"text":"fill the template with extracted content","type":"text","marks":[{"type":"em"}]},{"text":", not to rebuild the scaffolding from scratch.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User invokes ","type":"text"},{"text":"/reflect-solution","type":"text","marks":[{"type":"code_inline"}]},{"text":" (no args) → recap the ","type":"text"},{"text":"current session","type":"text","marks":[{"type":"strong"}]},{"text":" from the in-context conversation. Do ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" re-read the session JSONL — work from the agent's own memory of what was built.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User invokes ","type":"text"},{"text":"/reflect-solution \u003csession-id>","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"/reflect-solution \u003cpath-to-jsonl>","type":"text","marks":[{"type":"code_inline"}]},{"text":" → recap a different session. Run ","type":"text"},{"text":"scripts/analyze_session.py \u003cpath>","type":"text","marks":[{"type":"code_inline"}]},{"text":" directly (this skill runs forked — ","type":"text"},{"text":"context: fork","type":"text","marks":[{"type":"code_inline"}]},{"text":" — so the compressed transcript can enter your context safely). The script outputs a compact markdown transcript; ","type":"text"},{"text":"you","type":"text","marks":[{"type":"strong"}]},{"text":" then extract the solution.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Session JSONLs live under: ","type":"text"},{"text":"~/.claude/projects/\u003cencoded-cwd>/\u003csession-id>.jsonl","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"What to extract (menu, not template)","type":"text"}]},{"type":"paragraph","content":[{"text":"Outcome-focused. Drop the journey. An item belongs in the deck only if it would matter in a PR description.","type":"text"}]},{"type":"paragraph","content":[{"text":"The deck structure should fit the session — not the other way around.","type":"text","marks":[{"type":"strong"}]},{"text":" Pick from the menu below; skip what's irrelevant; add what isn't listed if the session calls for it. A 3-slide deck is fine. So is 8. Don't pad to hit a count, don't force a section just because it's in the list.","type":"text"}]},{"type":"paragraph","content":[{"text":"Common sections (use what fits):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Title","type":"text","marks":[{"type":"strong"}]},{"text":" — one-line elevator pitch of the shipped solution. Always include.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Problem / Goal","type":"text","marks":[{"type":"strong"}]},{"text":" — what the user brought. Skip if obvious from title.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Solution shipped","type":"text","marks":[{"type":"strong"}]},{"text":" — components, modules, behaviors. The ","type":"text"},{"text":"what","type":"text","marks":[{"type":"em"}]},{"text":", not the steps.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Artifacts","type":"text","marks":[{"type":"strong"}]},{"text":" — concrete files created/modified. Skip if there's only one file or the file list is trivial.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Key decisions & tradeoffs","type":"text","marks":[{"type":"strong"}]},{"text":" — locked-in choices + rejected alternatives. Skip if the session was straightforward (no real branch points).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verification / evidence","type":"text","marks":[{"type":"strong"}]},{"text":" — tests, builds, manual checks. If absent, say so — never invent.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Followups / known gaps","type":"text","marks":[{"type":"strong"}]},{"text":" — TODOs, deferred work. Skip if there are none.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Other sections that may earn a slide if the session reveals them: stakeholders, deadlines, related tickets/PRs, performance numbers, before/after diff, architecture sketch, a punchline pull-quote.","type":"text"}]},{"type":"paragraph","content":[{"text":"Always omit","type":"text","marks":[{"type":"strong"}]},{"text":": session metadata footer (id, date, turn count). The deck is about the solution, not the session.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Voice and language","type":"text"}]},{"type":"paragraph","content":[{"text":"The audience is technical (engineers, reviewers). Write like a commit message or a postmortem, not a launch announcement.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Direct and factual.","type":"text","marks":[{"type":"strong"}]},{"text":" State what is, what changed, what was decided. No hedging, no hype.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No marketing language.","type":"text","marks":[{"type":"strong"}]},{"text":" Banned: \"elegant\", \"powerful\", \"seamless\", \"robust\", \"leverages\", \"unlocks\", \"delivers\", \"best-in-class\", \"modern\", \"clean\", \"beautiful\", \"stunning\", \"delightful\". Also banned: rhetorical hooks (\"Imagine if…\", \"What if…\"), exclamation points, emoji.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No slogans or punchlines.","type":"text","marks":[{"type":"strong"}]},{"text":" Every line carries information. Skip the pull-quote slide unless the quote is a real artifact (a user message, a commit subject, a doc heading) — not something invented for flair.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No empty connectives.","type":"text","marks":[{"type":"strong"}]},{"text":" Drop \"In order to\", \"It is important to note that\", \"We are excited to\". Get to the noun.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Concrete over abstract.","type":"text","marks":[{"type":"strong"}]},{"text":" \"Replaced regex parser with PEG grammar in ","type":"text"},{"text":"parser/expr.ts","type":"text","marks":[{"type":"code_inline"}]},{"text":" — handles nested parens\" beats \"Improved parsing capabilities\".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Numbers when you have them.","type":"text","marks":[{"type":"strong"}]},{"text":" \"12 tests, 94% coverage\", \"reduced p99 from 240ms to 90ms\", \"3 files modified, 1 added\". Don't invent numbers.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Code identifiers in mono.","type":"text","marks":[{"type":"strong"}]},{"text":" Function names, file paths, flags, env vars → ","type":"text"},{"text":"\u003ccode>","type":"text","marks":[{"type":"code_inline"}]},{"text":". Prose stays prose.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Problem statement","type":"text"}]},{"type":"paragraph","content":[{"text":"This is the most important slide. A reader who only sees this slide should understand what was wrong before the session started. Treat it like the \"Background\" section of a bug ticket.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"One paragraph, 2–4 sentences.","type":"text","marks":[{"type":"strong"}]},{"text":" Or 3–5 short bullets. Not both.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Factual.","type":"text","marks":[{"type":"strong"}]},{"text":" State the prior state of the system, the observed defect or gap, and the constraint that forced the work. No motivation language (\"we wanted to…\"), no story arc.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Concrete.","type":"text","marks":[{"type":"strong"}]},{"text":" Name the file, the function, the error message, the failing case. If there was a ticket or incident, reference it.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No solution preview.","type":"text","marks":[{"type":"strong"}]},{"text":" The problem slide describes the problem only. What was done belongs on the next slide.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Easy to digest.","type":"text","marks":[{"type":"strong"}]},{"text":" Short sentences. One idea per sentence. If you need a comma-spliced run-on to fit, split it.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Good: ","type":"text"},{"text":"The deck template hard-coded a 7-section taxonomy. Sessions with no decisions or no followups produced empty slides. Agents had no guidance on when to drop a section.","type":"text","marks":[{"type":"em"}]}]},{"type":"paragraph","content":[{"text":"Bad: ","type":"text"},{"text":"We wanted to make the deck more flexible and adaptable so that it could elegantly handle a wider variety of sessions and deliver a more polished experience.","type":"text","marks":[{"type":"em"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Honesty rules","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Be specific. \"Added auth handling\" is useless; \"Added ","type":"text"},{"text":"validateBearerToken()","type":"text","marks":[{"type":"code_inline"}]},{"text":" in ","type":"text"},{"text":"src/auth/middleware.ts","type":"text","marks":[{"type":"code_inline"}]},{"text":", called from ","type":"text"},{"text":"app.use()","type":"text","marks":[{"type":"code_inline"}]},{"text":"\" is a recap.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Don't invent verification. If no tests were run, the Verification slide says \"No automated verification this session — manual smoke check only\" or similar.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Don't pad. A 4-slide deck is fine if the session was small.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Don't editorialize. Skip adjectives that don't carry information (\"nicely\", \"cleanly\", \"properly\"). If the change was correct, the diff shows it.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output","type":"text"}]},{"type":"paragraph","content":[{"text":"Resolve a temp dir from the environment, in this preference order:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"$TMPDIR","type":"text","marks":[{"type":"code_inline"}]},{"text":" (Unix/macOS)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"$TMP","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"$TEMP","type":"text","marks":[{"type":"code_inline"}]},{"text":" (Windows / Git Bash)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/tmp","type":"text","marks":[{"type":"code_inline"}]},{"text":" as fallback","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Create ","type":"text"},{"text":"\u003ctemp>/reflect-solution/","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"mkdir -p","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Write the deck as ","type":"text"},{"text":"\u003ctemp>/reflect-solution/\u003cslug>.html","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Slug rules","type":"text","marks":[{"type":"strong"}]},{"text":" — kebab-case, derived from the ","type":"text"},{"text":"solution","type":"text","marks":[{"type":"em"}]},{"text":" (not the session id):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"2–5 words, lowercase, hyphen-separated, ASCII only","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"describe what was shipped (e.g. ","type":"text"},{"text":"auth-middleware-rewrite","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"reflect-solution-skill-design","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"if the solution is unclear, fall back to ","type":"text"},{"text":"\u003cYYYY-MM-DD>-\u003ctopic>","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Open with ","type":"text"},{"text":"start \"\" \u003cpath>","type":"text","marks":[{"type":"code_inline"}]},{"text":" (Git Bash on Windows).","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":1},"content":[{"text":"How to render — fill the template, don't rebuild","type":"text"}]},{"type":"paragraph","content":[{"text":"The starter at ","type":"text"},{"text":"assets/template.html","type":"text","marks":[{"type":"code_inline"}]},{"text":" is a working deck: light theme by default (with a dark toggle persisted in localStorage), full slide shell, all six content blocks pre-styled, keyboard nav (↑/↓/Space/PageUp/PageDown/Home/End/j/k), touch swipe, IntersectionObserver reveals, nav rail, and ","type":"text"},{"text":"prefers-reduced-motion","type":"text","marks":[{"type":"code_inline"}]},{"text":" respect.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"assets/template.html","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"assets/viewport-base.css","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Copy","type":"text","marks":[{"type":"strong"}]},{"text":" the template to your temp output path as the deck's starting point.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Inline","type":"text","marks":[{"type":"strong"}]},{"text":" the full contents of ","type":"text"},{"text":"assets/viewport-base.css","type":"text","marks":[{"type":"code_inline"}]},{"text":" into the ","type":"text"},{"text":"\u003cstyle>","type":"text","marks":[{"type":"code_inline"}]},{"text":" block where the abridged base styles live (the comment marks the spot). Don't link to it — the deck must be a single self-contained HTML file.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Replace","type":"text","marks":[{"type":"strong"}]},{"text":" the ","type":"text"},{"text":"{{...}}","type":"text","marks":[{"type":"code_inline"}]},{"text":" placeholders with extracted content.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Duplicate / remove","type":"text","marks":[{"type":"strong"}]},{"text":" body-slide ","type":"text"},{"text":"\u003csection>","type":"text","marks":[{"type":"code_inline"}]},{"text":" elements as needed for your taxonomy. Keep one slide per taxonomy section by default; split if a section overflows density limits (see below). Update the nav rail ","type":"text"},{"text":"\u003ca>","type":"text","marks":[{"type":"code_inline"}]},{"text":" list to match.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pick the right content block","type":"text","marks":[{"type":"strong"}]},{"text":" per slide (see catalog) — don't default to bullets.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validate","type":"text","marks":[{"type":"strong"}]},{"text":" density and font/style rules before saving.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Light theme is the default","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003chtml data-theme=\"light\">","type":"text","marks":[{"type":"code_inline"}]},{"text":". Do NOT change this. The dark theme exists as a user-toggleable option (button bottom-right, key persists in localStorage). Both themes are wired; just leave them alone.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Content block catalog (copy from template, fill in)","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Block","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Class","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"When","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bullets","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cul class=\"bullets\">","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"4–6 substantial parallel items. Each ","type":"text"},{"text":"\u003cli>","type":"text","marks":[{"type":"code_inline"}]},{"text":" leads with ","type":"text"},{"text":"\u003cb>…\u003c/b> —","type":"text","marks":[{"type":"code_inline"}]},{"text":" then a sentence. Mono em-dash marker auto-rendered.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Artifact grid","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cdiv class=\"artifacts\">","type":"text","marks":[{"type":"code_inline"}]},{"text":" w/ ","type":"text"},{"text":".artifact","type":"text","marks":[{"type":"code_inline"}]},{"text":" cards","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Files created/modified. 2-col grid. Each card: ","type":"text"},{"text":".tag.added/.modified/.removed","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".path","type":"text","marks":[{"type":"code_inline"}]},{"text":" (mono), ","type":"text"},{"text":".purpose","type":"text","marks":[{"type":"code_inline"}]},{"text":" (sans). Banned: bulleted list of file paths.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Decision rows","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cdiv class=\"decisions\">","type":"text","marks":[{"type":"code_inline"}]},{"text":" w/ ","type":"text"},{"text":".decision","type":"text","marks":[{"type":"code_inline"}]},{"text":" rows","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Locked-in choices + rejected alternatives. Two columns (\"Chose\" / \"Rejected\") with reason underneath.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Code/output","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cpre class=\"codeblock\">","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Real command + output (8–10 lines max). ","type":"text"},{"text":".ln","type":"text","marks":[{"type":"code_inline"}]},{"text":" spans for line numbers.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pull-quote","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cdiv class=\"pullquote\">","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"One italic Newsreader sentence + mono attribution. For Title subtitle or a punchline slide.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Two-column prose","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cdiv class=\"cols2\">","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Dense paragraphs. Use for Problem when there's a story to tell.","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Slide shell (every body slide)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"html"},"content":[{"text":"\u003csection class=\"slide\" id=\"sN\">\n \u003cdiv class=\"eyebrow reveal\">\u003cspan class=\"num\">0N\u003c/span> SECTION\u003c/div>\n \u003ch2 class=\"title reveal\">\u003cem>Italic part\u003c/em> \u003cspan class=\"roman\">roman tail.\u003c/span>\u003c/h2>\n \u003cdiv class=\"hairline reveal\">\u003c/div>\n \u003cdiv class=\"body\">\n \u003c!-- one of the content blocks above -->\n \u003c/div>\n \u003cdiv class=\"hairline reveal\">\u003c/div>\n \u003cdiv class=\"footer reveal\">\n \u003cspan>EYEBROW · CONTEXT\u003c/span>\n \u003cspan class=\"right\">project / status\u003c/span>\n \u003c/div>\n\u003c/section>","type":"text"}]},{"type":"paragraph","content":[{"text":"The eyebrow + numbered title hairline anchors the top, the bottom hairline + footer rail anchors the bottom. Both are mandatory — they prevent the \"floating bullets in a void\" failure mode.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Title slide","type":"text"}]},{"type":"paragraph","content":[{"text":"Distinct layout (no eyebrow, no body):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"html"},"content":[{"text":"\u003csection class=\"slide title-slide\" id=\"s0\">\n \u003cdiv class=\"pitch reveal\">\u003cem>Italic pitch\u003c/em> \u003cspan class=\"roman\">roman tail.\u003c/span>\u003c/div>\n \u003cdiv class=\"meta reveal\">SOLUTION RECAP \u003cspan class=\"sep\">·\u003c/span> PROJECT-OR-CONTEXT\u003c/div>\n\u003c/section>","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Density (avoid empty slides)","type":"text"}]},{"type":"paragraph","content":[{"text":"The biggest failure mode is sparse slides — 3 short bullets in the upper third, the rest of the viewport empty. Counter it:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use the full viewport.","type":"text","marks":[{"type":"strong"}]},{"text":" Body content fills the middle 60–70vh between the title hairline and the footer rail. If you have less, switch to a richer content block (artifact grid, decision rows, code block) before adding padding.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Substantial bullets only.","type":"text","marks":[{"type":"strong"}]},{"text":" 4–6 bullets, each a full sentence with a bolded lead. If you only have 2 short bullets, merge with adjacent content or switch block types.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Footer rail is mandatory.","type":"text","marks":[{"type":"strong"}]},{"text":" Eyebrow + context on the left, project/status in italic on the right.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Banned","type":"text","marks":[{"type":"strong"}]},{"text":": floating bullets in the top third with >40% empty viewport below.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Typography rules","type":"text"}]},{"type":"paragraph","content":[{"text":"The template hard-codes these — don't override:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hero / slide titles","type":"text","marks":[{"type":"strong"}]},{"text":" → Newsreader italic, weight 500. Mix italic + roman in one title (","type":"text"},{"text":"\u003cem>…\u003c/em> \u003cspan class=\"roman\">…\u003c/span>","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Body prose & bullets","type":"text","marks":[{"type":"strong"}]},{"text":" → system sans, ","type":"text"},{"text":"clamp(0.95rem, 1.25vw, 1.1rem)","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Eyebrows / footer rail / mono labels","type":"text","marks":[{"type":"strong"}]},{"text":" → JetBrains Mono uppercase, ","type":"text"},{"text":"letter-spacing: 0.14–0.18em","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Inline code","type":"text","marks":[{"type":"strong"}]},{"text":" → ","type":"text"},{"text":"\u003ccode>literal\u003c/code>","type":"text","marks":[{"type":"code_inline"}]},{"text":" — the template enforces ","type":"text"},{"text":"display: inline","type":"text","marks":[{"type":"code_inline"}]},{"text":" so it does NOT break across lines. Never wrap a code span in a flex-column container.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Forbidden fonts","type":"text","marks":[{"type":"strong"}]},{"text":": Bodoni Moda, DM Sans, Plus Jakarta Sans, Space Grotesk, Archivo Black, Outfit, Fraunces, Cormorant, Inter, Roboto, Arial.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Animation guidance","type":"text"}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"assets/animation-patterns.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the slim crib sheet (entrance variants, what NOT to do, common breakage). The default ","type":"text"},{"text":".reveal","type":"text","marks":[{"type":"code_inline"}]},{"text":" class with stagger is already wired in ","type":"text"},{"text":"template.html","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"CSS gotcha","type":"text"}]},{"type":"paragraph","content":[{"text":"Do not negate CSS functions directly. ","type":"text"},{"text":"right: -clamp(...)","type":"text","marks":[{"type":"code_inline"}]},{"text":" is silently ignored. Use ","type":"text"},{"text":"right: calc(-1 * clamp(...))","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":1},"content":[{"text":"Files in this skill","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SKILL.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — this file: taxonomy, render workflow.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"assets/template.html","type":"text","marks":[{"type":"code_inline"}]},{"text":" — ","type":"text"},{"text":"working starter deck","type":"text","marks":[{"type":"strong"}]},{"text":". Light by default, dark toggle, all six content blocks pre-styled, keyboard nav + IntersectionObserver wired. Copy-and-fill, don't rebuild.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"assets/viewport-base.css","type":"text","marks":[{"type":"code_inline"}]},{"text":" — copied verbatim from ","type":"text"},{"text":"frontend-slides","type":"text","marks":[{"type":"code_inline"}]},{"text":". Inline its full contents in the ","type":"text"},{"text":"\u003cstyle>","type":"text","marks":[{"type":"code_inline"}]},{"text":" block of the generated deck.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"assets/animation-patterns.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — slim animation reference (variants, don'ts, troubleshooting).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"scripts/analyze_session.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" — JSONL compressor (duplicated from the ","type":"text"},{"text":"reflect","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill, independent). Strips system reminders, preserves real user messages, collapses tool calls/results to one-liners. Output is markdown to stdout. Use only for explicit sessions — never on the current in-context session.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"reference/example-deck.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — fully worked example showing how a real session maps to the seven sections (treat as inspiration for tone and density, not a template).","type":"text"}]}]}]},{"type":"heading","attrs":{"level":1},"content":[{"text":"Workflow","type":"text"}]},{"type":"paragraph","content":[{"text":"Default (no args)","type":"text","marks":[{"type":"strong"}]},{"text":" — recap current session:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"From conversation memory, walk the taxonomy: title, problem, solution, artifacts, decisions, verification, followups. Drop everything that's journey-not-outcome.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For each section, pick a content block. If a section has thin content, switch block types or merge.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Resolve temp dir, derive slug.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"assets/template.html","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"assets/viewport-base.css","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Copy the template to ","type":"text"},{"text":"\u003ctemp>/reflect-solution/\u003cslug>.html","type":"text","marks":[{"type":"code_inline"}]},{"text":". Inline ","type":"text"},{"text":"viewport-base.css","type":"text","marks":[{"type":"code_inline"}]},{"text":" into the ","type":"text"},{"text":"\u003cstyle>","type":"text","marks":[{"type":"code_inline"}]},{"text":" block. Replace placeholders. Add/remove body slides. Update nav rail.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Open with ","type":"text"},{"text":"start \"\" \u003cpath>","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Explicit session","type":"text","marks":[{"type":"strong"}]},{"text":" — ","type":"text"},{"text":"/reflect-solution \u003cid-or-path>","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Resolve to a JSONL path (if just an id, look under ","type":"text"},{"text":"~/.claude/projects/\u003cencoded-cwd>/\u003cid>.jsonl","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"scripts/analyze_session.py \u003cpath>","type":"text","marks":[{"type":"code_inline"}]},{"text":". Skill is forked, so the compressed transcript is safe in context.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Extract the taxonomy from the transcript yourself.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fallback to JSONL when transcript is lossy.","type":"text","marks":[{"type":"strong"}]},{"text":" Transcript truncates tool args/results and long messages. When detail matters (full file lists, full diff, full user goal statement), ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":" the JSONL directly with ","type":"text"},{"text":"offset","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"limit","type":"text","marks":[{"type":"code_inline"}]},{"text":" scoped to the relevant turn.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Steps 2–6 from the default workflow.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":1},"content":[{"text":"Notes","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The deck is the elevator pitch, not the changelog. If you find yourself listing every Edit, you're recapping the journey, not the solution — collapse to artifacts.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If verification was absent, say so. A missing-evidence slide is more useful than a fabricated one.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Decisions slide should include ","type":"text"},{"text":"what was rejected and why","type":"text","marks":[{"type":"em"}]},{"text":", not just what was chosen.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The skill is free to evolve its style independently of ","type":"text"},{"text":"frontend-slides","type":"text","marks":[{"type":"code_inline"}]},{"text":". Re-copy ","type":"text"},{"text":"viewport-base.css","type":"text","marks":[{"type":"code_inline"}]},{"text":" if you want to pick up upstream improvements.","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","author":"@skillopedia","source":{"stars":127,"repo_name":"claude-code-rules","origin_url":"https://github.com/nikiforovall/claude-code-rules/blob/HEAD/plugins/handbook-reflect/skills/reflect-solution/SKILL.md","repo_owner":"nikiforovall","body_sha256":"40af30c64f5ae48a698dda8afbabf2d712e9be077acfa406bd10e05db6eef348","cluster_key":"04449c4021894395caf274fec8f48ae105a13da4e9dc8e7e8d49f1282afa3ef7","clean_bundle":{"format":"clean-skill-bundle-v1","source":"nikiforovall/claude-code-rules/plugins/handbook-reflect/skills/reflect-solution/SKILL.md","attachments":[{"id":"09f6cd69-1912-584c-9e4a-d0061a9a9d23","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/09f6cd69-1912-584c-9e4a-d0061a9a9d23/attachment.md","path":"assets/animation-patterns.md","size":2550,"sha256":"bd425a209db275f2be1d49780c2fbf4a8a3a8dd8385988e026444e382a3ff65b","contentType":"text/markdown; charset=utf-8"},{"id":"859e14aa-c06c-5cae-ad33-8524c3ae3e3c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/859e14aa-c06c-5cae-ad33-8524c3ae3e3c/attachment.html","path":"assets/template.html","size":17011,"sha256":"fae8f8aaf99e1a11d7e45de8d219e5ae1b5c1d51fb9cb3f3f6e56371a9fd36a4","contentType":"text/html; charset=utf-8"},{"id":"900dfba8-90f8-5a20-abc7-3cb9740f10c8","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/900dfba8-90f8-5a20-abc7-3cb9740f10c8/attachment.css","path":"assets/viewport-base.css","size":4037,"sha256":"dab42c1a556a0fa51d3c39f7edfb93d8303e5c29625ade479a18ba97f2640734","contentType":"text/css; charset=utf-8"},{"id":"6cbbe07a-c45d-5352-a8e8-f1f23900baa2","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6cbbe07a-c45d-5352-a8e8-f1f23900baa2/attachment.md","path":"reference/example-deck.md","size":4112,"sha256":"8198dc4434dcb142241218cf1ea7bcdb6abe29f8ec10110f4a6a06fd8b2dd8ab","contentType":"text/markdown; charset=utf-8"},{"id":"74ffe6a6-eaa1-5030-a74f-90eb54fb2960","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/74ffe6a6-eaa1-5030-a74f-90eb54fb2960/attachment.py","path":"scripts/analyze_session.py","size":10687,"sha256":"4445739247e297d9bd45e3c22d3825bbea4d7e7817ca6553096c88aea975e5ab","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"8aa63c74ca78a6143ebfbb1f10df727757176a8ba2b12916dd274e47b5b66e4b","attachment_count":5,"text_attachments":5,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"plugins/handbook-reflect/skills/reflect-solution/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","import_tag":"clean-skills-v1","_yaml_error":"YAMLException: bad indentation of a mapping entry (4:16)\n\n 1 | name: reflect-solution\n 2 | description: Summarize WHAT WAS SHIPPED in a Cl ...\n 3 | context: fork\n 4 | argument-hint: `\u003ccurrent_session>"}},"renderedAt":1782979533650}

/reflect-solution — solution recap deck Produce a single-file HTML slide deck summarizing the outcome of a Claude Code session: what shipped, why, and how it was verified. Audience: someone who wants the elevator pitch, not the journey. Sibling to . Where looks at wrong turns , this skill looks at what was delivered . Tool-call churn, retries, dead-ends, and reversals are excluded unless they shaped a final decision. Self-contained. This skill ships its own working starter ( ) — fonts, CSS tokens, all six content blocks, IntersectionObserver, keyboard nav, theme toggle. The agent's job is to…