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

@gavana.ai/cli

v0.2.2

Published

JSON-first command-line client for the Gavana Canvas API

Downloads

514

Readme

Gavana CLI

The Gavana CLI is a JSON-first command-line client for the Gavana Canvas API. It can read and change canvases, work with assets, explicitly run Recipes, run deterministic Image Actions, and observe every execution through shared Run and Job interfaces without opening the browser. It also queues model-aware video generation with local or durable frame references.

Install from npm

npm install --global @gavana.ai/cli
gavana --help

The npm command works after the package owner publishes this release. For local package verification from the Gavana repository, run npm run test:canvas-cli-package.

Use of the published CLI is subject to the current Gavana Terms of Service. Its customer package license incorporates those terms by reference.

Node.js 20 or newer is required. craftboard and craftboard-canvas remain available as compatibility aliases.

Sign in

Browser OAuth is the default:

gavana auth login
gavana auth status

The CLI opens Gavana, asks the user to approve exact scopes, and returns through a loopback callback. On macOS the resulting revocable token is stored in Keychain; custom config paths and other platforms use the mode-0600 config file. Use --read-only for a browse-only profile.

Named profiles keep accounts and environments separate:

gavana auth login --profile work
gavana auth login --profile staging --base-url https://staging.example.com
gavana config list
gavana config use work
gavana canvas list --profile staging

Manual Agent Access tokens remain supported for automation and compatibility.

Create an Agent Access token in Gavana, then save it without putting the secret in shell history. On zsh (the default shell on current macOS):

read -rs 'GAVANA_AGENT_TOKEN?Paste Agent Access token: '; printf '\n'; printf '%s' "$GAVANA_AGENT_TOKEN" | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin; unset GAVANA_AGENT_TOKEN
gavana auth status

On Bash:

read -rsp 'Paste Agent Access token: ' GAVANA_AGENT_TOKEN; printf '\n'; printf '%s' "$GAVANA_AGENT_TOKEN" | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin; unset GAVANA_AGENT_TOKEN

On PowerShell:

$secureToken = Read-Host 'Paste Agent Access token' -AsSecureString
$token = [System.Net.NetworkCredential]::new('', $secureToken).Password
$token | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin
Remove-Variable token, secureToken

The saved configuration lives at ~/.config/gavana/agent.json with file mode 0600. Environment variables GAVANA_BASE_URL and GAVANA_AGENT_TOKEN override saved values. Existing ~/.config/craftboard/agent.json and CRAFTBOARD_* aliases remain readable.

Discover and diagnose

gavana doctor
gavana version
gavana completion zsh
gavana canvas --help
gavana api GET /canvases --field limit=10
gavana mcp install codex
gavana mcp install codex --read-only
gavana mcp config cursor

JSON remains the stable scripting default. Use --output human for a compact terminal view, or jsonl, markdown, raw, and --jq for composition. Transient network errors and 429/502/503/504 responses are retried only for safe GET requests, respecting Retry-After; paid generation writes are never retried automatically.

Examples

gavana canvas list
gavana canvas list --limit 25 --jq '.canvases[].handle' -r
gavana asset get asset:OWNER_UID:ASSET_ID
gavana element list
gavana element get element:ELEMENT_ID@v3
gavana element create --name "Soft window light" --type lighting --guidelines "Keep diffuse, cool window light."
gavana recipe search "product visual"
gavana recipe run recipe:product-visual-direction --input product-context="A matte black travel bottle" --destination agent-canvas
gavana model list --capability image.generate
gavana model get model:OPAQUE_MODEL_KEY
gavana action list
gavana action get action:resize
gavana action run action:resize --input ./product.png --destination agent-canvas --width 1080 --height 1350
gavana image generate --destination agent-canvas --model model:OPAQUE_MODEL_KEY --prompt "A studio product photograph"
gavana image generate --destination agent-canvas --prompt "A studio product photograph" --wait
gavana model list --capability video.generate
gavana video generate --model model:OPAQUE_MODEL_KEY --prompt "A slow product turntable" --duration 15 --aspect-ratio 9:16 --download ./turntable.mp4
gavana video generate --model model:OPAQUE_MODEL_KEY --prompt "Animate the fabric naturally" --first-frame ./product.png --no-wait
gavana video download job:JOB_ID --file ./result.mp4
gavana run wait run:RUN_ID --output markdown

video generate validates duration, aspect ratio, resolution, audio, and frame capabilities against the selected model before starting paid work. Use gavana model get model:OPAQUE_MODEL_KEY to inspect its exact values. First frame, last frame, and repeatable --reference inputs accept image node: or asset: handles, public HTTPS URLs, local image paths, stdin (-), or the macOS clipboard. Local images upload privately first. Pass --canvas canvas:<id> when any input is a node: handle. A last frame requires a first frame.

Video generation returns a job: handle. By default the CLI waits up to 30 minutes and returns the completed job with its authenticated video download path. Add --download ./output.mp4 to stream the successful result directly to disk, or use video download job:<id> --file ./output.mp4 later. Existing files are preserved unless --yes is supplied. Use --no-wait to return after queueing, then use job get, job wait, or job cancel. Waiting, downloading, and cancellation require job:manage; generation requires canvas:read, asset:read, and video:generate.

Image Actions resize, crop, reframe, composite, add text, overlay, color grade, or rotate existing images. They are deterministic and do not spend AI credits. Use action get to inspect the exact input order, valid fields, defaults, and limits. action run accepts node: and asset: handles, local image paths, stdin (-), or the macOS clipboard. Local, stdin, and clipboard inputs are privately uploaded first and therefore also require the token's image:generate scope; existing handles do not.

