npx skills add ...
npx skills add thedotmack/claude-mem --skill wowerpoint
Turn one document into a kawaii NotebookLM slide-deck PDF. Use for "wowerpoint this", "make a deck about <file>", "turn this report into slides", or any request to render a single document as shareable narrative slides.
npx skills add thedotmack/claude-mem --skill wowerpoint
One doc in, one PDF out. Slide-deck only — videos and podcasts from the same engine are noticeably worse and out of scope; refer the user to the notebooklm CLI directly if they want those.
If notebooklm auth check returns 0 and command -v jq resolves, skip.
jq is required by the workflow's JSON parsing; install if missing (brew install jq on macOS, or your distro's package manager).
Then the user authenticates interactively — do not script. Tell them to type ! notebooklm login so the OAuth ENTER lands in their terminal.
You need exactly one source doc. If it doesn't exist or is too thin to carry a deck, write it first — use mem-search and sequential thinking to make it comprehensive (long-form, narrative, several thousand words is normal). Do not paper over a weak source by adding more sources.
Exit 1 with Run 'notebooklm login' to authenticate. = halt and tell the user.
Title: H1 of the source doc, or its filename stem; append a date for dated work.
JSON envelope keys differ — create → .notebook.id, source add → .source.id, generate → .task_id. Wrong key = empty string = silent downstream failure.
Generation takes ~10 minutes; never block on it. Use the template below with run_in_background: true.
Print the notebook URL so the user can watch live:
The subagent's completion notification fires when the file is on disk.
Adjacent to the source, parallel filename:
If the source isn't somewhere that makes sense as an output location, default to reports/<stem>-slides.pdf.
After the PDF lands on disk, the subagent also POSTs it to the WOWerpoint Server, which converts the 16:9 deck into a 9:16 mobile twin and returns a share URL. The share URL is the primary deliverable to the user; the PDF on disk is the backup.
Required env (exported in the user's shell — the subagent inherits the parent's environment, so plain export is enough; no dotenv loader runs):
If any var is missing, skip the share-link step and just hand the PDF over.
Upload pattern (run AFTER the subagent confirms the PDF exists on disk). Capture the full response so empty id and error payloads are handled — jq -r '.id' returns the literal string null on a missing key, so always pipe through .id // empty:
The returned id is a kebab-case slug derived from the title with a random creature suffix (e.g. tokenrouter-quest-hawk, or velvet-comet-tiger if the title is empty or non-ASCII). The share URL is:
It works immediately (shows a "still converting…" page that auto-reloads when ready). Conversion takes ~1–2 min per slide. Print the share URL in your final response.
One sentence. Default:
Replace <subject> with a one-phrase description from the source doc's H1 or the user's framing. If the user supplies their own prompt, pass it through verbatim — don't expand it.
On warning, the PDF on disk is still a valid deliverable — do not retry the upload.
Report briefly (under 200 words):
Do NOT poll status manually. The wait commands handle backoff.
NOTEBOOK_ID=$(notebooklm create "<title>" --json | jq -r .notebook.id)
SOURCE_ID=$(notebooklm source add "<doc-path>" --notebook "$NOTEBOOK_ID" --json | jq -r .source.id)https://notebooklm.google.com/notebook/<NOTEBOOK_ID><source-dir>/<source-stem>-slides.pdfWOWERPOINT_API_BASE=https://wowerpoint-api.<subdomain>.workers.dev
WOWERPOINT_VIEWER_BASE=https://wowerpoint-viewer.<subdomain>.workers.dev
WOWERPOINT_UPLOAD_TOKEN=<token>if [ -n "$WOWERPOINT_API_BASE" ] && [ -n "$WOWERPOINT_UPLOAD_TOKEN" ] && [ -n "$WOWERPOINT_VIEWER_BASE" ]; then
UPLOAD_JSON=$(curl -sS --connect-timeout 10 --max-time 30 -X POST "$WOWERPOINT_API_BASE/api/decks" \
-H "Authorization: Bearer $WOWERPOINT_UPLOAD_TOKEN" \
-F "file=@<OUTPUT_PATH>" \
-F "title=<TITLE>")
DECK_ID=$(printf '%s' "$UPLOAD_JSON" | jq -r '.id // empty')
API_ERROR=$(printf '%s' "$UPLOAD_JSON" | jq -r '.error // empty')
if [ -n "$API_ERROR" ] || [ -z "$DECK_ID" ]; then
echo "WOWerpoint upload warning: ${API_ERROR:-missing id}"
else
echo "Share URL: $WOWERPOINT_VIEWER_BASE/$DECK_ID"
fi
fi$WOWERPOINT_VIEWER_BASE/<id>Use kawaii characters to tell the story of <subject>. Keep it warm and clear.