Fix/dx retro setup fixes - #21
Draft
daniellorente20-factorial wants to merge 5 commits into
Draft
Conversation
…) + retry with backoff and cleanup
daniellorente20-factorial
marked this pull request as draft
June 11, 2026 14:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
First-time local setup breaks in ways that are hard to diagnose, turning a routine npx welcome run into a debugging session. The failure modes this PR targets:
A flaky network during the repository clone aborts the entire setup on the first hiccup, with no retry — and the clone pulls every blob up front, maximizing the window for a stall.
The python install dies on python-build's GitHub-attestation verification (an extra fetch/verify step that fails on many networks), taking the whole version-manager step down with it.
The agent-skills step can hang forever: the underlying skills add git clone blocks on a prompt that is invisible (and unanswerable) under the Ink TUI.
An unsupported Node version crashes cryptically deep inside tsx/Ink instead of saying "you need Node ≥ 18" up front.
Each of these is a quiet, late, hard-to-attribute failure. This PR makes the fragile steps fail fast with clear messages, retry transient failures, and never hang.
What
Resilient repository clone (src/commands/steps/04-clone-repo.ts): clone with --filter=blob:none (blobless partial clone — file contents fetched on demand, so the initial transfer is far smaller and less likely to stall), and retry up to 3× with linear backoff (5s, 10s). A failed clone can leave a partial dir behind, so it's cleaned (rm -rf) before each retry to avoid "already exists". Fails loud only after all attempts are exhausted.
Disable python GitHub attestations on mise (src/commands/steps/05-version-manager.ts): set python.github_attestations=false (mise settings set) before any python install, so both mise use python@latest and mise install are safe. Best-effort — older mise versions don't recognize the setting and would error, so a failed set warns and continues instead of taking the step down.
Harden agent-skills install (src/commands/steps/14-agent-skills.ts): add a 3-minute per-skill timeout as a hard backstop (a stuck skill is killed and skipped, not hung) and force non-interactive git/SSH (GIT_TERMINAL_PROMPT=0, ssh -o BatchMode=yes) so a clone fails fast instead of waiting on an invisible prompt.
Node.js prerequisite gate (bin/welcome.mjs, package.json, src/commands/preflight.ts): check process.versions.node before loading tsx/Ink and exit with a clear message if < 18 (static imports converted to dynamic so the gate runs first); add engines.node ">=18" for an npm/npx-level warning; surface a Node.js version check in the wizard preflight.
Why mise only (not asdf)
The attestation setting is mise-specific (python.github_attestations); asdf has no equivalent, so its python path is left untouched rather than guessing at a different mechanism.
Why the skills step stays non-fatal
Agent skills are optional. A failed or timed-out skill warns and the run continues, so one bad skill repo never blocks completing the rest of the setup.
Test plan
npm run build (tsc), npm run lint, npm run format:check all pass.
Clone → --filter=blob:none produces a valid blobless partial clone; the retry loop retries, cleans up between attempts, backs off (5s→10s), and throws only after exhausting all attempts.
Python attestations → on current mise, mise settings set python.github_attestations false succeeds and reads back false; on a mise that doesn't know the key it warns and continues (no hard fail).
Agent-skills → a hung command is killed by the timeout (not waited out) and returns non-zero (→ non-fatal skip); the non-interactive git/SSH env reaches the child process.
Node gate → rejects Node 14/16 and garbage versions, accepts 18/22; preflight emits a Node.js result with the running version; node bin/welcome.mjs on Node ≥ 18 boots the wizard without hitting the gate.