Client decks as single-file HTML, with a built-in co-design loop for humans and AI agents.
The idea: slides live in a git repo as plain HTML, get served through one entry point that injects feedback tooling into every page, and deploy as a login-protected space your team can review, annotate and comment on. No slide software, no design tool exports — a deck is a file you can diff, and every review comment arrives in a form an AI coding agent can act on directly.
The bundled example: a fictional Acme × Northwind proposal built from the template — open example/acme-example-deck.html or press 3 slides in via template/deck-template.html#3. The toolbar bottom-right is Agentation; comment threads appear when served with GH_REPO set.
- A deck template (
template/deck-template.html) — fixed 16:9 stage (1280×720) scaled to the window, keyboard navigation, speaker notes drawer, and print output that is pixel-identical to the screen: Cmd+P gives one exact 16:9 page per slide. A restrained visual system (flat surfaces, one accent, no gradient-card slop) documented intemplate/README.md. - An auto-generated index —
deploy/stage.shbuildsmanifest.json(every deck, its title, its last git-commit date) andindex.htmlrenders it grouped by directory, sorted by recent activity with an A–Z toggle. Add a deck, it appears. - Annotation for agents — every served page carries Agentation (the vanilla port, MIT): press
A, click elements, write notes, pressC, and paste structured markdown — element selectors included — into Claude Code, Cursor or a Slack thread. - Comments as GitHub issues — the toolbar's speech-bubble pins a thread to any element; pins are visible to every viewer and follow their slide (selectors are stored slide-scoped, and a thread whose element disappears stays listed as orphaned). GitHub is the system of record: replies are issue comments, closing the issue resolves the thread, and agents read feedback with
gh issue list. - One-button PDF — hover top-right, press ⎙.
- Portable decks — every deck is one HTML file; the ⤓ button downloads a standalone copy you can email or paste back into GitHub as a new version.
node deploy/protect.js deck.html "passphrase"wraps a deck as a password-protected self-decrypting file (AES-256-GCM) for sharing outside your org. - A deploy story — a zero-dependency Node server (
deploy/server.js) serves the site and the comments API; instructions below put it on Azure App Service behind Entra ID login so the whole space is org-only.
git clone https://github.com/mattarderne/slides && cd slides
./deploy/serve.sh # → http://localhost:4600That script is the one way to run the site — it stages every page with the tooling injected, then serves. To enable comments, set GH_REPO to a repo your gh CLI can write issues to:
GH_REPO=you/your-slides ./deploy/serve.shStart a new deck by copying template/deck-template.html, then read template/README.md for the layout catalogue and style rules.
CLAUDE.md / AGENTS.md tell the agent the rules: always serve via serve.sh (so the annotation toolbar is present when it shows you a deck), treat pasted Agentation selectors as ground truth, read and resolve comment issues before calling a deck done. The loop in practice:
- Agent builds/edits a deck and serves it.
- You annotate in the browser, copy markdown, paste to the agent.
- Longer-lived decisions go in the comments drawer → GitHub issues.
- Agent addresses annotations and issues, closes threads, redeploys.
Any Node host works (the server is dependency-free). For an org-locked space on Azure:
az group create -n rg-slides -l westeurope
az appservice plan create -g rg-slides -n slides-plan --is-linux --sku F1
az webapp create -g rg-slides -p slides-plan -n <app-name> --runtime "NODE:22-lts"
az webapp config set -g rg-slides -n <app-name> --startup-file "node server.js"
az webapp config appsettings set -g rg-slides -n <app-name> \
--settings GITHUB_TOKEN=<issues-token> GH_REPO=<owner/repo> SCM_DO_BUILD_DURING_DEPLOYMENT=false
# Entra ID login (Easy Auth), locked to your tenant:
az ad app create --display-name slides-auth --sign-in-audience AzureADMyOrg \
--web-redirect-uris "https://<app-name>.azurewebsites.net/.auth/login/aad/callback" \
--enable-id-token-issuance true
az ad app credential reset --id <appId> --years 2
az webapp config appsettings set -g rg-slides -n <app-name> \
--settings MICROSOFT_PROVIDER_AUTHENTICATION_SECRET=<password>
az webapp auth config-version upgrade -g rg-slides -n <app-name>
az webapp auth microsoft update -g rg-slides -n <app-name> --client-id <appId> \
--client-secret-setting-name MICROSOFT_PROVIDER_AUTHENTICATION_SECRET \
--issuer "https://login.microsoftonline.com/<tenantId>/v2.0" --yes
az webapp auth update -g rg-slides -n <app-name> --enabled true \
--action RedirectToLoginPage --redirect-provider azureactivedirectoryThen deploy: stage, zip server.js package.json site/ (where site/ is _site/), and az webapp deploy --type zip — or set the AZURE_WEBAPP_NAME repository variable and AZURE_WEBAPP_PUBLISH_PROFILE secret and .github/workflows/deploy.yml deploys every push to main. The commenter identity on Azure comes from the Easy Auth header, so issues are attributed to whoever is logged in.
index.html landing page (renders manifest.json)
template/ the deck template + style rules
example/ a sample deck
assets/ agentation-vanilla.js (MIT), slides-ui.js (print + comments UI)
deploy/ stage.sh · serve.sh · server.js · package.json
Agentation by Benji Taylor; vanilla port by mearnest-dev (MIT, vendored in assets/). Template and tooling released under MIT.

