Skip to content

Self-updater should target the package manager that installed it (config: "packageManager") #966

Description

@PabloJustDevelops

Feature Description

The self-updater hardcodes npm, with no way to change it. This is the design-level follow-up to #862 (package manager support) and #641 (auto-detect the manager + an Auto-update toggle in /config); this issue proposes a concrete config surface and detection strategy so those can be implemented without ambiguity. #666 is the bug symptom.

Concretely, two things:

1. Detect the package manager that owns the running binary. Resolve the real path of the currently running entrypoint and map it to a manager, rather than assuming npm:

Path contains Manager Install command
install/global/node_modules bun bun add -g command-code@<version>
node_modules/.pnpm pnpm pnpm add -g command-code@<version>
yarn global dir yarn yarn global add command-code@<version>
otherwise npm npm i -g command-code@<version>

2. Add a persistent packageManager setting in /config:

packageManager: "auto" | "npm" | "bun" | "pnpm" | "yarn" | "none"
  • auto (default, backwards compatible) — detect as above
  • an explicit value — always use that manager
  • none — never self-update, only notify that a new version exists

Today the only controls are --no-auto-update (single run) and the COMMANDCODE_SKIP_UPDATES env var, so there is nowhere to make this choice persistently.

3. Related correctness fix, independent of manager support. Success should be determined by the on-disk version actually changing, not by the install command's exit code. Today cmd update can print ✔ Updated to v1.x.y while the binary on PATH is unchanged. Related: if the resolved binary lives outside the target prefix, skip the self-update and print the exact command for the detected manager instead of leaving an orphan copy behind.

Use Case

Installing the CLI with a non-npm global package manager is a normal thing to do, but it puts the install permanently out of sync with the updater. The updater writes a newer version into the npm prefix, the binary on PATH is never touched, and no message explains why. The result is a silent no-op plus wasted disk on every update cycle, and the only way out is to manually remember the right command for your manager.

A persistent packageManager setting makes the tool behave predictably for bun/pnpm/yarn users without anyone having to opt out of updates, and detecting the owning manager means the update lands on the binary that actually runs.

Additional Context

Verified on v1.73.2. In dist/cli.mjs the package manager is hardcoded: 6 occurrences of npm i -g, 2 of npm install -g, 1 of bunx, and 0 for pnpm or yarn globals. There is no detection of the manager that installed the running binary.

The auto-updater runs npm against the npm prefix, including a staging directory, and does not create bin links:

npm install --global --prefix <npm-prefix>/lib/node_modules/.command-code-stage-53164 \
  command-code@1.73.2 --no-audit --no-fund --no-progress

On a machine with bun + fnm/node + a root-level npm install, three copies existed at once:

Location Version On PATH?
~/.bun/install/global/node_modules/command-code 1.72.4 yes
~/.local/share/fnm/node-versions/v24.20.0/installation/lib/node_modules/command-code 1.65.0 → auto-updated to 1.73.2 no bin links, 252 MB
/usr/lib/node_modules/command-code 1.39.3 no

The npm-prefix copy had no bin entries at all, so --version kept reporting 1.72.4 while 252 MB of 1.73.2 sat next to it, silently.

Note this is reported regardless of which manager is used — the npm prefix is simply the wrong target when the binary was installed by another manager, which is the same root cause as the pnpm issue in #862.

I left detailed logs and full npm ls -g / bun pm ls -g output in a comment on #862 if that is useful.

How important is this to you?

Important for my workflow

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions