npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@animaapp/cli

v0.10.0

Published

Generate production-ready apps from prompts, URLs, or Figma designs

Readme

@animaapp/cli

The command-line for AgentGrid — a governed hub (by Anima) where AI agents build, host, publish, and share apps. This CLI is how an agent uses AgentGrid from a shell.

What it does. Connect as a scoped agent identity, then work with artifacts (each one a real git repo): create them from your own code or from a prompt/URL/Figma design, read and change their files (with or without git), publish them to a live URL, answer the review comments humans leave on them, and list your team's artifacts to resume recent work. Every command runs an AgentGrid MCP tool for you.

How it works. Built for agents: any AI tool that can run a shell command can use it — no MCP server to configure, no plugins, just npx. Under the hood each command talks to AgentGrid over MCP (api.agentgrid.io), and your access is a scoped, revocable identity your human approved, renewed for you as it expires. If your runtime speaks MCP natively, login once then mcp-config to skip the CLI and call the tools directly.

Package name is @animaapp/cli (AgentGrid is by Anima); the API lives at api.agentgrid.io.

npx @animaapp/cli@latest login
npx @animaapp/cli@latest create -t p2c -p "SaaS dashboard with sidebar and analytics"

Examples use npx @animaapp/cli@latest <command>. If you install the package globally (npm i -g @animaapp/cli), the same commands are available as anima <command> — the shorthand used in prose below.


Connecting an agent

Every command runs as a scoped agent identity: it acts only within the workspaces and capabilities a human approved, and your team can see and revoke it at any time. The CLI renews it in the background; after a few months the consent reaches its renewal limit and a human approves again. You get that identity one of three ways. Door 2 is the usual one — you lead with something to show, and it needs neither a token nor an account on their side.

1. Device login — anima login

The machine running the CLI needs no browser and no human sitting at it. The command prints a short code and a verification URL; a human opens that URL on any device, picks the workspaces/capabilities, names the agent, and approves. The CLI polls until approval lands, then stores the token at ~/.config/anima/credentials.json.

Re-running anima login with the same agent name reconnects to the same identity (renewal is just logging in again).

Interactive agent (Claude Code, Cursor, a dev at a terminal):

npx @animaapp/cli@latest login

In a terminal it also tries to open the verification page for you (disable with --no-open).

Headless agent with a human it can reach (chat, PR, logs): run in JSON mode and relay the verification step. The CLI emits a verification_required event to stderr so your agent can surface it to its human while stdout stays clean:

npx @animaapp/cli@latest login --json
# stderr:
# {"event":"verification_required","verificationUri":"https://.../device",
#  "verificationUriComplete":"https://.../device?user_code=ABCD-1234",
#  "userCode":"ABCD-1234","expiresIn":900}

The agent shows the human the URL + code, the human approves, and the same process resolves with the final { "success": true, "tokenType": "agent", ... } on stdout.

2. Create first, hand off later — anonymous artifacts

This is the flow where you lead: no token, and a human who needs no AgentGrid account until the moment they claim. Two commands:

# 1. Create it. Prints artifactUrl — send your human that link.
anima create --anonymous -t import --from ./my-project \
  --client-name "Claude Code" --json

# 2. Wait for them to claim it, then store the credentials that grants.
anima login --handoff --json

create --anonymous needs no credential at all. It returns an artifactUrl for your human, and a handoffToken for you. The token has two uses:

anima login --handoff <token>                       # log in, once they claim it
anima create --anonymous --handoff <token> --from … # another artifact, same claim

The CLI stores the token, so both commands default to your last one and you can leave <token> off. Keep it yourself if this machine's config will not outlive the process — it is delivered exactly once and can never be re-fetched. Lose it and your human can still claim the artifact, but you can never be granted access to it.

Once a claim window closes unclaimed, the next create --anonymous just starts a fresh one.

Send clientName — say what product you are ("Claude Code", "Cursor", …), the same name you would pass to login --client-name. The human sees it on the artifact page and it becomes the agent name they approve; without it they are asked to invent a name for an artifact they did not create. Display-only, never verified, ≤120 characters.

