{"id":50612366,"url":"https://github.com/sowenzhang/deckmark","last_synced_at":"2026-06-06T05:01:45.656Z","repository":{"id":360281590,"uuid":"1248417070","full_name":"sowenzhang/deckmark","owner":"sowenzhang","description":"In-browser annotation for AI-generated slide decks - click any element, leave a comment, the agent applies it","archived":false,"fork":false,"pushed_at":"2026-05-25T19:39:14.000Z","size":111,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T20:26:21.764Z","etag":null,"topics":["ai-mcp","ai-plugin","ai-presentation","ai-skill","ai-tools","deck-builder"],"latest_commit_sha":null,"homepage":"https://github.com/sowenzhang/deckmark","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sowenzhang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-24T16:04:31.000Z","updated_at":"2026-05-25T19:21:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sowenzhang/deckmark","commit_stats":null,"previous_names":["sowenzhang/deckmark"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sowenzhang/deckmark","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sowenzhang%2Fdeckmark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sowenzhang%2Fdeckmark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sowenzhang%2Fdeckmark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sowenzhang%2Fdeckmark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sowenzhang","download_url":"https://codeload.github.com/sowenzhang/deckmark/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sowenzhang%2Fdeckmark/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33969883,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-mcp","ai-plugin","ai-presentation","ai-skill","ai-tools","deck-builder"],"created_at":"2026-06-06T05:01:44.927Z","updated_at":"2026-06-06T05:01:45.651Z","avatar_url":"https://github.com/sowenzhang.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# deckmark\n\nIn-browser annotation for AI-generated presentations. Close the feedback loop without screenshots — works with any AI coding agent that speaks MCP.\n\nYou install deckmark once into your agent. Then you type `/deckmark:use-deckmark \u003ctopic\u003e` and the agent asks about **mode**, **style**, and **motion**, builds a slide deck, opens it in your browser with an annotation overlay, you click directly on elements to leave change requests, and when you come back to the agent it reads those annotations and applies them. No screenshots, no copy-paste, no terminal–browser ping-pong.\n\n---\n\n## Install\n\n### Claude Code\n\n```\n/plugin marketplace add sowenzhang/deckmark\n/plugin install deckmark@deckmark-marketplace\n```\n\nQuit and reopen Claude Code so the MCP server spawns. Verify with `/mcp` — deckmark should show as **connected**. Then `/deckmark:use-deckmark \u003ctopic\u003e` is available.\n\n### Other MCP-aware agents (Gemini CLI, Codex, GitHub Copilot CLI, Cursor, …)\n\ndeckmark ships an MCP server bundled in a GitHub Release tarball, fetched on demand via `npx`. Add the following to your agent's MCP config (typical paths: `~/.gemini/settings.json`, `~/.codex/config.toml`, `~/.cursor/mcp.json`, etc. — consult your agent's docs for the right file):\n\n```json\n{\n  \"mcpServers\": {\n    \"deckmark\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"--package\",\n        \"https://github.com/sowenzhang/deckmark/releases/latest/download/deckmark.tgz\",\n        \"deckmark-mcp\"\n      ]\n    }\n  }\n}\n```\n\nRestart the agent. The seven deckmark MCP tools become callable. (Note: the slash command `/deckmark:use-deckmark` and the design-system skill are Claude Code–specific packaging conventions and won't appear in other agents. The tools themselves work everywhere — just describe your intent in natural language and the agent will call them.)\n\n### Updating to a new release\n\nWhen a new version ships:\n\n```\n/plugin marketplace update deckmark-marketplace\n/plugin install deckmark@deckmark-marketplace\n```\n\nRestart Claude. The npx invocation always fetches the `latest` release tarball, so a Claude restart is usually enough on its own.\n\nFor non-Claude agents, no update step is needed — `latest/download/deckmark.tgz` is a redirect that always points at the newest release. Restart the agent and `npx` will pick up the new tarball automatically.\n\n---\n\n## Usage\n\nAfter install, in your agent's chat:\n\n```\n/deckmark:use-deckmark Build a deck about Q2 results for the engineering org, dark mode, technical style\n```\n\nThe agent will:\n\n1. Confirm three design choices: **mode** (light/dark), **style** (professional/academic/fashion/technical/fun), and **motion** (slide transitions / fragment reveals / auto-animate, multi-select). Skip what you've already specified.\n2. Ask audience and approximate length.\n3. Scaffold a project folder, write `content.md` from your brief, build the deck, and launch a local annotation server at `http://127.0.0.1:\u003cport\u003e`.\n4. Tell you the URL. You open it. Press `A` to enter annotation mode, click any slide element, type a comment, repeat. Click ✓ Done when finished.\n5. After you click Done, the agent reads your structured feedback, edits `content.md`, and rebuilds. (If you return later, you can still say “apply the comments”.)\n6. When the deck is final, ask the agent to publish. It'll offer two options: a single self-contained `.html` (good for email/USB/attachment), or a `published/` folder with `index.html` + cacheable assets (good for hosting on GitHub Pages, Netlify, S3, etc.).\n\n---\n\n## How it works\n\n```\nuser types /deckmark:use-deckmark \u003ctopic\u003e\n        ↓\nagent asks: mode? style? motion? audience? length?\n        ↓\nagent + user align on storyline outline (core argument per slide)\nagent: init_deck → writes content.md → build_deck\n        ↓\nagent: start_review → \"open \u003curl\u003e, press A to annotate, click Done\"\n        ↓\nuser annotates elements in the browser, clicks Done\n        ↓\nagent: get_annotations → applies each comment to content.md → build_deck\n        ↓\nagent: \"Want another round, or shall I publish?\"\n        ↓\nagent: publish_deck (single-file or multi-file)\n```\n\nAnnotations live in `./annotations/session-\u003ctimestamp\u003e.json` next to your deck. Writes are atomic (temp-file + rename) and serialized per-deck. Each annotation captures the slide index, CSS selector, DOM path, bounding box, element text, the user's comment, and optional overall summary.\n\n### The seven MCP tools\n\n| Tool | Purpose |\n|---|---|\n| `init_deck` | Scaffold a project (`content.md`, config, agent instructions, `.gitignore`). |\n| `build_deck` | Render `content.md` to `./build/index.html` with reveal.js. Accepts `style`/`mode`/`motion`/`slideNumbers` plus optional `customCss`/`template`/`markedPlugins` overrides. |\n| `start_review` | Launch the local annotation review server, return URL + session id. |\n| `wait_for_close` | Block until the user clicks \"Done\" in the browser, or until timeout. |\n| `get_annotations` | Read annotations from disk (works even if Done wasn't clicked). |\n| `stop_review` | Stop the review server explicitly (auto-stops 5 min after Done otherwise). |\n| `publish_deck` | Emit the final shareable artifact — single-file `.html` or multi-file `published/` folder. |\n\n### Design system\n\nThree orthogonal axes:\n\n- **Style** — `professional` (Inter sans, indigo accent), `academic` (Fraunces + Source Serif, terra accent), `fashion` (Space Grotesk display, amber accent), `technical` (terminal feel, cyan accent, monospace prominence), `fun` (Outfit, rounded, coral accent).\n- **Mode** — `light` or `dark`. Applies to all 5 styles via CSS variables.\n- **Motion** — multi-select: `slide-transitions`, `fragment-reveals`, `auto-animate`. Pass `[]` for no motion. Honors `prefers-reduced-motion`.\n\nThe agent can also accept free-form descriptions (\"Stripe Press feel, dark, smooth motion\") and map them to the three axes.\n\n---\n\n## Privacy \u0026 trust model\n\ndeckmark runs entirely on your machine. The annotation server binds to `127.0.0.1` only, annotations are JSON files in your project folder, and no telemetry is sent anywhere.\n\n**One exception:** the built-in themes load typefaces from Google Fonts (Inter, Fraunces, Source Serif 4, Space Grotesk, JetBrains Mono, IBM Plex Mono, Outfit — all OFL-licensed). When you or someone you've shared the deck with opens it in a browser, that browser fetches CSS and woff2 files from `fonts.googleapis.com` / `fonts.gstatic.com`. Google sees the requesting IP, User-Agent, and (since these are font files) a low-cardinality fingerprint. Every theme also declares a robust local font fallback stack (system-ui / Inter-equivalents) so if you're offline or have Google Fonts blocked, the deck still renders — just with system fonts.\n\nA future minor release will add a `loadFonts: false` build option to skip the `@import` lines entirely.\n\n**Trust model for `content.md`:** the markdown source you feed to `build_deck` is treated as trusted code. `marked` passes raw HTML through unchanged, so anything in `content.md` (including `\u003cscript\u003e` tags) ends up in the rendered deck and can call the local server's API. Treat your `content.md` like source code: don't paste in untrusted markdown, and don't review a deck whose `content.md` came from an unknown source.\n\n---\n\n## Architecture\n\nSingle Node 22+ package, TypeScript ESM. Three layers:\n\n- `runtime/` — engine (reveal.js adapter), Fastify review server with overlay script injection, atomic session store, sha256 build hash, browser overlay (vanilla TS bundled via esbuild), publish emitters (inline + multi-file), and project templates.\n- `mcp/` — stdio MCP server that exposes the seven tools by calling into the runtime modules.\n- `commands/`, `skills/`, `.claude-plugin/`, `.mcp.json` — the Claude plugin packaging surface.\n\nThe overlay knows nothing about reveal.js. It walks the rendered DOM and generates stable CSS selectors, so engine adapters for Slidev / Impress / Marp can be added later without changing a line of overlay code. reveal.js is vendored via npm (`node_modules/reveal.js/dist/`) — no CDN dependency, works offline.\n\nThe MCP server ships as a Node CLI in a GitHub Release tarball. `.mcp.json` invokes it via `npx`, which downloads the tarball (and its dependencies) into its cache on first use and re-uses it from then on. No build step at install time, and nothing is installed into the user’s deck project directory.\n\n---\n\n## Development\n\nFor working on deckmark itself (not for using it):\n\n```bash\ngit clone https://github.com/sowenzhang/deckmark.git\ncd deckmark\nnpm install\nnpm run build        # tsc + overlay typecheck + esbuild + template/theme copy\nnpm test             # unit + integration tests\nnpm run test:unit\nnpm run test:integration\nnpm run mcp          # run the MCP server over stdio (for manual debugging)\n```\n\nCI runs the same build + test on Ubuntu / macOS / Windows × Node 22 for every push to main and every PR. Releases are produced by tagging `v*` — a GitHub Actions workflow then builds, packs, and publishes the tarball as a release asset.\n\nTo cut a release: bump the version in `package.json`, `.claude-plugin/plugin.json`, and `.claude-plugin/marketplace.json` (the release workflow has a guard that fails if these drift from the tag), then `git tag -a vX.Y.Z -m \"...\" \u0026\u0026 git push origin vX.Y.Z`.\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsowenzhang%2Fdeckmark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsowenzhang%2Fdeckmark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsowenzhang%2Fdeckmark/lists"}