Agent skill · Audited from source
spine-animation
skill · GenielabsOpenSource/spine-animation-aiNOASSERTION licenceAudited 20 Oct 2026 · source 3e5e45670d91
Is it safe? With care — CAUTION, grade B (89/100). We read this skill's source at commit 3e5e45670d91 and observed filesystem and network access and no hard-coded secrets. The audit raised 21 findings, 0 critical or high. What it does: Create Spine 2D skeletal animations from pre-existing character assets (separated body-part PNGs, atlas spritesheet, or a full character image). Use this skill whenever the user wants to animate a 2D character, create…
Cite
Cite this page
ModelsAtlas. “spine-animation (GenielabsOpenSource/spine-animation-ai)”. Retrieved 20 Oct 2026. https://modelsatlas.com/skills/genielabsopensource/spine-animation-ai
Trust audit
Audit 0.4.1 · source read 20 Oct 2026
CAUTION means the audit found things worth knowing before you trust this skill. Grade B is shared by 16,667 of 17,602 audited skills.
What the source does
- FilesystemDeclared6 observations
- NetworkDeclared7 observations
- ShellNone observedNo commands run in the source
- DependenciesNot pinnedSome versions float
- SecretsNone foundNo keys in source
Five audit layers
| Layer | What we check | Result | Findings |
|---|---|---|---|
L0 Provenance | Repo owner, licence, archive status, activity | PASS | 5 |
L1 Static source | Secrets, path traversal, supply chain, hidden code | WARN | 16 |
L2 Instructions | Prompt injection, authority framing, hidden directives | PASS | 0 |
L3 Inventory | The files and declarations match the source | PASS | 0 |
L4 Sandbox | Run in isolation and watch behaviour | SKIPPED why | 0 |
Gates applied: no behavioural pass.
Findings (21)
MEDIUMNetwork egressnet.raw_ip · reskin-app/app/backend/server.py:52
allow_origins=["http://localhost:5173", "http://127.0.0.1:5173"],
- Why
- No further detail recorded for this rule.
- Fix
- —
MEDIUMNetwork egressnet.raw_ip · reskin-app/app/frontend/vite.config.ts:10
target: 'http://127.0.0.1:8765',
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWInsecure cryptocrypto.weak_hash · scripts/build_spine_json.py:493
data_hash = hashlib.md5(json.dumps(config, sort_keys=True).encode()).hexdigest()[:20]
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · reskin-app/app/frontend/src/components/canvas/CanvasTools.tsx:2
import { useStore } from '../../state/store';- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · reskin-app/app/frontend/src/components/canvas/CanvasTools.tsx:3
import { api, type Project } from '../../api/client';- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · reskin-app/app/frontend/src/components/canvas/SpineCanvas.tsx:4
import { useStore } from '../../state/store';- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · reskin-app/app/frontend/src/components/canvas/SpineCanvas.tsx:5
import { api, type Project } from '../../api/client';- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · reskin-app/app/frontend/src/components/canvas/SpineCanvas.tsx:6
import { registerCanvas, registerSpine } from '../../canvasSnapshot';- Why
- No further detail recorded for this rule.
- Fix
- —
LOWObfuscation / stealthobf.base64_blob · demo/spine_animation_preview.html:106
const PART_IMAGES = {"head": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAJpUlEQVR4nO2cy25b1xWGP8myLZu6UJIlxZLt2HHjJECboiDRSYsOCo454yv0GTgLOuMz5BU445joIGgnBYkgaAEnaRW7sq1YkiVR- Why
- No further detail recorded for this rule.
- Fix
- —
LOWObfuscation / stealthobf.base64_blob · demo/spine_preview.html:77
"skeleton.json": "data:application/json;base64,ewogICJza2VsZXRvbiI6IHsKICAgICJoYXNoIjogImJkZWYzMGIzMjk5OTAxOGQ2NWRmIiwKICAgICJzcGluZSI6ICI0LjIuMCIsCiAgICAieCI6IC0xNTAsCiAgICAieSI6IDAsCiAgICAid2lkdGgiO
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWObfuscation / stealthobf.base64_blob · demo/spine_preview.html:78
"skeleton.atlas": "data:application/octet-stream;base64,c2tlbGV0b24ucG5nCnNpemU6IDI1NiwyNTYKZm9ybWF0OiBSR0JBODg4OApmaWx0ZXI6IExpbmVhcixMaW5lYXIKcmVwZWF0OiBub25lCnRvcnNvCiAgcm90YXRlOiBmYWxzZQogIHh5OiAy
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWObfuscation / stealthobf.base64_blob · demo/spine_preview.html:79
"skeleton.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAJTklEQVR4nO3dsXHjSBoG0NbVJKAU6J1NhSB7PKYwm4K8rfUmhZ0U6I2tEER7PabAEHTGbUsQRFIEgWY38L9XtVWq1Qhogvi+boAilRIAAAAQwd2l/
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWObfuscation / stealthobf.decode_call · reskin-app/app/backend/ai/sam_provider.py:88
mask_bytes = base64.b64decode(m["mask_b64"])
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWObfuscation / stealthobf.decode_call · reskin-app/app/frontend/src/components/modals/MaskModal.tsx:314
const bin = atob(emb.image_embedding);
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWSupply chainsupply.unpinned · reskin-app/app/backend/requirements.txt
fastapi, uvicorn, pydantic, python-multipart, python-dotenv, Pillow, numpy, opencv-python
- Why
- 12 requirement(s) not pinned with ==
- Fix
- pin exact versions
LOWSupply chainsupply.unpinned · reskin-app/app/frontend/package.json
@esotericsoftware/spine-pixi-v8, ndarray, onnxruntime-web, pixi.js, react, react-dom, zustand, @types/react
- Why
- 12 dependency range(s) float
- Fix
- pin exact versions or ship a lockfile
INFOInventory / provenanceinv.oversize · demo/flow.gif
demo/flow.gif
- Why
- 4049639 bytes not read
- Fix
- —
INFOInventory / provenanceinv.oversize · demo/reskin.gif
demo/reskin.gif
- Why
- 3973897 bytes not read
- Fix
- —
INFOInventory / provenanceinv.oversize · demo/sombrero_demo.gif
demo/sombrero_demo.gif
- Why
- 10957365 bytes not read
- Fix
- —
INFOInventory / provenanceinv.oversize · demo/sombrero_editor.html
demo/sombrero_editor.html
- Why
- 4917173 bytes not read
- Fix
- —
INFOInventory / provenanceinv.oversize · demo/sombrero_idle.html
demo/sombrero_idle.html
- Why
- 4896779 bytes not read
- Fix
- —
Audit 0.4.1 · source sha 3e5e45670d91 · 20 Oct 2026Report an issue or request a re-scan
Provenance
Who published it, and what the verdict is pinned to
- PublisherGenielabsOpenSource GitHub organizationOwner of the repository this skill is read from
- Source folderGenielabsOpenSource/spine-animation-aiThe exact folder we audited
- LicenceNOASSERTIONAs the repository states it
- Commit pinned for this verdict3e5e45670d91A new audit runs when the source changes
- Repository statusNot archivedLast push 54 days ago
- Sandboxed runNot runSkills are read, not executed; layer L4 is skipped
What it tells the agent
Full source on GitHub ↗Its description: Create Spine 2D skeletal animations from pre-existing character assets (separated body-part PNGs, atlas spritesheet, or a full character image). Use this skill whenever the user wants to animate a 2D character, create…
---
name: spine-animation
description: >
Create Spine 2D skeletal animations from pre-existing character assets (separated body-part PNGs,
atlas spritesheet, or a full character image). Use this skill whenever the user wants to animate
a 2D character, create Spine JSON from existing art assets, rig a character with bones, build
walk/idle/run/attack animations, produce an interactive Spine Web Player preview, or generate
Spine-compatible export files (.json + .atlas + .png). Also trigger when the user mentions
"Spine animation", "2D rigging", "skeletal animation", "bone animation", "cutout animation",
"animate this character", "make this walk", "create walk cycle", or uploads separated character
body parts and wants them animated. This skill handles the full pipeline: asset analysis,
skeleton rigging, animation keyframing, Spine JSON export, and interactive HTML5 preview.
---
<!-- ⚠️ AUTO-GENERATED FILE — DO NOT EDIT DIRECTLY
Edit SKILL.template.md instead, then push to trigger rebuild.
Scripts are embedded automatically by build_skill.py via GitHub Actions. -->
# Spine Animation Skill
Turn pre-existing 2D character assets into fully animated, interactive Spine animations.
## Step 0: Set Up Scripts
This skill includes Python scripts that do the heavy lifting. Claude MUST write them to disk
before use. Each script is embedded below — Claude should save them to `/home/claude/spine-scripts/`
at the start of every session.
```bash
mkdir -p /home/claude/spine-scripts
pip install opencv-python Pillow numpy google-generativeai --break-system-packages -q
```
### Embedded Scripts
The following scripts are auto-injected from the repository's `scripts/` directory.
**Claude: read these carefully, then write each one to `/home/claude/spine-scripts/`**
before running the pipeline.
<!-- EMBED:scripts/split_character.py -->
<details>
<summary>📄 <code>scripts/split_character.py</code> (231 lines)</summary>
```python
#!/usr/bin/env python3
"""
split_character.py — Generate a sprite-sheet atlas from a full character image
using Google Gemini image generation, then segment individual body parts via
OpenCV connected-components analysis.
Usage:
python split_character.py <input_image> [--output-dir output_parts]
[--atlas-out atlas.png] [--min-area 500] [--padding 12]
[--bg-threshold 240]
Requires:
pip install google-generativeai opencv-python Pillow numpy
Environment variable GEMINI_API_KEY must be set.
"""
import argparse
import os
import sys
import cv2
import numpy as np
from PIL import Image
def get_gemini_client():
"""Initialise the Gemini generative-AI client, or exit with a helpful
error if the API key is missing."""
api_key = os.environ.get("GEMINI_API_KEY")
if not api_key:
print(
"ERROR: GEMINI_API_KEY environment variable is not set.\n"
"Get a free API key at: https://aistudio.google.com/app/apikey\n"
"Then run:\n"
" export GEMINI_API_KEY=your_key_here",
file=sys.stderr,
)
sys.exit(1)
from google import genai
client = genai.Client(api_key=api_key)
return client
POSITIVE_PROMPT = (
"A complete 2D game sprite sheet texture atlas for Spine animation of the "
"exact character in the reference image. The character is completely "
"deconstructed into separated, isolated body parts. Separated individual "
"parts laid out flatly: isolated head, isolated torso, isolated upper arms, "
"lower arms, hands, upper legs, lower legs, and feet. Spread out with clear "
"space between every single body part. No overlapping parts. Clean solid "
"white background. CRITICAL: Maintain the exact same art style, exact same "
"shading, exact face, and exact color palette as the reference image. "
"Identical style match, 2D game asset, flat layout, character design sheet."
)
NEGATIVE_PROMPT = (
"3D, realistic, altered style, different art style, different face, "
"redesign, overlapping parts, connected limbs, full body standing, dynamic "
"pose, background scenery, shadows, gradients on background, messy layout, "
"missing limbs, merged layers, text, watermarks."
)
def generate_atlas(client, input_image_path: str, atlas_out: str) -> str:
"""Send the reference image to Gemini and save the generated atlas PNG."""
from google.genai import types
ref_image = Image.open(input_image_path)
response = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=[
POSITIVE_PROMPT,
f"Negative prompt: {NEGATIVE_PROMPT}",
ref_image,
],
config=types.GenerateContentConfig(
response_modalities=["IMAGE", "TEXT"],
),
)
# Extract the generated image from the response parts
for part in response.candidates[0].content.parts:
if part.inline_data is not None:
image_data = part.inline_data.data
with open(atlas_out, "wb") as f:
f.write(image_data)
return atlas_out
print("ERROR: Gemini did not return an image in its response.", file=sys.stderr)
sys.exit(1)
def segment_parts(
atlas_path: str,
output_dir: str,
min_area: int = 500,
padding: int = 12,
bg_threshold: int = 240,
) -> list[str]:
"""Detect individual parts in the atlas using connected-components analysis.
Returns a list of saved part file paths.
"""
img = cv2.imread(atlas_path, cv2.IMREAD_UNCHANGED)
if img is None:
print(f"ERROR: Could not read atlas image: {atlas_path}", file=sys.stderr)
sys.exit(1)
# Convert to RGBA if needed
if img.shape[2] == 3:
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
# Build a foreground mask: pixels whose RGB channels are all below the
# background threshold are considered foreground.
bgr = img[:, :, :3]
gray = cv2.cvtColor(bgr, cv2.CExcerpt, first 6,001 characters of SKILL.md, verbatim from the audited commit. It is text from someone else’s repository, quoted so you can judge it before your agent reads it.
Install
Pinned to the audited commit 3e5e456
git clone https://github.com/your-username/spine-animation-ai pip install opencv-python Pillow numpy git clone https://github.com/GenielabsOpenSource/spine-animation-ai.git /mnt/skills/user/spine-animation pip install opencv-python Pillow numpy google-generativeai --break-system-packages -q pip install google-generativeai opencv-python Pillow numpy
git clone https://github.com/GenielabsOpenSource/spine-animation-ai git -C spine-animation-ai checkout 3e5e45670d91
Commands as the repository documents them: shown, never run by us. Our verdict covers commit 3e5e45670d91 only.
Works in which agents?
What its own text says, not a test
| Agent | Status | More |
|---|---|---|
| Cursor | Mentioned in its text, not tested | Skills for Cursor · About Cursor |
| OpenClaw | Mentioned in its text, not tested | Skills for OpenClaw · About OpenClaw |
Audit history
Every audit, every source change
- !CAUTION B 89 / 100
first audit · source
3e5e45670d91
README badge
For maintainers · shows the latest audit
[](https://modelsatlas.com/skills/genielabsopensource/spine-animation-ai/)
The badge shows our verdict and grade for this skill, and links back to this page. It changes when the audit does.
Similar skills
rohitg00/ai-engineering-from-scratch
One-time onboarding for the AI Engineering from Scratch curriculum (523 lessons, 20 phases). Interviews the learner, runs the placement quiz, and writes LEARNING.md, a persistent study plan the learn skill drives.…
rohitg00/ai-engineering-from-scratch
Interactive quiz that maps your AI/ML knowledge to a starting point in the 523-lesson, 20-phase AI Engineering from Scratch curriculum. Trigger phrases: "where should I start", "find my level", "what do I know", "which…
rohitg00/ai-engineering-from-scratch
Phase quiz for AI Engineering from Scratch. Trigger with "quiz me", "test phase", "check my understanding", "do I know phase 3", or `/check-understanding <phase>`.
alirezarezvani/claude-skills
Default entry point for any research request — a hybrid router that classifies the question deterministically and either delegates to a specialist research skill (pulse for trends/sentiment, grants for NIH funding,…
alirezarezvani/claude-skills
/cs:soc2-audit-prep <scope> — SOC 2 Type II readiness 6-question forcing interrogation. Observation-period focused. Use before Type II observation begins, mid-period checkpoint, or pre-field-test month-10 readiness.
alirezarezvani/claude-skills
/cs:fda-qsr-audit-prep <scope> — FDA 21 CFR 820 (QSR / QMSR) audit 6-question forcing interrogation. Post-Feb 2026 substantially harmonized with ISO 13485. Use before annual internal QSR audit, pre-FDA-inspection…
Add this badge to your README
[](https://modelsatlas.com/skills/genielabsopensource/spine-animation-ai/)
<a href="https://modelsatlas.com/skills/genielabsopensource/spine-animation-ai/"><img src="https://modelsatlas.com/skills/genielabsopensource/spine-animation-ai/badge.svg" alt="ModelsAtlas: CAUTION B"></a>
Questions about spine-animation
What does the spine-animation skill do?
Is spine-animation safe to install?
What can spine-animation access on my machine?
Which assistants does spine-animation work with?
How current is this page?
Sources
- github.com/GenielabsOpenSource/spine-animation-ai — the audited source at commit 3e5e45670d91 and every finding aboveObserved · 20 Oct 2026
Spotted something wrong? Report a correction · Methodology
Keep going in your AI
Opens with this page as the source. We add nothing else to the prompt.
- What does the spine-animation skill do?
- Is spine-animation safe to install?
- What can spine-animation access on my machine?