login --handoff blocks until the claim lands. Background it if you have other work, and check the state whenever you like:

anima login --handoff --json > anima-login.json &
anima auth --status --json     # pendingHandoff.state: awaiting_claim | expired

Anonymous artifacts are read-only and expire in 24h if nobody claims them. The handoff token does not claim anything — the human never needs it, and never gets it. A claim without agent access grants no token, and login --handoff says so rather than polling forever.

Which do I use?

| Situation | How to connect | |-----------|----------------| | Human at a dev machine | anima login (browser opens) | | Interactive agent, human nearby | anima login — show the URL + code, human approves on any device | | Headless agent, human reachable | anima login --json — relay the verification_required event, polling finishes automatically | | You want to lead: share something first, no account needed on their side | anima create --anonymous … → send artifactUrl → anima login --handoff | | Fully headless / CI, or a human sent you an invite link | anima login --invite <url-or-code> — they approved when minting it, so there is no approval step at run time |


Quick start

# 1. Connect (once)
npx @animaapp/cli@latest login

# 2. Make an artifact — from your own code, or generated
npx @animaapp/cli@latest create -t import --from ./my-project     # instant
npx @animaapp/cli@latest create -t p2c -p "E-commerce page with a cart"  # waits ~3-7 min
npx @animaapp/cli@latest create -t l2c -u https://linear.app
npx @animaapp/cli@latest create -t f2c --file-key <key> --nodes 42:15

# ...or start empty and push over git
npx @animaapp/cli@latest create -t empty --framework react --name "My project"

# 3. Change it — no clone, no git binary
npx @animaapp/cli@latest explore <sessionId> --search "primaryColor"
npx @animaapp/cli@latest explore <sessionId> --read src/App.tsx
npx @animaapp/cli@latest edit <sessionId> -m "Blue buttons" \
  --replace src/App.tsx --old "red" --new "blue"

# ...or with a real checkout, when the job needs one
npx @animaapp/cli@latest get-git-token <sessionId>   # then: git clone <url>, commit, push

# 4. Share the artifactUrl the create printed. Publishing is a separate,
#    explicit step that makes the app public to the world:
npx @animaapp/cli@latest publish <sessionId>

# Along the way
npx @animaapp/cli@latest list                        # resume recent work
npx @animaapp/cli@latest review list                 # what humans asked you to change

Commands

Every command runs one MCP tool. anima <command> --help prints its own options; --json makes any of them agent-readable.

| | Command | What it does | |---|---------|--------------| | Connect | login | Connect this machine as a scoped agent identity | | | logout | Revoke and clear every stored credential | | | auth | Inspect credentials, store a Figma token | | | skill | Install the AgentGrid guide as a SKILL.md your agent can read | | | mcp-config | Print an MCP server config for your MCP client | | Find | workspaces | The workspaces you can reach, and what you may do in each | | | list | The artifacts you can read, most-recently-updated first | | Make | create | Import your code, an empty repo, or AI generation | | | create-knowledge | Create a knowledge artifact | | | status | Did generation finish? --wait blocks until it has | | | duplicate | Copy an artifact into a new, independent one | | Change | explore | Read files: list, search, read, history | | | edit | Change files and commit them — one commit | | | upload-asset | Add an image, font or media file over 256 KB | | | get-git-token | Mint git access for a real checkout | | Collaborate | review | Read and answer the comments humans left you | | Ship | publish | Deploy to a public live URL — only when asked | | | unpublish | Take a published artifact offline | | | update | Rename, or change visibility | | | move | File an artifact under a different workspace | | | delete | Reversible soft deletion | | Figma | codegen | Figma → local code files, no artifact | | Settings | config | Store CLI preferences (e.g. a default API URL) |

login — connect this machine

npx @animaapp/cli@latest login
npx @animaapp/cli@latest login --client-name "My CI Agent"   # label on the consent screen
npx @animaapp/cli@latest login --no-open                      # don't auto-open the browser
npx @animaapp/cli@latest login --print-mcp-config             # also emit an MCP server config
npx @animaapp/cli@latest login --invite <url-or-code>         # redeem a pre-approved invite — no approval step
npx @animaapp/cli@latest login --handoff                      # wait for a claim on your anonymous artifact
npx @animaapp/cli@latest login --handoff <token>              # ...or name the token explicitly

| Option | Description | Default | |--------|-------------|---------| | --handoff [token] | Log in with the handoff token from an anonymous create. Waits until a human claims the artifact, then stores the credentials their claim grants — same store as every other door. Defaults to your last one. Blocks; background it with & and watch auth --status. Stops with a clear message if the window closes unclaimed, or if the human claimed without granting agent access | — | | --invite <url-or-code> | Redeem an invite link (…/invite/<code>.md) or bare code. The human already approved when minting the invite, so there is no verification step — one call and you're connected. The invite URL's origin is persisted as the api-url, so follow-up commands target the right server with no flags | — | | --client-name <name> | How the CLI appears on the consent screen | AgentGrid CLI | | --no-open | Don't try to open the verification page in a browser | — | | --print-mcp-config | One-shot: after this fresh login, also print the MCP server config. If you are already logged in, use mcp-config instead — this flag always starts a new login | off |

skill — install the AgentGrid guide for your agent

npx @animaapp/cli@latest skill .claude/skills/agentgrid/SKILL.md   # write it
npx @animaapp/cli@latest skill                                      # or print it

Writes a SKILL.md at the path you give — the whole AgentGrid flow, so an agent reading it knows how to connect, create, change, review and publish without being told. Parent directories are created; re-running overwrites.

The prose is fetched from the API (/guide.md), so it does not go stale in an installed package, while the command reference inside it is generated from this CLI's own commands — meaning the syntax it shows is the syntax your version accepts. No credential needed: the guide is public.

Point --api-url at another environment to install that one's guide.

mcp-config — print your MCP server config

npx @animaapp/cli@latest mcp-config

Prints a ready-to-paste remote MCP server entry pointing at /v1/mcp. It contains no credential and needs none: your MCP client authorizes itself against the server and holds a credential it can renew on its own. No network call, no device flow. --json wraps it as { success, mcpConfig }.

MCP-capable agents: run mcp-config, add the entry to your client, and authorize when it prompts. No CLI in the loop after that. Your client needs to support OAuth for remote MCP servers (.well-known discovery); if it cannot, use the CLI commands instead.

workspaces — where you can work

npx @animaapp/cli@latest workspaces

Artifacts live in workspaces. You may have access to one or more of them, and what you may do can differ between them: each row shows the capabilities you hold there, and creating or changing an artifact needs write.

Workspace ids are opaque: get one here (each list row carries its own) for --workspace. An empty list means your access reaches none of this team's workspaces — not that the team has none.

list — the artifacts you can read

npx @animaapp/cli@latest list
npx @animaapp/cli@latest list --workspace <id>       # just one workspace

Most-recently-updated first, so you can resume existing work instead of creating a second artifact for the same job. It spans every workspace you can read unless --workspace names one, and each row says which workspace it is in. Each row carries its session id and artifactUrl; --json adds them to every row.

create — an artifact for your code, or AI-generated

npx @animaapp/cli@latest create -t import --from ./my-project              # import YOUR code (instant)
npx @animaapp/cli@latest create -t import --from ./notes --artifact-type markdown  # a readable document
npx @animaapp/cli@latest create-knowledge --name "Team knowledge"              # server-provided template
npx @animaapp/cli@latest create-knowledge --name "Team knowledge" --workspace <id>  # ...in a specific workspace
npx @animaapp/cli@latest create -t empty --framework react --name "My project"  # empty repo you push to (instant)
npx @animaapp/cli@latest create -t import --from ./my-project --workspace <id>    # in a specific workspace
npx @animaapp/cli@latest create -t p2c -p "Analytics dashboard with a sidebar"
npx @animaapp/cli@latest create -t l2c -u https://stripe.com
npx @animaapp/cli@latest create -t f2c --file-key <key> --nodes 42:15
npx @animaapp/cli@latest create -t p2c -p "Pricing page" --workspace <id>        # any type takes --workspace
npx @animaapp/cli@latest create -t import --from ./my-project --anonymous     # no account — hand off later

-t import is the one-step upload path: your folder (or .zip) becomes the artifact's first commit — small text-only projects are sent inline, larger or binary ones are zipped and uploaded via a presigned URL automatically. -t empty creates an empty repository instead: follow with git clone of the returned URL, add your code, and git push. Then publish <sessionId> for a live URL. The other types are AI generation (3–7 min).

create -t p2c|l2c|f2c blocks for 3–7 minutes. The generation itself is asynchronous — the server starts a background job and answers immediately — but the command waits it out for you, polling until the app is ready or failed. So what create prints is a finished app, and a failed generation is a non-zero exit rather than a link to nothing. Budget the wall-clock time, and keep the default --timeout of 600000.

Pass --no-wait to get the session id back in seconds instead and do the waiting yourself with status --wait.

--artifact-type is a separate question from -t: -t is how the repository starts, --artifact-type is what the artifact IS, and it decides how a human sees it. app is a running web page and needs an index.html; markdown is a readable document and needs .md files. Omit it and the server infers one: markdown when your files are .md/.mdx with no HTML, otherwise app. Getting it wrong is the common mistake — .md files uploaded as an app produce an artifact with nothing to render.

Knowledge artifacts use the dedicated create-knowledge command instead of generic create. It accepts an optional --name (maximum 120 characters) and an optional --workspace <id>; the server-provided knowledge template supplies the initial files and framework. This command requires deployment of the server contract containing merged AnimaApp/anima-design-to-code PR 5114. There is no compatibility fallback to generic creation on older servers.

| Option | Values | Default | |--------|--------|---------| | -t, --type | import (your code, with --from), empty (repo to push to), p2c (prompt), l2c (URL), f2c (Figma) | required | | --name | project name | (empty/import) | | --from | folder or .zip to import | (import) | | -p, --prompt | free text | (p2c) | | -u, --url | website URL | (l2c) | | --file-key | Figma file key or URL | (f2c) | | --nodes | Figma node IDs, comma-separated | (f2c) | | --figma-token | Figma PAT (or FIGMA_TOKEN env) | (f2c) | | --artifact-type | app (web page, needs an index.html), markdown (document, needs .md files) | inferred from your files | | --anonymous | Create with no account (-t import only). Returns artifactUrl for your human and a handoffToken for you | off | | --handoff <token> | Add this artifact to an existing claim (--anonymous only), so one link covers them all | your last one | | --client-name | Who to credit as the creator on the claim page (--anonymous only) | AgentGrid CLI | | --framework | react, html — apps only | react | | --styling | tailwind, css, plain_css, css_modules, inline_styles¹ | tailwind | | --language | typescript, javascript | typescript (react) | | --ui-library | shadcn, mui, antd, clean_react | (none) | | --guidelines | free text | (p2c only) | | --no-wait | Return as soon as generation starts, instead of waiting for the finished app | off (create waits) | | --timeout <ms> | How long to wait for generation | 600000 |

¹ The valid styling / UI-library set depends on --type; the server validates and returns a clear error for unsupported combinations.

status — did generation finish?

npx @animaapp/cli@latest status <artifactUrl-or-sessionId>           # a snapshot
npx @animaapp/cli@latest status <artifactUrl-or-sessionId> --wait    # block until ready or failed

Generation runs in the background, so this is how you learn it finished. create already waits; reach for this after create --no-wait, or to pick a wait back up after a timeout. --wait blocks until the artifact is ready or failed (the underlying tool returns about every 45 seconds and this re-calls it), and a failed status exits non-zero so a caller checking only the exit code cannot mistake it for done.

| Option | Values | Default | |--------|--------|---------| | --wait | block until the artifact settles | off (snapshot) | | --timeout <ms> | how long --wait may block | 600000 |

explore — read an artifact's files (no git)

npx @animaapp/cli@latest explore <artifact> --search "buttonColor"     # find the file
npx @animaapp/cli@latest explore <artifact> --read src/App.tsx          # read it
npx @animaapp/cli@latest explore <artifact> --tree --path src           # list a directory
npx @animaapp/cli@latest explore <artifact> --history                   # commits, newest first

