Motion Sticker Pack|动态表情包制作器

SkillSearch

Create an animated sticker pack from a supplied character image or a text-defined character by collecting a style and Emoji or short reaction descriptions, generating and approving a static sheet, then routing video generation, cleanup, splitting, and packaging. Also process existing static sheets or grid videos. Use for animated emoji or sticker-pack production, not for designing a separate character identity artifact or general video editing.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Motion Sticker Pack|动态表情包制作器 skill

What this skill tells your AI

The instructions your AI receives, as published by kobingogo/motion-sticker-pack in SKILL.md and read by ahel’s review.

Create a usable animated sticker pack, not merely a video preview. Preserve the supplied character identity and produce independently looping stickers, transparent first frames, a machine-readable report, and a ZIP.

IP identity and prompt principles

  • Before writing a generation prompt, inspect the supplied image and derive the IP's visible identity features: face, hair or fur, silhouette and proportions, colors, clothing, accessories, existing props, pose language, scene cues, and overall mood.
  • Build the prompt from those observed features plus the user's selected style and reactions. Preserve the supplied IP's appearance and source-specific details by default; change them only when the user asks for a change.
  • Unless the user requests another presentation, use the default static-sheet treatment: a 3×3 illustrated reaction-card grid with no white border or heavy outline, subtle local background accents in each cell, and a consistent overall color tone. This changes the visual treatment, not the transparent-alpha and cell-isolation requirements.
  • Interpret each Emoji or text reaction semantically. Offer a compact choice for short reaction text: default to avoiding text, while allowing the user to opt in. This is a preference, not a rejection gate—if the model adds text despite the default, keep the sheet eligible for review and let the user decide whether to keep it. When it helps the expression read clearly, add a small number of matching decorative accents—such as hearts, music notes, sparkles, tears, blush marks, sweat drops, motion lines, or stars—using the selected style's visual language. Use them selectively rather than forcing the same accents into every cell, and do not turn them into unrelated large props.
  • Do not add unsolicited moral, modesty, sexualization, age, wardrobe, pose-cleanup, or scene-removal instructions. In particular, do not insert wording such as “改成得体、日常、非性感化的简化服装” or “不要保留汽车、夜景、原照片背景或暧昧姿势” unless the user explicitly requests that transformation.
  • Keep the source reference label neutral (for example, 所附图像 or 附件中的角色参考图). Do not encode an unrequested redesign into reference_label.
  • A transparent sticker sheet may require removing the source background as a technical canvas operation, but do not otherwise remove existing clothing, props, setting cues, or pose characteristics unless requested. If the user wants the original scene retained, preserve it within each cell where technically feasible.

Pre-generation fidelity check

Before writing a prompt or an intake/confirmation message, explicitly check that no unrequested transformation has been introduced. Remove any wording or instruction that asks to make the character more “得体、日常、非露骨、非性感化”, to simplify or replace clothing, clean up the pose, remove scene cues, or make the result “适合公开分享”. These are not defaults. Preserve the supplied character's observed appearance, clothing, pose language, props, setting cues, and mood unless the user requests a change or a higher-priority platform safety rule requires one. If a safety-driven change is required, state only the necessary constraint and do not broaden it into an aesthetic redesign.

Ambiguous-request confirmation

  • When the user supplies a character image but does not specify a style, reactions, or both, do not generate immediately. First present a concise confirmation card with the proposed defaults: 3D 卡通风, the illustrated reaction-card treatment, a practical set of nine chat reactions (开心、喜欢、委屈、惊讶、亲亲、谢谢、加油、困困、点赞), and the default 3×3 layout.
  • When no character image is supplied, accept a named or text-defined character and use the same intake defaults when style or reactions are missing. After confirmation, generate the complete static sheet directly. Do not insert a separate single-character concept image, identity card, or character-approval stage.
  • State that the prompt will be derived from the image's observed IP features and the selected style, with the character's appearance and source details preserved by default. Do not add redesign or moralizing constraints.
  • Accept either an explicit confirmation (确认 / 开始生成) or a revision such as 风格改为写实还原 or 表情改为 🎸😍🥹😘🥰. After a revision, show the updated summary and wait for confirmation again. Once confirmed, generate the static sheet directly, then follow the normal layout inspection and static-review gate before any video generation.
  • If the user already supplied both a clear style and reactions, skip this intake confirmation and proceed to static generation. The post-generation static-review approval before video remains mandatory.

