Guide

Build a deck locally with open-slide and your favourite AI coding agent, then publish it here with one command.

1 · Author your deck (open-slide)

Slides are React components in an open-slide workspace — build them locally (with Claude Code, Codex, or by hand). Start from open-slide's own docs:

A deck lives in slides/<id>/index.tsx with export const meta = { title }. pnpm dev previews it.

2 · Connect (one time)

  1. Install the CLI: npm i -g wmslide
  2. Sign in, then create a token in API tokens, then export WMSLIDE_TOKEN=wms_…
  3. Check it: wmslide whoami

3 · Publish

cd your-open-slide-workspace
wmslide deploy --deck my-talk --verify
# → https://d<id>.slide.wanmeivn.com/  (or your custom name)

--verify confirms the live URL actually serves before reporting success.

Then in your dashboard: organize into folders, set each deck Public/Private, share with specific emails, or claim a custom subdomain (Account).

4 · Troubleshooting

For AI agents

Point your LLM at /llms.txt or give it the deploy skill ↓. It documents the exact commands, JSON contract, exit codes, and failure handling so any agent deploys correctly.

# WanmeiVN Slides — deploy guide for AI agents

You help a user publish an open-slide presentation deck to https://slide.wanmeivn.com using the
`wmslide` CLI. The deck is BUILT ON THE USER'S MACHINE; our server only stores and serves it.
Use the CLI's JSON output and process exit code as the source of truth — never guess URLs or claim
success without confirmation.

## 1. Author the deck (open-slide)
Slides are React components in an open-slide workspace. Set it up from open-slide's own docs:
- GitHub: https://github.com/1weiho/open-slide
- Docs:   https://open-slide.dev
Each slide-set lives in `slides/<id>/index.tsx` and exports `meta = { title }`. Run `pnpm dev` to preview.

## 2. One-time setup
1. Install the CLI:  `npm i -g wmslide`   (or run via `npx wmslide`)
2. The user signs in at https://slide.wanmeivn.com → API tokens → Create, then:
   `export WMSLIDE_TOKEN=wms_xxxxxxxx`     (or `wmslide login --token wms_xxxxxxxx`)
3. Confirm auth:  `wmslide whoami`  → prints the account email.

## 3. Deploy (run from the open-slide workspace directory)
```
wmslide deploy --deck <slug> --json --verify
```
- Builds locally, uploads the static bundle, and (`--verify`) confirms the live URL serves.
- Success JSON: {"ok":true,"deck":"<slug>","version":N,"url":"https://.../","visibility":"private"}

ALWAYS check BOTH the exit code and `ok`:
- exit 0, ok:true  → success. Give the user `url`.
- exit 2           → AUTH error (token missing/invalid/revoked). Ask the user for a new token; do not retry blindly.
- exit 1           → USER error (bad slug, build failed, bundle too large). Read `error`, fix, retry once.
- exit 3           → SERVER/NETWORK error, or --verify failed. Retry up to 3× with backoff (~10s).
                     If still failing, tell the user the platform may be unavailable. DO NOT claim success.

## 4. Share / manage
- Decks are PRIVATE by default. Make public:  `wmslide share <slug> --public`  (or `--private`).
- Private decks are viewable by the owner and people they share with (via the dashboard).
- List decks + URLs:  `wmslide ls --json`
- Custom subdomain (e.g. you.slide.wanmeivn.com) is set in the dashboard → Account.

## 5. Mobile static reader (automatic)
`wmslide deploy` also renders a flat image (WebP) of every slide on YOUR machine and ships it with
the bundle. Phones/tablets are served this crash-proof static reader at `/m/<slide>` by default;
desktops get the full interactive deck. A non-sticky "View full version" link (`?mode=full`) lets a
mobile viewer opt into the real deck. Why: heavy decks (full-screen SVG `feTurbulence`, `mixBlendMode`,
WebGL/Three.js, big `backdrop-filter` blurs) can exhaust iOS Safari's memory and crash-loop; a flat
image cannot. Desktop is unaffected, so you may not see it while authoring on a computer.
- Requires a system Chrome/Chromium on the build machine (set `WMSLIDE_CHROME=/path/to/chrome` if not
  auto-detected). Missing browser → deploy still succeeds, just without a mobile reader.
- Skip it:  `wmslide deploy --no-mobile`.
- Bring your own: if a `_mobile/` dir with `index.json` ({ slides: { "<slide>": { pages: N } } } and
  `<slide>/<n>.webp`) sits in the workspace root, it is shipped as-is instead of auto-rendering.
- The deploy JSON includes `mobileImages`; `wmslide ls` shows 📱 (reader) or 🖥 (desktop only).
- Keeping decks light for phones still helps: prefer CSS `transform`/`opacity` animations; avoid
  full-screen live `feTurbulence`/`mixBlendMode`/`backdrop-filter` and many WebGL contexts.

## Failure model (so you can trust the result)
- Deploys are ATOMIC: the live version flips only after a successful unpack — a failed upload never
  leaves a half-broken deck. The previous version stays live until a new one fully succeeds.
- A non-zero exit means the deploy did NOT take effect — report the `error` verbatim to the user.
- A brand-new deck/custom host can take ~20s on its first visit (TLS issuance); `--verify` retries.
- If unsure whether it published, run `wmslide ls --json` and check the deck's `url`.

Exit codes: 0 ok · 1 user error · 2 auth error · 3 server/network error.