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.7.1

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, edit them over git, publish them to a live URL, 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 four ways. Door 3 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. Pre-issued token — ANIMA_API_TOKEN

For CI or a fully headless agent with no human in the loop, skip login and provide a token directly:

export ANIMA_API_TOKEN=<agent-or-personal-token>
export ANIMA_TEAM_ID=<team-id>        # optional
export FIGMA_TOKEN=<token>            # only for codegen / f2c

Resolution priority: ANIMA_API_TOKEN env var → stored credentials file → error.

3. 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 claim 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 | | Fully headless / CI, no human | set ANIMA_API_TOKEN — no login step | | You want to lead: share something first, no account needed on their side | anima create --anonymous … → send artifactUrlanima login --handoff | | Your human led: they sent you an invite link to join | anima login --invite <url-or-code> — one exchange, no approval step |


Quick start

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

# 2. Create from a prompt / URL / Figma
npx @animaapp/cli@latest create -t p2c -p "E-commerce product page with cart"
npx @animaapp/cli@latest create -t l2c -u https://linear.app
npx @animaapp/cli@latest create -t f2c --file-key <key> --nodes 42:15

# 3. Or bring YOUR OWN code: import it in one step -> publish
npx @animaapp/cli@latest create -t import --from ./my-project
npx @animaapp/cli@latest publish <sessionId>

# ...or start empty and push over git
npx @animaapp/cli@latest create -t empty --framework react --name "My project"
npx @animaapp/cli@latest get-git-token <sessionId>   # then: git clone <url>, add code, git push

# ...or create an independent copy of an existing artifact
npx @animaapp/cli@latest duplicate <artifactUrl-or-sessionId> --name "My copy"

Commands

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 |

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.

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 -t empty --framework react --name "My project"  # empty repo you push to (instant)
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 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).

--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.

| 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) |

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

duplicate — copy an existing artifact

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

Creates a new, independent artifact in the current team's Default workspace. 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, duplicate name, playgroundUrl, previewUrl, 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 playgroundUrl. 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.

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 the git flow (get-git-token).

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

npx @animaapp/cli@latest get-git-token https://dev.animaapp.com/chat/<sessionId>

An artifact is a git repository, and git is the only way to read or edit its code. 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 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

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

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

Available on the network commands (login, create, duplicate, codegen, publish, get-git-token):

| Flag | Description | Default | |------|-------------|---------| | --json | Emit a single JSON object to stdout (for agents) | off (pretty in a TTY) | | --verbose | Stream progress to stderr in JSON mode¹ | off | | --api-url <url> | API base URL (point at local/staging)³ | https://api.agentgrid.io | | --log-file <path> | Append a JSON debug log of each step to a file | off | | --timeout <ms> | Request timeout² | 600000 (10 min) |

¹ --verbose applies to create / duplicate / codegen / publish / get-git-token. ² --timeout applies to create / codegen. Don't lower it — generation takes minutes. ³ Falls back to ANIMA_API_URL, then anima config set api-url, then the default. Set it once with config instead of passing --api-url every time.


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 .playgroundUrl

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 (--api-url) or use ANIMA_API_TOKEN.


License

MIT