Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Spec2DeckNew to Visual Studio Code? Get it now.
Spec2Deck

Spec2Deck

Spec2Deck

| (0) | Free
Turn an OpenAPI spec into an audience-targeted presentation (Developer / Business / Manager) as PPTX, HTML, or Markdown — right from VS Code.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Spec2Deck

Turn an openapi.yaml into a presentation — but pick who it's for first.

This is a working prototype of the idea from a shared ChatGPT conversation: programmers keep the truth in openapi.yaml, everyone else wants "a document that makes sense" — a PPTX for a business stakeholder, a PDF/HTML for a manager, full technical detail for another developer. Same spec, three completely different documents, picked from a dropdown.

openapi.yaml ──▶ parse ──▶ internal model ──▶ [Developer|Business|Manager view] ──▶ PPTX / HTML / Markdown

What's actually real here

  • Core engine (src/core/): OpenAPI parser (local $ref resolution, no external tooling), an audience layer that decides how much technical detail to show and how to phrase things, and four generators (Markdown, HTML, PPTX via pptxgenjs, PDF via pdfkit).
  • CLI (src/cli.ts): fully working, tested end-to-end against the sample spec below. This is the fastest way to see it work.
  • VS Code extension (src/extension.ts): registers a right-click command ("Spec2Deck: Generate API Presentation...") with a QuickPick for audience + output format, same engine underneath. It compiles cleanly against @types/vscode, but hasn't been click-tested inside a real VS Code Extension Development Host (no GUI in this environment) — see "Trying the extension for real" below.
  • No AI/Claude call anywhere yet — see core/audience.ts's own comment for the one function (purposeFor) that's the actual drop-in slot for it. Everything works today with a deterministic, template-based fallback.
  • Licensing (src/core/license.ts, src/core/watermark.ts, src/licenseStore.ts): Free tier = PDF preview (watermarked) and Markdown, unlimited use. HTML and PPTX are Pro-only exports outright. Pro = pay once, activate a license key, get the same PDF preview but clean, plus real HTML and a fully-editable .pptx. Deliberately not gated on file count or endpoint count — see license.ts's own docstring for why that's trivially defeated (just split the spec into smaller files). ⚠️ Simplified 2026-09-07, two changes same day. First: PPTX used to carry a watermark the same way HTML did (a slide.addText(...) shape) — found via real testing that this is trivially removable (PPTX is inherently editable; select the shape, delete it). No shape-based watermark inside an editable format can ever be un-removable. Second, rather than leave "request pptx, quietly get a pdf instead" as the rule (confusing), HTML and PPTX became Pro-only outright and PDF became the one universal preview format everyone can generate — watermarked free, clean licensed, same generator either way. See generators/pdf.ts's and watermark.ts's own header comments for the full reasoning.

Licensing model (pay once, not per file)

Free   — unlimited files, unlimited runs. "pdf" (watermarked) and
         "markdown" only — "html"/"pptx" are skipped with a message.
Pro    — one-time purchase, "Activate License" command — "pdf" is clean,
         plus real, editable, unwatermarked "html"/"pptx" unlock.

