Claude Skill

add-vercel

Add Vercel deployment capability to NanoClaw agents. Installs the Vercel CLI in agent containers and sets up OneCLI credential injection for api.vercel.com. Use when the user wants agents to deploy web applications to Vercel.

LLM Mart · 0 points · 16 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download nanocoai-nanoclaw-.claude_skills_add-vercel-ad8837c.zip · 7 KB
Part of nanocoai/nanoclaw — 49 skills

Install

skills CLI npx skills add https://github.com/nanocoai/nanoclaw/tree/main/.claude/skills/add-vercel
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install nanocoai-nanoclaw@llmmart
Git git clone https://github.com/nanocoai/nanoclaw.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole nanocoai/nanoclaw collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Add Vercel

This skill gives NanoClaw agents the ability to deploy web applications to Vercel. It installs the Vercel CLI in agent containers and configures OneCLI to inject Vercel credentials automatically.

Principle: Do the work — don't tell the user to do it. Only ask for their input when it genuinely requires manual action (pasting a token).

Phase 1: Pre-flight

Check if already applied

Check if the container skill exists:

test -d container/skills/vercel-cli && echo "INSTALLED" || echo "NOT_INSTALLED"

If INSTALLED, skip to Phase 3 (Configure Credentials).

Check prerequisites

Verify OneCLI is working (required for credential injection):

onecli version 2>/dev/null && echo "ONECLI_OK" || echo "ONECLI_MISSING"

If ONECLI_MISSING, tell the user to run /init-onecli first, then retry /add-vercel. Stop here.

Phase 2: Install Container Skill

Copy the bundled container skill into the container skills directory:

rsync -a .claude/skills/add-vercel/container-skills/ container/skills/

Verify:

head -5 container/skills/vercel-cli/SKILL.md

Phase 3: Configure Credentials

Check if Vercel credential already exists

onecli secrets list 2>/dev/null | grep -i vercel

If a Vercel credential already exists, skip to Phase 4.

Set up Vercel API credential

The agent needs a Vercel personal access token. Tell the user:

