-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix: resolve version at runtime to fix stale version display #670
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
- Add new src/shared/version/ module with: - Zero-dependency semver parsing and comparison - Release channel detection (stable/beta/alpha/rc) - NPM registry integration (fetches all dist-tags) - Runtime version resolution (avoids build-time bundling) - Fix CLI to use runtime version resolution instead of bundled package.json - Resolves issue where --version showed stale version after updates - Update auto-update checker to be channel-aware: - Beta users now get whichever is newer (beta OR stable) - Stable users only see stable updates - Proper semver comparison instead of string equality - Update get-local-version command to show channel info
|
Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA). To sign the CLA, please comment on this PR with: This is a one-time requirement. Once signed, all your future contributions will be automatically accepted. I have read the CLA Document and I hereby sign the CLA dev seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 issues found across 11 files
Confidence score: 3/5
- Local dev detection no longer works because
src/hooks/auto-update-checker/index.tsnever flags file/local entries, so auto-updates would continue running even when someone is hacking locally—real user impact if merged. src/shared/version/semver.tsusesparseInton prerelease identifiers, so mixed alphanumeric tags like1abcare mis-sorted and could trigger incorrect upgrade/downgrade decisions.- The same semver module also accepts invalid prerelease/build strings (e.g., empty identifiers), meaning bad version strings are treated as valid and could propagate through version checks.
- Pay close attention to
src/hooks/auto-update-checker/index.ts,src/cli/get-local-version/index.ts,src/shared/version/semver.ts- regressions in local dev detection and semver validation need fixes before merge.
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/shared/version/semver.ts">
<violation number="1" location="src/shared/version/semver.ts:7">
P2: Permissive semver regex accepts invalid prerelease/build with empty identifiers (e.g., trailing or double dots), causing parse() to treat invalid versions as valid</violation>
<violation number="2" location="src/shared/version/semver.ts:60">
P2: Using `parseInt` incorrectly identifies mixed alphanumeric prerelease identifiers as numeric. For example, `parseInt('1abc', 10)` returns `1` (not NaN), so `'1.0.0-1abc'` would be incorrectly compared against `'1.0.0-2'`. Per semver spec, only identifiers consisting entirely of digits should be compared numerically. Use a regex test like `/^\d+$/` to check for pure numeric identifiers first.</violation>
</file>
<file name="src/cli/get-local-version/index.ts">
<violation number="1" location="src/cli/get-local-version/index.ts:14">
P2: Local dev detection regressed: findPluginEntry never returns file:// entries, so the new file:// check always fails and local dev configs are misclassified as non-local.</violation>
</file>
<file name="src/hooks/auto-update-checker/index.ts">
<violation number="1" location="src/hooks/auto-update-checker/index.ts:69">
P1: Local dev mode detection is broken—`findPluginEntry` never returns file/local entries, so `isLocalDev` is always false and auto-updates run during local development</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
|
||
| // Check for local dev mode | ||
| const pluginInfo = findPluginEntry(ctx.directory) | ||
| const isLocalDev = pluginInfo?.entry.startsWith("file://") ?? false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Local dev mode detection is broken—findPluginEntry never returns file/local entries, so isLocalDev is always false and auto-updates run during local development
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/hooks/auto-update-checker/index.ts, line 69:
<comment>Local dev mode detection is broken—`findPluginEntry` never returns file/local entries, so `isLocalDev` is always false and auto-updates run during local development</comment>
<file context>
@@ -50,13 +58,17 @@ export function createAutoUpdateCheckerHook(ctx: PluginInput, options: AutoUpdat
+
+ // Check for local dev mode
+ const pluginInfo = findPluginEntry(ctx.directory)
+ const isLocalDev = pluginInfo?.entry.startsWith("file://") ?? false
+
+ if (isLocalDev) {
</file context>
| const aNum = parseInt(ai, 10) | ||
| const bNum = parseInt(bi, 10) | ||
|
|
||
| if (!isNaN(aNum) && !isNaN(bNum)) { | ||
| if (aNum > bNum) return 1 | ||
| if (aNum < bNum) return -1 | ||
| } else if (!isNaN(aNum)) { | ||
| // Numeric < alphanumeric | ||
| return -1 | ||
| } else if (!isNaN(bNum)) { | ||
| return 1 | ||
| } else { | ||
| // Both alphanumeric, compare as strings | ||
| if (ai > bi) return 1 | ||
| if (ai < bi) return -1 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Using parseInt incorrectly identifies mixed alphanumeric prerelease identifiers as numeric. For example, parseInt('1abc', 10) returns 1 (not NaN), so '1.0.0-1abc' would be incorrectly compared against '1.0.0-2'. Per semver spec, only identifiers consisting entirely of digits should be compared numerically. Use a regex test like /^\d+$/ to check for pure numeric identifiers first.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/shared/version/semver.ts, line 60:
<comment>Using `parseInt` incorrectly identifies mixed alphanumeric prerelease identifiers as numeric. For example, `parseInt('1abc', 10)` returns `1` (not NaN), so `'1.0.0-1abc'` would be incorrectly compared against `'1.0.0-2'`. Per semver spec, only identifiers consisting entirely of digits should be compared numerically. Use a regex test like `/^\d+$/` to check for pure numeric identifiers first.</comment>
<file context>
@@ -0,0 +1,188 @@
+ if (bi === undefined) return 1
+
+ // Numeric identifiers compared as integers
+ const aNum = parseInt(ai, 10)
+ const bNum = parseInt(bi, 10)
+
</file context>
| const aNum = parseInt(ai, 10) | |
| const bNum = parseInt(bi, 10) | |
| if (!isNaN(aNum) && !isNaN(bNum)) { | |
| if (aNum > bNum) return 1 | |
| if (aNum < bNum) return -1 | |
| } else if (!isNaN(aNum)) { | |
| // Numeric < alphanumeric | |
| return -1 | |
| } else if (!isNaN(bNum)) { | |
| return 1 | |
| } else { | |
| // Both alphanumeric, compare as strings | |
| if (ai > bi) return 1 | |
| if (ai < bi) return -1 | |
| } | |
| const aIsNumeric = /^\d+$/.test(ai) | |
| const bIsNumeric = /^\d+$/.test(bi) | |
| if (aIsNumeric && bIsNumeric) { | |
| const aNum = parseInt(ai, 10) | |
| const bNum = parseInt(bi, 10) | |
| if (aNum > bNum) return 1 | |
| if (aNum < bNum) return -1 | |
| } else if (aIsNumeric) { | |
| // Numeric < alphanumeric | |
| return -1 | |
| } else if (bIsNumeric) { | |
| return 1 | |
| } else { | |
| // Both alphanumeric, compare as strings | |
| if (ai > bi) return 1 | |
| if (ai < bi) return -1 | |
| } |
| const pluginInfo = findPluginEntry(directory) | ||
|
|
||
| // Check for local dev mode (file:// protocol) | ||
| const isLocalDev = pluginInfo?.entry.startsWith("file://") ?? false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Local dev detection regressed: findPluginEntry never returns file:// entries, so the new file:// check always fails and local dev configs are misclassified as non-local.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/get-local-version/index.ts, line 14:
<comment>Local dev detection regressed: findPluginEntry never returns file:// entries, so the new file:// check always fails and local dev configs are misclassified as non-local.</comment>
<file context>
@@ -1,29 +1,39 @@
+ const pluginInfo = findPluginEntry(directory)
+
+ // Check for local dev mode (file:// protocol)
+ const isLocalDev = pluginInfo?.entry.startsWith("file://") ?? false
+
+ if (isLocalDev) {
</file context>
|
|
||
| import type { ParsedVersion, VersionDiff } from "./types" | ||
|
|
||
| const SEMVER_REGEX = /^v?(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.-]+))?(?:\+([a-zA-Z0-9.-]+))?$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Permissive semver regex accepts invalid prerelease/build with empty identifiers (e.g., trailing or double dots), causing parse() to treat invalid versions as valid
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/shared/version/semver.ts, line 7:
<comment>Permissive semver regex accepts invalid prerelease/build with empty identifiers (e.g., trailing or double dots), causing parse() to treat invalid versions as valid</comment>
<file context>
@@ -0,0 +1,188 @@
+
+import type { ParsedVersion, VersionDiff } from "./types"
+
+const SEMVER_REGEX = /^v?(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.-]+))?(?:\+([a-zA-Z0-9.-]+))?$/
+
+/**
</file context>
| const SEMVER_REGEX = /^v?(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.-]+))?(?:\+([a-zA-Z0-9.-]+))?$/ | |
| const SEMVER_REGEX = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/ |
|
recheck |
Summary
--versionshows stale/incorrect version after updatesProblem
The CLI was bundling
package.jsonat build time, causing the version to be frozen to whatever was in the source when built - not the actual installed version. This led to:oh-my-opencode --versionshowing2.14.0even when3.0.0-beta.2was installed!==) instead of semver causing incorrect update suggestionsSolution
Created a new
src/shared/version/module with:semver.tschannels.tsregistry.tsresolver.tsindex.tscheckVersion()APIKey Changes
Runtime version resolution - Version is now read from
package.jsonat runtime by walking up from the executing file, not bundled at build timeChannel-aware updates:
3.0.0-beta.2and3.0.0stable releases, user is offered stableProper semver comparison - Uses actual semver logic instead of string equality
Testing
Files Changed
src/shared/version/- New version management module (6 files)src/cli/index.ts- Use runtime versionsrc/cli/get-local-version/- Use new version utilities, show channel infosrc/hooks/auto-update-checker/index.ts- Channel-aware update checkingSummary by cubic
Fixes stale --version by resolving the version at runtime and adds channel-aware updates using proper semver. CLI and auto-update now respect and display release channels so users get the right updates.
New Features
Bug Fixes
Written for commit fc554c5. Summary will update on new commits.