release: v0.1.8#3
Conversation
There was a problem hiding this comment.
🧪 PR Review is completed: Release PR bumps version to 0.1.8, adds --force flag to update command, and fixes global install detection by resolving symlinks. Found one potential crash path and a logic edge case in the new symlink resolution.
Skipped files
CHANGELOG.md: Skipped file patternpackage-lock.json: Skipped file pattern
⬇️ Low Priority Suggestions (2)
src/utils/updateCheck.ts (1 suggestion)
Location:
src/utils/updateCheck.ts(Lines 178-193)🔴 Error Handling
Issue:
resolveEntrypoint()catches errors fromfs.realpathSync()silently with an emptycatchblock, but ifargvPathexists and is a broken symlink,realpathSyncthrows and we silently fall through toimport.meta.url. More critically, ifargvPathis provided butrealpathSyncthrows for any reason (permissions, broken symlink), we ignore the error and fall through. The bigger issue: ifargvPathis a directory or non-existent path that doesn't throw,realpathSyncreturns it, but thenisGlobalInstallregex might fail. However, the actual crash risk: ifprocess.argv[1]is undefined, we checkimport.meta.url, but in some bundled/compiled environments (e.g., pkg, nexe, esbuild),import.meta.urlcan be undefined or not a string despite the check, and we return"". ThenisGlobalInstall()regex on empty string returns false, which is fine. But the real issue: ifargvPathis a relative path likenode_modules/.bin/orbcode,realpathSyncresolves it relative to CWD, not the actual install location, giving wrong results.Actually, re-reading:
realpathSyncresolves relative toprocess.cwd(), butargv[1]is usually absolute. The more concrete issue:fs.realpathSyncis sync I/O on the main thread; not critical but acceptable for CLI startup. The actual bug: ifargvPathexists butrealpathSyncthrows for any reason, we fall through silently and may returnimport.meta.urlwhich could befile:///.../src/index.tsx(notnode_modules), causingisGlobalInstall()to falsely return false for a global install. This breaks the update flow for users with broken symlinks or permission issues.Fix: At minimum log the
realpathSyncfailure for debugging, and consider falling back more carefully. The primary fix: also tryfs.realpathSynconimport.meta.urlif it's afile:URL to ensure we get the real filesystem path, not a symlinked path.Impact: Prevents false "local install" detection for global installs with symlink issues, ensuring
orbcode updateworks correctly- function resolveEntrypoint(): string { - const argvPath = process.argv[1]; - if (argvPath) { - try { - return fs.realpathSync(argvPath); - } catch { - // fall through to import.meta.url - } - } - // import.meta.url is the real file:// URL of the running module, which - // already points inside node_modules for a global install. - if (typeof import.meta.url === "string" && import.meta.url) { - return import.meta.url; - } - return ""; - } + function resolveEntrypoint(): string { + const argvPath = process.argv[1]; + if (argvPath) { + try { + return fs.realpathSync(argvPath); + } catch (err) { + // fall through to import.meta.url + } + } + if (typeof import.meta.url === "string" && import.meta.url) { + try { + const filePath = fileURLToPath(import.meta.url); + return fs.realpathSync(filePath); + } catch { + return fileURLToPath(import.meta.url); + } + } + return ""; + }
src/index.tsx (1 suggestion)
Location:
src/index.tsx(Lines 99-100)🟡 Code Quality
Issue: The
--forceflag parsing usesargs.includes("--force") || args.includes("-f"), butargsisprocess.argv.slice(2)per context. There's no check that--forceor-fisn't being interpreted as a prompt value or other positional argument. More importantly, if a user runsorbcode update --force --forceor-f -f, it's harmless, but if they runorbcode "update --force"as a prompt string, the shell quotes won't matter here. The real issue:args.includes("-f")is very broad —-fis a common flag. What if someone runsorbcode -f "my prompt"intending-ffor something else? But in this context,args[0] === "update"is checked first, so it's only for the update command. Still,args.includesdoesn't validate position —orbcode update some-prompt --forcewould still trigger force. That's probably intended (flag can be anywhere). Not a bug.Wait, looking closer:
args[0] === "update"is checked, but what ifargsis["update", "--force"]? Thenforce = true, correct. What aboutargs = ["update", "--force", "something"]?force = true, still works. The issue is minor: using.includes()means--forcecould be confused with a prompt that contains--forceas a substring, but.includes()checks exact array element equality, not substring. So"--force"as a prompt would need to be the exact argument. A user runningorbcode update "fix the --force bug"would passargs = ["update", "fix the --force bug"]andincludesreturns false. So it's safe.However, there is a real issue:
args.includes("-f")— if the user passes-fas a shorthand, it works, but this is inconsistent with the help text which only documents--force. The help text doesn't mention-f. This is a minor documentation/UX inconsistency.Fix: Remove the
-fshorthand or add it to help text. Given it's not documented, either remove it to match docs, or update docs.Impact: Improves CLI UX consistency
- const force = args.includes("--force") || args.includes("-f") - const code = await runUpdate(force) + const force = args.includes("--force") + const code = await runUpdate(force)
Bumps version to 0.1.8 and ships:
orbcode update --force/-fto force a global install with a warningisGlobalInstallnowrealpathSyncs symlinks so symlinked global installs are no longer mis-detected as localoverrides.formdata-node: ^6.0.3to silence thenode-domexception@1.0.0 deprecatedinstall warningTagged
v0.1.8on main will trigger the existing.github/workflows/release.ymlto publish to npm + create the GitHub Release.