Motion Sticker Pack|动态表情包制作器
SkillSearchCreate 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.
No other account needed.
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 intoreference_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 default3×3layout. - 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.backgroundandimage_generation_request.arguments.output_format. Select the background policy by input mode: reference-image generation uses an opaque, uniform#00FF00source 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 callableimage_genschema exposes them; when it does not, omit only unsupported fields and record them instatic-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. Derivecount = 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), andscripts/grok_build_video_adapter.pymust 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 sharedwork/folder. Resolve the directory withscripts/character_workspace.py --name <角色名>before static generation. - Treat
assets/sticker-production.default.jsonas the single editable production-default file. Validate it withscripts/sticker_production_config.py; copy it into each work directory assticker-production.jsonso 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 itinvoked. After the call, resolve the result before considering any retry. The current image tool may return a top-levelimage_urlandoutput_hint, a data URL/image bytes, or an image block undercontent; absence ofcontentalone is never a failure. Copy or materialize the first usable result tostatic-sheet-source.png, then mark the attemptaccept. Only an explicit provider failure with no artifact, or a local normalization/QC rejection recorded withreject, may unlock the bounded fallback attempt. Keepstatic-generation-attempts.jsonbesidestatic-generation.json.
Workflow
- 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 importedcharacter.jsonas 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-suppliedand skip the explicit approve step; it is already the selected source.
- personal IP handoff → read references/personal-ip-handoff.md, run
- 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 receivedhandoff.jsonpluscharacter.jsonin that work directory; use the verified absoluteanchor,resolved_style, andresolved_reactionsfromcharacter.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 callableimage_genschema and runscripts/prepare_image_gen_call.py, repeating--supported-argumentfor its exposed fields. The compiled contract automatically selects opaque-green-first for reference images and transparent-first for text-defined characters;static-generation.jsonrecords the source mode, resolved policy, passed/omitted fields, bounded retry, and single-call execution protocol. Create the attempt ledger and claim attempt 1 withscripts/static_generation_guard.py; mark itinvokedimmediately before the one image call. Resolve the returned object in this order: top-levelimage_url/output_hint, top-level data URL or bytes, thencontentimage 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.pngand 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. - 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 1rejectwith 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.pngwithscripts/inspect_sticker_sheet.py, then create the hash-boundstatic-reviewstate. - For a generated or regenerated sheet, show the normalized sheet, detected layout,
text_policy, andstatic-alpha.jsonwarnings. 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. - After explicit approval of a generated sheet, record it with
scripts/manage_job_state.py approve; for a user-supplied sheet, use the alreadystatic-approvedstate 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 atile-plan.jsonwith exactly one vision-informed entry per detected cell. Compile it withscripts/prompt_compiler.py. Do not use generic motions unless explicitly accepting the lower-quality fallback. - 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 runscripts/prepare_workflow.py --character <角色名> --skill-root /Users/bingo/Documents/ChatGPT/motion-sticker-packwhen working from this repository, sovideo-providers.json,video-task.json, andartifact-manifest.jsonland in the sameworks/<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 createsattempt-ledger.json; review the routepreflightbefore any external execution. - Execute the selected mode:
native-video(native-toolin provider configuration): runmanage_job_state.py verifyfirst, then use a callable local Agent video tool with the approved image andprompts.json; after the host call returns, register that exact video throughscripts/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 withscripts/execute_video_route.py; never execute all attempts automatically and never delete/editattempt-ledger.jsonto 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, setprovider: grok-build-localandallow_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, compilescripts/compile_keypose_plan.pywith the approved image/layout/state, validate generated 2×2 pose sheets withscripts/prepare_keyposes.py --plan <keypose-plan>, then assemble the exact four contract poses per sticker withscripts/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: runmanage_job_state.py verify, then usescripts/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. Accepttransform-localonly as a deprecated configuration alias;postprocess-only: process a supplied video without generation. If no layout is supplied, extract a representative frame first withffmpeg -y -i input.mp4 -frames:v 1 representative-frame.png, then inspect it.prompt-only: when no video or local image-processing capability exists, runscripts/assemble_prompt_only.py, deliver its prompt artifacts, and stop without claiming a generated video.
- 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 autoonly when visual inspection confirms actual camera drift. Request duration comes fromgeneration.provider_duration_seconds; the shipped map isgrok-build-local: 6andxai-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 create3s/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--trialfor the configured cell (default01) 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 inprocessing.json. Longer or identity-ambiguous merges remain withheld. Only an inseparable merge is withheld, while successful cells and the failure report remain deliverable. - Read references/output-contract.md before delivery. Run
scripts/assemble_delivery.py --cleanup-media-dirso media andjob-state.json,prompts.json, androute.jsonare 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:
- callable native/local image-to-video capability;
- configured external providers that satisfy the task, in configured priority order;
- key-pose generation plus local assembly;
- transform-only local animation when key-pose generation is unavailable;
- 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