Skip to content

Add one-shot ./ide --bootstrap for fresh-machine setup#104

Open
kyleve wants to merge 3 commits into
mainfrom
cursor/ide-bootstrap-one-shot
Open

Add one-shot ./ide --bootstrap for fresh-machine setup#104
kyleve wants to merge 3 commits into
mainfrom
cursor/ide-bootstrap-one-shot

Conversation

@kyleve

@kyleve kyleve commented Jul 18, 2026

Copy link
Copy Markdown
Owner

What

Make ./ide --bootstrap (alias --setup) the single command a new Mac runs to get from a fresh clone to a generated project. It:

  1. Verifies Xcode — a full Xcode.app (not just the Command Line Tools) that's selected and runnable; otherwise it prints the exact xcode-select / runFirstLaunch / license accept steps and exits. It does not auto-install Xcode (large, interactive App Store download).
  2. Installs mise via its official installer if missing — self-contained, so Homebrew is no longer a prerequisite — and idempotently adds mise activate to your shell rc (zsh/bash).
  3. Installs the pinned tools (mise install): Tuist, SwiftFormat, and now Ruby.
  4. Falls through to the normal flow — Git hooks, sync-agents --install, tuist generate.

It composes with the existing flags, so ./ide --bootstrap -i --team-id ABCDE12345 is the true one-shot. Plain ./ide stays the fast path but now fails fast when mise isn't found, pointing at --bootstrap.

Ruby pin

sync-agents previously relied on Apple's deprecated system Ruby. This pins Ruby 3.4.10 in .mise.toml and routes sync-agents through mise exec from both ./ide and the pre-commit hook so the pinned Ruby is used regardless of shell activation.

We use mise's precompiled Ruby (ruby.compile = false): building from source with ruby-build failed on a clean Mac (the psych extension couldn't configure against libyaml), which would break the one-shot. Precompiled installs in ~30s with no toolchain and becomes mise's default in 2026.8.0.

Resolving mise without shell activation

Right after ./ide --bootstrap, mise lives at ~/.local/bin/mise but isn't on PATH until a new shell picks up activation. Both ./ide and the pre-commit hook shell out to mise, so a commit in that window would otherwise fail with mise: command not found. Two things address this:

  • A shared find_mise (PATH -> official-installer ~/.local/bin -> Homebrew -> /usr/local) resolves the binary directly, and the hook installs a small mise() function shim so its existing mise exec ... call sites work regardless of PATH. Both surfaces guard with a clear "run ./ide --bootstrap" message when mise genuinely can't be found.
  • On a fresh install, bootstrap idempotently appends mise activate to the user's shell rc (zsh -> ~/.zshrc, bash -> ~/.bashrc; a manual pointer for other shells) so new interactive shells have mise + tools on PATH. This is convenience only — nothing depends on it thanks to find_mise.

Verified locally (macOS, Xcode 27 beta, arm64)

  • Full ./ide --bootstrap --no-open runs clean end-to-end (tools installed, sync-agents ran, tuist generate --no-open succeeded).
  • Pinned Ruby 3.4.10 loads psych/yaml/json; sync-agents runs under it via mise exec.
  • find_mise resolves via the ~/.local/bin fallback with mise off PATH, and the mise() shim delegates correctly.
  • rc activation is idempotent (no duplicate line on re-run) and prints a manual note for non-zsh/bash shells.
  • Fast-path guard fires: plain ./ide with no resolvable mise prints the run ./ide --bootstrap first error and exits non-zero.

Docs

README.md (Getting started leads with ./ide --bootstrap; Homebrew is now an optional alternative) and AGENTS.md (Ruby row in the build-system table + bootstrap note). Generated CLAUDE.md regenerated via sync-agents.

kyleve added 3 commits July 17, 2026 18:39
Make ./ide --bootstrap (alias --setup) the single command a new Mac runs:
verify a full Xcode is installed and selected, install mise via its official
installer if missing (no Homebrew needed), install the pinned tools, then fall
through to the normal hooks/sync/generate flow. Plain ./ide now fails fast when
mise is missing, pointing at --bootstrap.

Pin Ruby (3.4.10) in .mise.toml so sync-agents no longer relies on Apple's
deprecated system Ruby, and route sync-agents through 'mise exec' from ./ide and
the pre-commit hook so the pinned Ruby is used. Use mise's precompiled Ruby
(ruby.compile = false) since source builds fail on a clean Mac (psych/libyaml).

Update README and AGENTS.md to lead with the bootstrap step.
The pre-commit hook shells out to mise (SwiftFormat, sync-agents) with a bare
`mise`, so right after `./ide --bootstrap` — before the user has added `mise
activate` to their shell rc — a commit would fail with 'mise: command not
found'. Give the hook the same find_mise resolution as ./ide (PATH, then the
official-installer and Homebrew locations) and a `mise()` function shim so the
existing call sites work regardless of PATH, plus a clear guard pointing at
./ide --bootstrap. Broaden ./ide's find_mise with the same fallbacks so the two
stay symmetric.
When bootstrap installs mise via the official installer, idempotently append
`mise activate` to the user's shell rc (zsh -> ~/.zshrc, bash -> ~/.bashrc) so
mise and the pinned tools are on PATH in new interactive shells, replacing the
printed note. Never duplicates the line, creates the rc if absent, and prints a
manual pointer for other shells. This is convenience only — ./ide and the git
hooks resolve mise directly, so nothing depends on it. Update README to match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant