CLI Reference¶
New here?
docs/concepts.mdexplains how WorkItem / Spec / Plan / Task / worktrees / agents relate, with diagrams.
All task-scoped commands (status, phase, test, journal, view …, etc.) resolve their target task in this priority order:
--task <slug>flag — explicit, highest priority.MSHIP_TASKenv var — scope a whole shell session to one task.- cwd — if your shell is inside a task's worktree, that task is the default.
With 0 active tasks the command errors with "no active task". With exactly 1 active task and no anchor, the command targets that task. With 2+ active tasks and no anchor you'll get an "Ambiguous" error listing the active slugs — fix by anchoring via any of the three mechanisms above.
Lifecycle¶
mship init [--detect | --name N --repo PATH:TYPE] # scaffold mothership.yaml
mship init --install-hooks # (re)install Git hooks plus lifecycle integrations:
# Claude at workspace .claude/settings.json;
# Codex and OMP in every configured Git root:
# .codex/hooks.json (review via Codex /hooks)
# .omp/extensions/mship.ts
# Commit project artifacts so worktrees inherit them.
# Main-edit bypass: MSHIP_ALLOW_MAIN_EDIT=1.
mship spawn "description" (--work-item <id> | --hotfix) [--repos a,b] [--skip-setup] [--bypass-reconcile]
# --work-item <id> required (create via `mship item new`);
# bypass the gate with --hotfix. Also: --depends-on, --base, --slug.
mship switch <repo> # cross-repo context switch
mship phase plan|dev|review|run [-f] # transition with soft-gate warnings
mship block "reason" | mship unblock
mship test [--all] [--repos|--tag] [--no-diff]
mship journal [-] # read task log; pass message to append
mship journal "msg" [--action X] [--open Y] [--repo R] [--test-state pass|fail|mixed]
mship journal --show-open # list open questions
mship finish [--body-file PATH | --body TEXT] [--base B] [--base-map a=B,b=B] [--push-only] [--handoff] [--force-audit] [--bypass-reconcile] [--force]
mship close [--yes] [--abandon] [--force] [--skip-pr-check] [--bypass-reconcile]
mship commit "message" [--task <slug>] # commit staged changes across the task's worktrees; pushes if finished
mship depends add|remove|list # manage task-to-task dependency edges (#104)
mship init --install-hooks writes the project-local Codex hook files, but it
does not enable Codex features or trust the project. If setup reports the hook
capability as disabled or unavailable, run codex features enable codex_hooks.
Then open /hooks in Codex to review and trust the project hooks. Trust remains
a manual action even when the capability is already enabled.
mship doctor reports these boundaries separately: whether the project hook
artifact is valid, whether the Codex hook feature capability is enabled, and
whether manual project trust remains unresolved. A current registration is
therefore configured but untrusted, not reported as fully active.
Entry point — spawn vs. spec dispatch:
mship spawnstarts an ad-hoc task directly, but for spec-driven work you don't call it first.mship spec dispatch <id>(see Work items & specs below) is the entry point: it binds an approved spec and spawns its own task. Runningspawnand thenspec dispatchagainst the same spec double-creates tasks (#296). Rule of thumb: have an approved spec →spec dispatch; ad-hoc chore/bug →spawn.
Setup & admin¶
mship bootstrap [--repos a,b] [--token TOK] # clone missing workspace members (fresh clone -> full workspace)
mship skill install|list [--only claude,codex,gemini,omp,pi] [--force] [-y] # pi is the canonical alias for omp
mship gh preflight # fail-fast check that GitHub auth covers the workspace repos
mship bind refresh # re-sync bind_files + symlink_dirs from source repos into worktrees
mship layout init|launch # write / launch the mothership zellij layout
Codex and OMP/Pi use the same user-level .agents/skills/mothership link to
the bundled skills; installing both does not create a second copy. Install
safe-skips foreign links, files, and directories unless --force is explicit.
mship doctor reports OMP skill discovery independently from project lifecycle
extension compatibility and recommends mship skill install --only omp (plus
--force for foreign content) when repair is needed.
mship relay manages reverse-tunnel client keys and relay-owner state (for
mship serve --relay, see relay-hosting.md). Every
relay-owner command uses the same explicit <store> as enroll-server:
mship relay setup # generate the client relay SSH key
mship relay enroll # request relay access from a new device
mship relay enroll-server --store-dir <store> ... # run the public endpoint on the relay host
mship relay requests --store-dir <store> # list pending enrollment requests
mship relay approve <id> --store-dir <store> --pubkeys-dir <pubkeys>
mship relay deny <id> --store-dir <store>
mship relay fleet-token --label phone --relay-domain <relay> --store-dir <store>
mship relay hosts --store-dir <store> # list the daemon host directory
Work items & specs¶
A work item is the durable unit of intent (feature/bug/chore/question) that a task implements; a spec is its approved design and a plan is its implementation breakdown. Feature work items gate phase dev/finish on BOTH an approved linked spec AND a linked/discovered implementation plan (bugs and chores need neither).
mship item new "title" --kind feature|bug|chore|question # create a work item
mship item list [--all] # list work items (--all includes archived)
mship item show <id> # detail incl. linked spec/tasks
mship item phase <id> <phase> # move the item through its lifecycle
mship item link-spec|link-task|link-url <id> <ref> # attach a spec, task, or URL
mship item link-plan <id> <path> # attach an implementation plan doc (feature plan-gate)
mship item archive|unarchive <id> # soft-hide / restore
mship spec new --title "title" # create a spec (lands in needs_review)
mship spec draft <id> [--from-text "..."] # emit an authoring prompt for an agent
mship spec apply <id> --from-json <file> # populate the spec from JSON
mship spec review <id> | mship spec show <id> # read a spec
mship spec verdict <id> <criterion> <verdict> # record a per-criterion review verdict
mship spec request-changes <id> --reason "..." # send a spec back with a reason
mship spec approve <id> # mark approved (unblocks dev/finish)
mship spec dispatch <id> [--task <slug>] # bind an approved spec to a task + emit handoff
mship spec list # list specs
Specs live at <workspace>/specs/<date>-<id>.md. Lifecycle: new → draft → apply → review → approve → dispatch.
Plans are first-class too. A feature work item can't enter dev or finish without a valid implementation plan — either linked via mship item link-plan or discovered at <docs_dir>/plans/<date>-<slug>.md (what the writing-plans skill produces), and containing at least one task block. Bypass with mship phase dev --bypass-plan-gate or mship finish --hotfix. Build dispatch is plan-driven: once a plan is linked, mship dispatch --task <slug> --plan-task N mints the implementer prompt from the plan (no --plan needed), and mship spec dispatch points the build at the plan's tasks instead of re-deriving from the spec.
Messaging & serve¶
mship serve exposes a JSON API over the spec + task model (reads plus review/approve writes) — the backend for the Ground Control app and remote agents. The mailbox is a durable store-and-forward channel between a phone and an agent.
mship serve [--relay] [--port N] # run the JSON API over the spec/task model (+ mailbox)
mship inbox wait [--since TS] [--timeout S] # block until a new human message arrives (JSON)
mship reply <thread_id> "text" # reply to a mailbox thread
mship ask <thread_id> "question" --option A --option B # post a decision (>=2 tappable options; --recommend/--multi/--no-free-text)
mship messages <thread_id> # print a mailbox thread's conversation in order
mship pair # print a pairing deep-link + QR to connect the Ground Control app
Inspection¶
mship status # task, phase, branch, drift, last log, finished warning
mship context # one-shot agent-readable JSON snapshot of workspace state
mship dispatch --task <slug> -i "<instruction>" # emit self-contained subagent prompt to stdout (default: implementer framing — report back, no PR)
mship dispatch --task <slug> --mode standalone -i "<instruction>" # standalone framing — subagent finishes and opens its own PR
mship audit [--repos r] [--json]
mship reconcile [--json] [--ignore SLUG] [--clear-ignores] [--refresh]
mship pr # PR state for every active task with recorded PR URLs
mship debug hypothesis "..." | rule-out "..." | resolved # structured debugging journal entries (#30)
mship view status|journal|diff|spec [--watch]
mship view spec --web # serve rendered spec on localhost
mship graph
mship worktrees
mship doctor [--no-network] # workspace health; --no-network skips connectivity probes
mship net status [--no-network] # connectivity topology: serve, relay, run hosts, gh auth, egress
mship ui [--no-browser] [--host h] [--port p] # open the serve-host console (opens a browser, else prints a copyable link)
The console has three pages: /ui (connectivity topology, worst-first,
self-refreshing), /ui/doctor (the full mship doctor report), and /ui/pair
(a pairing QR — on its own page because a pair link embeds the serve token, so
that page displays a credential).
The console lives at /ui on the serve host. When the serve runs with auth (any
relay setup does), a browser cannot send the bearer header from its address bar —
so visit it once via mship ui, which builds /ui?token=<serve token>; the
console exchanges that for a short-lived cookie and cleans the URL. GET
/net/topology continues to accept only the Authorization header.
Maintenance¶
mship sync [--repos r] # fast-forward behind-only clean repos
mship prune [--force] # remove orphaned worktrees
mship export [--redacted] [--format dir|zip] # bundle a task's journal/plan/spec/state/diffs (opt-in secret redaction)
Long-running services¶
mship run [--repos a,b] [--tag t] # start services per dependency tier
mship logs <service> # tail logs for a service
mship run-host add|list|remove # manage per-machine run-host connections (role -> {url, token})
mship build [--all] [--repos a,b] [--tag t] [--remote[=role]] # `task build` across repos in dependency order
mship capture [--repo R] [--platform P] [--kind image|layout|all] [--out DIR] [--remote[=role]]
# screenshot + layout of the running UI into files;
# task-aware but not required (ad-hoc against a repo's main checkout)
mship build and mship capture accept --remote to execute on a mapped run-host role (an iOS-sim / Android-emu machine): bare --remote auto-resolves the repo's run_host (or the sole configured run_hosts entry), --remote=<role> picks one explicitly.
mship finish¶
PR body¶
mship finish rejects empty PR bodies. Two ways to provide one:
mship finish --body-file /tmp/pr-body.md # read from file
echo "..." | mship finish --body-file - # read from stdin
mship finish --body "inline text" # inline (also supports `-` for stdin)
A TTY guard on both - forms errors fast if stdin is an interactive terminal instead of hanging.
PR base branch¶
Each repo's PR can target a non-default base. Resolution order (most-specific wins):
--base <branch>— global override for all repos.--base-map cli=main,api=release/x— per-repo overrides.base_branchin the repo'smothership.yamlentry.- Remote default branch.
mship finish verifies every resolved base exists on origin before any push.
--force vs normal re-finish¶
mship finish is idempotent: a second run after finished_at is stamped is a no-op. To push additional commits to the existing PRs (e.g., reviewer feedback), use mship finish --force. It pushes, updates finished_at, writes a re-finished journal entry, and does NOT create a new PR or modify the existing body. Edit the body separately via gh pr edit <url> --body-file <path>.
Drift audit & sync¶
Issue codes¶
- Errors (block
spawn/finish):path_missing,not_a_git_repo,fetch_failed,detached_head,unexpected_branch,dirty_worktree,no_upstream,behind_remote,diverged,extra_worktrees. - Warnings (don't block):
dirty_untracked(untracked files only). - Info-only:
ahead_remote.
Per-repo policy¶
repos:
schemas:
path: ../schemas
expected_branch: marshal-refactor
allow_dirty: false
allow_extra_worktrees: false
Workspace policy¶
audit:
block_spawn: true
block_finish: true
Commands¶
mship audit [--repos r1,r2] [--json]— exit 1 on any error-severity drift.mship sync [--repos r1,r2]— fast-forwards behind-only clean repos.mship spawn --force-audit/mship finish --force-audit— bypass with a line logged to the task log.
Live views¶
mship view provides read-only TUIs designed for tmux/zellij panes. All views support --watch and --interval N.
mship view status [--task <slug>] [--watch]— all tasks stacked by default;--tasknarrows to one.mship view journal [--task <slug>] [--watch]— tail the task's journal.mship view diff [--task <slug>] [--watch]— per-worktree git diff.mship view spec [name-or-path] [--task <slug>] [--watch] [--web]— cross-task spec index picker by default.
Keys: q quit, j/k or arrows to scroll, PgUp/PgDn, Home/End, r force refresh.