I need your Vercel personal access token. Go to https://vercel.com/account/tokens and create one with these settings:

  • Token name: nanoclaw (or any name you'll recognize)
  • Scope: "Full Account" — the agent needs to create projects, deploy, and manage domains
  • Expiration: "No expiration" recommended (avoids credential rotation), or pick a date if your security policy requires it

After creating the token, copy it — you'll only see it once.

Once the user provides the token, add it to OneCLI:

onecli secrets create \
  --name "Vercel API Token" \
  --type generic \
  --value "<TOKEN>" \
  --host-pattern "api.vercel.com" \
  --header-name "Authorization" \
  --value-format "Bearer {value}"

Verify:

onecli secrets list | grep -i vercel

Assign the secret to all agents

OneCLI uses selective secret mode — secrets must be explicitly assigned to each agent. Get the Vercel secret ID from the output above, then assign it to every agent:

# set-secrets replaces the entire list — read and merge for each agent.
VERCEL_SECRET_ID=$(onecli secrets list | jq -r '.data[] | select(.name | test("(?i)vercel")) | .id' | head -1)
for agent in $(onecli agents list | jq -r '.data[].id'); do
  CURRENT=$(onecli agents secrets --id "$agent" | jq -r '[.data[]] | join(",")')
  MERGED=$(printf '%s' "$CURRENT,$VERCEL_SECRET_ID" | tr ',' '\n' | sort -u | paste -sd ',' -)
  onecli agents set-secrets --id "$agent" --secret-ids "$MERGED"
done

Phase 4: Ensure Vercel CLI in Container Image

The Vercel CLI is not in the agent image by default — this skill is what adds it. It goes in container/cli-tools.json as a json-merge rather than a Dockerfile edit, which is what keeps the change deterministic and removable.

grep -q '"vercel"' container/cli-tools.json && echo "PRESENT" || echo "MISSING"

If MISSING, append the entry, keeping an exact pinned version — the manifest rejects ranges, so the supply-chain policy still applies:

{ "name": "vercel", "version": "52.2.1" }

Then apply it:

./container/build.sh

On an install that builds its own image, that rebuilds it. On one that fetches a published image, the same command adds Vercel as a single layer on top of the image already there, so the publisher's patched components underneath are kept — you are adding a tool, not replacing the runtime. The command says what that does and does not cover.

If PRESENT, the CLI is already in the manifest — skip the rebuild.

Phase 4b: Copy and Run the Dependency Guard

The Vercel CLI is a globally-installed binary — not importable or typed — so a structural test guards the install. Copy it into the host test tree and run it:

cp .claude/skills/add-vercel/vercel-manifest.test.ts src/vercel-manifest.test.ts
pnpm exec vitest run src/vercel-manifest.test.ts

The test asserts both halves of the install: a pinned vercel entry in container/cli-tools.json, and the container skill at container/skills/vercel-cli/. Either alone is a broken install — a manifest entry with no skill leaves the agent a binary nobody told it about, and a skill with no entry tells it to run a command that is not there.

Phase 5: Sync Skills to Running Agent Groups

Container skills are copied once at group creation and not auto-synced. After installing or updating a container skill, sync it to all existing agent groups:

for session_dir in data/v2-sessions/ag-*; do
  if [ -d "$session_dir/.claude-shared/skills" ]; then
    rsync -a container/skills/ "$session_dir/.claude-shared/skills/"
    echo "Synced skills to: $session_dir"
  fi
done

Phase 6: Restart Running Containers

Stop all running agent containers so they pick up the new skills on next wake:

docker ps --filter label=nanoclaw-session -q | xargs -r docker stop

Done

The agent can now deploy web applications to Vercel. Key commands:

  • vercel deploy --yes --prod --token placeholder — deploy to production
  • vercel ls --token placeholder — list deployments
  • vercel whoami --token placeholder — check auth

For the full command reference, the agent has the vercel-cli container skill loaded automatically.

Files (nanoclaw)
  • container-skills
    • vercel-cli
      • SKILL.md 5.7 KB
        ---
        name: vercel-cli
        description: Deploy apps to Vercel. Use when asked to deploy, ship, or publish a web application, or manage Vercel projects, domains, and environment variables.
        ---
        
        # Vercel CLI
        
        You can deploy web applications to Vercel using the `vercel` CLI.
        
        **HARD RULE: You MUST NOT write HTML, CSS, or JavaScript yourself. When asked to build a website or web app, you MUST delegate to a Frontend Engineer subagent (see "Building Websites" section below). This is not optional. Violation wastes your context window on code that belongs in a separate agent.**
        
        ## Auth
        
        Auth is handled by OneCLI — the HTTPS_PROXY injects the real token into API requests automatically. The Vercel CLI requires a token to be present to skip its local credential check, so **always pass `--token placeholder`** on every command. OneCLI replaces this with the real token at the proxy level.
        
        Before any Vercel operation, verify auth:
        
        ```bash
        vercel whoami --token placeholder
        ```
        
        If this fails with an auth error, ask the user to add a Vercel token to OneCLI. They can create one at https://vercel.com/account/tokens and register it via `onecli secrets create` on the host. Once added, retry `vercel whoami`.
        
        ## Deploying
        
        Always use `--yes` to skip interactive prompts and `--token placeholder` for auth (OneCLI replaces with real token).
        
        ```bash
        # Deploy to production
        vercel deploy --yes --prod --token placeholder
        
        # Deploy from a specific directory
        vercel deploy --yes --prod --token placeholder --cwd /path/to/project
        
        # Preview deployment (not production)
        vercel deploy --yes --token placeholder
        ```
        
        After deploying, verify the live URL:
        
        ```bash
        # Check deployment status
        vercel inspect <deployment-url> --token placeholder
        ```
        
        ## Pre-Send Checks (do this before sharing the URL)
        
        Don't send the deployment URL to the user until you've confirmed it's actually working. At minimum:
        
        1. **Local build passes** — run `npm run build` (or the project's build command) before `vercel deploy`. If the build fails locally, fix it first; don't deploy broken code.
        2. **Deployment succeeded** — the `vercel deploy` output shows a "Production: https://..." URL and the status is READY (confirm with `vercel inspect`).
        3. **Live URL responds** — `curl -sI <url> | head -1` should return `HTTP/2 200` (or another 2xx/3xx). A 404/500 means something's broken even though Vercel reported success.
        4. **Optional visual check** — if `agent-browser` is loaded, open the URL and eyeball it. Helpful for catching broken layouts that a 200 response wouldn't reveal.
        
        If any check fails, fix the issue and redeploy before reporting to the user.
        
        ## Project Management
        
        ```bash
        # Link to an existing Vercel project (non-interactive)
        vercel link --yes --token placeholder
        
        # List recent deployments
        vercel ls --token placeholder
        
        # List all projects
        vercel project ls --token placeholder
        ```
        
        ## Domains
        
        ```bash
        # List domains
        vercel domains ls --token placeholder
        
        # Add a domain to the current project
        vercel domains add example.com --token placeholder
        ```
        
        ## Environment Variables
        
        ```bash
        # Pull env vars from Vercel to local .env
        vercel env pull --token placeholder
        
        # Add an env var (use echo to pipe the value — avoids interactive prompt)
        echo "value" | vercel env add VAR_NAME production --token placeholder
        ```
        
        ## Common Errors
        
        | Error | Fix |
        |-------|-----|
        | `Error: No framework detected` | Ensure the project has a `package.json` with a `build` script, or set the framework in `vercel.json` |
        | `Error: Rate limited` | Wait and retry. Don't loop — report to user |
        | `Error: You have reached your project limit` | User needs to upgrade Vercel plan or delete unused projects |
        | `ENOTFOUND api.vercel.com` | Network issue. Check proxy connectivity |
        | Auth error after `vercel whoami` | Credential may be expired. Ask the user to refresh the Vercel token in OneCLI |
        
        ## Building Websites — Delegate to Frontend Engineer
        
        When asked to **build, create, or redesign** a website or web app, do NOT build it yourself. You MUST delegate to a Frontend Engineer agent. This is a two-step process and **both steps are required**:
        
        **Step 1 — Create the agent** (skip if you already have a "frontend-engineer" destination):
        
        ```
        create_agent({
          name: "Frontend Engineer",
          instructions: "You are a dedicated frontend engineer. Your frontend-engineer skill has your full workflow. Build what is requested, test it visually with agent-browser, deploy to Vercel, and send back the live URL + screenshots to your parent agent when done."
        })
        ```
        
        **Step 2 — Send the build request** (MANDATORY — do this immediately after step 1):
        
        ```
        send_message(to: "frontend-engineer", text: "<full description of what to build, including design requirements, content, colors, and any assets>")
        ```
        
        ⚠️ **CRITICAL**: If you skip step 2, nothing happens. The agent exists but has no work. You MUST send the message. Do NOT tell the user "it's working on it" until you have actually called send_message.
        
        After sending, tell the user you've handed it off and will share the result when it comes back. The Frontend Engineer will send you the live URL + screenshots when done — forward those to the user.
        
        **When to delegate vs do it yourself:**
        - **Delegate**: building new sites, redesigns, multi-page apps, anything that needs visual testing
        - **Do yourself**: simple `vercel deploy` of an existing project, checking deployment status, managing domains/env vars
        
        ## Best Practices
        
        - Run `pnpm run build` locally before deploying to catch build errors early
        - Use `--cwd` instead of `cd` to keep your working directory stable
        - For Next.js projects, `vercel deploy` auto-detects the framework — no extra config needed
        - Use `vercel.json` only when you need custom build settings, rewrites, or headers
        
  • REMOVE.md 1.5 KB
    # Remove Vercel
    
    Every step is idempotent — safe to re-run. Steps delete the files and config the apply created.
    
    ## 1. Remove the container skill
    
    Delete the copied container skill and its per-group session copies:
    
    ```bash
    rm -rf container/skills/vercel-cli
    for session_dir in data/v2-sessions/ag-*; do
      rm -rf "$session_dir/.claude-shared/skills/vercel-cli"
    done
    ```
    
    ## 2. Remove the dependency guard test
    
    ```bash
    rm -f src/vercel-manifest.test.ts
    ```
    
    ## 3. Remove the OneCLI credential
    
    Delete the Vercel secret and strip its id from every agent's assigned list. `set-secrets` replaces the whole list, so read, filter, and write back per agent:
    
    ```bash
    VERCEL_SECRET_ID=$(onecli secrets list | jq -r '.data[] | select(.name | test("(?i)vercel")) | .id' | head -1)
    if [ -n "$VERCEL_SECRET_ID" ]; then
      for agent in $(onecli agents list | jq -r '.data[].id'); do
        REMAINING=$(onecli agents secrets --id "$agent" | jq -r --arg id "$VERCEL_SECRET_ID" '[.data[] | select(. != $id)] | join(",")')
        onecli agents set-secrets --id "$agent" --secret-ids "$REMAINING"
      done
      onecli secrets delete --id "$VERCEL_SECRET_ID"
    fi
    ```
    
    ## 4. The Vercel CLI in the container image
    
    Remove the `vercel` entry from `container/cli-tools.json` — this skill added it, and it is
    not part of the base image. Then `./container/build.sh` so the image matches the manifest.
    
    ## 5. Restart running containers
    
    So sessions stop loading the removed `vercel-cli` skill on next wake:
    
    ```bash
    docker ps --filter label=nanoclaw-session -q | xargs -r docker stop
    ```
    
  • SKILL.md 5.8 KB
    ---
    name: add-vercel
    description: Add Vercel deployment capability to NanoClaw agents. Installs the Vercel CLI in agent containers and sets up OneCLI credential injection for api.vercel.com. Use when the user wants agents to deploy web applications to Vercel.
    ---
    
    # Add Vercel
    
    This skill gives NanoClaw agents the ability to deploy web applications to Vercel. It installs the Vercel CLI in agent containers and configures OneCLI to inject Vercel credentials automatically.
    
    **Principle:** Do the work — don't tell the user to do it. Only ask for their input when it genuinely requires manual action (pasting a token).
    
    ## Phase 1: Pre-flight
    
    ### Check if already applied
    
    Check if the container skill exists:
    
    ```bash
    test -d container/skills/vercel-cli && echo "INSTALLED" || echo "NOT_INSTALLED"
    ```
    
    If `INSTALLED`, skip to Phase 3 (Configure Credentials).
    
    ### Check prerequisites
    
    Verify OneCLI is working (required for credential injection):
    
    ```bash
    onecli version 2>/dev/null && echo "ONECLI_OK" || echo "ONECLI_MISSING"
    ```
    
    If `ONECLI_MISSING`, tell the user to run `/init-onecli` first, then retry `/add-vercel`. Stop here.
    
    ## Phase 2: Install Container Skill
    
    Copy the bundled container skill into the container skills directory:
    
    ```bash
    rsync -a .claude/skills/add-vercel/container-skills/ container/skills/
    ```
    
    Verify:
    
    ```bash
    head -5 container/skills/vercel-cli/SKILL.md
    ```
    
    ## Phase 3: Configure Credentials
    
    ### Check if Vercel credential already exists
    
    ```bash
    onecli secrets list 2>/dev/null | grep -i vercel
    ```
    
    If a Vercel credential already exists, skip to Phase 4.
    
    ### Set up Vercel API credential
    
    The agent needs a Vercel personal access token. Tell the user:
    
    > I need your Vercel personal access token. Go to https://vercel.com/account/tokens and create one with these settings:
    >
    > - **Token name:** `nanoclaw` (or any name you'll recognize)
    > - **Scope:** "Full Account" — the agent needs to create projects, deploy, and manage domains
    > - **Expiration:** "No expiration" recommended (avoids credential rotation), or pick a date if your security policy requires it
    >
    > After creating the token, copy it — you'll only see it once.
    
    Once the user provides the token, add it to OneCLI:
    
    ```bash
    onecli secrets create \
      --name "Vercel API Token" \
      --type generic \
      --value "<TOKEN>" \
      --host-pattern "api.vercel.com" \
      --header-name "Authorization" \
      --value-format "Bearer {value}"
    ```
    
    Verify:
    
    ```bash
    onecli secrets list | grep -i vercel
    ```
    
    ### Assign the secret to all agents
    
    OneCLI uses selective secret mode — secrets must be explicitly assigned to each agent. Get the Vercel secret ID from the output above, then assign it to every agent:
    
    ```bash
    # set-secrets replaces the entire list — read and merge for each agent.
    VERCEL_SECRET_ID=$(onecli secrets list | jq -r '.data[] | select(.name | test("(?i)vercel")) | .id' | head -1)
    for agent in $(onecli agents list | jq -r '.data[].id'); do
      CURRENT=$(onecli agents secrets --id "$agent" | jq -r '[.data[]] | join(",")')
      MERGED=$(printf '%s' "$CURRENT,$VERCEL_SECRET_ID" | tr ',' '\n' | sort -u | paste -sd ',' -)
      onecli agents set-secrets --id "$agent" --secret-ids "$MERGED"
    done
    ```
    
    ## Phase 4: Ensure Vercel CLI in Container Image
    
    The Vercel CLI is not in the agent image by default — this skill is what adds
    it. It goes in `container/cli-tools.json` as a json-merge rather than a
    Dockerfile edit, which is what keeps the change deterministic and removable.
    
    ```bash
    grep -q '"vercel"' container/cli-tools.json && echo "PRESENT" || echo "MISSING"
    ```
    
    If `MISSING`, append the entry, keeping an exact pinned version — the manifest
    rejects ranges, so the supply-chain policy still applies:
    
    ```json
    { "name": "vercel", "version": "52.2.1" }
    ```
    
    Then apply it:
    
    ```bash
    ./container/build.sh
    ```
    
    On an install that builds its own image, that rebuilds it. On one that fetches a
    published image, the same command adds Vercel as a single layer on top of the
    image already there, so the publisher's patched components underneath are kept —
    you are adding a tool, not replacing the runtime. The command says what that does
    and does not cover.
    
    If `PRESENT`, the CLI is already in the manifest — skip the rebuild.
    
    ## Phase 4b: Copy and Run the Dependency Guard
    
    The Vercel CLI is a globally-installed binary — not importable or typed — so a structural test guards the install. Copy it into the host test tree and run it:
    
    ```bash
    cp .claude/skills/add-vercel/vercel-manifest.test.ts src/vercel-manifest.test.ts
    pnpm exec vitest run src/vercel-manifest.test.ts
    ```
    
    The test asserts both halves of the install: a pinned `vercel` entry in `container/cli-tools.json`, and the container skill at `container/skills/vercel-cli/`. Either alone is a broken install — a manifest entry with no skill leaves the agent a binary nobody told it about, and a skill with no entry tells it to run a command that is not there.
    
    ## Phase 5: Sync Skills to Running Agent Groups
    
    Container skills are copied once at group creation and not auto-synced. After installing or updating a container skill, sync it to all existing agent groups:
    
    ```bash
    for session_dir in data/v2-sessions/ag-*; do
      if [ -d "$session_dir/.claude-shared/skills" ]; then
        rsync -a container/skills/ "$session_dir/.claude-shared/skills/"
        echo "Synced skills to: $session_dir"
      fi
    done
    ```
    
    ## Phase 6: Restart Running Containers
    
    Stop all running agent containers so they pick up the new skills on next wake:
    
    ```bash
    docker ps --filter label=nanoclaw-session -q | xargs -r docker stop
    ```
    
    ## Done
    
    The agent can now deploy web applications to Vercel. Key commands:
    
    - `vercel deploy --yes --prod --token placeholder` — deploy to production
    - `vercel ls --token placeholder` — list deployments
    - `vercel whoami --token placeholder` — check auth
    
    For the full command reference, the agent has the `vercel-cli` container skill loaded automatically.
    
  • vercel-manifest.test.ts 2.3 KB
    /**
     * Dependency guard for the Vercel CLI integration point (host tree, vitest).
     *
     * add-vercel installs the `vercel` CLI into the agent image by appending to
     * `container/cli-tools.json`, and drops its container skill into
     * `container/skills/vercel-cli/`. A globally-installed CLI binary is not
     * importable or typed, so neither `tsc` nor a runtime import can catch its
     * removal — only an image build would, and the skill's validate step does not
     * rebuild the image in CI. This structural test stands in for that leg.
     *
     * It checks both halves, because either alone is a broken install: a manifest
     * entry with no skill leaves the agent a binary it was never told about, and a
     * skill with no manifest entry tells the agent to run a command that is not
     * there.
     *
     * Supersedes `vercel-dockerfile.test.ts`, which asserted an `ARG VERCEL_VERSION`
     * / `pnpm install -g vercel@…` pair in the Dockerfile. That shape stopped
     * existing when cli-tools.json took over the global CLIs, so the old guard was
     * asserting against a file that no longer decides anything.
     */
    import fs from 'fs';
    import path from 'path';
    
    import { describe, it, expect } from 'vitest';
    
    /** Repo root — the dir holding container/, wherever this file is copied to. */
    function repoRoot(): string {
      let dir = __dirname;
      for (let i = 0; i < 8; i++) {
        if (fs.existsSync(path.join(dir, 'container', 'cli-tools.json'))) return dir;
        dir = path.dirname(dir);
      }
      throw new Error('container/cli-tools.json not found walking up from ' + __dirname);
    }
    
    describe('the Vercel CLI is installed in the agent image', () => {
      const root = repoRoot();
      const manifest = JSON.parse(
        fs.readFileSync(path.join(root, 'container', 'cli-tools.json'), 'utf8'),
      ) as Array<{ name: string; version: string }>;
    
      it('appears in the CLI manifest', () => {
        expect(manifest.map((t) => t.name)).toContain('vercel');
      });
    
      it('is pinned to an exact version, so the supply-chain policy still applies', () => {
        const vercel = manifest.find((t) => t.name === 'vercel');
        expect(vercel?.version).toMatch(/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/);
      });
    
      it('ships its container skill, so the agent knows the CLI is there', () => {
        expect(fs.existsSync(path.join(root, 'container', 'skills', 'vercel-cli', 'SKILL.md'))).toBe(
          true,
        );
      });
    });
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related