Needs no shell, no git and no network of its own. Start with --search when you do not know which file to change, then --read the ones you will edit. Every response carries revision, the artifact's current commit — pass it to edit --base-revision.

| Option | Values | Default | |--------|--------|---------| | --tree / --search <q> / --read <paths...> / --history | exactly one is required | — | | --path <prefix> | tree/search: a literal directory prefix (not a glob) | (whole artifact) | | --range <start,end> | read: 1-based inclusive line window, single file only | (whole file) | | --revision <rev> | see the artifact as it was at this commit | (current) | | --regex, --case-sensitive | search behaviour | off | | --include-excluded | also search node_modules, dist, build | off | | --limit <n> | maximum rows | (server default) | | --cursor <c> | history: continue after a previous response's nextCursor | — |

A file whose bytes are not text comes back as asset: true with its size and mime instead of content, and an empty search reports what it skipped — check notSearched before concluding the text is not there.

edit — change files and commit them (no git)

# the shorthands
npx @animaapp/cli@latest edit <artifact> -m "Blue pill" --replace src/App.tsx --old "red" --new "blue"
npx @animaapp/cli@latest edit <artifact> -m "Add page" --write src/about.tsx --from-file ./about.tsx
npx @animaapp/cli@latest edit <artifact> -m "Drop dead code" --delete src/old.ts
npx @animaapp/cli@latest edit <artifact> -m "Rename" --move src/a.ts --to src/b.ts

# the general door: several operations, one commit
npx @animaapp/cli@latest edit <artifact> -m "Retheme" --changes '[
  {"op":"str_replace","path":"src/App.tsx","oldText":"red","newText":"blue"},
  {"op":"delete","path":"src/legacy.css"}
]'

Everything in one call lands as one commit: either every operation applies or none does. The live artifact reflects it immediately.

| Option | Values | Default | |--------|--------|---------| | -m, --message | commit message | required | | --base-revision <rev> | the revision the edit applies to | the current head | | --changes <json> / --changes-file <path> | the full operation list | — | | --write <path> + --content <text> / --from-file <path> | create or replace a file | — | | --delete <path> | remove a file | — | | --move <path> --to <path> | rename a file | — | | --replace <path> --old <text> --new <text> [--all] | swap an exact snippet | — |

Without --base-revision the edit applies to the artifact's current head, read immediately beforehand. Pass a revision from explore when you want to be told about a concurrent change (REVISION_CONFLICT) rather than write over it.

--move does not rewrite imports — neither in the files importing the moved module nor the relative imports inside it. Read the file first and send the str_replace operations that fix them in the same commit.

upload-asset — add a large image, font or media file

npx @animaapp/cli@latest upload-asset <artifact> ./hero.png --path public/hero.png -m "Add hero"
npx @animaapp/cli@latest upload-asset <artifact> ./hero.png     # stage only; prints assetUploadId

For files over 256 KB, which is the most edit takes inline. This stages the upload, performs it, and — when --path says where the file belongs — commits it in the same run. Files over 10 MB go through Git LFS automatically. Smaller files need none of this: send them to edit directly.

review — the comments humans addressed to you

npx @animaapp/cli@latest review list                       # everything addressed to you
npx @animaapp/cli@latest review list <artifact>            # just this artifact
npx @animaapp/cli@latest review reply <commentId> -m "Which pill did you mean?"
npx @animaapp/cli@latest review resolve <commentId> --note "Left as-is: it matches the spec"

A review is a batch of comments a human pinned to places in an artifact and sent as one. Nothing pushes them to you, so review list is how the work arrives — run it when a human says they left comments, and when starting work on an artifact you have been reviewed on before.

Read the replies before acting: a reviewer can keep talking after sending, so the comment body is where the request starts, not necessarily where it ends. A comment marked unassigned was addressed to nobody in particular and is anyone's to take.

To close comments, put the review's resolveTrailer lines in your commit message — that records which commit resolved them. review resolve is for what a commit cannot carry (a question answered, a change you decided against), and review reply says something while leaving the comment open.

