Skip to content

fix(statusline): resolve global ruflo version on Homebrew Node installs#2270

Draft
mamd69 wants to merge 1 commit into
ruvnet:mainfrom
mamd69:fix/statusline-homebrew-global-version
Draft

fix(statusline): resolve global ruflo version on Homebrew Node installs#2270
mamd69 wants to merge 1 commit into
ruvnet:mainfrom
mamd69:fix/statusline-homebrew-global-version

Conversation

@mamd69

@mamd69 mamd69 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Problem

On macOS with Homebrew-installed Node, the status bar shows the hard-coded fallback RuFlo V3.6 even when ruflo is correctly installed globally and up to date.

The cause is in getPkgVersion() (in statusline-generator.ts, emitted into every generated statusline.cjs). It derives the global node_modules directory from path.dirname(process.execPath):

const binDir = path.dirname(process.execPath);
for (const gm of [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')]) { ... }

Homebrew symlinks /opt/homebrew/bin/node (Apple Silicon) — or /usr/local/bin/node (Intel) — into a Cellar path, and Node resolves the symlink in process.execPath. So the derived probe becomes:

/opt/homebrew/Cellar/node/<v>/bin/../lib/node_modules   # inside the Cellar — no global packages here

while global packages actually live at /opt/homebrew/lib/node_modules. The probe misses, no package.json is found, and the version falls back to '3.6'.

This is the same blind spot #2221 set out to fix for global installs — it just didn't account for Homebrew's Cellar layout, which is the most common macOS Node setup.

Repro

$ which node
/opt/homebrew/bin/node
$ node -p process.execPath
/opt/homebrew/Cellar/node/26.0.0/bin/node
# derived probe : /opt/homebrew/Cellar/node/26.0.0/lib/node_modules   (no ruflo)
# actual global : /opt/homebrew/lib/node_modules/ruflo  ->  3.10.33
# status bar     : "RuFlo V3.6"   (should be V3.10.33)

Fix

Add the canonical prefix-based global module directories to the probe list, after the existing execPath-derived paths:

const globalDirs = [
  path.join(binDir, '..', 'lib', 'node_modules'),
  path.join(binDir, 'node_modules'),
  '/opt/homebrew/lib/node_modules',   // Homebrew (Apple Silicon)
  '/usr/local/lib/node_modules',      // Homebrew (Intel) / common prefix
  '/usr/lib/node_modules',            // standard Linux
];

The execPath-derived paths stay first, so nvm / mise / Windows behaviour is unchanged. No npm spawn is added (the statusline renders often, so the no-spawn constraint is preserved).

Scope

  • v3/@claude-flow/cli/src/init/statusline-generator.ts — source of truth (the template ruflo init writes out).
  • .claude/helpers/statusline.cjs — the repo's own generated statusline, kept in sync so existing checkouts benefit without a regen.

The older v3/@claude-flow/{cli,mcp}/.claude/helpers/statusline.cjs copies are a different (V3.5 / #1951-era) implementation and are intentionally left out of scope.

Verification

After the fix, the generated statusline renders RuFlo V3.10.33 (the real global install) instead of RuFlo V3.6.

getPkgVersion() derives the global node_modules dir from
path.dirname(process.execPath). On Homebrew, /opt/homebrew/bin/node
(and Intel's /usr/local/bin/node) is a symlink that Node resolves to a
Cellar path (.../Cellar/node/<v>/bin/node), so the derived
bin/../lib/node_modules points INSIDE the Cellar — where global
packages are not installed. The probe misses and the statusline falls
back to the hard-coded "3.6".

This is the same blind spot ruvnet#2221 set out to fix for global installs; it
just didn't cover Homebrew's Cellar layout (the most common macOS setup).

Add the canonical prefix-based global module dirs
(/opt/homebrew/lib/node_modules, /usr/local/lib/node_modules,
/usr/lib/node_modules) to the probe list so Homebrew (Apple Silicon +
Intel) and standard Linux global installs resolve correctly. The
execPath-derived paths are kept first, so nvm/mise/Windows are unaffected.

Applied in both the generator template (statusline-generator.ts) and the
repo's own generated .claude/helpers/statusline.cjs so existing checkouts
benefit without a regen.

Repro:
  $ which node            # /opt/homebrew/bin/node
  $ node -p process.execPath
  /opt/homebrew/Cellar/node/26.0.0/bin/node
  # derived probe: /opt/homebrew/Cellar/node/26.0.0/lib/node_modules (no ruflo)
  # actual global: /opt/homebrew/lib/node_modules/ruflo  ->  3.10.33
  # status bar before fix: "RuFlo V3.6"  /  after: "RuFlo V3.10.33"
meefs pushed a commit to meefs/claude-code-flow that referenced this pull request Jun 2, 2026
…ing (ruvnet#2270 was a typo for ruvnet#2268)

Co-Authored-By: RuFlo <ruv@ruv.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant