fix(upgrade): fall back to the installer when a native updater refuses - #130
Merged
Conversation
…ater `moshcode upgrade` asked privacycode to update itself, and it always refused: ■ opencode is installed to /home/anthony/.privacycode/bin/privacycode ● Using method: unknown ■ Upgrade failed — Unknown installation method: unknown privacycode is an opencode derivative, so `privacycode upgrade` is opencode's updater, and that updater picks its method by recognising where the binary was installed. It knows opencode's own locations; it does not know this fork's ~/.privacycode/bin, so it resolves `unknown` and stops before doing anything. Nothing about the machine makes this intermittent — it can never upgrade an install made by that installer. Drop the native updater from the engine and let upgradeSpec fall through to the installer, which is idempotent and fetches the latest. Plain opencode keeps its updater: run against a real opencode install it reports `Using method: curl` and upgrades cleanly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`moshcode upgrade` left targets stranded on old versions: ● Using method: unknown ■ Upgrade failed — Unknown installation method: unknown opencode-family updaters choose how to update by recognising where the binary was installed. When they don't recognise the location they resolve `unknown` and stop — the same on every run, so the target never moves. It is not machine-specific luck: the same `opencode upgrade` reports `Using method: curl` and succeeds where the install is one it knows, and fails where it isn't. A fork living under its own directory hits this every time. Try the installer when the native updater fails. Installers are idempotent and fetch the latest, which is why they are already what an uninstalled target runs. The fallback only exists where the updater is a different command, so it can never repeat the one that just failed, and it says so rather than retrying silently. privacycode loses its native updater outright: it is opencode's, pointed at ~/.privacycode/bin, so it cannot ever work — no reason to spend a failed run discovering that every time. Adds an injectable runner to runUpgrade so the retry is testable without spawning real installers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
The sweep over every entry with a native updater guarded itself with `length >= 5`, which is a number that moves whenever an entry gains or loses an updater — privacycode just lost one, and the sweep failed despite the invariant it exists to protect still holding for all four that remain. Assert what the guard is for instead: that at least one engine and at least one tool are in the sweep, so neither code path can silently drop out of it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
moshcode upgradeleft targets stranded on old versions:opencode-family updaters decide how to update by recognising where the binary
was installed. When they don't recognise the location they resolve
unknownand stop — every run, so the version never moves.
This isn't machine-specific luck. The same
opencode upgradereportsUsing method: curland upgrades cleanly where the install is one it knows,and fails where it isn't — which is exactly what was observed: it worked on one
box and failed on another. A fork living under its own directory
(
~/.privacycode/bin) hits it every time.Fix
Fall back to the installer when a native updater fails. Installers are
idempotent and fetch the latest — they're already what an uninstalled target
runs, so this is reusing a path that's known good.
never re-run the one that just failed (
claude,codex,geminiarenpm i -g, which is already the installer — those aren't retried)a directory opencode doesn't know, so it can never work. No reason to burn a
failed run rediscovering that each time.
runUpgradegains an injectable runner so the retry is testable withoutspawning real installers.
Verified
4 new tests, 10/10 in
test/upgrade.test.mjs: the refusal→installer sequenceruns in that order and reports success from the fallback; a target whose
"updater" is already its installer is not retried; privacycode plans the
installer while plain opencode keeps its updater.
🤖 Generated with Claude Code