Repository navigation
feat: install the launcher's CLI version locally from a tested lockfile - #540
Conversation
|
@claude /review |
|
Claude finished @theCodeDrift's task in 5m 33s —— View job Review completeReview mode: incremental — read 0 prior review thread(s) before reviewing.
Overall assessmentThis is a large, carefully specified change (design doc, proposal, and specs all line up with the implementation), and the test suite is unusually thorough — missing/mismatched lockfile, npm failure, no-bin, npm-not-on-PATH, install race, Two [New] findings posted inline on
Nothing else rose to the level of a correctness, security, performance, or test-coverage finding. The two already-flagged, non-blocking follow-ups in the PR body (a Windows end-to-end run; no end-to-end exercise of a runtime rule through the new install path) are the author's own call, not repeated here. |
Both inline findings are fixed in c4d0f58 (homedir guard in the — AI Coding Agent |
…eadable temp entry homedir() can throw in a container with no HOME and no passwd entry; the .npmrc walk now runs to the filesystem root instead. prune() now contains each step's failure, as pruneLauncherCache does, so one unreadable .tmp-* entry no longer skips dropping superseded versions.
c4d0f58 to
12fe3ec
Compare
Stack (root → tip):
The project launcher from #537 still ran every command through
npx --yes <package>@<version>. With this change it installs the recorded version once into a git-ignored.taskless/.cache/, from a lockfile the release build derived from our ownpnpm-lock.yaml, then runs it from there with the samenode. After the first run, a Taskless command touches neither the network nor npm, and every machine installs the dependency tree CI tested.Why a lockfile, and why not a shrinkwrap
A published package carries only its
package.jsonranges, so a fresh install of 0.13.1 resolvedtsx4.23.15 andesbuild0.28.x, where we test 4.21.0 and 0.27.3 (#538). A publishednpm-shrinkwrap.jsoncan't fix that for this package. Measured with npm 11.8 through a local registry:npm unpacks a dependency's shrinkwrap after its platform check, which is exactly the case our per-platform optional packages hit. Rewriting
package.jsonto exact versions at publish was ruled out.What changes
pnpm-lock.yaml, offline, and embed it (scripts/install-lockfile.ts).os/cpu.package.jsonkeeps its ranges, so development stays loose.init: writes.taskless/bin/cli.lock.json(orcli-nightly.lock.json) beside the launcher, reported ascreated/restoredlike the launcher, never touching the other package's pair. The--jsonenvelope gains alockfilefield.install.launchersno longer records.npm ci --ignore-scriptsfrom its lockfile into a temporary directory, renamed into place only when complete. A concurrent first run that loses the rename uses the winner's copy..taskless/.cache/.gitignore(*) and prunes after a new install.process.execPathand no shell, socmd.exequoting is now needed only for npm..npmrcat or above the project into the install directory, then removes it. npm reads project settings only from the directory it installs into.npm prefix: npm masks token-like strings in its output, UUID path segments included. The end-to-end run caught it printing…/***/…and silently using the public registry.cirecipe (topic v8) caches.taskless/.cache, keyed onrunner.osandhashFiles('.taskless/bin/cli.lock.json'). Theinitrecipe (topic v12) documentslockfile. Thehooksrecipe (topic v5) and the skill describe the one-time install.Verification
pnpm typecheckandpnpm lintclean, and 2,460 tests pass. New tests:npm: first and second run, clean--json, lost rename race, missing or mismatched lockfile, npm failing or missing,.npmrccopied from the project and from a parent and not kept, self-ignore, pruning;initwriting, restoring and pruning, for both the release and the nightly.pnpm-lock.yamlfor 0.13.1, run through realnpm ci, installed tsx 4.21.0, esbuild 0.27.3 and get-tsconfig 4.13.6, only darwin-arm64 binaries, 109 MB.initin a scratch project, then./.taskless/bin/cli.mjs checkfrom the real registry.npmonPATHthat records any call; it was never called.git check-ignoreconfirms the cache is ignored and the lockfile is not..npmrcpointing at an unreachable registry and an empty npm cache, the install failed with npm'sECONNREFUSEDand left no temporary directory or.npmrc.Follow-ups (not blocking)
Delivery shape: single PR, stacked on #537, merging forward after it. It depends on the launcher and is safe on its own once #537 lands. The changeset extends
.changeset/pinned-cli-wrapper.mdrather than adding a second one.Fixes #538