fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(server): upgrade the actually-installed Homebrew formula - #6247

Closed
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection
Closed

fix(server): upgrade the actually-installed Homebrew formula#6247
rohitashwin wants to merge 2 commits into
pingdotgg:mainfrom
rohitashwin:fix/homebrew-formula-detection

Conversation

@rohitashwin

@rohitashwinrohitashwin commented Aug 12, 2026

Copy link
Copy Markdown

Problem

Auto updating provider in T3 Code Desktop for macOS (e.g., claude-code) would fail because claude-code was installed using homebrew using the command brew install claude-code@latest rather than brew install claude-code. T3 Code would try to run brew upgrade claude-code which fails. The correct approach is to find the right install variant of claude-code actually installed on the machine. This PR does that and automatically calls brew install claude-code@latest.

What Changed

Provider auto-update no longer relies solely on each driver's hardcoded default Homebrew formula name. resolvePackageManagedProviderMaintenance now extracts the actual installed formula name from the resolved Homebrew Cellar/Caskroom path (e.g. .../Caskroom/claude-code@latest/2.1.228/claude) and runs brew upgrade against that formula, falling back to the driver's default when the path can't be parsed.

Why

ClaudeDriver.ts hardcodes homebrewFormula: "claude-code". Anyone who installed via brew install claude-code@latest (a different formula from plain claude-code) gets brew upgrade claude-code from the in-app update control, which fails loudly:

$ brew upgrade claude-code
==> Downloading Homebrew API data
Error: Cask 'claude-code' is not installed.
$ echo $?
1

Fixes#6245

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • pnpm exec vitest run src/provider/providerMaintenance.test.ts — 18/18 pass, including a new case covering a Homebrew install under a different formula name than the driver's default
  • Verified against this machine's actual claude install (/opt/homebrew/bin/claude/opt/homebrew/Caskroom/claude-code@latest/2.1.228/claude): resolver now produces brew upgrade claude-code@latest instead of the failing brew upgrade claude-code

Note

Low Risk
Localized change to provider maintenance command resolution with new unit tests; no auth or data-path impact.

Overview
Provider auto-update now builds brew upgrade from the formula name on disk, not only each driver’s default homebrewFormula.

When a binary resolves through Homebrew, the resolver parses the installed formula from Cellar/Caskroom paths (e.g. package-tool@latest or claude-code@latest) and passes it into Homebrew maintenance capabilities. resolveHomebrewFormula keeps tap-qualified names like example/tap/scoped-package-tool when the path basename matches the definition; otherwise it uses the detected installed name. If nothing can be resolved, behavior still falls back to the definition default or manual-only updates.

Tests cover tap-qualified formulas and variant formula names that differ from the driver default.

Reviewed by Cursor Bugbot for commit d71fabd. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Fix Homebrew upgrade to target the actually-installed formula instead of the definition default

  • Adds extractHomebrewFormulaFromPath to detect the installed Homebrew formula from a binary's Cellar/Caskroom path, and resolveHomebrewFormula to pick between the installed and definition formulas, preferring the tap-qualified definition name when basenames match.
  • Updates makeHomebrewProviderMaintenanceCapabilities to accept an optional installed formula and use the resolved formula in the brew upgrade command, falling back to manual-only capabilities when no formula is available.
  • Updates resolvePackageManagedProviderMaintenance to extract the installed formula from command paths and pass it into the capabilities factory.
  • Behavioral Change: brew upgrade commands now target the detected installed formula (e.g. package-tool@latest) rather than the static definition formula when they differ.

Macroscope summarized d71fabd.

@coderabbitai

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855008a1-8a81-4736-a99c-51ad50c39789

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
Comment threadapps/server/src/provider/providerMaintenance.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 805e2f1a99130dbb2f22adbd7117e6ce7fe3b3bb. Configure here.

Comment threadapps/server/src/provider/providerMaintenance.ts
@macroscopeapp

macroscopeappBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This bug fix modifies which formula name is passed to brew upgrade commands at runtime. While the logic is straightforward with good test coverage, the change affects actual system behavior during package upgrades, warranting human review.

You can customize Macroscope's approvability policy. Learn more.

@rohitashwin

Copy link
Copy Markdown
Author

Good catch — that was a real regression, not a hypothetical. Homebrew's Cellar path is keyed by the formula's bare name only (rack = HOMEBREW_CELLAR/name in formulary.rb), so a tap-qualified formula like anomalyco/tap/opencode (OpenCode's driver) could never be recovered from the path, and my extraction would have silently swapped it for the bare opencode, which Homebrew's FromNameLoader can resolve to a different tap's formula or raise TapFormulaAmbiguityError.

Pushed a fix: the extracted formula only overrides the configured homebrewFormula when it actually diverges from that formula's basename (e.g. claude-code vs. the installed claude-code@latest). When they match, the configured tap-qualified name is kept as-is. Added a regression test (keeps the tap-qualified Homebrew formula when the Cellar path only has the bare name) using the existing scoped-package-tool fixture, which mirrors OpenCode's example/tap/scoped-package-tool shape. Full suite (19 tests) passes.

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 12, 2026
rohitashwinand others added 2 commits August 25, 2026 21:46
Provider auto-update hardcoded each driver's default Homebrew formula
name (e.g. "claude-code"), so `brew upgrade <formula>` silently no-ops
for anyone who installed a differently-named formula or cask, such as
`claude-code@latest`. Now the resolver extracts the real formula name
from the resolved Cellar/Caskroom path and upgrades that instead.
Fixespingdotgg#6245
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Homebrew Cellar/Caskroom paths are keyed by the formula's bare name
only ("rack = HOMEBREW_CELLAR/name"), so a tap-qualified formula like
"anomalyco/tap/opencode" can never be recovered from the install path.
Only override the configured formula with the extracted one when the
extracted name actually diverges from the configured formula's
basename, so tapped formulas keep their tap qualifier and bare-name
formulas still pick up divergent installs like "claude-code@latest".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #6436, which includes the installed Homebrew formula fix, preserves tap-qualified names, and handles cask upgrades. Keeping provider-update review there. Thanks for the fix and follow-up regression coverage.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Provider auto-update ignores which Homebrew formula is actually installed for claude-code

2 participants

@rohitashwin@juliusmarminge