Install
sscc ships with the ScreenShotComposer macOS app. The Mac app installs the binary at/usr/local/bin/sscc on first launch (you can disable this in Settings → Advanced).
If you cloned the repo to build from source:
git clone https://github.com/luigiinred/ScreenShotComposer.git cd ScreenShotComposer bin/sscc --help
Confirm the API version your scripts target — sscc bumps it on every breaking change to the JSON envelope:
sscc --api-version
Conventions
- Address by UUID, never by title. Every command that mutates a composition or layer takes
--id <uuid>. Capture UUIDs at create-time with--emit-id. - Add
--jsonfor machine-readable output. Every command returns a stable envelope —{ "ok": true, "data": ... }on success,{ "ok": false, "error": { "code", "message" } }on failure. - Mutations are atomic. Either the bundle is updated cleanly or it is untouched on disk. No partial writes.
- Frames are
X,Y,W,Hin plate points, top-left origin. Negative origins are valid (for edge bleeds); use the=form soswift-argument-parserdoesn’t mistake a leading-for a flag boundary:--frame=-200,300,800,1200. - Text accepts
\nonly. Pass it literally inside double-quoted bash strings; the CLI converts it at parse time.<br/>renders as the literal characters. - Image sizing is frame-only. There is no
--scaleflag. To grow an image, pass a bigger frame.
catalog
Enumerate live catalogs — templates, bezels, presets, fonts.
| sscc catalog templates [--json] | Every bundled template — id, label, supported platforms. |
| sscc catalog bezels [--platform <p>] [--json] | Every device bezel — id, platform, inner rect coordinates. |
| sscc catalog presets [--json] | Every ASC export preset — token, platform, pixel dimensions. |
| sscc catalog fonts [--json] | Every installed font available to text layers — PostScript names + families. |
These four catalogs are the source of truth for any id your scripts pass elsewhere. Always cross-check before freehand-typing a bezel id, font name, or preset token.
# Pick the iPhone 17 Pro bezel from the live catalog. sscc catalog bezels --platform iphone --json | jq -r '.data[].id' | head
schema
Emit JSON Schema for the document nodes. Use these to validate generated payloads, build editors, or teach an agent the field grammar.
| sscc schema manifest [--json] | Top-level info.json shape (schemaVersion, app, presets, sidebar order). |
| sscc schema composition [--json] | One CompositionRecord — title, plateFill, preset, layers[]. |
| sscc schema layer [--kind text|image|background|group] [--json] | Layer record for one (or all) kinds. |
new
Create a new .screenshot document.
sscc new <path> [--template <id>] # bundled template id (sscc catalog templates) [--platforms mac,iphone,ipad] # default: all three [--overwrite] [--emit-id] # print only the absolute created path [--json]
Each requested platform gets a <platform>.json with an empty compositions: [].
info
Summarize what’s in a bundle.
sscc info <path> [--json]
The JSON variant is the right way to assert composition counts in a scaffold script.
sscc info MyApp.screenshot --json | jq '.data.compositions | map_values(length)'
# { "mac": 6, "iphone": 6, "ipad": 6 }show
Print the full bundle (or one composition or one layer) as JSON.
sscc show <path> [--composition <uuid>] # limit to that composition [--layer <uuid>] # limit to that layer [--json]
validate
Validate a bundle against the documented schema.
sscc validate <path> [--strict] [--json]
--strict promotes warnings to errors. Run this after every batch of edits.
Note: validate proves the file is well-formed JSON; it does not prove the bundle will render correctly. For that, see the create-screenshot-file skill’s pre-render verify gate.
composition
Manage compositions inside a bundle.
| sscc composition add <path> --platform <p> [--title <t>] [--plate-color <#hex>] [--preset <token>] [--emit-id] | Append a composition to a platform bucket. Returns the new UUID. |
| sscc composition set <path> --id <uuid> [--title <t>] [--plate-color <#hex>] [--preset <token>] | Mutate composition metadata. |
| sscc composition remove <path> --id <uuid> | Remove a composition. |
| sscc composition reorder <path> --platform <p> --order <uuid,uuid,...> | Reorder compositions inside a platform bucket. |
Heads up: composition add auto-creates one empty backgroundlayer per composition. Don’t add another via layer add background — see Known quirks.
layer
Manage layers (text, image, background, group) inside a composition.
| sscc layer add text --composition <uuid> --content <str> [--style headline|body|caption] [--font-size N] [--font-weight <token>] [--frame X,Y,W,H] [--color <#hex>] [--align H,V] [--emit-id] | Add a text layer. Use \n for line breaks. |
| sscc layer add image --composition <uuid> --source <png> [--bezel <id>] [--frame X,Y,W,H] [--radius N] [--inset N] [--border W,#hex] [--rotation deg] [--emit-id] | Add a (optionally bezeled) image layer. |
| sscc layer add background --composition <uuid> [--source <png>] | Add a plate-filling background layer. (Avoid — use layer set on the auto-created bg.) |
| sscc layer add group --composition <uuid> [--title <t>] | Group nested layers. |
| sscc layer set --id <uuid> [--content <str>] [--source <png>] [--frame ...] [--color <#hex>] [--font-size N] [--font-weight <t>] [--align H,V] [--style <s>] [--bezel <id>|none] [--rotation deg] | Mutate any field on an existing layer. |
| sscc layer remove --id <uuid> | Remove a layer. |
| sscc layer reorder --composition <uuid> --order <uuid,uuid,...> | Re-stack layers inside a composition (sets sortOrder). |
| sscc layer move --id <uuid> [--composition <uuid>] [--parent-group <uuid>|none] | Move a layer between compositions or in/out of a group. |
asset
Manage embedded image assets inside a bundle.
| sscc asset embed <path> --source <file> [--id <id>] | Copy an external image into the bundle's assets/ dir. |
| sscc asset list <path> | Enumerate every asset — id, byte size, references. |
| sscc asset clear <path> [--dry-run] | Remove orphan assets that no layer references. |
export
Render PNGs for every composition (or a filtered subset).
sscc export <path> --output <dir> [--platform mac|iphone|ipad] # restrict to one bucket [--composition <uuid>] # repeatable [--format png] # default & only option today [--opaque] # alpha-stripped RGB PNG (ASC-friendly) [--at-preset <token>] # render-time preset override [--naming preset|uuid|title-slug] [--overwrite] [--json]
--at-preset is a render-time override; the document on disk keeps its original presets, so the same source can produce every ASC slot:
# Largest required sizes for every platform. sscc export MyApp.screenshot --output ship/largest \ --opaque --naming title-slug --json > ship/largest/manifest.json # Plus an additional iPhone 6.5" slot. sscc export MyApp.screenshot --output ship/iphone-6.5 \ --platform iphone --at-preset 1284x2778 --opaque
Heads up: --opaque currently paints a gray transparency-checkerboard into plain (non-bezel) image layers that have alpha. Drop --opaque when your bundle has stickers, badges, or other transparent decorations. See Known quirks.
Exit codes & --json envelope
Every command exits 0 on success and a non-zero code on a known error class:
0— ok2— usage error (bad / missing flag)3— not found (path, composition, layer, asset)4— validation error5— render error10— internal error
On success, --json emits:
{
"ok": true,
"apiVersion": 1,
"data": { /* command-specific payload */ },
"warnings": [
{ "code": "FONT_FALLBACK", "message": "..." }
]
}On failure:
{
"ok": false,
"apiVersion": 1,
"error": { "code": "NOT_FOUND", "message": "Layer ABC… not found" }
}Parse the envelope, never the human text. Codes are stable across minor versions.
Known quirks
sscc is shipping in phases. These behaviours bite agents and humans equally — if you write a scaffold script, read this list once first.
layer add background --source is silently dropped
The flag is accepted but never written to the JSON; renders fall back to the plate fill color, so every panel looks like a flat background. Workaround: each composition is born with one empty background layer — read its UUID from <bundle>/<platform>.json and attach the wallpaper with sscc layer set --id <bg> --source bg.png.
composition add auto-creates an empty background layer
Treat that as the canonical bg. Calling layer add background on top produces two stacked bg layers per composition.
Negative --frame origins parse as flag boundaries
Use the = form: --frame=-100,700,2264,3019.
Text layers don't interpret HTML entities
<br/> renders as literal characters. Use \n inside double-quoted bash strings; the CLI converts it at parse time.
No --scale flag for image layers
Resize by editing the frame: sscc layer set --id <id> --frame X,Y,W,H.
--rotation on image layers is a Phase 0 stub
Bake the rotation into the source PNG.
export --opaque paints a checkerboard into transparent regions of plain image layers
Drop --opaque for any bundle with plain (non-bezel) image layers that have alpha (stickers, badges, decorations). Bezeled images are unaffected.
GenerateImage may bake the transparency checkerboard as opaque pixels
Some image-generation tools produce RGB PNGs (no alpha) where the “transparent” checkerboard is opaque gray. Verify with magick identify -format "%[channels]". For crisp transparent stickers (rounded rectangles, polygons, short text), build the PNG procedurally with ImageMagick.