scripts/michel/michel-cli-demo-recorder/SKILL.md
--- name: michel-cli-demo-recorder description: Produce proof-of-execution demos of the Packmind CLI (`packmind-cli`) as static terminal-styled SVG images (colors and formatting preserved exactly), for embedding in a GitHub PR. Use this whenever a dev task touches the CLI — new command, changed output, new flag, bug fix in terminal rendering — and the PR would benefit from showing the tool actually running. Trigger it when the user says "record a CLI demo", "show the command output", "add a term
npx skillsauth add PackmindHub/packmind scripts/michel/michel-cli-demo-recorderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Turn a local packmind-cli invocation into a polished, colored terminal screenshot (SVG) that drops straight into a GitHub PR. The companion to michel-ui-demo-recorder — that one records the browser UI; this one captures the terminal.
apps/cli/) — attach a demo by default; reviewers shouldn't have to clone and run it to see the output.The deliverable is one or more SVG images, each a terminal window showing a fake prompt line (user@host dir % <command>) followed by the command's real, fully-colored output. SVG because it is crisp at any zoom, a few KB, exact-color, and renders inline on GitHub when committed to the repo and referenced by a relative path.
Capturing colored CLI output correctly has three non-obvious traps that waste time if you hit them mid-task:
packmind-cli colors its output with chalk (see apps/cli/src/infra/utils/consoleLogger.ts), which — like most well-behaved CLIs — emits ANSI only when it detects a real terminal or FORCE_COLOR is set. Pipe the output to a file with neither and you get plain, colorless text — the exact opposite of the goal. The bundled converter both sets FORCE_COLOR=3 and runs the command under a pseudo-terminal (PTY), so color survives even for commands that gate strictly on isTTY. Don't hand-roll the capture.script (script -q <file> <cmd>); Linux ships util-linux script (script -qec "<cmd>" <file>). And BSD script only writes the full session to its typescript file, not to a piped stdout. The bundled converter handles both — don't hand-roll it.scripts/render-cli-demo.mjs codifies the working recipe so you don't relearn it each time.
PACKMIND_EDITION=oss node .claude/skills/michel-cli-demo-recorder/scripts/render-cli-demo.mjs \
--out docs/cli-demos/standards-list.svg \
--text-out docs/cli-demos/standards-list.txt \
--title "packmind-cli — standards list" \
--prompt-cmd "packmind-cli standards list" \
-- node dist/apps/cli/main.cjs standards list
| Flag | Meaning |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --out | where to write the SVG (required) |
| -- <command...> | everything after -- is the command run under the PTY (required). For this repo that is node dist/apps/cli/main.cjs <subcommand…>. |
| --prompt-cmd | the text drawn on the fake prompt line. Defaults to the actual executed command. Since the real invocation is the verbose node dist/apps/cli/main.cjs …, pass the friendly packmind-cli … form here so the demo reads cleanly — that is how an installed user runs it. |
| --title | window title-bar caption. Omit for no caption. |
| --cwd | directory to run the command in (default: current dir — i.e. the repo root, where dist/apps/cli/main.cjs lives). |
| --text-out | also write an ANSI-stripped plain-text copy. Always pass this — see "Verify". |
| --theme | dark (default) or light. |
Runs under node.
dist/, so build it with npm run packmind-cli:build. It produces dist/apps/cli/main.cjs, which you then run with node dist/apps/cli/main.cjs. A demo of stale dist/ proves nothing about your change.PACKMIND_EDITION=oss (per the repo's CLAUDE.md), or the CLI may behave differently than expected.login, whoami, standards/commands/skills pulls, playbook) need the local stack up, or they only print the error/unauthenticated path. If you want populated, colorful output, bring the stack up and confirm it's serving before recording — see the michel-run-local-dev-stack skill (docker compose up -d). Local-only commands (--help, --version, lint, diff, config) need no server. If the point of the demo is the error message, skip the server deliberately.--help, and any new/changed flag. One SVG per invocation — small focused images beat one giant scroll.docs/cli-demos/ is a good home; create it).docker compose down — see the michel-run-local-dev-stack skill).You usually can't see an SVG directly (and Linux CI hosts have no rasterizer), so verify by content, not by eye:
--text-out sidecar. It's the exact text that got captured, ANSI stripped. Confirm it shows what your change should produce — right rows, right counts, the new flag's effect, aligned columns. If the sidecar is empty or shows an error you didn't intend, the demo is wrong regardless of how the SVG looks.qlmanage -t -s 1400 -o /tmp <file>.svg produces <file>.svg.png, which you can open/Read. Handy while authoring; not available on Linux workers, which is why the text sidecar is the primary check.A demo that captured the wrong state (server down, stale build, not logged in, empty DB) is worse than no demo — it misleads the reviewer. Treat the sidecar as a required gate.
Commit the SVG (and optionally the .txt) into the repo, then reference it by relative path in the PR body:
## CLI demo

