node bin/mdslides.js <command> [args] (install it as mdslides with
npm link, or rely on the explicit node bin/… path). Every command also
accepts --json for machine-readable output — use that when an agent
consumes the result.
| command | purpose |
|---|---|
new |
create a deck (from a topic/outline, from --llm, or verbatim from stdin) |
list |
list decks in decks/ with slide counts |
show |
print a deck's raw markdown |
render / build |
write a self-contained .html presentation |
pdf |
write a print-ready page, and a real PDF if a headless browser exists |
lint |
check a deck for structural problems (exit code 1 on errors) |
themes |
list the 16 built-in themes |
serve |
start the web app + API on PORT (default 4210) |
open |
render a deck to ./<name>.html and open it in the browser |
help |
full usage text |
node bin/mdslides.js new <name> [flags]Flags:
| flag | effect |
|---|---|
--topic "T" |
title + title slide (front matter title:) |
--slides "a,b,c" |
outline, one slide per comma-separated title |
--theme NAME |
theme name (run mdslides themes to list all 16) |
--author A |
front matter author: |
--subtitle S |
front matter subtitle: |
--llm |
ask the MDSLIDES_LLM command to author the deck |
--json |
JSON output |
Two ways to create a deck:
- Skeleton from a topic + outline:
node bin/mdslides.js new quick --topic "Kubernetes 101" \ --slides "Why,Concepts,Example,Next steps" --theme dark --json
- Verbatim deck from stdin (the reliable way for agents to write exact
content). stdin is only consumed when it is a pipe (FIFO).
printf '%s' '# Title
- item
' | node bin/mdslides.js new hello
With `--json`, `[stdin]` writes return the path; `source` is `"stdin"`. Without a name and with no `--topic`, the deck is named `deck`.
node bin/mdslides.js list --json
# { "ok": true, "decks": ["api-deck", "cli-deck", "welcome"] }node bin/mdslides.js show quick # prints decks/quick.md rawnode bin/mdslides.js render <name|path.md|-> [-o out.html] [--theme NAME] [--json]<name>resolves againstdecks/; a path containing a separator or ending in.mdis read as a file;-reads stdin.- Default output is
./<name>.html(or./deck.htmlfor stdin). --theme NAMEoverrides the front-matter theme for this export only.- Output is fully self-contained: no network, inlined CSS/JS.
- JSON:
{ "ok": true, "action": "render", "name": "welcome", "html": "/abs/out.html", "size": 18075, "theme": "per-front-matter" }
node bin/mdslides.js pdf <name|path.md|-> [-o out.pdf.html] [--json]Writes a print-ready HTML (injecting an auto window.print()). If Chrome /
Chromium is on PATH (or CHROME_BIN is set) it also writes a real PDF.
Otherwise it prints JavaScript output with pdf: null and a note telling
the user to use the browser print dialog — that is expected behaviour,
not an error:
{ "ok": true, "action": "pdf", "html": "…/out.pdf.html",
"pdf": null, "note": "No headless browser found; opened print page instead…" }node bin/mdslides.js lint <name|path.md|-> [--json]Checks a deck for structural problems and exit code 1 if errors are found. Use it in CI before publishing:
node bin/mdslides.js lint welcome --json
# { "ok": true, "errors": 0, "warnings": 0, "hints": 2, "score": 99, ... }| rule | level | meaning |
|---|---|---|
unclosed-fence |
error | a ``` or ~~~ code fence was never closed |
unclosed-columns |
error | odd number of ::: markers |
unbalanced-math |
error | odd number of $$ display-math delimiters |
empty-deck |
error | no slides at all |
blank-slide |
error | slide with no content |
no-heading |
warning | slide without a heading line |
dense-slide |
warning | > 220 words on one slide |
missing-image |
warning | image file not found relative to the deck |
speaker-notes |
hint | deck has no notes anywhere |
duplicate-heading |
hint | two slides share the same heading |
node bin/mdslides.js themes # prints: light dark gradient ...
node bin/mdslides.js themes --json # { "themes": [...16 names] }node bin/mdslides.js serve [--port N] # or PORT=... Starts the web app and API. Prints the URL. The web listens on the default
port 4210 unless overridden.
node bin/mdslides.js open <name>Renders to ./<name>.html in the current directory and opens it with the
system browser.
Create + render + verify in one line:
node bin/mdslides.js new demo --topic "Topic" --slides "A,B,C" --theme light --json >/tmp/new.json
node bin/mdslides.js render demo -o /tmp/demo.html --json >/tmp/render.json
# /tmp/render.json.html now exists, self-contained and presentableContract with the LLM hook (MDSLIDES_LLM): a shell command whose stdin it
reads the writing prompt from and whose stdout is the markdown deck.
MDSLIDES_LLM="claude -p --output-format text" \
node bin/mdslides.js new ai-deck --topic "Q3 review" --slides "Wins,Misses,Next" --llm --jsonThe generated decks/<name>.md is plain markdown (see docs/format.md).
Human polish happens in the web app: node bin/mdslides.js serve.