Skill v1.0.1
Automated scan100/100+1 new
version: "1.0.1" name: run description: Use when the user wants to bring up a corgi-compose stack — start, launch, run, spin up, or boot the whole stack or a slice (e.g. "run the stack", "run with tunnel and logs", "run web + mobile against the remote backend", "run just the api", "run for the android emulator"). Boots detached, waits until healthy with a timeout, flags anything stuck, reports URLs + how to stop. NOT for authoring corgi-compose.yml (use the corgi skill), shipping tickets/features (stories), or diagnosing an already-broken stack (use the debug skill).
Corgi run
Bring up a corgi stack — or a slice — from chat. Boot detached, wait until healthy (timeout), flag stuck, report URLs + how to stop. What runs and how = read from the repo (corgi-compose.yml, Makefile, README); never hard-coded, never company-specific.
Guardrails (non-negotiable)
- Detached only — never a synchronous foreground `corgi run`. Blocks
indefinitely streaming logs; a sync Bash call hangs until the 10-min timeout and truncates boot output. Use --detach; on a cold stack launch with run_in_background: true (Phase 2). See ../corgi/references/long-running.md.
- Never start a service the user wants pointed remote — a local run overrides
the remote URL.
- Don't `--force`/`restart` a live run without asking —
corgi psfirst. - Diagnosis = the debug skill. Boot + quick stuck-triage here; real
investigation → debug.
Phase 0 — Locate + first-run preflight
cwd must hold corgi-compose.yml (ls corgi-compose.yml *.corgi-compose.yml). None → tell the user to open the stack folder; don't guess a layout. Read only needed keys — services.<name>.{path,cloneFrom,depends_on_services,depends_on_db,start,port, tunnel,manualRun,runner}, db_services, envTiers, useAwsVpn, useDocker, init, required (schema: ../corgi/references/yml-schema.md).
- First run → `corgi init` first.
corgi runclones missing repos + runs the
compose-level beforeStart, but NOT the init: block (env gen, config copy) or required: installs — those run only on corgi init. Most stacks: run target = corgi init && corgi run. Service dirs missing OR env files / generated config absent → corgi init first (cold machine = long: clones + installs).
- corgi auto-handles VPN + Docker. Compose sets
useAwsVpn/useDocker(or any
service uses the docker runner) → corgi run starts VPN + Docker itself in preflight. Don't add a manual VPN/docker step.
Phase 1 — Resolve intent → command
Sources, priority: `corgi-compose.yml` authoritative (services/dbs/tunnels/tiers
- each
start:); `Makefile` targets = the team's named shortcuts
(grep -E '^[a-zA-Z][a-zA-Z0-9_-]*:' Makefile); `README` = remote URLs + host quirks. Match the user's words → translate to a detached command.
| Intent | Command | |
|---|---|---|
| Whole stack | corgi run --detach | |
| A subset | corgi run --services <a,b> --detach (--with-deps pulls each one's deps + dbs) | |
| Frontend(s) → remote backend | corgi run --services <frontends> --dbServices none --detach. Backend excluded → its depends_on_services alias is not generated — the frontend uses ONLY its own env file. Read that env file (Read the frontend's source .env) and confirm the API URL is the remote one, not a localhost default corgi init seeded; if localhost, user sets the remote URL there before you declare success. (Don't use corgi env <frontend> for this — it ignores the run set and annotates vars with depends_on sources for the backend you excluded, so it misleads.) | |
| Captured logs | on by default; --logs=false opts out | |
| + webhook tunnel | can't combine with --detach — see Tunnel, Phase 2 | |
| Staging/prod tier | --tier <name> if envTiers: defines it; else the repo's run<X>Staging make target's underlying corgi command (tier run usually --dbServices none — no local dbs) | |
| One DB only | corgi run --dbServices <name> --services none --detach |
Names match compose keys exactly. --services/--dbServices = exact-name match. A Makefile target may pass a non-key name (e.g. --dbServices supabase when the key is <name>-supabase → selects nothing, stack boots with a dead db URL). Resolve every name against corgi-compose.yml keys; or --with-deps to let corgi resolve the db closure from depends_on_db instead of hand-listing.
Omitting a dependency from a hand-picked slice hard-fails preflight with E_DANGLING_DEP: service "<x>" depends on unknown service/db_service "<y>" — corgi validates the whole selected graph, and --services/--dbServices do not auto-pull what the named services depends_on. Don't chase it by hand-listing every dependency; corgi run --services <x> --with-deps --detach resolves the full depends_on closure (services + their dbs) in one command. A runOnly<X> make target that hand-lists --dbServices … --services <x> without --with-deps dangles the moment <x> gains a new depends_on — prefer --with-deps.
Carry the Makefile target's env-var prefix verbatim. WEB_DEV_CMD=dev:host MOBILE_PLATFORM=android corgi run --services … sets process env vars a service's start: reads (yarn ${WEB_DEV_CMD:-dev}, bun ${MOBILE_PLATFORM:-ios}). corgi can't inject these (sources only the env file), so dropping the prefix silently changes behavior — and corgi env won't show them (process env, not env-file). Grep the matched start: for ${VAR placeholders; reproduce every prefix the target sets.
Host (mobile/device/emulator). Default localhost. corgi run --host <ip> = blanket replace of every localhost in the service's generated .env — the API URL AND its db-dependency URLs (e.g. Supabase). The db containers stay bound to the host; only the URLs the service consumes are rewritten. Does NOT launch a simulator/emulator, does NOT change start:.
- Android emulator → literal
--host 10.0.2.2(host-loopback alias) so both API
and supabase resolve from inside the emulator — not auto.
- Real device / LAN → an explicit IP the user names; API + any db it points at
must be reachable on that interface. --host auto = first physical LAN IPv4 (en0/en1/eth0/wlan0), skips VPN/Docker/tunnel interfaces → a VPN address won't be picked by auto; pass it explicitly.
- A "mobile" service whose
start:isexpo start --web/bun webis a web
target — corgi only gives you that. Real native run: corgi run --services <mobile> --with-deps --host 10.0.2.2 --detach (--with-deps lets corgi resolve the exact db key from depends_on_db — a hand-typed --dbServices token must be the exact compose key or it selects nothing; see the name rule above) for env + deps, then launch the native build yourself (cd <mobile> && expo run:android) or via a corgi script if one exists. corgi brought up env + deps + the web bundler only — the emulator launches separately and is not covered by the ready gate; don't claim it's running off a green web port.
- Verify a host rewrite by Reading the written `<mobile-dir>/.env` (Read
limit: ~40) — corgi env does NOT apply --host (shows localhost by design). Use corgi env only for the non-host remote-backend case above.
Run a branch / worktree — a feature/PR branch or an existing worktree
Run a service from code other than its compose `path:` — a feature/PR branch, or an existing worktree dir — without touching the main checkout. Per-service, repeatable, <svc>=<value>, mixable (named svcs from branch/dir, the rest from compose path:); combine with --detach, --with-deps, --services. Flag-existence guard (newer flags): corgi run --help | grep service-branch — missing → no fallback; use git checkout <branch> && corgi run --services <svc>.
- Committed/pushed branch —
--service-branch <svc>=<branch>. corgi makes (or
reuses) its own non-destructive worktree off that branch under corgi_services/.worktrees/; main checkout untouched. Reviewer-facing shape (the stories Phase 5 "Run line"). Branch must exist locally; source must be a git repo (clones first if needed). Gotcha — fails if that branch is currently checked out in the main repo (git one-branch-one-worktree) → switch the main repo off it. Fresh worktree has no `node_modules` (gitignored) → first run needs the service's beforeStart (e.g. npm install); reused worktrees keep it.
- Existing worktree dir —
--service-dir <svc>=<path>. Runs that exact dir's env - beforeStart/afterStart + process; pure cwd swap, no git touch, no clone. Dir must
exist. For uncommitted/live code in a known worktree (stories Phase 3 shape, /tmp/corgi-wt/<wt-id>-<svc>). (--service-checkout <svc>=<branch> = in-place checkout of the service's own dir; refuses on a dirty tree, leaves the dir on that branch.)
--with-depsonly expands the--servicesset throughdepends_on— it does
not auto-worktree pulled-in deps; you get a worktree/dir only for svcs you name.
# impacted services on a pushed branch (reviewer Run line)corgi run --with-deps --detach \--service-branch api=feature/ABC-200/user-phone \--service-branch web=feature/ABC-200/user-phone# live worktree code for some, compose path: for the restcorgi run --detach \--service-dir api=/tmp/corgi-wt/ABC-200-api \--service-dir web=/tmp/corgi-wt/ABC-200-web# admin, worker, db_services (unnamed) run from their compose path:
Cleanup (only --service-branch worktrees; --service-dir/in-place checkouts leave nothing): corgi worktree list shows corgi-made worktrees, corgi worktree prune removes them + their git entries (corgi run --fromScratch / corgi clean prune too).
Phase 2 — Launch detached
corgi run <flags> --detach [--logs] --json
Not instant on a cold stack. corgi run --detach runs every service's beforeStart (bundle/yarn install, migrations, webpack, image pulls) synchronously before it writes state and returns — minutes to tens of minutes on a first run. Launch with run_in_background: true (or Bash timeout ≥ 600000ms), poll corgi ps --json; don't assume a quick return or treat the wait as a hang.
Output: --detach --json prints the run-state object — services[] each name/pid/port/status, plus dbServices[]; a service crashed on spawn shows status:"crashed" in that array (no separate failed[]). E_ALREADY_RUNNING → a run is already live: corgi ps to show it; ask before --force/corgi restart. (Stale .state.json after a crash also triggers it — corgi ps reconciles, --force clears it.)
Tunnel (if requested): --tunnel can't combine with --detach. Detach services first, then — only after confirming the tunnel's hostname env resolves (corgi env <svc>, from tunnel.hostname: ${VAR}) AND provider auth is done (ngrok/cloudflared; corgi doctor) — background corgi tunnel <svc> (run_in_background: true). Standalone corgi tunnel hard-fails (exit 1) on a missing hostname var or missing auth (unlike corgi run --tunnel, which only skips-with-warning) — don't background one that will die. After backgrounding, read the shell output until ✓ <svc> :PORT → https://… (live) or ✗ …/process-exit (died — fix env/auth); only then report the public URL.
Phase 3 — Ready gate (with a timeout)
corgi status --ready --json --timeout <T> [--service <started ones>]
<T> = a Go duration — always 120s/300s/10m, never a bare number. Size it: warm stack ~120s; a first cold boot (clones repos / pulls images / builds a venv) 7–10 min+ → 600s+, or skip the strict gate and poll corgi status --json every ~30s comparing the healthy count (rising = progress, not stuck). A multi-hour DB dump/restore (make initDatabase-style) is separate, out-of-scope — never block the gate on it.
- Healthy (exit 0) → report. Uptime (
startedAt)/ports fromcorgi ps --json.
But the gate only probes targets with a declared `port:`. No port-bearing service in the started slice (status prints "No services with ports declared — nothing to check", exits 0) → the gate verified nothing: fall back to corgi ps --json (status running + a live pid) + a bounded corgi logs --service <x> --idle 2s. A port-less db whose port comes from a driver default (notably the supabase driver) is invisible to the gate even when others are probed — cross-check out-of-band (curl its health URL / corgi ps --json / docker ps). Never report ready on a no-op exit 0.
- Timeout (exit 1) — don't hang, don't retry blindly. Final JSON lists each
target healthy:false. Before handing off, separate crashed-after-boot from never-opened-its-port: corgi ps --json status:"crashed" only for pid-tracked services — db_services and docker-runner/pid-0 services never show "crashed", judge those by corgi status healthy:false + docker ps. Triage: corgi doctor + a bounded corgi logs --service <X> --idle 2s. Name the likely cause, pass the crashed-vs-never-opened distinction along, hand a real investigation to the `debug` skill.
- Partial ready → backends healthy but a frontend bundler (Expo/Vite first
build) still warming: report what's up + what's warming rather than failing the whole gate; re-poll the warming one.
Phase 4 — Report
- What's up (services + ports + URLs), what's down/warming.
- Some services open a browser themselves in
start:(open -a Chrome <url>) — note
it so the user isn't surprised (harmless headless).
- Watch logs:
corgi logs --service <x>(detached always captures logs). Stop:
corgi stop (or corgi stop --service <x>; runs afterStart, brings dbs down). Unhealthy → "run the debug skill / /corgi-debug".