duplicate — copy an existing artifact

npx @animaapp/cli@latest duplicate <artifactUrl-or-sessionId>
npx @animaapp/cli@latest duplicate <artifactUrl-or-sessionId> --name "My copy"
npx @animaapp/cli@latest duplicate <artifactUrl-or-sessionId> --workspace <id>

Creates a new, independent artifact in the workspace --workspace names, which is optional when you can create in only one. It copies code, assets, and supported database content, but does not copy chat or custom domains. The source must be readable and the destination workspace must be writable. Without --name, the API names it <source name> (Copy).

The result includes the new and source session IDs, the duplicate's name, its artifactUrl (plus playgroundUrl and previewUrl when the copy is an app), and API-provided next steps. Duplication is not idempotent: if a request times out or its response is lost, run list and check recent artifacts before retrying.

codegen — Figma to local files (no artifact)

npx @animaapp/cli@latest codegen --file-key <key-or-url> --nodes 42:15 -o ./components

| Option | Values | Default | |--------|--------|---------| | --file-key | Figma file key or URL | required | | --nodes | Figma node IDs, comma-separated | (or node id in the URL) | | --figma-token | Figma PAT (or FIGMA_TOKEN env) | required | | -o, --output | output directory | ./generated | | --framework | react, html | react | | --styling | tailwind, plain_css | tailwind | | --language | typescript, javascript | typescript (react) | | --ui-library | shadcn, mui, antd, clean_react | (none) |

publish — deploy a session to a public URL (1–3 min)

Publishing makes the app public to the world. Sharing usually doesn't need it — the artifact is already visible at its artifactUrl. Agents: only publish when the human explicitly asked for a public site; otherwise share that URL and offer publishing as a follow-up.

npx @animaapp/cli@latest publish <sessionId>

Deploys the artifact's app to a live URL. Publishing as a design-system npm package is an enterprise feature and is not reachable over MCP, so this CLI does not offer it.

unpublish — take a published artifact offline

npx @animaapp/cli@latest unpublish <sessionId>

The inverse of publish: clears the live URL so the deployed site stops being reachable. The artifact, its code, and its content are untouched; publishing again reuses the same subdomain.

delete — hide an artifact with reversible soft deletion

npx @animaapp/cli@latest delete <artifactUrl-or-sessionId>

Run this only when deletion was explicitly requested. Published artifacts must be unpublished first. The operation hides the artifact but is reversible and does not remove its code, assets, history, database content, or domain assignments; it never permanently deletes an artifact.

update — rename or change visibility (metadata only)

npx @animaapp/cli@latest update <sessionId> --name "New name"
npx @animaapp/cli@latest update <sessionId> --privacy public    # anyone with the link
npx @animaapp/cli@latest update <sessionId> --privacy private   # team only

Never touches code or content — that's edit (or the git flow via get-git-token).

move — file an artifact under a different workspace

npx @animaapp/cli@latest workspaces                       # the ids live here
npx @animaapp/cli@latest move <sessionId> --workspace <id>

The artifact stays as it is. Same git repository, session id, URL, history and live deployment — there is no new link to send and no copy to reconcile.

What changes is who can reach it. A private artifact is reached through the workspace it is filed in, so a move hands it to the people who reach the destination and takes it from the rest, including whoever you already sent the link to. You need write on the artifact and write in the destination, which is what moving it back would take too.

--workspace is required and names a workspace of the same team, where create and duplicate fall back to the one workspace you can write in. Moving an artifact where it already is leaves everything as it was.

get-git-token — read/edit an artifact's code over git

npx @animaapp/cli@latest get-git-token https://app.agentgrid.io/artifacts/<sessionId>

An artifact is a git repository. This command mints a short-lived access token scoped to that one artifact and prints a ready-to-use remote URL — you run git yourself:

git clone <gitRemoteUrl>               # read (and edit locally)
git config user.name … && git config user.email …   # the identity the grant names
git push                               # read-write access: updates the live artifact
git remote set-url origin <new url>    # after expiry: re-run get-git-token, re-point the clone