Backend is Gumroad's own native License Key feature (added directly on the "Spec2Deck Pro" product page, no separate tool needed) + its free License Verification API (POST https://api.gumroad.com/v2/licenses/verify, no secret token required). Real product created 2026-09-07 — GUMROAD_PRODUCT_ID in core/license.ts is the real Product ID from the live "Spec2Deck Pro" product's Content tab, so verifyLicenseKeyRemote now actually calls Gumroad for real. (Earlier drafts of this doc/code targeted Lemonsqueezy instead — switched to Gumroad after confirming Thailand payout support directly in the Gumroad dashboard, see Payments settings' own "minimum payout threshold for Thailand is $100" message.)

Tested (node dist/cli.js ... --license-key <key>), including against a real purchased Gumroad key:

  • No key → --output pdf writes a watermarked preview (rendered thumbnails checked by eye, including mixed Thai/English text); --output html,pptx are skipped with a "requires a Pro license" message, nothing written.
  • Malformed key → rejected locally, no network call, same free-tier output.
  • Real valid key → "License: valid — Pro output (no watermark)"; pdf is clean (no watermark stamped), html/pptx are written — the .pptx confirmed clean by unzipping it and grepping every slide's XML for the watermark string.

In the VS Code extension: Spec2Deck: Activate License... command prompts for a key, verifies it, stores it in SecretStorage (not a plain settings file), and caches the yes/no result in globalState so every "Generate" doesn't re-hit the network. A status bar item ("Spec2Deck Free" / "Spec2Deck Pro ✓") shows current state and is a shortcut to the Activate command. Deactivate License command clears it (useful for testing, or moving a key off a machine).

Selling it — the two accounts this needs (not something I can set up for you)

  1. VS Code Marketplace Publisher — for distributing the extension (free to list; the Marketplace itself has no paid-extension concept). Needs a Microsoft account → Azure DevOps org → Personal Access Token → vsce publish.
  2. Gumroad store — for selling the Pro unlock. Handles payment and issues the license keys this code validates against (payout requires connecting a payout method in Gumroad's Payments settings before the product can go live for real sale).

Both need real identity/payment details, so they're on you, not something this session can do on your behalf.

Try it (30 seconds)

npm install
npm run build
node dist/cli.js sample/openapi.yaml --audience developer,business,manager --output markdown,pdf --out-dir out
open out/api-business.pdf   # or api-developer.pdf, api-manager.md

# with a real Pro license key, html/pptx unlock too:
node dist/cli.js sample/openapi.yaml --audience business --output pdf,html,pptx --license-key <KEY> --out-dir out

The sample spec (sample/openapi.yaml) is the exact "Customer API" example from the original conversation — /auth/login, /customer/profile, /customers, /customers/{id}.

Compare out/api-developer.pdf (HTTP verbs, types, status codes) against out/api-business.pdf (plain-language "ใช้สำหรับ...", "ข้อมูลที่ส่ง", "ผลลัพธ์") — same spec, deliberately different documents. That contrast is the whole product idea.

Trying the extension for real

This repo isn't opened as a VS Code workspace in this session, so the extension side has only been compiled, not clicked through. To actually try it:

  1. Open this folder in VS Code.
  2. npm install && npm run build.
  3. Press F5 (Run Extension) — opens a new "Extension Development Host" window.
  4. In that window, open sample/openapi.yaml, right-click it in the Explorer → Spec2Deck: Generate API Presentation... → pick an audience → pick output format(s).
  5. Files land in docs/ next to the spec.

Project layout

src/
  core/
    model.ts            internal types (ApiModel, EndpointModel, ...)
    parseOpenApi.ts      openapi.yaml/json -> ApiModel
    audience.ts          the "same data, different story" logic
    license.ts            Gumroad license-key validation (framework-free)
    watermark.ts          free-tier watermark text, used by pdf.ts only
    generators/
      markdown.ts          always free, never watermarked
      pdf.ts               the universal preview -- watermarked free, clean licensed
      html.ts              Pro only -- clean, unwatermarked
      pptx.ts              Pro only -- clean, unwatermarked, fully editable
  cli.ts                 standalone CLI (no VS Code needed)
  extension.ts           VS Code command + QuickPick UI + status bar
  licenseStore.ts        VS Code SecretStorage/globalState wrapper around license.ts
assets/fonts/            bundled OFL-licensed Thai font (pdf.ts needs a real embedded
                         Unicode font -- PDF viewers can't be assumed to have one)
sample/openapi.yaml       Customer API example from the original chat

Known rough edges (prototype, not a product)

  • Schema flattening is one level deep by design (a slide shouldn't show 4 levels of nested objects) — deeply nested request/response bodies will look sparse.
  • $ref resolution is local-document only (#/components/...); no external file refs or remote $refs.
  • PPTX layout is fixed-position text boxes, not a real template engine. Fixed 2026-09-07: found via a real 46-schema, 40-endpoint spec (the Grid Eagle Eye API) that the Data Model slide put every schema side-by-side on ONE slide — dividing 9" by 46 columns produced ~0.2"-wide columns, unreadable. Now paginates at SCHEMAS_PER_SLIDE = 3 and caps each schema to MAX_FIELDS_SHOWN = 12 fields (+N more beyond that); the endpoint-list slide got the same treatment (MAX_ENDPOINTS_PER_LIST_SLIDE = 15) since a real resource group already had 10. Still not real reflow (fixed page size, not "shrink text to fit"), just a hard cap instead of unbounded growth into a fixed box.
  • npm audit flags a transitive image-size DoS advisory inside pptxgenjs's own dependency tree. Not exploitable here (this tool never feeds it untrusted images), but worth knowing before shipping this anywhere real.
  • generators/pdf.ts embeds the bundled Thai font as .woff, deliberately NOT .woff2 — the currently pinned pdfkit/fontkit version pair silently drops every base Thai glyph (only combining marks survive) from a woff2 embed, confirmed by rendering a real thumbnail, not just "no exception." woff2 renders fine standalone through fontkit alone; the bug is specifically in pdfkit's embedding of it. Re-verify visually before ever touching this.
  • pdfkit cannot be bundled by esbuild (its ICC color-profile path resolution breaks under esbuild's CJS output) — it ships unbundled, a real node_modules/pdfkit (+ its own dependency tree) inside the packaged extension. See esbuild.js's and .vscodeignore's own comments.

Where the original idea goes from here

The chat's own pitch was "one engine, many micro-tools" — OpenAPI -> {PPTX, PDF, HTML, Markdown, Diagrams} today, then reuse the same core/generators/ against a different parser: Postman collection, SQL schema, GitHub README, etc. The parser/generator split here was built with exactly that in mind — a new input just needs a new parseX.ts that produces an ApiModel (or a sibling model), nothing downstream changes.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft