Skip to content
Development
Command

/setup

Scaffold a new shiploop workspace or upgrade one. Routine bumps -> /update; push fixes upstream -> /push.

From plugin
shiploop
78 skills3 agents8 commands
Install
> /plugin marketplace add anshss/shiploop
> /plugin install shiploop@shiploop

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/setup

Context preview

What this command does when you run it.

Scaffold a new shiploop workspace or upgrade one. Routine bumps -> /update; push fixes upstream -> /push.

Command definition

setup.md
# sonnet on purpose: every judgment-heavy step is delegated to a deterministic script
# (detect-inputs.sh, wrap.sh --preflight/--yes, scaffold.sh) with explicit exit codes,
# so the command itself is orchestration — and per-turn latency is the dominant cost
# of a live onboarding (a measured run spent ~7 min on model turns vs ~30s in tools).
model: sonnet
effort: medium
description: Scaffold a new shiploop workspace or upgrade one. Routine bumps -> /update; push fixes upstream -> /push.

You are the meta-repo setup command. You convert the current folder into — or upgrade an existing — **meta-repo workspace**: an npm/pnpm/yarn/bun root (`ROOT_PM`, operator's choice) wrapping N independent git sub-repos, with cross-cutting tooling, parallel worktrees, a ticket queue, a governor (autonomous ticket loop), and the SessionStart/End/Stop hooks.

The full pattern is documented in the plugin's `SKILL.md` (read if you need context). All mechanical file writes are executed by `scaffold.sh` — you own the interview and judgment; it owns byte-level writes, deterministically and idempotently.

Locate the plugin

Templates and `scaffold.sh` live together. Resolve `PLUGIN_ROOT` in priority order: 1. `${CLAUDE_PLUGIN_ROOT}` (plugin run) 2. `~/.claude/skills/shiploop/` (legacy clone-into-skills) 3. `~/.claude/plugins/**` cache lookup by plugin name

`SCAFFOLD=$PLUGIN_ROOT/scaffold.sh`.

Architecture (read once)

Every mechanism script sources ONE config file, `scripts/lib/workspace.sh` (repo names, dev commands, ports, GitHub org, worktree base, merge-allowlist). Mechanism scripts are therefore identical across installs — a bump just refreshes them from templates and only ever (re)generates `workspace.sh`. **Never hand-edit a mechanism script; put the value in `workspace.sh`.**

Interview doctrine — ONE pause

1. **Detect first, ask second.** Run EVERY detection (mode, sub-repos, ports, dev commands, org, root PM, worktree base, visibility) AND — in wrap mode — `wrap.sh --preflight` BEFORE the first question. Preflight is read-only and surfaces every `REFUSE`/`NEEDS-CONFIRM` item up front. 2. **One batched interview.** Ask everything in a SINGLE `AskUserQuestion` call (4-question limit is enough — see per-mode specs below). Print the detected-defaults table BEFORE the call; detected values aren't questions — override via "Other". 3. **Then run to completion without pausing.** Legitimate post-interview stops are ONLY: wrap.sh exit 1 (rolled back), exit 4 (name collision preflight missed), or a NEW exit-5 item preflight could not have seen. Never re-ask something the interview covered.

Workspace layout scaffold.sh produces:

<root>/
  package.json            scripts/lib/workspace.sh        queue/tickets.md
  .gitignore              scripts/lib/{workspace,session-state,preflight,githooks}.sh
  .worktrees/.gitkeep     scripts/{doctor,dev,sync,tail}.sh   queue/tickets-parked.md
  governor/*.md           scripts/{check-main-on-main,ticket-sweep-reminder,session-snapshot,router-posture-*}.sh
  .claude/settings.json   scripts/worktree/*  + worktree/lib/registry.sh
  .claude/commands/*.md   scripts/govern/*    + govern/lib/common.sh
  CLAUDE.md               learnings.md                    .githooks/{pre-push,prepare-commit-msg}
  README.md               (workspace landing page — "<name> on Shiploop"; never overwritten)

---

Phase 0 — Detect the mode

Print `── meta-repo setup ──`, then `pwd` and `ls -la`.

WRAP="$PLUGIN_ROOT/templates/lib/wrap.sh"
MODE="$(bash "$WRAP" --detect --workspace-dir "$(pwd)")"
echo "mode: $MODE"

| `$MODE` | Context | Do | |---|---|---| | `upgrade` | `scripts/lib/workspace.sh` present | **BUMP MODE** → Phase B | | `fresh` | not inside any git repo | **FRESH MODE** → Phase 1 | | `wrap` | AT the root of a git repo, `.git` is a directory | **WRAP OFFER** → Phase W | | `refuse:gitfile` | `.git` is a FILE (linked worktree/submodule) | STOP — wrapping corrupts the main repo's back-pointers; out of scope for v1 | | `refuse:below-root` | inside a git repo, below its root | STOP — "cd to the repo root and re-run" (print root path) | | `refuse:bare` | bare repository | STOP — nothing to wrap |

`fresh` with **zero** sub-repos detected in Phase 1 does not stop — it routes to **Phase G** (greenfield), which materializes the first sub-repo itself.

Back-compat: an older meta-repo predating `scripts/lib/workspace.sh` but with a `package.json` whose `"doctor"` script is `"bash scripts/doctor.sh"` is still **upgrade** even though `--detect` returns `fresh` — treat as BUMP MODE (scaffold.sh re-parameterizes the core scripts). Very old installs also carry the retired `"status"`/`"branch"`/`"switch"`/`"pull"`/`"push"`/`"health"` aliases; scaffold's purge removes the scripts they point at, so drop those lines from `package.json` in the same pass.

Phase W — Wrap-in-place (`$MODE == wrap`)

Gather everything first (W0), then run the single interview (W1). Do NOT ask anything before W1.

W0 — Detect + preflight (ONE combined bash call)

Chain detection and preflight in a SINGLE call — don't hand-run per-value probes or split turns:

DET="$(bash "$PLUGIN_ROOT/templates/lib/detect-inputs.sh" --workspace-dir "$(pwd)" --mode wrap)"
printf '%s\n' "$DET"     # root_pm= / worktree_base= / org= / repo=<NAME>|<port>|<cmd>|<visibility> / repos_spec=
NAME="$(printf '%s\n' "$DET" | sed -n 's/^repo=\([^|]*\).*/\1/p' | head -1)"
bash "$WRAP" --preflight --workspace-dir "$(pwd)" --name "$NAME"   # read-only; surfaces every REFUSE / NEEDS-CONFIRM

`repo=` carries the wrap subfolder name (`NAME`, from `origin` else folder name — where the repo lands: `<path>/<NAME>/`), its port + dev command, and visibility (`PUBLIC` unlocks auto-externalization; `unknown` = no `gh`, treat as private). Only override a detected value you can SEE is wrong.

Preflight is fail-closed; a single **prunable** worktree no longer refuses (auto-pruned), only LIVE linked work

Read more
Ships withshiploop

A harness for Claude Code. It changes what runs: which model, with what context, how many in parallel, so the same work ships on fewer tokens.

Get the whole plugin
Stats
7
Stars
0
Forks
Active
Maintenance
Shell
Language
Apache-2.0
License
1d ago
Last commit
4mo ago
Created

Repo: anshss/shiploop

Other commands on shiploop.

bench
Command

bench

Print the published shiploop benchmark result (backlog and arms named) and the exact command to run a fresh with-shiploop-vs-without-shiploop A/B locally.…

@anshss@anshssView Command