fix(updater): resolve the dsh CLI through symlinks #45

Merged
dsh merged 1 commit from fix/44-updater-symlink into master 2026-10-24 01:56:28 +00:00
Owner

What

Fixes #44. On a normal global install DSH runs through a symlink chain (/usr/local/bin/dsh -> .../@deepseek-ai/dsh/lib/bin.js). findDshCliEntry() resolved process.argv[1] without following symlinks, walked from /usr/local/bin, found no package.json, returned undefined, and the updater failed before spawning dsh plugin. The status endpoint correctly said canAutoUpdate: false, but the UI ignored it and still offered the Update button.

This PR:

  • realpaths the entry and the candidate bin before comparing, with realpathSync;
  • exports findDshCliEntry(entryValue) for direct testing;
  • makes installExact say exactly what to run when the CLI cannot be found:
    Automatic update is unavailable: could not locate the dsh CLI. Install manually: dsh plugin --profile web add <tarball>;
  • stores canAutoUpdate from the status response, hides the Update button when false, and shows an inline “install the tarball manually” hint;
  • adds en/zh locale strings.

Verification

  • New tests:
    • temp @deepseek-ai/dsh package tree + bin/dsh symlink → findDshCliEntry(symlink) returns the real lib/bin.js; direct path also works; missing path returns undefined.
    • installExact missing-CLI error includes the manual command.
  • npm test 143/143, leak scan + syntax clean (CHECK_EXIT=0).
  • Against the real deployment layout:
    • before: findDshCliEntry('/usr/local/bin/dsh') → not found;
    • after: → /opt/node-v24.22.0-linux-x64/lib/node_modules/@deepseek-ai/dsh/lib/bin.js.

Release

This needs a 0.8.1 publish; an installed 0.7.40-dsh.7 updater cannot fix itself, so bootstrap 0.8.1 once with the manual tarball command, then the UI updater works.

Closes #44.

## What Fixes #44. On a normal global install DSH runs through a symlink chain (`/usr/local/bin/dsh -> .../@deepseek-ai/dsh/lib/bin.js`). `findDshCliEntry()` resolved `process.argv[1]` without following symlinks, walked from `/usr/local/bin`, found no `package.json`, returned `undefined`, and the updater failed before spawning `dsh plugin`. The status endpoint correctly said `canAutoUpdate: false`, but the UI ignored it and still offered the Update button. This PR: - realpaths the entry **and** the candidate `bin` before comparing, with `realpathSync`; - exports `findDshCliEntry(entryValue)` for direct testing; - makes `installExact` say exactly what to run when the CLI cannot be found: `Automatic update is unavailable: could not locate the dsh CLI. Install manually: dsh plugin --profile web add <tarball>`; - stores `canAutoUpdate` from the status response, hides the Update button when false, and shows an inline “install the tarball manually” hint; - adds en/zh locale strings. ## Verification - New tests: - temp `@deepseek-ai/dsh` package tree + `bin/dsh` symlink → `findDshCliEntry(symlink)` returns the real `lib/bin.js`; direct path also works; missing path returns `undefined`. - `installExact` missing-CLI error includes the manual command. - `npm test` **143/143**, leak scan + syntax clean (`CHECK_EXIT=0`). - Against the real deployment layout: - before: `findDshCliEntry('/usr/local/bin/dsh')` → not found; - after: → `/opt/node-v24.22.0-linux-x64/lib/node_modules/@deepseek-ai/dsh/lib/bin.js`. ## Release This needs a **0.8.1** publish; an installed 0.7.40-dsh.7 updater cannot fix itself, so bootstrap 0.8.1 once with the manual tarball command, then the UI updater works. Closes #44.
Global installs run /usr/local/bin/dsh -> .../lib/bin.js; the updater walked the symlink path and never found the DSH manifest, so one-click updates failed with canAutoUpdate=false. Realpath the entry and bin, respect canAutoUpdate in the UI, and include the manual dsh plugin command when the CLI cannot be found.
dsh merged commit e43e4ca399 into master 2026-10-24 01:56:28 +00:00
Sign in to join this conversation.
No description provided.