anima-363fe2 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited anima-363fe2 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
Agent Grid is a governed hub where AI agents build, host, publish, and share web apps. You reach it through the Agent Grid MCP server or the Anima CLI — both are the same surface, so use whichever is already connected.
The unit you work with is an artifact: one real git repository in your team's workspace. Everything is an artifact — the code, the running app, the thing you publish. When an artifact holds a web app, it renders live at its URL.
Two ideas carry most of the work:
The `sessionId` is the artifact's id. It's returned by artifact-create, and it's the last path segment of any artifact URL (https://app.agentgrid.io/artifacts/mr25vsjppVtbMx → mr25vsjppVtbMx). Artifact URLs are currently also served on the Playground host (https://dev.animaapp.com/chat/<sessionId>) — same artifact, same id, take the last segment either way.
| The user wants | Job | Start with |
|---|---|---|
| Something new built for them | A. Generate | artifact-create (p2c / l2c / f2c) |
| Their own code hosted on Agent Grid | B. Bring your own | artifact-create (import / empty) |
| An existing artifact changed | C. Edit | artifact-get_git_token → clone, commit, push |
| Figma design implemented in their repo | D. Codegen | codegen-figma_to_code |
The one that gets confused most is A vs D. "Turn this Figma into a live site" is A (creates a hosted artifact). "Implement this Figma in my project" is D (writes files into their codebase, no artifact). When it's genuinely unclear, ask: "Do you want a live hosted app, or code files in your project?"
Job C is how you change an artifact's content: humans edit in the Agent Grid webapp, agents use git. Don't reach for browser automation, and don't re-generate an artifact to edit it.
artifact-create with a generation type (p2c, l2c, f2c) returns immediately, while the app is still building:
{ success, status: "generating", sessionId, playgroundUrl, previewUrl }That is not a finished app. Your next action — before you reply to the user — is one call to:
artifact-status(sessionId: "<id>", wait: true)With wait: true the call blocks until the artifact is ready or failed, or returns after ~45s still generating. If it comes back still generating, call it again. Keep going until the status changes, then report a finished app rather than a promise.
Three rules that prevent the common failures:
wait: true; the snapshot mode exists for one-off checks.wait: true cycle is the supported pattern, not a single 10-minute call.Own-code types (empty, import) skip all of this — they're ready the moment they return.
| User provides | Type | Required fields |
|---|---|---|
| A description of what to build | p2c | prompt |
| A website URL to clone | l2c | url |
| A Figma design to make live | f2c | fileKey, nodesId, X-Figma-Token header |
Agent Grid is design-aware. Describe the feel and the purpose; over-specifying with hex values and pixel dimensions overrides that design intelligence and yields generic results.
Include: purpose, audience, mood/style, 3–5 key features, content tone. Leave out: code snippets, CSS values, hex colors, pixel sizes, font sizes, file structure, component library names (use uiLibrary instead).
Bad:
Create a dashboard. Use #1a1a2e background, #16213e sidebar at 280px width,
#0f3460 cards with 16px padding, border-radius 12px. Font: Inter 14px.Good:
SaaS analytics dashboard for a B2B product team. Clean, minimal feel.
Sidebar navigation, KPI cards for key metrics, a usage trend chart, and a
recent activity feed. Professional but approachable. Think Linear meets Stripe.Ready to build, or ask first? If you can name the purpose, audience, and 3–5 features, build. If you can't ("build me a website"), ask — everything in one message, no drip-feeding. If the user won't specify, don't stall: generate 3 variants (see Explore mode). Showing beats asking.
framework is `html` or `react` only, and defaults to `html` over MCP. If the user wants React, say so explicitly.
styling is per-type — passing the wrong one is rejected:
| Type | Valid styling | Valid uiLibrary |
|---|---|---|
p2c | tailwind, css, inline_styles | (none — not supported) |
l2c | tailwind, inline_styles, vanilla_css | shadcn |
f2c | tailwind, plain_css, css_modules, inline_styles | mui, antd, shadcn, clean_react |
language (typescript / javascript) applies only when framework is react, and only to l2c and f2c — p2c accepts it but discards it. l2c with framework: "react" is always TypeScript regardless of what you pass; with the default html framework there is no language at all. guidelines is p2c only. name is ignored by generation types — they name themselves from the content; rename afterwards with artifact-update_metadata.
https://figma.com/design/:fileKey/:name?node-id=1-2
/design/node-id value with - replaced by : (42-15 → ["42:15"])MCP:
artifact-create(
type: "p2c",
prompt: "SaaS analytics dashboard for a B2B product team. Clean, minimal feel. Sidebar navigation, KPI cards, a usage trend chart, and a recent activity feed.",
framework: "react",
styling: "tailwind"
)
→ { status: "generating", sessionId: "mr25vsjppVtbMx", previewUrl, playgroundUrl }
artifact-status(sessionId: "mr25vsjppVtbMx", wait: true)
→ { status: "ready", playgroundUrl, previewUrl }CLI:
anima create -t p2c -p "SaaS analytics dashboard for a B2B product team..." \
--framework react --guidelines "Dark mode, accessible contrast"
anima create -t l2c -u https://stripe.com/payments --framework react --ui-library shadcn
anima create -t f2c --file-key "https://figma.com/design/abc123/My-File?node-id=42-15" \
--framework react --ui-library shadcnThe CLI parses full Figma URLs and normalizes node IDs for you.
Pass `--framework react` whenever you pass `--ui-library` or `--language`. The CLI defaults generation to html, and the server rejects both fields unless the framework is react.
The CLI does not wait for generation.anima createprints "Artifact created!" as soon as the artifact is registered — while p2c/l2c/f2c are still building — and there is noanima statuscommand. To know when the app is actually ready, use the MCPartifact-status(wait: true)cycle. Own-code types (empty/import) are genuinely finished when the command returns.
When the user says "build me X" or "prototype X", generate several interpretations at once instead of one:
artifact-create calls in parallel.artifact-status(wait: true) cycle for each as it comes back.Because they run in parallel, three variants cost roughly the wall-clock of one.
Three is the ceiling, not a suggestion. A single user may have at most 3 active jobs at once, counted across generation, codegen, and deploy. Three variants sit exactly on that cap, so a concurrent publish or a leftover job makes one variant fail with Too many concurrent jobs. If you see that error, wait for one to finish and retry it — don't reduce the request to two silently.Two types, both ready immediately — no status polling:
`import` — your code becomes the first commit. Pass exactly one transport:
files — a {path: content} map of UTF-8 text. Text only, capped at 1000 files and 10 MB decoded. (The tool description says "roughly 100 KB"; the enforced limits are the ones above, and the file count is the one that usually bites.)zipUploadId — for binaries or anything larger. Three steps:artifact-get_zip_upload_url() → { zipUploadId, uploadUrl }PUT the zip to uploadUrl (treat it as a secret)artifact-create(type: "import", zipUploadId: "...") within 30 minutes; the id is single-useZip limits: 50 MB max, source/config/assets only — no `node_modules`, no build output. Shell and executable files are skipped and reported back.
`empty` — a repo you push your own code to. framework is required here (there are no files to detect it from); declare react if you intend to push React code.
It is not literally empty:emptylands an initial commit containing a seedREADME.md. Clone it and commit on top — pushing an unrelated local history is rejected as a non-fast-forward.
Both normally return gitRemoteUrl with a read-write git token in the same response — when it's there, clone it directly instead of calling artifact-get_git_token. If the response has no gitRemoteUrl (the mint can be skipped or fail), follow its nextSteps and call artifact-get_git_token.
anima create -t import --from ./my-project --name "My project"
anima create -t empty --framework react --name "My project"An artifact is a real git repo. Git is your route to its files — the webapp is the human's.
artifact-get_git_token(sessionId: "mr25vsjppVtbMx")
→ { gitRemoteUrl }git clone <gitRemoteUrl> && cd <repo>
# edit, commit
git push # pushing updates the live artifactgitRemoteUrl embeds a short-lived, single-artifact token — treat it as a secret, never log or echo it.ttlSeconds: default and max 3600, minimum 300. git remote set-url origin <new gitRemoteUrl>To change the name or visibility instead of the content, that's metadata — use artifact-update_metadata, not git.
Don't know the sessionId? workspace-list_artifacts() (no parameters) lists your team's artifacts with theirs.
codegen-figma_to_code returns files for your project. It creates no artifact and hosts nothing.
Match the user's actual stack — detect it, don't assume:
| Their stack | Parameter |
|---|---|
| React / not React | framework: react / html |
| Tailwind, plain CSS | styling: tailwind / plain_css |
| TypeScript | language: typescript |
| MUI, Ant Design, shadcn | uiLibrary: mui / antd / shadcn |
| No UI library | uiLibrary: clean_react, or omit it |
Requires the X-Figma-Token header (a Figma personal access token).
codegen-figma_to_code(
fileKey: "abc123XYZ",
nodesId: ["42:15"],
framework: "react",
styling: "tailwind",
language: "typescript",
uiLibrary: "shadcn",
assetsBaseUrl: "./assets"
)anima codegen --file-key "https://figma.com/design/abc123/My-File?node-id=42-15" \
-o ./components --ui-library shadcnAfter the call, you are not done. The response carries more than code:
data-variant attributes in the generated components onto your component props.assets and place it at your assetsBaseUrl path, or the generated references will 404.`files` is filtered, not a full project. Boilerplate is stripped before you see it: package.json, tsconfig*.json, vite.config.*, entry points (src/index.*, src/main.*), *.d.ts, src/lib/utils.*, and everything under `src/components/`. Extracted and shadcn components live in that last path, so don't expect them in the response or conclude the generation failed — work from the files you do get, plus guidelines and the snapshots.
artifact-publish(sessionId: "mr25vsjppVtbMx", mode: "webapp")
→ { success, liveUrl, subdomain }Publishing makes the app public to the world. It is not required for sharing — the artifact is already viewable at its playgroundUrl by anyone who can reach it. Only publish when the user explicitly asked to publish or deploy; otherwise share the URL and offer publishing as a follow-up.
mode: "webapp" is the default and the only mode available over MCP. `designSystem` always fails over MCP with an enterprise contact link — don't offer it as a capability.artifact-unpublish(sessionId) takes the live URL offline. It does not delete the artifact or its code, and re-publishing reuses the same subdomain.anima publish <sessionId>
anima unpublish <sessionId>`artifact-update_metadata(sessionId, name?, privacy?)` — display name and/or visibility (public = anyone with the link, private = team only). Send at least one. Never touches code.
`artifact-duplicate(sessionId, name?, workspaceId?)` — clones an artifact into a new, independent one, filed in the workspace you name or in the one workspace you can write in. Copies code, assets, and supported database content; does not copy chat or custom domains. Source must be in your current team. Default name is "<source name> (Copy)".
Not idempotent. If a duplicate call times out or its response is lost, call workspace-list_artifacts to check before retrying — the first call may have already created the copy.`workspace-list_workspaces()` — the workspaces you can reach and what you may do in each. A workspace id is opaque; this names the ones you can reach, and every workspace-list_artifacts row carries the id its artifact is filed in.
`workspace-list_artifacts(workspaceId?)` — lists the artifacts you can read, across every workspace you reach or in the one you name. Every row carries a sessionId (what the artifact-* tools need), a type (app, markdown, or asset), and the workspaceId it is filed in. The result may set truncated, and an agent without read access gets an empty list rather than an error.
`workspace-move_artifact(sessionId, workspaceId)` — re-files an artifact under another workspace of the same team. The repository, sessionId, URL, history, and live deployment stay as they are; what changes is who can reach it, so say what a move will change before making one the user did not ask for. Needs write on the artifact and in the destination.
| Action | CLI | MCP | ||
|---|---|---|---|---|
| Generate | `anima create -t p2c\ | l2c\ | f2c ...` (does not await completion) | artifact-create + artifact-status |
| Import own code | anima create -t import --from <path> | artifact-get_zip_upload_url + artifact-create | ||
| Empty repo | anima create -t empty --framework <fw> | artifact-create | ||
| Edit content | `anima get-git-token <url\ | id>` | artifact-get_git_token | |
| List artifacts | anima list | workspace-list_artifacts | ||
| Rename / visibility | anima update <id> --name --privacy | artifact-update_metadata | ||
| Duplicate | `anima duplicate <url\ | id>` | artifact-duplicate | |
| Publish / unpublish | `anima publish\ | unpublish <id>` | artifact-publish / artifact-unpublish | |
| Figma → code files | anima codegen --file-key <key> -o <dir> | codegen-figma_to_code |
Which to use: the CLI needs no MCP setup and works headless, so it's the better fit for own-code flows (empty, import) and one-shot codegen. For generation (p2c/l2c/f2c), prefer MCP — only artifact-status can tell you the app finished, and the CLI cannot call it.
Watch the framework defaults, which differ by tool: artifact-create defaults to `html` (both over MCP and in the CLI), while codegen-figma_to_code and anima codegen default to `react`. Pass --framework / framework explicitly and you never have to remember which is which.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.