screens
Skill0 starsChanged 30 days agoMITView on GitHub
Builds and maintains a complete, current screenshot catalog of every view in every applicable state (data/viewport/theme/role) for a project, plus App-Store-ready marketing renders. First run discovers views via an agent and scaffolds a demo seeder + capture drivers; later runs are scripted and incremental (only new/changed views recapture). NOT for before/after proof of one change (/delegate shows that live in Chrome or the iOS Simulator instead). Use when the user runs /screens, wants a full visual inventory of the app, or needs App-Store screenshots.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- genkovich/sddtheir own version, first seen Oct 25, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- genkovich/sdd★ 187same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository13 other files it gives its agents.
- audit/CLAUDE.mdCLAUDE.md
- CLAUDE.mdCLAUDE.md
- delegate/CLAUDE.mdCLAUDE.md
- plan-it/CLAUDE.mdCLAUDE.md
- screens/CLAUDE.mdCLAUDE.md
- ship/CLAUDE.mdCLAUDE.md
- store-assets/CLAUDE.mdCLAUDE.md
- auditSkill
- delegateSkill
- plan-itSkill
- readinessSkill
- shipSkill
- store-assetsSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 100
Single
AskUserQuestion: before anything runs: show, per platform, the entry count, the state axes that apply, the planned total, the … - Distinctive: line 131
After the executor returns, run a seeder dry run:
- Very specific: line 172
When files matching route_sources changed since state.commit (git diff --name-only <state.commit>..HEAD -- <route_sources>), dispatch …
- Very specific: line 243
Before the first marketing call ever (same first-run guard as Phase 1/2), also instantiate screens/templates/marketing.html into …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/screens: Screenshot Catalog of Every View in Every State
Architecture note: Discovery is agent work (
agents/screens-view-discoverer.md, worker specscreens/agents/view-discoverer.md), capture is scripted (screens/bin/screens.mjs). Per-project files (config, manifest, state, drivers, secrets) live under.screens/in the TARGET project, never under.claude/(subagents cannot write there: orchestrator writes, subagents return). The PNG catalog itself lives OUTSIDE the project, under~/Developer/screens/<project-slug>/(orconfig.output_dirwhen set) --resolveScreensOutputRootinscreens.mjsresolves it, seereferences/config-schema.md"Output root". The web driver (screens/references/platform-web.md,screens/templates/capture.spec.ts) is live as of stage b; marketing rendering andindex.html(screens/templates/marketing.html,render-marketing.mjs,index.html) are live as of stage c; the Apple driver (iOS + macOS, XCUITest,screens/references/platform-apple.md,screens/templates/ScreensCatalogTests.swift) is live as of stage d, including real dedicated-simulator setup inscreens.mjs up/down(deviceSetupHook->iosDeviceSetup/macosDeviceSetup). The Maestro driver (Android + a Capacitor app's Android build,screens/references/platform-maestro.md,screens/templates/maestro-flow.yaml,screens/templates/generate-maestro-flows.mjs) is live as of stage e, including dedicated-AVD setup inscreens.mjs up/down(deviceSetupHook->androidDeviceSetup). Capacitor iOS is out of scope (platform-apple.md's XCUITest driver covers native iOS only).
Phase 0: Preflight
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
type orch_run_log >/dev/null 2>&1 || echo "lib-orchestrator.sh not found; run log and helpers unavailable (skill continues)"
orch_run_log --start --skill screens
SCREENS_BIN="$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/screens/bin/screens.mjs"
[ -f "$SCREENS_BIN" ] || SCREENS_BIN="$HOME/.claude/skills/screens/bin/screens.mjs"
[ -f "$SCREENS_BIN" ] || { echo "Aborted: screens.mjs not found."; exit 1; }
DETECT="$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/detect-framework.sh"
[ -f "$DETECT" ] || DETECT="$HOME/.claude/skills/audit/bin/detect-framework.sh"
[ -f "$DETECT" ] && eval "$("$DETECT")"
echo "FRAMEWORK=${FRAMEWORK:-unknown} PLATFORM=${PLATFORM:-unknown}"
if [ -f ".screens/.lock" ]; then
echo "Aborted: a /screens run is already in progress in this repo (.screens/.lock present)."
exit 1
fi
REQUESTED_PLATFORM=""
FULL_FLAG=""
for a in $ARGUMENTS; do
case "$a" in
web|ios|android|macos) REQUESTED_PLATFORM="$a" ;;
--full) FULL_FLAG="--full" ;;
esac
done
echo "RequestedPlatform=${REQUESTED_PLATFORM:-all} Full=${FULL_FLAG:-no}"
orch_state_save SCREENS_BIN REQUESTED_PLATFORM FULL_FLAG/screens <platform> scopes the whole run to one platform and never touches .screens/config.json
(product decision, plan Invocation section). --full ignores fingerprints (passed straight to
screens.mjs plan --full).
Phase 1: Discovery (first run only)
Skip this phase entirely when .screens/config.json already exists; go to Phase 2.
detect-framework.sh reports a CLI or WordPress/Local project (FRAMEWORK=generic with no known
web/native signature): report SCREENS_RESULT=SKIP (unsupported project type) and stop (Non-Goal:
CLI/WordPress-Local projects).
Otherwise, dispatch screens-view-discoverer (subagent_type: screens-view-discoverer, model:
sonnet, run_in_background: false; worker spec screens/agents/view-discoverer.md) once per
configured/detected platform, MODE=full. Input per the worker spec's Input contract:
PLATFORM, PROJECT_ROOT, FRAMEWORK, SURFACE_TAXONOMY (screens/references/surface-taxonomy.md
next to this skill).
From the returned MANIFEST_ENTRY/CONFIG_DRAFT/DEMO_DATA_BRIEF/MARKETING_HERO lines, write
.screens/config.json and .screens/manifest.json yourself (Write tool) per the schema in
references/config-schema.md. Compute the planned total (entries x applicable axes) for the
summary below.
Single AskUserQuestion before anything runs: show, per platform, the entry count, the state
axes that apply, the planned total, the marketing hero list with proposed headlines, and the exact
start/seed commands that will run (Trust boundary: this is the first confirmation of them). On
confirmation, write .screens/state.json with command_hash from screens.mjs trust --confirm
(run after config.json is written) so later runs do not re-ask unless a command changes.
Phase 2: Scaffold
First run only (same guard as Phase 1). Dispatch a general-purpose subagent (model: sonnet,
run_in_background: false) with the demo-data brief and config/manifest paths: write the demo
seeder and the platform driver files the plan's "Per-project files" table names
(database/seeders/ScreensDemoSeeder.php or the framework's equivalent, .screens/web/capture.spec.ts,
.screens/web/playwright.config.ts (verbatim, no templating, screens/references/platform-web.md
"Invocation"), etc.; driver templates for stages d/e are not present in this repo yet, and when a
template is missing, the executor writes only the seeder and reports which drivers it deferred). On a PHP
project, also instantiate screens/templates/php/fixed-clock.php verbatim into
.screens/web/fixed-clock.php and screens/templates/php/zz-screens.ini into
.screens/web/php/zz-screens.ini with {{PROJECT_ROOT}} replaced by the project's absolute path,
and set config.web.fixed_now to the same instant as capture.spec.ts's FIXED_TIME
(screens/references/platform-web.md "Server-side fixed clock"), also instantiate
screens/templates/php/FixedClockDateTime.php into .screens/web/php/FixedClockDateTime.php and
have the demo seeder require it and register it on fake() and app(\Faker\Generator::class)
before calling the project's own seeders, and follow the "Seeder determinism rules" checklist
(screens/references/platform-web.md) for Str::create*Using seeding and any ->random(-family
call inside the seeders it calls. On an android/Capacitor project, also instantiate
screens/templates/maestro-flow.yaml verbatim into .screens/android/maestro-flow.yaml and
screens/templates/generate-maestro-flows.mjs verbatim into .screens/android/generate-maestro-flows.mjs
(no templating, both read config.json/manifest.json at generation time,
screens/references/platform-maestro.md "Flow generation"). The orchestrator never writes these
files itself (subagent Write scope is the target project, not .claude/).
After the executor returns, run a seeder dry run:
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_state_load
node "$SCREENS_BIN" up --platform "${REQUESTED_PLATFORM:-web}"A FAIL line here (seeder error, DB guard, missing tool) stops before any capture: keep
config/manifest, report the error, the next run retries the scaffold (Edge Cases: "Seeder fails on
first run").
Phase 3: Trust check
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_state_load
node "$SCREENS_BIN" trustTRUST_RESULT=NEEDS_CONFIRM (a command field changed since the last confirmation, or a fresh
clone): show the current command fields via one AskUserQuestion, then run
node "$SCREENS_BIN" trust --confirm on approval. TRUST_RESULT=OK: continue silently.
Phase 4: Plan + delta discovery
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_state_load
node "$SCREENS_BIN" plan $FULL_FLAGWhen files matching route_sources changed since state.commit (git diff --name-only
<state.commit>..HEAD -- <route_sources>), dispatch screens-view-discoverer again, MODE=delta,
DELTA_FILES from that diff. Apply MANIFEST_ENTRY/REMOVED_ENTRY additions to
.screens/manifest.json without asking (triage decision, plan's "Incremental rule"); report the
delta in the Phase 8 summary. Hand-edited entries (no matching discoverer proposal this run) are
never touched.
Phase 5: Per-platform loop
For each platform in scope (REQUESTED_PLATFORM or every platform in config.json, macOS last,
it takes focus visibly): up -> driver -> promote -> down, down always runs even on a driver
failure (trap semantics; a single-entry failure does not abort the platform, a driver failure does
not skip promote/down).
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_state_load
PLATFORM="${REQUESTED_PLATFORM:-web}"
node "$SCREENS_BIN" up --platform "$PLATFORM"
orch_state_save PLATFORM # read back by the promote/down block belowUP_RESULT=SKIP (...) (toolchain or device setup not available/not implemented yet): report and
move to the next platform, no capture attempted. UP_RESULT=FAIL (...): report the reason and run
down before moving on.
Driver step: read screens/references/platform-web.md (web, added stage b),
screens/references/platform-apple.md (iOS/macOS, added stage d),
screens/references/platform-maestro.md (Android/Capacitor, stage e); when the reference file does
not exist yet, report DRIVER=SKIP (driver added in a later stage) for that platform and skip
straight to down. On the web platform, run the driver command under nice -n 10 with --config
.screens/web/playwright.config.ts (keeps test-results//playwright-report/ out of the project
root, screens/references/platform-web.md "Invocation") and pass --workers=<PLAYWRIGHT_WORKERS>
from up's own output line (min(4, floor(cores/2)), plan's "Capture efficiency"; the user reported
earlier runs overloading the machine), never a hardcoded --workers=4. On iOS/macOS, run xcodebuild
test under nice -n 10 with -derivedDataPath
<up's DERIVED_DATA_PATH output line>, -destination "platform=iOS Simulator,id=<up's
SIMULATOR_UDID output line>" (iOS only), and xcrun simctl ui <SIMULATOR_UDID> appearance
light|dark before each themed pass (platform-apple.md "Invocation"); the per-entry stale filter is
the TEST_RUNNER_SCREENS_ENTRIES env var, not -only-testing (platform-apple.md "Filtering"). On
macOS specifically, the xcodebuild invocation also carries -resultBundlePath
.screens/.build/macos/Result.xcresult, and node "$SCREENS_BIN" macos-export runs right after
each themed pass, before the next theme's xcodebuild call overwrites that bundle: the macOS UI test
runner is sandboxed and cannot write a PNG into the project directory, so every macOS screenshot
arrives as an XCTAttachment inside the result bundle instead of a direct file write
(platform-apple.md "Invocation" and "Known limits"). On
android, npx cap sync android + the isolated capacitor.config.json server.url rewrite (Capacitor
apps only, skip both for a plain Android project) + nice -n 10 ./gradlew assembleDebug + adb -s
<up's ANDROID_SERIAL output line> install -r, then for each theme: adb -s <serial> shell cmd uimode
night yes|no, node .screens/android/generate-maestro-flows.mjs <comma-separated stale entry ids>
<theme>, nice -n 10 maestro --device <serial> test .screens/.maestro-generated/, then move that
pass's *__<theme>.png files (Maestro writes them to the project root, not an arbitrary path) into
.screens/.incoming/android/ (platform-maestro.md "Invocation"). UP_RESULT=SKIP (avdmanager not
found; ...) or any other preflight SKIP line means no build/install/capture is attempted for that
platform, same as a missing web/Apple toolchain.
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_state_load
node "$SCREENS_BIN" promote --platform "$PLATFORM"
node "$SCREENS_BIN" down --platform "$PLATFORM"Phase 6: Marketing
Before the first marketing call ever (same first-run guard as Phase 1/2), also instantiate
screens/templates/marketing.html into .screens/web/marketing.html and
screens/templates/render-marketing.mjs into .screens/web/render-marketing.mjs verbatim (no
templating; both read config.json/job data at render time), same "no project source file changes"
convention as the PHP fixed-clock files.
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_state_load
node "$SCREENS_BIN" marketingnode "$SCREENS_BIN" marketing spawns .screens/web/render-marketing.mjs as a child process (the
project's own Playwright devDependency, not this repo's (repo CLAUDE.md "Stack": no npm
dependencies here) for every entry x locale whose source PNG hash, headline text, or review state
changed since the last render (marketingNeedsRender); everything else is reported
MARKETING_SKIP ... (unchanged). MARKETING_RESULT=FAIL (...) (e.g.
.screens/web/render-marketing.mjs missing, or the render script errored): report the reason,
continue to Phase 7 (marketing is best-effort, never blocks the catalog). Collect MARKETING_RENDER
lines whose target path still contains _draft for the Phase 8 NEEDS REVIEW list.
Phase 7: Index
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_state_load
node "$SCREENS_BIN" indexWrites <output root>/index.html (embedded JSON + vanilla JS, screens/templates/index.html
instantiated with the current catalog + marketing state, no dependency, opens straight from disk),
plus <output root>/catalog.json and a regenerated ~/Developer/screens/index.html listing every
project that has a catalog there (TOP_INDEX_RESULT=OK projects=<n>, now also the last run's changed
count per project). INDEX_RESULT=OK path=...: report that path. INDEX_RESULT=FAIL (...): report
the reason, the run still completes (the PNGs themselves are unaffected).
index.html's "Verlauf" section (change history, references/config-schema.md "Change history")
reads <output root>/runs.jsonl, one line per promote invocation: a timeline of runs newest first,
each expandable to its changed/drift entries with a before/after view (side-by-side plus a
keyboard-accessible slider overlay) linking the _history/<run-id>/ PNG and the current one. Every
catalog view carries an "n Versionen" badge when it has historical versions, opening the same
before/after view against its own most recent one. promote moves the previous PNG into
_history/<run-id>/ on every changed/drift verdict (never on new/unchanged/tolerated),
retained per config.history_keep (default 5 versions per combo) and config.history_max_mb
(default 1024, whole-project cap, oldest run folders pruned first, never the current run's).
Phase 8: Report
Table: platform x new/updated/unchanged/removed/drift/failed (from the PLAN_ENTRY/PROMOTE_ENTRY
(PROMOTE_ENTRY <id> <combo> new|changed|unchanged|tolerated|drift|known_nondeterministic)/
PROMOTE_REMOVED lines collected above; drift only appears on a --full run, see plan's
"Incremental rule"). NEEDS REVIEW list: MARKETING_RENDER lines whose target still contains
_draft. Path to <output root>/index.html. Suggest --full when the last full run is older than
30 days (from state.json, once state carries that timestamp).
for c in "$(dirname "${CLAUDE_SKILL_DIR:-/nonexistent}")/audit/bin/lib-orchestrator.sh" \
"$HOME/.claude/skills/audit/bin/lib-orchestrator.sh"; do
[ -f "$c" ] && { . "$c"; break; }
done
orch_run_log --skill screens --outcome "{ok|partial|fail}" \
--counts "new={N_NEW},updated={N_UPDATED},failed={N_FAILED}"Fill {ok|partial|fail} and the {N_...} placeholders with the outcome and counts tallied from
this phase's own report table before running the block (same convention as audit/SKILL.md
Phase 4's {N_CRITICAL} placeholders: the orchestrator writes literal values, not a shell
variable read from an earlier block).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