Non-negotiable invariants

  • Treat the image model's requested grid as a preference, not observed fact. After image generation, inspect the returned sheet and write detected_layout; every later stage must use that result.
  • Compile every static request with image_generation_request.arguments.background and image_generation_request.arguments.output_format. Select the background policy by input mode: reference-image generation uses an opaque, uniform #00FF00 source first because the current Codex image_gen runtime does not reliably return native Alpha with a reference image; text-defined generation uses transparent-first because it can emit native Alpha. Pass the resolved fields when the callable image_gen schema exposes them; when it does not, omit only unsupported fields and record them in static-generation.json. In both modes, inspect returned pixels, reject checkerboards and non-uniform backgrounds, and locally convert only an accepted native Alpha or uniform key to the final real Alpha sheet. Do not override the reference-image policy by merely adding a transparent prompt.
  • Express layout unambiguously as columns × rows. Derive count = columns * rows; never mix 3×3 with 12 items or 4×3 with 9 items.
  • If automatic layout confidence is below 0.75, inspect the overlay/report and confirm or override the grid before animation or cropping.
  • When this Skill generated the static illustrated-card sheet, never generate video until the user explicitly approves that exact sheet. Regeneration invalidates the old approval and all downstream artifacts.
  • Persist the review revision with scripts/manage_job_state.py. Hash verification is mandatory before bundled Provider execution; a conversational “approved” flag alone is insufficient.
  • Keep the camera fixed. Each cell moves only inside its own bounds. Do not invent characters, new captions, large props, scenery, or cross-cell effects. Preserve any text or symbols already present in the approved source, including when they were model-generated. Small semantic reaction accents are allowed when they support the requested emotion and remain inside the cell. Preserve source elements when they already exist in the approved source unless the user asks to remove them or transparent-sheet/cell-isolation requirements make that technically necessary.
  • Do not trust a video model or adapter's claimed transparency. Decode the returned video with the local Alpha probe. Prefer real alpha when detected; otherwise use a uniform key that contrasts with the character (chroma such as green or magenta, not a near-black or near-white plate) and deterministic local matting.
  • For Grok image-to-video, the output contract is stricter: use #00FF00, never a checkerboard or simulated transparency. The input sent to Grok must already have real alpha (or a verified uniform green plate), and scripts/grok_build_video_adapter.py must pass every native returned frame through background QC. Each execution makes exactly one Grok call (max_retries: 0) and must never fall through to local animation. A user-requested new execution is allowed only after a separate, explicit retry approval bound to the same approved inputs and route; it is never an implicit replay.
  • For Grok image-to-video, compile a compact execution prompt from the approved per-cell tile-plan.json: keep the grid dimensions, identity lock, fixed-camera rule, one action per cell, green-screen contract, and loop timing, while removing repeated prose. Keep the final adapter instruction below 3,800 UTF-8 bytes so Grok's 4,096-byte CLI limit is not reached; reject early with a local validation error if a custom tile plan still exceeds the budget.
  • Never put credentials in prompts, config files, reports, command arguments, or logs. Configuration refers to environment-variable names only.
  • Keep every generated artifact for one character under works/<character-slug>/ in this skill directory. Do not write new job files to the skill root or a shared work/ folder. Resolve the directory with scripts/character_workspace.py --name <角色名> before static generation.
  • Treat assets/sticker-production.default.json as the single editable production-default file. Validate it with scripts/sticker_production_config.py; copy it into each work directory as sticker-production.json so generation and post-processing use the same immutable job snapshot. Do not duplicate duration, size, fps, color-budget, key-color, or GIF-budget defaults in prompts or scripts.
  • Treat each static image-generation attempt as a billable, non-idempotent operation. Before calling the image tool, claim it with scripts/static_generation_guard.py claim; immediately before the call, mark it invoked. After the call, resolve the result before considering any retry. The current image tool may return a top-level image_url and output_hint, a data URL/image bytes, or an image block under content; absence of content alone is never a failure. Copy or materialize the first usable result to static-sheet-source.png, then mark the attempt accept. Only an explicit provider failure with no artifact, or a local normalization/QC rejection recorded with reject, may unlock the bounded fallback attempt. Keep static-generation-attempts.json beside static-generation.json.

