CLI commands

Exact setup and doctor commands, flags, environment inputs, effects, checks, and exit behavior.

Installing @cavuno/board adds the cavuno-board binary. It has exactly two verbs:

text
cavuno-board <setup|doctor>

Run it through the package or binary name:

bash
npx @cavuno/board setup
npx @cavuno/board doctor

An omitted or unknown verb prints the usage line and exits 1.

setup

bash
npx @cavuno/board setup

Setup reads the current directory and the package’s shipped skill manifest. It does not create application routes, source files, environment files, or a Board SDK client.

Framework detection

The current detector reads dependencies and devDependencies from the project’s package.json:

  • @tanstack/react-start present → tanstack-start.
  • Anything else, including no package.json → no detected framework.

Setup always selects core skills. It also selects the flavor whose manifest framework matches the detected value. Other framework wiring remains a manual documentation task until a matching flavor ships.

Target directories

Setup checks these roots:

  1. .agents/skills
  2. .claude/skills
  3. .codex/skills
  4. .cursor/skills

If any exists, the corpus is copied to every existing root. If none exists, setup creates .agents/skills. Each selected cavuno-board-* directory is created and copied recursively. Re-running overwrites matching versioned skill files and does not intentionally touch unrelated skills.

The output lists:

  • Installed package/manifest version.
  • Detected framework or none (core skills only).
  • Target roots and unique copied skill names.
  • The required PUBLIC_CAVUNO_BOARD value and optional PUBLIC_CAVUNO_API_URL override as next-step instructions.

Setup only prints those environment variables; it does not write them.

Verify setup

bash
test -f .claude/skills/cavuno-board-setup/SKILL.md || \
test -f .codex/skills/cavuno-board-setup/SKILL.md || \
test -f .cursor/skills/cavuno-board-setup/SKILL.md || \
test -f .agents/skills/cavuno-board-setup/SKILL.md

Run setup again after every SDK upgrade. Doctor compares installed SKILL.md content with the corpus shipped by the currently installed package.

doctor

bash
npx @cavuno/board doctor [--frontend <url>] [--sandbox]

Doctor reads the current working directory and these environment variables:

VariableRequiredEffect
PUBLIC_CAVUNO_API_URLNoAPI-origin override. Default: https://api.cavuno.com. Use only when Cavuno supplies another environment.
PUBLIC_CAVUNO_BOARDYesDoctor requires a publishable key in the exact form pk_ plus 32 hexadecimal characters. Unlike the runtime client, doctor does not accept a board ID or slug.
RESEND_API_KEYOnly for one platform sandbox checkLets the email-boundary probe confirm that registration produced a verification send. Without it, that check skips loudly.

Tier 1 — static and API checks

These run on every invocation:

  • env.api-url: the default or explicit override is a valid URL.
  • env.board-key: key has the exact publishable-key shape.
  • static.api: {apiBase}/v1/openapi.json returns a JSON object with an OpenAPI version string.
  • static.board: /v1/boards/{key} resolves to JSON board context, including for a password-protected board.
  • static.skills: installed Cavuno skill files match the current package corpus. Missing skill roots or no installed Cavuno skills are reported as skipped, not passed.
  • static.theme: when src/tokens.css exists, its SHA-256 hash must match src/theme/resolved.ts and the board context’s platform snapshot. A non-migrated project without the token file skips this check.

--frontend <url> — tier 2 reads

bash
npx @cavuno/board doctor \
--frontend https://jobs.example.com

The flag adds five deployed frontend checks:

  • read.home: the root returns successful HTML.
  • read.jobs: /jobs contains a canonical /companies/{company}/jobs/{job} detail link.
  • read.jsonld: the first linked detail page contains parseable JobPosting JSON-LD.
  • read.sitemap: /sitemap.xml parses, a child sitemap is followed when necessary, and a sample page resolves.
  • read.robots: /robots.txt contains a User-agent directive.

The frontend base is used for probes even when sitemap <loc> values contain the production canonical host. Without --frontend, all five checks remain visible as skipped.

--sandbox — tier 3 writes

bash
PUBLIC_CAVUNO_BOARD=pk_0123456789abcdef0123456789abcdef \
npx @cavuno/board doctor --sandbox

--sandbox opts into these write checks:

  1. Confirm the resolved board context has sandbox: true.
  2. Register one generated candidate and log in with the same credentials.
  3. If RESEND_API_KEY exists, poll the platform Resend account for the verification send.
  4. Apply as that candidate to the first job returned by the sandbox.
  5. Create an anonymous, consented job-alert subscription.

Doctor refuses the entire write tier when the board is not the platform sandbox. The remaining write checks then skip. Probe data is not cleaned up; the platform sandbox is reset separately.

Registration can hit its server rate limit after repeated runs. Doctor reports that failure and advises waiting rather than claiming the downstream checks passed.

Exit and output behavior

Every check prints an ID, tier, status mark, and detail. The summary lists passed, failed, and skipped IDs.

  • Exit 0: no check failed. Skips can still be present and are printed as “NOT verified.”
  • Exit 1: one or more checks failed.
  • Exit 1: doctor crashed before producing a normal summary.
  • Setup returns 0 when copying completes; filesystem or manifest failures terminate non-zero.

Skipped checks never count as passes or failures. A zero exit therefore means “everything that ran passed,” not “every tier ran.”

bash
npx @cavuno/board setup
npx @cavuno/board doctor --frontend https://preview.jobs.example.com

Use --sandbox only in a separate run pointed at the platform sandbox key. See Run doctor for the release workflow.