image-compose — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited image-compose (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 4 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 4 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Standard tier:
node "$PAI_REPO_ROOT/server/cli/generate_image.js" --prompt "..." [--aspect-ratio 16:9] [--image-size 2K] [--label "..."] [--subtype <character|location|edit|reference|split|storyboard>] [--name "..."] [--role "..."] [--description "..."] [--source-node-id <id>] [--ref-source-id <id> ...]Pro tier for storyboard mosaics and video-bound character sheets:
node "$PAI_REPO_ROOT/server/cli/generate_image_pro.js" --prompt "..." --size 2560x1440 [--label "..."] [--subtype <character|location|edit|reference|split|storyboard>] [--name "..."] [--role "..."] [--description "..."] [--source-node-id <id>] [--ref-source-id <id> ...]Pro accepts --size only; no --aspect-ratio / --image-size. Common sizes: 1024x1024, 1280x720, 720x1280, 1920x1920, 2560x1440, 1440x2560, 3840x2160, 2160x3840.
--label defaults to the truncated prompt (≤30 chars) if omitted; pass an explicit one when you have a better caption.
Use @Image1, @Image2, … in --ref-source-id order. The CLI emits one derived edge per ref.
Mirror external URLs first with mirror_url.js --url <URL>, then pass the returned node_id via --ref-source-id.
If a note authored the image, pass --source-node-id <note_id>.
Do not attempt to invent images via ASCII art or markdown embedding — call the CLI.
For the ask-once flow and per-mode prices, see the project PROJECT_AGENT.md § "First-use generation choices".
Mode mapping: Standard 2K -> generate_image.js --image-size 2K; Pro 2K -> pro exact 2K; Max quality -> pro exact 4K.
Pick the one that fits. For source lookup, follow the project PROJECT_AGENT.md § "Choosing context"; this skill only owns image-specific prompt and CLI shape.
Character pre-flight. First ask: will this character appear in downstream video (video, clip, promo, 宣传片, 短片, 连续剧, film, scene, 拍片, shot, short film)?
workflow.json for uploaded refs (subtype:"reference", metadata.source:"user_upload", not archived).This pre-flight is non-negotiable. Pattern 1's single front portrait gives the video model an anchor that's too narrow; identity drifts shot-to-shot. Skipping straight to Pattern 1 for video work is the single most-common mistake.
Story/script anchor defaults. When script-compose or story-to-video-workflow routes a breakdown here:
Triggers: character portrait/headshot/hero/villain/lead only for one-off static stills. Video-bound -> Pattern 7.
node "$PAI_REPO_ROOT/server/cli/generate_image.js" --prompt "..." --aspect-ratio 9:16 --image-size 2K --subtype character --name "Detective Morris" --role "..." --description "..." — no refs. A character is an identity anchor, not a derivative.[style] character portrait of [NAME], [role]. [age, build, wardrobe, distinguishing features]. Front-facing medium close-up, eye-level, looking directly at camera, neutral expression. Plain neutral background, soft even lighting. No dramatic shadows, no stylized lighting, no side profile, no multiple views.--ref-source-id.Triggers: establish/design/picture a location, or approval of a script-compose location offer.
node "$PAI_REPO_ROOT/server/cli/generate_image.js" --prompt "..." --aspect-ratio 16:9 --image-size 2K --subtype location --name "Causeway" --description "..." [--source-node-id <script_or_shot_note_id>] — no refs. A location is a setting anchor, not a derivative.[style] establishing still of [LOCATION NAME]. [visual brief — architecture, lighting, atmosphere]. Wide shot, eye-level, no characters present.--source-node-id so the authorship edge lands.Triggers: change/edit/swap/replace/add/remove/tweak/what-if/variation on an existing image.
image_result, or one the user named). Grab source.id and source.metadata.aspect_ratio.node "$PAI_REPO_ROOT/server/cli/generate_image.js" --prompt "..." --aspect-ratio <source ratio> --image-size <source size or 2K> --subtype edit --source-node-id <source.id> --ref-source-id <source.id>.<concrete change>. Preserve everything else.✅ "Change the rain to falling snow. Keep the detective, wardrobe, and camera framing unchanged." ✅ "Render as a full 3D turnaround sheet of the same character. Preserve face, wardrobe, and proportions." ❌ "A detective in a snowy alley at night wearing a trench coat…" — over-specifies, identity drifts.
<source.id> based on --ref-source-id.Triggers: put character in setting / shot of X and Y / character action in location.
image_result of that person (up to 16). Collect each one's id.node "$PAI_REPO_ROOT/server/cli/generate_image.js" --prompt "..." --aspect-ratio <fit the shot> --image-size 2K --ref-source-id <char1.id> --ref-source-id <char2.id> ....@Image1, @Image2, … in --ref-source-id order.--ref-source-id.Triggers: a fresh image unrelated to existing canvas content ("generate a mountain at dusk", "a noir alley — just the setting").
node "$PAI_REPO_ROOT/server/cli/generate_image.js" --prompt "..." with sensible defaults (16:9, 2K unless the user asks otherwise). No subtype, no refs.Triggers: storyboard, mosaic, grid, shot list, coverage, keyframe sheet, shot planning, image previs. Output is ONE composite per clip/<=15s shot note, not one image per panel.
generate_image_pro.js --size 2560x1440 --subtype storyboard --label "Storyboard — Shot <N>" --source-node-id <shot_note_id> per mosaic.2560x1440; grid shape is cell layout, not canvas shape. Override only for explicit portrait/square/vertical/ratio:2560x1440 (default)1920x19201440x25601440x2560For the canvas pre-flight, per-shot-note iteration logic, missing-anchor nudge, verbatim prompt template, and default panel coverage when no script slice exists: see references/storyboard-mosaic.md.
#### Node fields the CLI sets
image_result node PER mosaic.data.subtype = "storyboard" by passing --subtype storyboard.Use proactively for any character that will appear in downstream video, regardless of actor refs.
Mode A — ≥3 uploaded actor refs. Pass photos as --ref-source-id; add --source-node-id <note_id> if a script/shot authored the design.
Mode B — 0-2 refs / from scratch. Omit actor refs; describe age/build/wardrobe/distinguishing features explicitly. Add --source-node-id <note_id> when authored by a note.
Also fires on explicit asks: "design a character sheet / turnaround / reference sheet / character design for [character]", "make a 4-panel character design", "generate a production reference sheet for downstream video work".
Output: one Front-full / Profile-full / Back-full / Closeup-bust sheet, passed directly to video as --ref-source-id.
subtype:"reference", ideally ≥3 photos). Confirm ref count in one line.node "$PAI_REPO_ROOT/server/cli/generate_image_pro.js" --prompt "..." --size 2560x1440 --subtype character --name "<character_name>" --role "..." --ref-source-id <ref1> --ref-source-id <ref2> --ref-source-id <ref3> [--source-node-id <script_or_shot_note_id>] — pro tier is the default for character sheets because panel layout, text suppression, and identity consistency are load-bearing. Do not pass --aspect-ratio or --image-size. Never fire Mode A with fewer than 3 refs (model overfits to the one angle it has).references/character-sheet.md: same pro command, but omit every actor-photo --ref-source-id; include --source-node-id only when a script or shot note authored the design.--ref-source-id <sheet_id> for downstream shots; no normal cropping needed.For the verbatim 4-panel prompt template, optional per-angle crops, and gotchas (no-text rule, photo-priority, exact panel counts): see references/character-sheet.md.
#### Node fields the CLI sets
image_result node with data.subtype = "character".data.name, data.role, data.description from the CLI flags.derived edge per --ref-source-id (so the sheet is provenance-linked to each actor photo it triangulated from).For draft-stage JSON, one sentence with the price/status — see the project PROJECT_AGENT.md § "Draft gate". For terminal results, follow the project manual's next-step recommendation rule.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.