Browse Ship docs
Ship docs
Ship docsshipctl — the local CLI

shipctl — the local CLI

Audience

This page is for the engineer who sits next to the product owner — the person who runs commands in the repo to wire it up, keep it in sync, and unstick it when CI complains. The product owner does not need to read this; they need to know it exists so they can hand it to you.

shipctl is published as @elmundi/ship-cli. The binary is shipctl. It is read-only from the server's point of view in the sense that the server's source-of-truth state is mutated only through the workspace runner — the CLI never bypasses that path. It exists to give the repo a useful local life: setup, sync, diagnostics, knowledge reads from inside an agent run, and a clean way to draft feedback against catalog artifacts.

Install

npm install -g @elmundi/ship-cli
# or one-off
npx @elmundi/ship-cli help

Requires Node.js 20 or newer. After install, shipctl --version should print the package version.

First-time setup in a repo

The wizard is shipctl init. Always preview first:

npx @elmundi/ship-cli init --dry-run

The dry run prints what would be written without touching the working tree. When the preview looks right:

npx @elmundi/ship-cli init --yes \
  --agents cursor,codex \
  --tracker github-issues \
  --ci gh-actions \
  --preset web-app \
  --copy-rules

That creates .ship/, writes .ship/config.yml, fetches the artifact bundle, installs the agent rules into the targets your --agents flag named, and stamps the lockfile. Run shipctl verify afterwards to confirm the repo is wired correctly.

Core commands

CommandUse
shipctl doctorCheap health checks. Agent rule files installed? Config valid? Lock fresh? Network reachable? Run this first when something feels off.
shipctl verifyHeavier post-adoption checks. Artifact contract, marker drift, network/provider reachability. The CI gate.
shipctl syncRefresh catalog artifacts into .ship/cache/. Pass --lock to write a lockfile.
shipctl configshow / validate / get / set / init / path for .ship/config.yml.
shipctl initBootstrap .ship/, fetch artifacts, install agent rules. Use --dry-run first.
shipctl pattern | tool | collectionList, show, fetch, or search artifact bodies.
shipctl searchSearch over docs and prompts.
shipctl knowledge fetch <slug>Read a workspace bucket's articles and sync state. This is the agent's read path.
shipctl runThe per-stage agent entry-point. Invoked by Ship's ship-agent-run.yml workflow when the server dispatcher pins a ticket to a routine. Resolves the specialist, fetches the FSM-staged ticket, launches the agent runtime, pushes commits + opens the PR (--commit-and-pr).
shipctl triggerLegacy cron picker (pre-E16). Retained for manual/offline use; the live dispatch path is now server-side (tracker poll → dispatcher → ship-agent-run.yml), so you rarely call this directly.
shipctl feedbackLocal markdown drafts. Submitting one creates a tracked issue against a cited artifact.
shipctl telemetryOpt-in usage telemetry. Default off.

Run shipctl <command> --help for the exact flag surface — flags evolve faster than this page.

Configuration

The CLI reads .ship/config.yml from the repo root. The file records stack hints, the workspace API base, artifact pins, telemetry preference, cache behaviour, and the process.routines wiring that maps states to specialists.

Inspect with shipctl config show. Validate with shipctl config validate. Edit by hand and re-validate. Never check .ship/config.yml in with stale shipctl_min — the CLI will refuse to run.

Auth

  • SHIP_API_TOKEN — bearer PAT minted at /settings. Required for any command that talks to the workspace API. Never commit it.
  • SHIP_WORKSPACE_ID — optional. Skips the workspace lookup when the token has access to more than one.

Base URL resolution: --base-url flag, then SHIP_WORKSPACE_API_BASE, then SHIP_API_BASE, then https://api.ship.elmundi.com. The CLI deliberately does not read SHIP_RUN_TOKEN — that is a short-lived pipeline handle, not a user PAT.

Knowledge from inside an agent run

Inside a routine, the agent calls shipctl knowledge fetch to pull a bucket's articles into context:

shipctl knowledge fetch code-style
shipctl knowledge fetch security --workspace ws_abc123
shipctl knowledge fetch release-procedure --json | jq '.articles[].title'

The command fetches the bucket header, every published article, and the sources list. With --json you get machine-readable output; without, a plain text dump that an LLM can consume directly.

Exit codes:

  • 0 — bucket fetched.
  • 1 — argument or config error.
  • 2 — auth error (401). Mint or rotate SHIP_API_TOKEN.
  • 3 — network or HTTP 5xx after retries.

The retry policy covers 502 / 503 / 504 and network errors with three attempts and exponential backoff. 4xx errors and other 5xx exit on the first attempt — fail fast on real bugs.

Feedback drafts

Feedback is how an engineer escalates "this artifact is wrong" to the artifact's owners.

shipctl feedback draft --kind collection --id role-developer \
  --title "duplicate-PR class regression on cloud agent runs" \
  --summary "the developer prompt encourages opening a PR before checking …"

The draft is a local markdown file under .ship/feedback-drafts/. Edit it (the CLI will open $EDITOR if set), iterate, then submit:

shipctl feedback list
shipctl feedback show .ship/feedback-drafts/2026-05-15-...md
shipctl feedback submit .ship/feedback-drafts/2026-05-15-...md

Submission posts the draft to the workspace API, which opens a tracked issue against the cited artifact and moves the draft to .ship/feedback-drafts/sent/. The issue URL is printed to stdout. If the same artifact already has an open ticket for the same class of feedback, the submission is deduplicated and added as a comment — the CLI tells you.

CI integration

Use shipctl verify as the gate. In offline CI, commit the cache or narrow checks:

shipctl verify --no-network

Warnings do not fail by default; failures do. Treat warnings as review prompts, not as proof the setup is broken — the framework is intentional about that distinction.

Agent dispatch itself is no longer driven from CI cron: Ship's backend polls the tracker (~every 5 min), and when a ticket becomes eligible for a stage the dispatcher fires the seeded ship-agent-run.yml workflow for that one (routine, ticket) pair, which runs shipctl run. You can still fire a single routine+ticket by hand via the workflow's workflow_dispatch debug inputs.

Telemetry

Off by default. Opt in with shipctl telemetry on. The CLI emits a small, bounded set of operator-facing events — artifact fetch, artifact use, doctor result, feedback submit — to your workspace's own backend. Events are anonymous, do not name humans, and never carry customer data. Forwarding to the shared Ship telemetry endpoint is a separate decision in .ship/config.yml. Inspect with shipctl telemetry status; disable with shipctl telemetry off.

When to reach for shipctl

  • A new repo needs onboarding → shipctl init --dry-run, then init --yes.
  • The agent rule files drifted → shipctl doctor, then shipctl sync.
  • CI is green but the bundle looks stale → shipctl verify.
  • You suspect a class regression in an artifact → shipctl feedback draft ….
  • An agent run is failing to read knowledge → shipctl knowledge fetch <slug> from your shell and read what comes back.

If the command does not exist, that is intentional. The console handles workspace state. The CLI handles the repo.

shipctl — the local CLI — Ship docs — Harbor Gang