{"slug":"slideops","title":"slideops","summary":"Use when the user asks for slides, a slide deck, or a presentation about a code repository, one of its subsystems, a feature, an architecture area, or its recent changes. Triggers include \"make slides\", \"build a slide deck\", \"create a presentation\", \"HTML slides for this repo\", \"","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-07T18:43:43.965809Z","repo":{"url":"https://github.com/glukicov/slideops","stars":53,"forks":3,"license":"MIT","updatedAt":"2026-09-03T15:05:45Z"},"bodyHtml":"<hr>\n<h2>name: slideops\ndescription: 'Use when the user asks for slides, a slide deck, or a presentation about a code repository, one of its subsystems, a feature, an architecture area, or its recent changes. Triggers include \"make slides\", \"build a slide deck\", \"create a presentation\", \"HTML slides for this repo\", \"overview deck\", \"team update slides\", \"slides for our latest changes\", or naming a topic and asking for a deck about it. Also use when the user asks whether an existing deck still matches the code, or wants one rechecked, refreshed, or kept in sync automatically: \"is this deck still accurate\", \"check the slides against the code\", \"did anything we documented change\", \"refresh the architecture deck\", \"these docs are stale\", \"fail the build when the deck stops matching the code\", or asks to wire that check into CI, a pull request, or an agent hook. Also use for Markdown documentation instead of slides (\"write markdown docs\", \"a design doc with citations\", \"docs that know when they go stale\"), including PDF export of a doc.'\nlicense: MIT\ncompatibility: Needs a headless Chrome or Chromium binary (Playwright cache or system install) and Python 3 for the verification pass. Reads the target repository with git. Network access only if you opt into Mermaid diagrams (one npx download) or brand-colour extraction; everything else works offline.\nmetadata:\nauthor: Gleb Lukicov\nversion: 1.1.2</h2>\n<h1>SlideOps: generate a deck from a repository, and keep it true</h1>\n<p>This skill has two jobs, and the second one is the point.</p>\n<p><strong>Build</strong>: turn a repository into a deck whose every claim came from the code, not from a\nmodel's impression of the code. <strong>Keep in sync</strong>: make that deck able to prove, months\nlater, whether it still matches the repository, cheaply enough that nobody has to\nremember to care.</p>\n<p>The mechanism joining them is a citation. Every quoted snippet records the file, the line\nrange, and a hash of those source lines at build time, and the deck records the commit it\nwas built from. That turns \"is this deck still accurate?\" from a question somebody has to\nanswer by reading into a command that answers itself:</p>\n<pre><code>python3 scripts/check.py docs/slides/ --repo .\n</code></pre>\n<p>Standard library only. No model, no network, no tokens, milliseconds to run. Two scripts\nship with this skill and do all of it: <a href=\"scripts/cite.py\"><code>scripts/cite.py</code></a> writes the\ncitations while you build, and <a href=\"scripts/check.py\"><code>scripts/check.py</code></a> reads them back\nafterwards. Writing the citations as you go (Step 3) is therefore not optional decoration:\nit is the entire reason the deck can be maintained instead of rewritten. See\n<a href=\"references/freshness.md\"><code>references/freshness.md</code></a> for the mechanism and\n<a href=\"references/automation.md\"><code>references/automation.md</code></a> for wiring it into pull requests,\nscheduled refreshes, and agent hooks.</p>\n<h2>Which job is this?</h2>\n<ul>\n<li>The user wants a <strong>new deck</strong>: start at Step 0 below.</li>\n<li>The user wants <strong>Markdown documentation instead of slides</strong> (a doc that lives in the\nrepo and renders on GitHub, with the same citations and the same freshness check):\nfollow <a href=\"references/markdown.md\"><code>references/markdown.md</code></a>. It reuses this file's\nresearch, confidentiality, and refresh rules and swaps the build and verify steps;\n<a href=\"references/markdown-pdf.md\"><code>references/markdown-pdf.md</code></a> covers exporting such a doc\nto PDF. Checking or refreshing an existing <code>.md</code> doc is the same <code>check.py</code> workflow\nas decks; sweeps pick both up together.</li>\n<li>The user is asking whether an existing deck is <strong>still accurate</strong>, wants one\n<strong>refreshed</strong>, or wants the check <strong>automated</strong>: go straight to\n<a href=\"#refreshing-an-existing-deck\">Refreshing an existing deck</a> near the end. Do not rebuild\na deck from scratch because a few slides drifted.</li>\n</ul>\n<hr>\n<p>Produces a single self-contained HTML slide deck (no build step, no CDN dependencies):\none 1280×720 slide per screen, click/arrow-key/URL-hash navigation, a progress bar and\nslide counter, an Esc-toggled overview grid (deep-linkable as <code>#overview</code>), optional\nper-slide speaker notes (<code>&lt;aside class=\"notes\"&gt;</code>, toggled with N, invisible in exports),\nand, on request, a paginated PDF export. Every slide is grounded in the real repository:\nreal code snippets, real commands, real screenshots, real numbers. Nothing is invented\nto fill space.</p>\n<p>A worked example ships with the skill: <a href=\"examples/skill-demo.html\"><code>examples/skill-demo.html</code></a>\nis a 17-slide deck about this skill, built by this skill, showing the patterns, all four\ntheme presets on real decks, and an inlined Mermaid diagram.</p>\n<p>Two starting points, chosen with the user up front:</p>\n<ul>\n<li><strong>General overview</strong>: what the project is, how to install/set it up, how to run it,\nits main features, its architecture at a glance. Mirrors a README/onboarding walkthrough.</li>\n<li><strong>Focused topic</strong>: one subsystem, one recent change, one architecture decision, one\nworkflow. Goes deep rather than wide.</li>\n</ul>\n<hr>\n<h2>Step 0: Orient, then ask</h2>\n<p>Spend ~2 minutes scanning the repo <strong>before asking anything</strong>, so every question you ask\nis concrete and every option you offer actually exists: read the README and the\nmanifest(s) that define the product (per-app in a monorepo), run <code>git log --oneline -15</code>\nand glance at the top-level tree and <code>docs/</code>, and check whether <code>docs/slides/</code> already has\ndecks (open one: its title slide, theme and build stamp show the local conventions). Do\nnot start slide research yet; this pass is only to ask good questions. The scan itself may hit stale doc pointers; note them\nand move on (Step 1's code-wins rule deals with drift later).</p>\n<p>What you find shapes the candidates:</p>\n<ul>\n<li><strong>Existing decks remove or reframe candidates.</strong> A topic an existing deck already covers\nis off the proposal list, unless meaningful commits have landed since that deck's date,\nin which case offer \"update the existing X deck\" as its own candidate. Disclose the\nexisting decks in one line at the top of the intake.</li>\n<li><strong>Skip meta noise in \"why now\".</strong> Recent commits about tooling, docs, or slide decks\nthemselves don't justify a deck; reach back to the most recent <em>product</em> activity, and\ndon't re-justify a candidate with work an existing deck already presents.</li>\n</ul>\n<p>Then ask everything in <strong>one compact intake</strong> (use your environment's structured-question\ntool if it has one; otherwise a single message with lettered options). Mark the default\nin each list, skip any item the user already answered, and never exceed these six:</p>\n<ol>\n<li><strong>Topic.</strong> Propose 3-4 concrete candidates you found in the scan, each with a one-line\n\"why now\" (e.g. \"v2.3 shipped last week: a what's-new deck\", \"the <code>sync/</code> subsystem is\nthe largest and undocumented: a deep dive\", \"no onboarding doc exists: a general\noverview\"), plus \"something else: tell me\". Never ask a bare \"what should the deck be\nabout?\": the scan is what makes this question answerable in one click. Mark as default\nthe candidate you would genuinely bet the user wants given the repo's core domain and\nits deck history (a core subsystem with zero coverage usually beats a\nrecently-changed-but-already-presented area), not mechanically the most recent change.</li>\n<li><strong>Audience and venue.</strong> New joiners (onboarding) · team sprint/standup · stakeholder or\nexec review · conference/meetup. This drives jargon level, pacing, and the Sizing row.</li>\n<li><strong>Length.</strong> Offer the Sizing table rows as time slots (\"5-min lightning ≈ 8-15 slides\",\n\"20-min deep dive ≈ 12-20\", \"45-min onboarding ≈ 20-35\").</li>\n<li><strong>Design.</strong> Theme menu from <a href=\"references/themes.md\"><code>references/themes.md</code></a>: Ledger\nLight (default) · Ledger Dark · midnight · graphite · match a brand (ask for the URL/style\nguide; fetch it for real per <a href=\"references/style-guide.md\"><code>references/style-guide.md</code></a>\n§ Theming, never invent colors from a description). Optionally a font choice\n(themes.md § Font options) if the user signals caring about typography. If the user\nhesitates between themes or asks to see them, show rather than tell: copy the\ntemplate, swap in each candidate preset's <code>:root</code> block, screenshot the title slide\nof each (the recipe in <a href=\"references/verification.md\"><code>references/verification.md</code></a>),\nand present the images side by side before they choose.</li>\n<li><strong>Scope and sensitive data.</strong> Confirm what the deck may draw on and who will see it:\n\"internal team\" and \"conference talk\" are different redaction bars. Name anything\noff-limits up front (unannounced features, customer names, internal hostnames). The\ndefaults in \"The confidentiality rule\" below apply regardless of the answer.</li>\n<li><strong>Extras.</strong> Three independent toggles, so don't letter them as alternatives: state the\ndefaults and ask the user to object to any (\"PDF export: no · Mermaid diagrams: built-in\nflow boxes only (Mermaid needs one-time <code>npx</code> network access, see\n<a href=\"references/diagrams.md\"><code>references/diagrams.md</code></a>) · output:\n<code>&lt;repo&gt;/docs/slides/&lt;topic-slug&gt;-&lt;date&gt;.html</code>\"). The deck (plus a PDF if asked for) is\nthe only file this produces, so there is nothing else to agree on.</li>\n</ol>\n<p>For \"what changed\" style decks, also pin the <strong>recency window</strong> (a date range or \"since\nthe last release\") and resolve it with <code>git log</code> before writing anything, not from memory.</p>\n<p><strong>The outline checkpoint.</strong> After the first research pass, show the user a proposed\n<strong>topic list and slide flow</strong> (like a table of contents) and get a thumbs-up <em>before</em>\nwriting any HTML: this is the single highest-leverage checkpoint. Building 25 slides\naround the wrong 6 topics wastes far more time than a 30-second review would have.\nSkip the checkpoint only when one of these observable conditions holds:</p>\n<ul>\n<li>the user already gave you an explicit topic list or outline (not just scope/audience), or</li>\n<li>you are running non-interactively (no user available to answer): proceed, and say in\nyour final summary that the outline was not reviewed.</li>\n</ul>\n<h2>The confidentiality rule (applies to every step)</h2>\n<p>A deck is a document that leaves the repository: it gets emailed, screen-shared, and\nposted. Treat everything you put on a slide as public from the moment it is written.</p>\n<p><strong>Never read for slide content, and never quote:</strong> <code>.env</code> and any <code>*.env*</code>, key/certificate\nfiles (<code>*.pem</code>, <code>*.key</code>, <code>id_rsa*</code>, <code>*.p12</code>, service-account JSON), <code>secrets/</code>,\n<code>credentials*</code>, <code>.npmrc</code>/<code>.pypirc</code>/<code>.netrc</code>, CI secret definitions, production logs,\ndatabase dumps, fixtures containing real customer data, and any path the repository's own\nignore files exclude. If a file you need is on this list, describe its <em>shape</em> (\"a service\naccount JSON, mounted at runtime\") instead of its content.</p>\n<p><strong>Redact even from files that are safe to quote:</strong> credentials, tokens, API keys, private\nhostnames and internal URLs, IP addresses, account and customer identifiers, personal\nnames and emails that are not public contributors, and precise infrastructure paths where\na generic description carries the same meaning. Replace with a clear placeholder\n(<code>&lt;project-id&gt;</code>, <code>db.internal.example</code>), never a plausible-looking fake.</p>\n<p><strong>Ask when it is the user's call, not yours:</strong> if a slide would be materially weaker\nwithout a detail that looks sensitive (an internal hostname in a diagram, a real customer\ncount, an unannounced feature name), ask the user before including it, and say what you\nare about to expose. Silence is not consent.</p>\n<p><strong>Screenshots carry more than you think.</strong> A screenshot of a terminal, dashboard, or\neditor also captures window titles, file trees, branch names, ticket numbers, other\ntabs, and notifications. Crop to the region that makes the point, and read the image back\nbefore embedding it.</p>\n<p>Verification includes a redaction scan of the finished artifacts: see\n<a href=\"references/verification.md\"><code>references/verification.md</code></a> § Redaction scan.</p>\n<h2>Step 1: Research (never skip, never approximate)</h2>\n<p>The deck is only as credible as its weakest verified claim. For every slide you plan to\nwrite:</p>\n<ul>\n<li><strong>Respect the confidentiality rule below</strong> when choosing what to open and what to quote:\nsecrets, credentials, production logs, and real customer data are out of scope for slide\ncontent even when they would be interesting.</li>\n<li><strong>Read the real files.</strong> README(s), package manifest (<code>pyproject.toml</code>, <code>package.json</code>,\n<code>go.mod</code>, …), the actual source of anything you plan to quote or diagram, existing\narchitecture docs, existing agent-instruction files (<code>CLAUDE.md</code>, <code>.agents/skills/</code>,\n<code>.claude/skills/</code>, and similar: these often already describe real user-facing\ncapabilities accurately, a goldmine for \"say to your assistant\" style bubbles).</li>\n<li><strong>Prefer code intelligence / grep+view over guessing.</strong> If you're about to describe a\nclass, a config schema, a CLI flag, or a directory layout, go find it and read it. If you\ncan't find where a claim comes from, don't make the claim.</li>\n<li><strong>When the repo's own docs contradict its code, the code wins.</strong> Docs drift; verify any\ndoc-sourced claim against the current source before putting it on a slide, and if the\ndrift is itself notable, say so on the slide rather than repeating the stale claim.</li>\n<li><strong>For \"what's new\" / recent-changes decks:</strong> use <code>git log --oneline --since=... -- path</code>\n(and <code>git log -p</code> for real diff content) to ground every \"shipped this month\" claim in an\nactual commit, not a vague impression. Cross-check version bumps (e.g. <code>pyproject.toml</code>\nhistory) against the commits that produced them. A file added inside your window may\nalready be deleted again by a later commit: <code>git show &lt;commit&gt;:&lt;path&gt;</code> recovers it, and\nthe deletion may itself be worth a slide note.</li>\n<li><strong>For architecture/flow diagrams:</strong> trace the real call path (imports, function calls,\nthe actual sequence a request follows) rather than inferring structure from the file tree\nalone. A plausible-looking but wrong diagram is worse than a smaller, correct one. For\nrendering (built-in flow boxes vs pre-rendered Mermaid SVG), see\n<a href=\"references/diagrams.md\"><code>references/diagrams.md</code></a>.</li>\n<li><strong>For screenshots/plots:</strong> use only real artifacts: a real chart the repo's own tooling\nproduced, a real trace/log screenshot, a real terminal output. If a genuinely useful image\ndoesn't exist yet, either generate it by actually running the repo's own code (reuse its\nexisting plotting/export/reporting functions against real data on disk rather than\nwriting new ad hoc plotting code) or fall back to a non-image pattern; never fabricate\na fake chart.</li>\n<li><strong>Delegate research for large/unfamiliar repos.</strong> If the repo is large or you're\nunfamiliar with it, a read-only exploration sub-agent pass (\"find the CLI entry points,\nthe README, the test/dataset conventions, and any existing architecture docs\") is worth\nit before drafting the topic list, if your environment provides sub-agents. Don't\ndelegate the actual slide writing: that needs your own judgment about pacing and what's\ngenuinely interesting.</li>\n</ul>\n<h2>Step 2: Draft the topic list</h2>\n<p>Before writing HTML, sketch the flow as a short outline (title → agenda → N sections, each\nwith 2-6 slides → close) and share it per the outline checkpoint above. A well-paced deck\nopens with a title slide, an agenda, and 2-3 \"the project in one picture\" slides (what it\nis, one or two real results/screenshots), then either a section-divider-led deep dive per\ntopic (for a general/multi-topic deck) or straight into content (for a focused deck), and\nends on a closing/roadmap slide. Typical density: <strong>1 idea per slide</strong>; resist cramming two\nideas onto one slide just to save a slide.</p>\n<h3>Sizing</h3>\n<p>Section dividers count toward the slide budget.</p>\n<table>\n<thead>\n<tr>\n<th>Deck type</th>\n<th>Rough slide count</th>\n<th>Section dividers?</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Lightning update (one topic, one meeting)</td>\n<td>8-15</td>\n<td>No, straight into content</td>\n</tr>\n<tr>\n<td>Focused deep dive (one subsystem/feature)</td>\n<td>12-20</td>\n<td>Optional, only if it has 2+ sub-topics</td>\n</tr>\n<tr>\n<td>General overview / onboarding</td>\n<td>20-35</td>\n<td>Yes, one per major section</td>\n</tr>\n</tbody>\n</table>\n<h2>Step 3: Build</h2>\n<ol>\n<li><p>Copy <a href=\"assets/template.html\"><code>assets/template.html</code></a> to the output path. It already has\nthe full verified CSS + navigation JS; do not rewrite either from scratch. All slide\nmarkup lives between the <code>&lt;!-- SLIDES START --&gt;</code> and <code>&lt;!-- SLIDES END --&gt;</code> markers;\neverything outside them stays untouched (a scripted splice against those markers is the\neasiest way to replace the body in one pass), with two exceptions: set the <code>&lt;head&gt;</code>'s\n<code>&lt;title&gt;</code> to the real deck title, and swap the <code>:root</code> theme block if the user chose a\nnon-default theme (<a href=\"references/themes.md\"><code>references/themes.md</code></a>).</p>\n</li>\n<li><p>Work through your topic list slide by slide, copying the matching <code>PATTERN:</code> block from\nthe template for each slide (title, agenda, section-divider, prose+cards, image+caption,\ntable, before/after code, single annotated snippet, flow diagram, chat-bubble examples,\nlane comparison, closing: see the template's own comments for when to use which) and\nreplacing every bracketed placeholder with real, verified content. Delete every pattern\nblock you didn't end up using; delete the illustrative comments too once real content\nreplaces them.</p>\n</li>\n<li><p><strong>Cite every snippet as you write it</strong>, with the script, never by hand:</p>\n<pre><code>python3 scripts/cite.py app/main.py:40-58 --repo &lt;repo&gt; --snippet\n</code></pre>\n<p>It prints the <code>data-src</code> / <code>data-sha256</code> pair to paste onto the <code>&lt;pre&gt;</code>, warns when the\nlines are too wide for the pattern you chose, and with <code>--snippet</code> prints the source\nalready HTML-escaped. Stamp the build commit once, when the deck is otherwise finished:</p>\n<pre><code>python3 scripts/cite.py --stamp &lt;deck.html&gt; --repo &lt;repo&gt;\n</code></pre>\n<p>A hand-computed hash is worse than no hash: it silently reports CHANGED months later\nand nobody can tell whether the code moved or the build was sloppy. Same for the date,\nwhich is easy to invent and impossible to verify afterwards. Cite anything you quote or\nassert from one place; prose summarising a whole subsystem needs no citation. See\n<a href=\"references/freshness.md\"><code>references/freshness.md</code></a>.</p>\n</li>\n<li><p><strong>HTML-escape every verbatim snippet</strong>: <code>&amp;</code> → <code>&amp;amp;</code>, <code>&lt;</code> → <code>&amp;lt;</code>, <code>&gt;</code> → <code>&amp;gt;</code>\ninside <code>&lt;pre&gt;</code>/<code>&lt;code&gt;</code>. Unescaped source code (generics, arrows, includes) silently\ncorrupts the markup downstream. Mind snippet line width too: see\n<a href=\"references/style-guide.md\"><code>references/style-guide.md</code></a> § Code snippets.</p>\n</li>\n<li><p>Follow every rule in <a href=\"references/style-guide.md\"><code>references/style-guide.md</code></a> as you\nwrite: sentence case, no em dashes in prose, tag accuracy, real-content-only, rather\nthan fixing it all in a pass at the end.</p>\n</li>\n<li><p>Keep slide numbering visible to yourself: an HTML comment <code>&lt;!-- N: LABEL --&gt;</code> above each\n<code>&lt;section class=\"slide\"&gt;</code>. Comments are 0-indexed; the URL hash and the on-screen\ncounter are 1-indexed. Worked example: <code>&lt;!-- 6: ARCHITECTURE --&gt;</code> is display slide 7,\nreached at <code>deck.html#7</code>. <strong>Renumber the comments any time you insert or delete a\nslide</strong>, and when the user later says \"slide 12\", re-derive which section that is from\nthe file itself (<code>grep -n '&lt;!-- [0-9]*:' deck.html</code>) rather than trusting a remembered\ncount: a stale comment index is a fast path to editing the wrong slide.</p>\n</li>\n</ol>\n<h2>Step 4: Verify (every single slide, every single edit)</h2>\n<p>Do not consider the deck done until you've actually looked at it. This is not optional\npolish: run for the first time on any deck, this step reliably catches real bugs: broken\nimage paths, text overlapping the nav pill, tables overflowing their card, stale slide\nnumbering, wrong aggregate numbers.</p>\n<ol>\n<li><strong>Render every slide to an image</strong> with headless Chrome and look at each one. Chrome\ndiscovery is platform-dependent: use the cross-platform recipe in\n<a href=\"references/verification.md\"><code>references/verification.md</code></a>, which also covers staging\ndirectories (always a fresh per-deck directory, never fixed shared paths: parallel deck\nbuilds collide) and a faster batched screenshot loop.</li>\n<li>View each screenshot. Check specifically for: text clipped by or overlapping the bottom\nnav pill, cards/boxes stretching to fill unexpected empty space (add the <code>fill</code> class\nonly where stretching is wanted; the grids default to content height), tables or code\nblocks overflowing their container, and images that failed to load (a small\nbroken-image icon with visible alt text, almost always a relative-path problem: see the\nPDF workflow note in verification.md).</li>\n<li><strong>Check citations resolve</strong> before shipping: <code>python3 scripts/check.py &lt;deck&gt; --repo &lt;repo&gt;</code>\nshould report every citation CURRENT. Anything else means the deck is already stale on\nthe day it was built: CHANGED means you quoted something and then it moved under you (or\nthe hash was hand-computed), UNVERIFIED means a snippet has no hash at all. Both are\nbuild defects, not future problems. Fix them now with <code>scripts/cite.py</code>.</li>\n<li><strong>Check structural balance</strong> after every edit: a stray unclosed <code>&lt;div&gt;</code> breaks\neverything downstream silently:\n<pre><code>python3 -c \"\nimport re\nc = open('deck.html').read()\nprint('section:', len(re.findall(r'&lt;section class=\\\"slide', c)), len(re.findall(r'&lt;/section&gt;', c)))\nprint('div:', len(re.findall(r'&lt;div', c)), len(re.findall(r'&lt;/div&gt;', c)))\n\"\n</code></pre>\n</li>\n<li>Fix what you find, re-screenshot <em>those</em> slides, confirm the fix. Clean up every temp\nscreenshot/scratch file when you're done: nothing but the deck (+ optional PDF)\nshould remain.</li>\n</ol>\n<h2>Step 5: Optional PDF export</h2>\n<p>If asked for a PDF, use the companion <strong>slides-to-pdf</strong> skill (distributed alongside this\none; its SKILL.md is the full self-contained recipe if it isn't installed as a skill).\nIt screenshots every slide at 2x, prints a page-per-slide PDF with a centred page number\non every page, and verifies the result by rendering the PDF back to images, which is\nrequired because headless Chrome cannot rasterize a local PDF for a visual check and image\npages can be silently blank.</p>\n<h2>Step 6: Ship it, and say how to keep it honest</h2>\n<p><strong>The deck is the only file you leave behind.</strong> Do not write a companion <code>README.md</code>,\nindex, summary or notes file next to it, and do not add the deck to an existing one unless\nthe user asks: the deck already states what it covers, the build stamp already records\nwhere it came from, and a hand-written sidecar is one more thing to go stale. If the repo\nalready keeps such an index and the user wants it updated, that is their call to make, not\na default.</p>\n<p>Everything that would have gone in that file belongs in your final message instead: what\nthe deck covers, its slide count, where it was written, how to view and navigate it\n(click, arrow keys, <code>Esc</code> for the overview, <code>N</code> for notes) and, since decks get edited\nslide-by-slide over many follow-up requests, one paragraph on how the file is structured\nfor future edits (the pattern-block/comment-numbering conventions above).</p>\n<p>Tell the user, in that same message, how to find out when the deck has gone stale:</p>\n<pre><code>python3 scripts/check.py &lt;deck-or-folder&gt; --repo &lt;repo&gt; --suggest\n</code></pre>\n<p>Then <strong>ask whether this deck should be kept in sync</strong>, and make it concrete rather than\nleaving it as a suggestion. The answer depends on what kind of document it is, so say so:</p>\n<ul>\n<li><strong>Evergreen</strong> (onboarding, architecture, anything linked from a README): offer to add\nthe pull-request check from <a href=\"references/automation.md\"><code>references/automation.md</code></a>.\nReport-only first (<code>--exit-zero</code>), so it annotates a PR without blocking anyone. Vendor\n<code>check.py</code> into the repo (<code>tools/slideops-check.py</code>), because it is one dependency-free\nstandard-library file and the deck's repo should not depend on a skill being installed.</li>\n<li><strong>A snapshot</strong> (sprint update, \"what shipped in March\", a conference talk): recommend\n<em>not</em> automating it. It describes a moment and is supposed to freeze. Say this out loud\nrather than silently skipping it.</li>\n</ul>\n<p>Do not propose blocking every commit. A docs check on the fast path trains people to pass\n<code>--no-verify</code>, and drift is a review-time concern. The reasoning, the workflow files, the\nadvisory hook variants, and the delegated-refresh recipe are all in\n<a href=\"references/automation.md\"><code>references/automation.md</code></a>.</p>\n<h2>Refreshing an existing deck</h2>\n<p>When the user asks whether a deck is still accurate, or wants one brought back in line,\n<strong>repair it; do not rebuild it</strong>. A rebuild throws away the pacing, the narrative and the\nreview that went into the original, and costs far more than fixing three slides.</p>\n<ol>\n<li><p><strong>Detect, for free.</strong> Sweep the folder and read the result:</p>\n<pre><code>python3 scripts/check.py docs/slides/ --repo . --json\n</code></pre>\n<p>This costs no tokens and no model call. The JSON is a complete repair brief: per stale\ncitation it carries the status, the unified diff, the commits that caused it, the\ncorrected <code>data-src</code>/<code>data-sha256</code>, and the current source. Read that instead of\nre-reading the repository. If nothing is stale, say so and stop: that is the common\ncase and it should be cheap.</p>\n</li>\n<li><p><strong>Triage by status</strong>, because they need different work:</p>\n<ul>\n<li><code>MOVED</code>: the code is identical, only the line numbers shifted. Update the two\nattributes. <strong>Do not touch the slide's prose</strong>, and do not re-verify visually: nothing\nrendered changed.</li>\n<li><code>CHANGED</code>: read the diff <em>and the commit subjects</em>. A rename needs a re-quote; a\ndeleted branch of logic may have killed the claim the slide makes. Decide about the\nclaim first, then the snippet.</li>\n<li><code>MISSING</code>: the file is gone. The slide is probably obsolete. Find where it went\n(<code>git log --diff-filter=D -- &lt;path&gt;</code>) and ask the user before deleting a slide.</li>\n<li><code>UNVERIFIED</code>: no hash was recorded. Re-cite it with <code>scripts/cite.py</code> so it is\ncheckable from now on.</li>\n</ul>\n</li>\n<li><p><strong>Repair only what drifted.</strong> Edit those slides, re-trim snippets to the width budget\n(<a href=\"references/style-guide.md\"><code>references/style-guide.md</code></a> § Code snippets), and leave\nevery other slide alone.</p>\n</li>\n<li><p><strong>Re-stamp and re-verify.</strong> <code>python3 scripts/cite.py --stamp &lt;deck&gt; --repo .</code>, then\n<code>check.py</code> until clean, then re-screenshot <strong>only the slides you touched</strong> (Step 4): a\nlonger snippet can push content under the nav pill. Re-export the PDF only if one exists.</p>\n</li>\n<li><p><strong>Report what changed and why.</strong> Name the slides you edited, the commits that caused\nthe drift, and anything you judged still-true-despite-the-diff. That last category is\nwhere a human may disagree with you, so surface it rather than burying it.</p>\n</li>\n</ol>\n","files":[{"path":"assets/template.html","sizeBytes":35177,"isText":false},{"path":"assets/template.md","sizeBytes":1928,"isText":true},{"path":"examples/skill-demo.html","sizeBytes":1049793,"isText":false},{"path":"examples/skill-demo.md","sizeBytes":4942,"isText":true},{"path":"references/automation.md","sizeBytes":6634,"isText":true},{"path":"references/diagrams.md","sizeBytes":4305,"isText":true},{"path":"references/freshness.md","sizeBytes":6084,"isText":true},{"path":"references/markdown.md","sizeBytes":6302,"isText":true},{"path":"references/markdown-pdf.md","sizeBytes":5295,"isText":true},{"path":"references/style-guide.md","sizeBytes":8665,"isText":true},{"path":"references/themes.md","sizeBytes":6721,"isText":true},{"path":"references/verification.md","sizeBytes":6166,"isText":true},{"path":"scripts/check.py","sizeBytes":21456,"isText":true},{"path":"scripts/cite.py","sizeBytes":7859,"isText":true},{"path":"SKILL.md","sizeBytes":26443,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"notes-only","suspicious":0,"notes":10,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-07T18:44:30.605979Z","sha256":"D44BD6788FAE3380EB114A3B08FE752911A068E5054F680A6637EBFA4127164A","sizeBytes":824188},"review":null,"source":{"repositoryUrl":"https://github.com/glukicov/slideops","path":"skills/slideops","license":"MIT","commit":"6020266bc3678f9cfb096455ea9016a3e5e399c2","subtreeSha":"C38CBC6D101BF80F8534F4A9A1F6E2C4B495529B5A2D498E2973C085161B5121","lastSyncedAt":"2026-09-25T06:49:30.292538Z"},"reviewedAt":"2026-09-07T18:52:23.342988Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/glukicov/slideops/tree/main/skills/slideops"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install glukicov-slideops@llmmart"},{"target":"git","command":"git clone https://github.com/glukicov/slideops.git"}]}