Screenshot the app or the CLI
SkillMediaTake a screenshot of the running Mycelium app, or of CLI output rendered as a terminal card, or record a short video of a flow with a visible cursor and click/zoom animations. Use when you need to SEE the UI — verifying a frontend change, checking a layout at phone/tablet/desktop widths, driving a multi-step flow and looking at each step, producing an image of a `mycelium` command's output for a doc or PR, or showing a flow in motion. Triggers on "screenshot", "show me the app", "what does it look like", "check the layout", "responsive", "capture the terminal", "record a video", "screen recording", "demo clip", "show it in motion".
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Screenshot the app or the CLI skill
What this skill tells your AI
The instructions your AI receives, as published by mycelium-io/mycelium in .claude/skills/screenshot/SKILL.md and read by ahel’s review.
shotkit/ is this repo's camera. It holds a browser open in a background
daemon, so the first shot costs ~2s and every later one ~150ms.
Run it from the repo root:
node shotkit/bin/shot.mjs <command> [flags]
The absolute PNG path is the only thing on stdout — read that file back to see the result. Timings and warnings go to stderr.
First run on a machine
node shotkit/bin/shot.mjs doctor
It reports the browser, script(1), whether the frontend's deps are installed,
whether an app is already listening, and whether webfonts load here. Fix
anything it marks ✗ before capturing. Terminal and code cards need no app at
all.
If the webfont check warns, add --offline to every app capture and don't
publish shots taken on this machine — they will render in fallback fonts. A
capture that takes more than a few seconds prints the same hint.
Screenshot the app
# boot the mock frontend (no backend, SLIM or LLM needed) and shoot a route
node shotkit/bin/shot.mjs app /room/atlas-migration --mock
# against an app you already have running
node shotkit/bin/shot.mjs app / --base-url http://localhost:3000
--mock boots pnpm dev:mock inside the daemon, so it stays warm across
shots — pass it on the first capture and omit it afterwards. An already-running
dev server is found automatically, whatever port it is on.
Add --offline when a capture takes more than a few seconds. The frontend
links Google Fonts; where those are unreachable, each navigation waits ~13s on
them. --offline resolves nothing but localhost and the app renders with
fallback fonts.
Check a layout across breakpoints
node shotkit/bin/shot.mjs app / --responsive --sheet --offline
Four frames — phone, tablet, laptop, wide — plus one contact sheet composing
them at their true relative widths. Read the sheet: it answers "is this
responsive" in a single look. --viewports phone,wide picks a subset;
--viewport 1280x800@2 takes an exact size.
Drive a flow, then look
For a state behind a click, either pass ordered steps to one capture:
node shotkit/bin/shot.mjs app /room/atlas-migration --offline \
--do click:Negotiate --do wait:.offer-grid
…or hold the page open and work against it, which is what you want when you need to see each step before deciding the next:
node shotkit/bin/shot.mjs open /room/atlas-migration --session r --offline
node shotkit/bin/shot.mjs do click:Negotiate --session r
node shotkit/bin/shot.mjs shoot --session r --name negotiate # ~250ms
node shotkit/bin/shot.mjs close --session r
Anything without CSS punctuation is matched by accessible name, then visible
text — click:Negotiate, and phrases too: click:Install CLI is a button, not a
descendant selector. Words that are also tag names are no exception, so
click:table finds a button labeled "table" before it considers a <table>.
For a selector use #id, .class, role=button[name="Save"], text=Save, or
css= when it is only tag names and spaces. shot help shoot lists every verb.
Record a short video
When the thing to show is a flow rather than a state — a demo clip for a PR or a doc, or checking that an interaction feels right:
node shotkit/bin/shot.mjs video /room/atlas-migration --mock --offline \
--do click:Negotiate --do wait:.offer-grid --auto-zoom
Same --do verbs as a screenshot. The recording adds what a still does not
need: the pointer travels to each target (moving the real mouse, so hover states
fire), a ring marks each click, and --auto-zoom pushes the camera in on what is
being pressed and back out after. zoom:<sel>, zoom:<sel>@2.2 and zoomout
place the camera by hand.
The output path on stdout is an .mp4 where the machine has a full ffmpeg, and
a .webm otherwise — Playwright's bundled build is webm-only. shot doctor
says which. You cannot watch it: hand the path to the user, or pull a frame out
of it to look at. Keep takes short (a few actions); --max-seconds caps one.
Screenshot CLI output
Runs the command under a pty, so Rich keeps its colors and box drawing:
node shotkit/bin/shot.mjs term --cols 84 -- mycelium memory --help
# run one command, label it as another (the CLI often needs `uv run` locally)
node shotkit/bin/shot.mjs term --cwd mycelium-cli --command "mycelium doctor" \
-- uv run mycelium doctor
Flags must come before the command; everything after the first plain word
belongs to the child. shot text <file> renders an ANSI log you already have,
and shot code <file> --range 40:80 makes a syntax-highlighted code card.
Framing for a PR or doc
node shotkit/bin/shot.mjs app /room/atlas --chrome --offline # browser window frame
node shotkit/bin/shot.mjs app / --chrome --theme light --backdrop dusk
node shotkit/bin/shot.mjs app / --chrome --backdrop mycelial --padding 90
--theme switches the app itself, not just the browser's media query.
--backdrop mycelial is the desktop behind the window: the docs site's own
mycelial network, the same one docs/banner.png is cut from. Give it padding to
show — and prefer a quiet backdrop (mycelium, ink, paper) when the screen
itself is busy.
Rules
- Never commit anything from
.shotkit/. It is gitignored scratch. The committed docs screenshots have their own pipeline —pnpm screenshotsinmycelium-frontend/, publishing perscreenshots/targets.ts. Run that, and commit its output, only when asked to update the docs assets. - Don't hand-roll Playwright for a screenshot. If shotkit is missing a
capability, add it there;
capture()inshotkit/src/api.mjsis importable. - Leave the daemon running. It idles out after 15 minutes.
shot stoponly if you need a clean slate.
Signals
- GitHub stars
- 117
- Forks
- 12
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
screenshot-mycelium-io- Source
- github.com/mycelium-io/mycelium