Workflow

  1. Inspect the input and choose an entry mode:
    • personal IP handoff → read references/personal-ip-handoff.md, run scripts/import_personal_handoff.py <handoff.json> --work-dir <work_dir>, and use the imported character.json as the job-local identity/style/reaction manifest; never copy the original photo or edit the personal card;
    • character reference → read references/intake-and-approval.md; if the request is vague, present the default proposal and wait for confirmation before generating the static sticker sheet;
    • named or text-defined character without an image → compile that definition and generate the full static sheet directly; do not generate a separate character image first;
    • static sheet → detect the actual grid;
    • grid video → obtain the source sheet/layout or extract a representative frame with ffmpeg -y -i input.mp4 -frames:v 1 representative-frame.png, then detect the grid;
    • separate static stickers → do not invent a grid; run scripts/process_independent_stickers.py <input-dir> <output-dir> --manifest <work_dir>/artifact-manifest.json;
    • user-supplied static sheet → create state with --source-type user-supplied and skip the explicit approve step; it is already the selected source.
  2. Choose a short character name and resolve the work directory with scripts/character_workspace.py --name <角色名>. For a personal handoff, import first and keep the received handoff.json plus character.json in that work directory; use the verified absolute anchor, resolved_style, and resolved_reactions from character.json, and do not route through the generic photo intake. For other entry modes, compile the confirmed style and reactions into <work_dir>/static-prompt.json: use --reference-image <source-image> when supplied, or --character-description <definition> when no image exists. The no-image route goes straight to one complete sheet. Inspect the callable image_gen schema and run scripts/prepare_image_gen_call.py, repeating --supported-argument for its exposed fields. The compiled contract automatically selects opaque-green-first for reference images and transparent-first for text-defined characters; static-generation.json records the source mode, resolved policy, passed/omitted fields, bounded retry, and single-call execution protocol. Create the attempt ledger and claim attempt 1 with scripts/static_generation_guard.py; mark it invoked immediately before the one image call. Resolve the returned object in this order: top-level image_url/output_hint, top-level data URL or bytes, then content image block. Do not call again merely because the host did not render the result. Save the first usable raw result as <work_dir>/static-sheet-source.png and mark it accepted. A reference-image request must use a backend that accepts that exact image; a text-defined request may use text-only generation.
  3. Run scripts/normalize_static_sheet.py <work_dir>/static-sheet-source.png <work_dir>/static-sheet.png --report <work_dir>/static-alpha.json. Native alpha is preserved for text-defined generation when present. Reference-image generation is expected to be opaque: accept only a uniform, high-contrast chroma key (normally #00FF00) suitable for deterministic local matting. Simulated checkerboards/two-tone previews, light plates, gradients, scenery, and ambiguous backgrounds fail closed. If local normalization rejects the accepted raw result, mark attempt 1 reject with the QC reason, then claim and invoke the recorded opaque fallback exactly once; never replay an unresolved attempt. Save the retry result as the new raw source, mark it accepted, and re-run normalization; if it still fails, stop and request regeneration rather than sending the bad sheet to video. Inspect only the normalized <work_dir>/static-sheet.png with scripts/inspect_sticker_sheet.py, then create the hash-bound static-review state.
  4. For a generated or regenerated sheet, show the normalized sheet, detected layout, text_policy, and static-alpha.json warnings. If text appeared, report it as an observation only; do not reject or auto-regenerate for that reason. Offer 确认,继续生成视频 or 重新生成. Stop and wait. Do not route or call video generation while the sheet is unapproved. For a user-supplied sheet, report the detected layout and continue without asking for a duplicate approval.
  5. After explicit approval of a generated sheet, record it with scripts/manage_job_state.py approve; for a user-supplied sheet, use the already static-approved state created with --source-type user-supplied. In both cases use the exact source image. For animation prompt rules, read references/prompt-contract.md and write a tile-plan.json with exactly one vision-informed entry per detected cell. Compile it with scripts/prompt_compiler.py. Do not use generic motions unless explicitly accepting the lower-quality fallback.
  6. For backend discovery and selection, read references/runtime-routing.md. Inspect callable tools/skills in the current runtime first and record their exact names, reference-image support, video support, and cost status in <work_dir>/runtime-tools.json. Then run scripts/prepare_workflow.py --character <角色名> --skill-root /Users/bingo/Documents/ChatGPT/motion-sticker-pack when working from this repository, so video-providers.json, video-task.json, and artifact-manifest.json land in the same works/<slug>/ directory; use --provider <id> and repeated --fallback-provider <id> for task-level selection instead of editing the shared template. Use those same files for probe, route, and execute. Routing creates attempt-ledger.json; review the route preflight before any external execution.
  7. Execute the selected mode:
    • native-video (native-tool in provider configuration): run manage_job_state.py verify first, then use a callable local Agent video tool with the approved image and prompts.json; after the host call returns, register that exact video through scripts/execute_video_route.py --native-video <host-video>, which applies the common QC, result receipt, ledger, and Manifest path;
    • external-video: execute one selected AI SDK or command route with scripts/execute_video_route.py; never execute all attempts automatically and never delete/edit attempt-ledger.json to replay an attempt. A failed/rejected/uncertain attempt needs either explicit selection of the next numbered route or a user-requested, hash-bound retry approval passed with --retry-approval; the latter is a new billable execution. Only a submitted/uncertain xAI attempt with a persisted request ID may use --resume, which continues that same remote request. When Grok is required, set provider: grok-build-local and allow_fallback: false; a failed green-screen QC is a failed Grok job, not permission to use local animation;
    • keypose-local: when image generation is callable but video is not, compile scripts/compile_keypose_plan.py with the approved image/layout/state, validate generated 2×2 pose sheets with scripts/prepare_keyposes.py --plan <keypose-plan>, then assemble the exact four contract poses per sticker with scripts/render_keypose_pack.py --image <approved-sheet> --state <job-state> --plan <keypose-plan> --preparation-report <keypose-preparation>. Read references/keypose-workflow.md for the auditable flow;
    • light-motion-local: run manage_job_state.py verify, then use scripts/light_motion_fallback.py --state <job-state> only as the zero-generation-cost affine fallback. Describe it as light motion, never as synthesized character articulation. Accept transform-local only as a deprecated configuration alias;
    • postprocess-only: process a supplied video without generation. If no layout is supplied, extract a representative frame first with ffmpeg -y -i input.mp4 -frames:v 1 representative-frame.png, then inspect it.
    • prompt-only: when no video or local image-processing capability exists, run scripts/assemble_prompt_only.py, deliver its prompt artifacts, and stop without claiming a generated video.
  8. Split and matte a grid video with scripts/process_emoji_grid.py --layout <layout.json> --settings <work_dir>/sticker-production.json. Probe the actual returned duration, select the matching configured profile, and run native-frame matting, instance assignment, and safety QC before duration sampling. Whole-grid registration is disabled by default because per-frame integer correction can create micro-jitter; use --registration auto only when visual inspection confirms actual camera drift. Request duration comes from generation.provider_duration_seconds; the shipped map is grok-build-local: 6 and xai-direct: 3, with both outputs at 240×240 and 8 fps. A direct API result matching 3 seconds is preserved as-is and is never duration-compressed. For Grok, preserve the complete 6-second result as the root version and also create 3s/ from the initial 24 sampled frames. Record endpoint pose difference for audit, but do not reject or retime the 3-second derivative when the first and last poses differ. Never replace or discard the full Grok result. First run --trial for the configured cell (default 01) and require both Grok variants to pass encoded-frame and 1 MiB GIF-budget checks. If they pass, reuse the same source grid video for the complete pack—never make a second Grok call. Later full-pack GIF overages are warnings rather than pack blockers; encoded-frame failures remain hard failures. Grok grid inputs are repacked from each cell's real Alpha bounding box with at least a 10% two-sided green corridor. Animated WebP stays lossless; GIF gets an adaptive binary-alpha threshold; both are decoded again for hard frame QC before packaging. A seam crossing is not itself a failure. Treat a balanced, inseparable cross-cell component as a bad native-frame run; only a short bounded run (up to 0.2 seconds) may be repaired from temporally adjacent safe frames, with frame numbers recorded in processing.json. Longer or identity-ambiguous merges remain withheld. Only an inseparable merge is withheld, while successful cells and the failure report remain deliverable.
  9. Read references/output-contract.md before delivery. Run scripts/assemble_delivery.py --cleanup-media-dir so media and job-state.json, prompts.json, and route.json are collected into one canonical delivery directory and ZIP, then the intermediate media directory is removed only after packaging succeeds. Composite each GIF onto a light background before showing it. Report any low-confidence layout, alpha damage, interior holes, loop discontinuity, residual hold jitter, provider fallback, or failed cell instead of hiding it.

When processing generated video, pass --manifest <work_dir>/artifact-manifest.json to process_emoji_grid.py so accepted processed outputs extend the job's SHA-256 lineage.

Grid layout safety is a hard default: target each cell's combined foreground bounding box at approximately 70%–75% of the cell, never above 75% in the static prompt contract or video repack, and keep at least a 10% two-sided corridor. The static sheet prompt records this contract; Grok/keypose/local input preparation enforces the 75% maximum even when a source cell is fuller.

For public style evidence, keep gallery/styles/<id>/provenance.json in sync with the media by running scripts/build_gallery_provenance.py --verify-only. Legacy gallery cases are allowed only with an explicit legacy-evidence-partial status and a declared approval/manifest gap.

Routing behavior

Use this fixed order unless the user explicitly selects a provider:

  1. callable native/local image-to-video capability;
  2. configured external providers that satisfy the task, in configured priority order;
  3. key-pose generation plus local assembly;
  4. transform-only local animation when key-pose generation is unavailable;
  5. prompt-and-plan-only output when neither video nor local image processing is possible. Deliver the prompts and route artifacts and stop without claiming a generated video.

Before the first external-provider call, state which provider will receive the image and that the request may incur charges, unless the user already explicitly selected that provider and authorized external generation. Run only attempt 1; a later route attempt requires a failed prior result and another explicit execution step. If the user actively asks to retry after a failed, rejected, or uncertain attempt, pause for a retry approval card naming the provider, explaining that a new request may incur another charge, and asking for an explicit confirmation. After confirmation, create a hash-bound retry approval with scripts/manage_job_state.py approve-video-retry, then pass it as --retry-approval to the executor. A plain request to continue, silence, or an earlier static approval is not retry authorization.

Retry only another configured route or the affected sticker. Do not repeatedly charge the same external provider without a clear transient failure and a bounded attempt count.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
50
Forks
5
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
motion-sticker-pack
Source
github.com/kobingogo/motion-sticker-pack