<details><summary>Plain text</summary>
```text
<paste docs/cli-demos/standards-list.txt here, or link it>
```
</details>
```
The plain-text <details> block is a courtesy fallback for anyone whose viewer won't render the SVG, and it's searchable/diff-able in a way an image isn't.
packmind-cli … form (via --prompt-cmd) — that's how an installed user invokes it — while the command actually executed under the PTY is the repo's node dist/apps/cli/main.cjs ….scripts/render-cli-demo.mjs — the whole pipeline: PTY capture (OS-aware) → ANSI/SGR parse → terminal-styled SVG, plus optional plain-text sidecar. Zero dependencies.tools
Record polished UI demo videos and screenshots of a running web app using Playwright MCP — for client deliverables, release notes, feature walkthroughs, or bug repros. Produces an HD WebM video with chapter markers, a mandatory animated cursor overlay, and a mandatory subtitle bar that narrates each step (positioned deliberately so it never masks the UI being demonstrated), plus full-page screenshots at each step. Use this whenever the user asks to "record a demo", "create a screencast", "make a UI walkthrough video", "document this feature with video", "show the client how X works", "capture screenshots of the app", or anything similar — even when the user only says "make a video" or "take screenshots" in the context of a running frontend. Also use it when the user wants to demonstrate a workflow, generate marketing-quality footage of an app, or produce repeatable visual documentation.
tools
The canonical recipe for starting, checking, and stopping the Packmind local dev stack with Docker Compose — the single source of truth other skills and the Michel agent defer to. Covers bringing the full stack (PostgreSQL, Redis, NestJS API, React/Vite frontend on :4200, MCP server, nginx) up in the background, the init services (dependency install + TypeORM migrations) you must wait on, the critical host-port trap that the API on container port 3000 is NOT exposed to the host and must be reached via the frontend Vite proxy at localhost:4200/api/v0, confirming the API and frontend are actually serving before you depend on them, the persistent-volume gotcha that leaves stale Postgres schema and node_modules behind between runs, building the CLI, and tearing everything down so no container is left blocking the run. Use this whenever you need Packmind running locally — to verify a change, record a UI or CLI demo, hit the API, seed data, or reproduce a bug — and whenever you are about to start or stop `docker compose`. If you are an autonomous agent (e.g. Michel) that started the stack, you MUST use the teardown half before finishing. Prefer this over running `nx serve` on the host for anything that needs the real, containerized stack.
tools
Best practices for creating GitHub pull requests that include inline images — CLI terminal screenshots (from cli-demo-recorder), UI screenshots/videos (from ui-demo-recorder), or any other visual artifact. Use this skill whenever opening or updating a PR that has visual artifacts to embed, or when images aren't rendering in a PR description. Also use it when asked "how do I add screenshots to a PR", "why isn't my image showing", or "embed a demo in the PR".
tools
--- name: michel-create-packmind-dataset description: Seed a local Packmind instance with a realistic dataset — one organization populated with standards, commands, and skills — so an autonomous agent can exercise its own changes against lifelike data instead of an empty app. Use this whenever you need populated Packmind data to verify a change end-to-end: reproducing a bug that only shows with existing artifacts, recording a UI/CLI demo that needs content on screen, smoke-testing a new endpoint