fix(cli): classify a pnpm dlx runtime as ephemeral - #12
Draft
andromarces wants to merge 2 commits into
Draft
Conversation
isEphemeralRuntime recognized npm's _npx cache and the OS temp directory but not pnpm's dlx cache, so `pnpm dlx @richhardry/codor install` reported the install as durable and skipped the copy into ~/.codor/runtime. The registered service was left pointing at the dlx cache, which pnpm can prune or expire independently of the service's lifetime, breaking it later with no configuration change on the user's part. Match on the `dlx` path segment, the same way the existing `_npx` check works, so the durable-runtime copy (and everything gated on it) engages for pnpm's dlx layout too.
…ring Codex review on PR 6 caught that this comment still described ephemeral installs as only npx cache / temp dir, missing the dlx case isEphemeralRuntime now also matches.
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.
Problem
pnpm dlx @richhardry/codor installcompletes and registers a service whose entrypoint lives inside pnpm's dlx cache (<cacheDir>/dlx/<hash>/<timestamp>/...). The service works until that cache is pruned or expires, then fails to start with no configuration change on the user's part and no diagnostic pointing at the cause.isEphemeralRuntime(packages/cli/src/runtime-install.ts) recognized two shapes only: npm's_npxcache and the OS temp directory. Neither matches pnpm's dlx layout, soresolveInstallSourcereporteddurable: truefor a dlx-sourced install,installDurableRuntimeshort-circuited toaction: 'in-place', andrunSetuppointed the registered service at the transient cache instead of copying it into~/.codor/runtime. The durable-runtime machinery that exists precisely to prevent this was bypassed by a predicate that didn't recognize the layout.Fix
isEphemeralRuntimenow also matches a${sep}dlx${sep}path segment, alongside the existing_npxand temp-dir checks, so a pnpm dlx-cache runtime is classified ephemeral and gets copied into the durable location like an npx runtime already does.Matching on the
dlxsegment rather than the cache's absolute location was deliberate: pnpm's dlx cache path is platform-specific and user-configurable viacacheDir, and pnpm does not publish the internal<cacheDir>/dlx/<hash>/<timestamp>/shape as a contract — it documentscacheDiritself, not what's under it. This matcher is derived from an observed tree on Windows, not a documented guarantee. Widening the match is safe in the direction that matters: a false positive costs one extra tree copy into~/.codor/runtime(still durable), while the previous false negative left a service pointed at a directory that can disappear with no diagnostic.Testing
isEphemeralRuntimetest block.installDurableRuntimecase asserting a dlx-shaped runtime producesaction: 'installed'(not'in-place') and acliEntrypointrooted at~/.codor/runtimecontaining nodlxsegment, mirroring the existing npx case's.not.toContain('_npx')check..toContain(LOCATION)rather than.toBe(...)against a full literal path. The sibling npx-case assertion (runtime-install.spec.ts:129, pre-existing) fails on Windows for an unrelated, already-tracked reason:path.resolve()drive-qualifies the spec's POSIX-shaped fixture paths. Reusing that assertion style would have added a distinct-looking sixth failure to the suite that is actually the same known cause..toContainproves the same fact (rooted at the durable location, not the dlx cache) without depending on that drive-letter behavior.Commands run on Windows 11 / Node 26.2.0 / pnpm 10.9.0, branched from
origin/mainatbc47942(no other pending fixes present on this branch):Result: 176 passed, 18 skipped, 5 failed — the same 5 pre-existing failures unrelated to this change (Windows path-portability issues in test fixtures, tracked separately), no new failures introduced.
pnpm -r testwas also run to confirm scope: it aborts inpackages/adapters/antigravityon an unrelated, pre-existing failure and never reachespackages/cli; this is untouched by this PR.What was not verified
pnpm dlxinstall was exercised end-to-end (dlx install → cache removal/expiry → confirming the registered service survives). The fix is verified at the unit level (the predicate, and its effect throughresolveInstallSource/installDurableRuntime); the end-to-end durability claim is a manual check that wasn't performed here.runtime-install.tspredicate only, platform-independent), but were not exercised on those platforms.Scope
Only
packages/cli/src/runtime-install.tsandpackages/cli/src/runtime-install.spec.tsare touched. No other behavior changes.