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
| Command | Use |
|---|---|
shipctl doctor | Cheap health checks. Agent rule files installed? Config valid? Lock fresh? Network reachable? Run this first when something feels off. |
shipctl verify | Heavier post-adoption checks. Artifact contract, marker drift, network/provider reachability. The CI gate. |
shipctl sync | Refresh catalog artifacts into .ship/cache/. Pass --lock to write a lockfile. |
shipctl config | show / validate / get / set / init / path for .ship/config.yml. |
shipctl init | Bootstrap .ship/, fetch artifacts, install agent rules. Use --dry-run first. |
shipctl pattern | tool | collection | List, show, fetch, or search artifact bodies. |
shipctl search | Search 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 trigger | CI entry-point. Compute due routines and claim each schedule window. |
shipctl run | Spawned per routine by shipctl trigger. Resolves a pattern, fetches a ticket if FSM-staged, launches the agent runtime. |
shipctl feedback | Local markdown drafts. Submitting one creates a tracked issue against a cited artifact. |
shipctl telemetry | Opt-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 rotateSHIP_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.
shipctl trigger is the workflow entry-point. It is invoked by your scheduler (GitHub Actions, Cloud Build, whatever your stack uses), and it spawns shipctl run once per routine that is due.
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, theninit --yes. - The agent rule files drifted →
shipctl doctor, thenshipctl 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.