For reference-aware image generation, repeat --reference for every durable visual and repeat --reference-role in the same order when the role is known: identity, construction, texture, fit, or style. Gavana records the exact handles and roles in the job result and target-node provenance, and sends the request through the reference/edit backend rather than dropping inputs into a prompt-only fallback.

recipe run takes repeatable named inputs such as --input product-context="A matte black travel bottle" and --input [email protected]. Use the exact keys returned by recipe get. For distinct product variants, use a Prompt List: connect the product image once to the List, make one explicit direction per row, and connect the List to an image generator. Each row inherits the same reference; agents should state that the exact product must be preserved and never substituted. For a style that belongs to only one row, use that row's referenceBindings with the durable image handle ({ "nodeId": "node:<id>", "role": "style" }), rather than inserting a copied image name into prompt text. Gavana preserves the shared Product -> Prompt List -> output path and draws the row Style -> output edge separately. Written ports accept text, text/sticky node: handles, and image handles when the Recipe asks for “an image or written note.” Image ports may also use local raster paths, stdin, or the clipboard and are uploaded privately first. Upload a local visual first and pass its asset: handle when using it on a written reference port; @path on that port reads the file as text. Starting a Recipe creates a private instance when needed, materializes its declared outputs on the destination canvas, and returns their durable node: and asset: handles. recipe fork remains setup-only and never starts a Run. All Recipe starts currently require image:generate and its dependent scopes, including text-only Recipes.

Recipe, image, and Action work returns a shared run: handle with typed outputs, duration estimates, observed queue/execution timing, and stable retry guidance. Image commands return as soon as Gavana has created the durable Canvas targets and queued the Run, so the caller can continue while generation proceeds. Add --wait only when the completed image is needed in the same command. --no-wait remains accepted for existing image scripts. Recipe and Action commands retain their existing wait-by-default behavior. Waiting and run get|wait|cancel require job:manage; a start-only token can queue image work directly or use --no-wait with a signed webhook. The legacy job: handle remains an image and Action compatibility alias; it is never used for Recipes. Image and Action run: and job: handles point to the same temporary record and expire together: the default retention is 24 hours while unacknowledged, 15 minutes after the first successful server finalization (from a Run GET or callback), and seven days for the expired tombstone. Recipe Run records currently persist without that temporary TTL. Persist the returned durable asset and node handles. For a signed terminal callback, provide the endpoint and read the secret from an environment variable:

read -rs 'GAVANA_WEBHOOK_SECRET?Webhook signing secret: '; printf '\n'
export GAVANA_WEBHOOK_SECRET
gavana image generate \
  --destination agent-canvas \
  --prompt "A studio product photograph" \
  --webhook-url 'https://automation.example.com/hooks/gavana' \
  --no-wait
unset GAVANA_WEBHOOK_SECRET

Use --webhook-secret-env NAME to select a different variable. The CLI never prints the secret. Successful Image and Action callbacks are sent only after Gavana has stored the durable canvas, node, and asset results. Failed, canceled, or expired callbacks describe the terminal state without requiring images; Recipe callbacks contain their typed terminal outputs. A start-only token remains revocable while Gavana's worker resumes the Run independently of the original CLI process. If the token expires or is revoked first, the Recipe stops with delegation_revoked and sends its signed failed callback.

Commands emit one JSON result to stdout by default. Progress and errors go to stderr, making the CLI safe to compose in scripts and agent workflows. List commands for canvases, recipes, assets, Actions, models, and providers accept --limit and --cursor; responses return the continuation at page.nextCursor. Use --output jsonl for line-oriented output. The built-in --jq selector supports property paths, array indexes, and [] projections without requiring a separate jq installation.

Elements

Elements are reusable visual references, not copied image files. Use element list, element get element:<id>@v<n>, and element history to inspect current or immutable historical revisions. Create or update with one or more --source-asset asset:<id> references, --guidelines, or both. element archive asks for interactive confirmation; in scripts and other non-interactive environments it requires --yes. An archived Element remains restorable with element restore. element collection-delete follows the same confirmation rule and never deletes the Elements it organized.

Apply an exact immutable revision during image work with repeatable --element element:<id>@v<n> flags. JSON callers may also pass { "handle": "element:<id>@v<n>", "role": "style", "influence": 0.8 }. An image job accepts up to eight Elements; their source images share the existing 16-reference limit.

Chat-first work

Use work_prepare or gavana work prepare for a broad campaign request. It returns exactly three directions and a recommendation without paid generation. Use work_continue or gavana work continue to answer a factual question, select one direction, adjust the brief, or acknowledge a changed Canvas with --rebase. work_execute and gavana work execute work:<id> --confirm --idempotency-key KEY send confirm: true, start only the selected direction, and return durable progress immediately; they never wait or automatically retry paid work. work_get is read-only and never polls providers or writes state; use gavana work refresh work:<id> to reconcile provider progress. The snapshot returns the latest brief, choice, outputs, and Canvas synchronization state.

JavaScript client

The same dependency-free client is exported for Node.js applications:

import { createCanvasAgentClient } from "@gavana.ai/cli";

const client = createCanvasAgentClient({
    baseUrl: process.env.GAVANA_BASE_URL,
    token: process.env.GAVANA_AGENT_TOKEN,
    surface: "api",
});

const result = await client.listCanvases();

Remote servers must use HTTPS. Plain HTTP is accepted only for local loopback development.