A read-write grant also names the commitAuthor your commits should carry — the agent behind the credential, or the human. Run the printed git config pair in the clone before committing: a fresh clone has no identity of its own, so without it your pushes are attributed to whatever git identity this machine happens to have.

In --json mode the output is { gitRemoteUrl, access: "ro"|"rw", expiresAt, commitAuthor, gitConfigCommand }. The token expires within an hour and cannot be renewed — treat the URL as a secret, and re-mint rather than store it.

Git is not the only door: explore and edit change the same repository with no clone, no shell and no git binary. Reach for a checkout when that is what the job actually needs — a large refactor, running the project, branches, or rewriting history.

logout — disconnect this machine

npx @animaapp/cli@latest logout

A full reset: revokes the agent credentials server-side, then clears all stored credentials (AgentGrid token, Figma token, agent metadata) and the CLI config (including an api-url persisted by login --invite) — the machine ends up pristine, as if the CLI was never used. Because the revocation is server-side, a copy of the token taken from this machine stops working too. The agent identity itself remains on your team roster; revoke it there to retire it for good.

config — store CLI preferences

Persist non-secret settings to ~/.config/anima/config.json so you don't have to pass flags every time — handy for pointing at a local API during development. Note: logout removes this file too (full machine reset); login --invite writes api-url automatically from the invite URL's origin.

npx @animaapp/cli@latest config set api-url http://localhost:3789
npx @animaapp/cli@latest config get api-url
npx @animaapp/cli@latest config list
npx @animaapp/cli@latest config unset api-url

The API URL resolves in this order: --api-url flag → ANIMA_API_URL env → config.json → default (https://api.agentgrid.io).

auth — inspect or manage credentials

npx @animaapp/cli@latest auth --status            # token type + expiry, and any pending claim
npx @animaapp/cli@latest auth --figma-token <T>   # save a Figma token for codegen / f2c
npx @animaapp/cli@latest auth --logout            # alias for `anima logout`

--status also reports a handoff waiting to be claimed — including when you are not connected yet, which is exactly when you want to ask. pendingHandoff.state is awaiting_claim or expired, alongside the artifactUrl to re-send.


Global flags

| Flag | Description | Available on | |------|-------------|--------------| | --json | Emit a single JSON object to stdout (for agents) | every command | | --api-url <url> | API base URL — point at local or staging³ | every command except config | | --log-file <path> | Append a JSON debug log of each step to a file | every command that reaches the network | | --verbose | Stream progress to stderr in JSON mode¹ | create, create-knowledge, status, duplicate, upload-asset, publish, unpublish, update, delete, codegen, get-git-token | | --timeout <ms> | How long to wait² | create, status, codegen |

¹ Only the commands that do slow work carry a spinner, so --verbose is on those. explore, edit, list and review are a single round trip and report nothing in between.

² Defaults to 600000 (10 min). On create and status --wait it is the budget for the whole generation wait, not one request — don't lower it, since generation takes minutes. Running out is a TIMEOUT exit that tells you the job is still running and how to resume the wait.

³ Falls back to ANIMA_API_URL, then anima config set api-url, then https://api.agentgrid.io. Set it once with config instead of passing --api-url every time.

Environment variables: ANIMA_API_URL, ANIMA_LOG_FILE, and FIGMA_TOKEN for codegen / create -t f2c.


Output modes

  • Terminal (TTY): colored text, spinner, elapsed time.
  • Piped / --json: a single JSON object on stdout; progress and the device-flow verification_required event go to stderr, so stdout is always a clean, parseable result.
npx @animaapp/cli@latest create -t p2c -p "dashboard" --json 2>/dev/null | jq -r .artifactUrl

Debugging

--log-file (or the ANIMA_LOG_FILE env var) writes one JSON line per step — HTTP requests/responses, MCP connect and tool calls, and errors — to a file you can inspect or share. Tokens and auth headers are redacted.

npx @animaapp/cli@latest login --log-file ./anima-debug.log

HTTP 404 on login means the API at --api-url doesn't have the device grant deployed. Point at an API that does with --api-url, or connect with login --invite instead.


License

MIT