Skip to content

Restore Claude Code oauth, remember settings and fixes - #2119

Closed
jasonkneen wants to merge 12 commits into
Twigpine:mainfrom
jasonkneen:jason-dev
Closed

jasonkneen wants to merge 12 commits into
Twigpine:mainfrom
jasonkneen:jason-dev

Conversation

@jasonkneen

@jasonkneen jasonkneen commented Aug 12, 2026 •

Copy link
Copy Markdown

This pull request introduces significant improvements to the provider management and OAuth flow, particularly enhancing support for activating and managing Claude Code (Anthropic) via OAuth. The changes ensure that Claude Code OAuth can be selected and activated as a provider in the same way as other credential-backed providers, and that user model preferences are preserved during provider switches. Additionally, the test coverage and internal state handling for provider selection and activation have been expanded and clarified.

Enhancements to Claude Code OAuth support and provider management:

  • Claude Code (Anthropic) OAuth can now be selected and activated as a provider from both the preset picker and the provider management menu, using a distinct option value (CLAUDE_OAUTH_OPTION_VALUE). The activation process ensures that the correct state is set and that the user's model preference is preserved if it is a valid first-party Claude model. [1] [2] [3] [4]
  • The provider menu and picker logic have been updated to correctly reflect the availability and active state of Claude Code OAuth, including UI state for when it is active and gating actions like edit/delete to only valid providers. [1] [2] [3]
  • Internal state and effect hooks now track and refresh Claude Code OAuth credentials, ensuring that the UI updates in response to authentication changes and that the active state is correctly set and displayed. [1] [2] [3] [4] [5]

Test and utility improvements:

  • Added utility function isSuccessfulProviderSetupResult to standardize the detection of successful provider setup results, with corresponding unit tests to ensure correct behavior for different provider actions. [1] [2] [3] [4]
  • Updated test setup and teardown in StartupScreen.test.ts to correctly reset and restore provider-related global config keys, preventing test state leakage. [1] [2] [3] [4]

Codebase organization and clarity:

  • Improved code comments, variable naming, and option handling to clarify the distinct roles of built-in Anthropic, Claude Code OAuth, and other providers, reducing the risk of UI or logic drift. [1] [2] F51432b7L559R574, [3]

These changes collectively improve the flexibility and reliability of provider selection and activation, especially for users authenticating with Claude Code via OAuth, and ensure a more robust and maintainable codebase.## Summary

  • what changed
  • why it changed

Impact

  • user-facing impact:
  • developer/maintainer impact:

Testing

  • bun run build
  • bun run smoke
  • bun run check
  • focused tests:

Notes

  • provider/model path tested:
  • screenshots attached (if UI changed):
  • follow-up work or known limitations:

Summary by CodeRabbit

  • New Features

    • Added Claude Code OAuth support, including credential detection, activation, profile selection, and startup labeling.
    • Added Claude Fable 5, Opus 5, and Sonnet 5 models across supported model pickers.
    • Added broader agent and productivity tool support, including file management, diagnostics, search, planning, and todo workflows.
  • Bug Fixes

    • Improved provider activation handling and preserved compatible Anthropic model selections.
    • Prevented stale provider settings from overriding the selected Anthropic profile.
    • Improved OAuth completion and model-name recognition.

Add recovered __esm wrapper files for many services/tools modules under src/services/tools (agents, ask-user-question, edit-file, enter/exit plan mode, get-diagnostics, get-self-knowledge, glob, grep, read-file, write-file, shell-command, killshell, read-directory, read-multiple-files, skills, thinking, todo-write, web-fetch, web-search, and various utils/types/formatters). These files are recovered wrapper slices extracted from bundled segments to preserve module initialization logic and enable per-path inspection and debugging. Note: these are wrapper/inspection files (recovered .recovered.js) from bundling segments, not the original TypeScript source files.
Add a dedicated Claude Code (OAuth) path in ProviderManager when stored Claude AI tokens are available, keep it hidden in bare mode, and avoid sending users through Anthropic API key setup when selecting it. Also register the new Claude 5 model family across Anthropic model definitions, canonicalization, and model option lists for first-party API and Claude subscriber flows, with tests covering both behaviors.
Improves Claude Code OAuth behavior across provider setup and switching. ProviderManager now treats OAuth activation as a successful first-run result, exposes OAuth in the active-provider picker when credentials exist, correctly marks it active via the Anthropic sentinel, and preserves a saved first-party /model choice instead of resetting to defaults. Startup provider detection now labels persisted OAuth sessions correctly, and Anthropic sentinel env application now clears stale third-party env so restarts don’t route Claude models through leftover OpenGateway/MiMo settings. Adds focused regression tests for these paths.
Copilot AI lite review requested due to automatic review settings August 12, 2026 19:18
@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Claude Code OAuth provider

Layer / File(s) Summary
OAuth activation and setup results
src/components/ProviderManager.tsx, src/components/ConsoleOAuthFlow.tsx
Claude Code OAuth credentials are detected and activated through the Anthropic sentinel. Successful setup results now include saved and activated actions.
Provider state and startup detection
src/components/ProviderManager.tsx, src/components/StartupScreen.ts, src/utils/providerProfiles.ts
Provider menus and startup detection now represent Claude Code OAuth. Stale managed provider environment is cleared when the Anthropic sentinel is active.
OAuth regression coverage
src/components/ProviderManager.test.tsx, src/components/StartupScreen.test.ts, src/components/ConsoleOAuthFlow.test.tsx, src/utils/providerProfiles.test.ts
Tests cover OAuth discovery, activation, model preservation, active-state rendering, deletion behavior, bare mode, startup labels, and setup-result validation.

Anthropic model catalog

Layer / File(s) Summary
Claude model definitions and options
src/integrations/models/claude.ts, src/utils/model/model.ts, src/utils/model/modelOptions.ts
Claude Fable 5, Opus 5, and Sonnet 5 are defined, canonicalized, and added to Anthropic model pickers.
Model option regression coverage
src/utils/model/*.test.ts
Tests cover model canonicalization and model availability for first-party Anthropic and Claude subscriber branches.

Recovered tool modules

Layer / File(s) Summary
Recovered tool wrappers
src/services/tools/**/*.recovered.js
Recovered ES module wrappers initialize agent, interactive, file, search, process, planning, skills, utility, web, and file-writing tools. They preserve tool schemas, registrations, dependencies, and execution bindings.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Risk Surface Disclosed ⚠️ Warning The diff changes Claude OAuth, provider routing, and startup configuration, but the PR description and review comments do not explicitly state the risk surface or whether a blocker exists. Add an explicit review note covering OAuth/provider-routing/startup risks and state clearly whether the changes introduce a release blocker.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately identifies the main Claude Code OAuth and settings changes.
Description check ✅ Passed The description explains the OAuth, provider, model, and testing changes, but the template checklist and notes remain largely unfilled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No Hidden Policy Change ✅ Passed OAuth, sentinel routing, model, and provider-action changes are explicit in the PR and feature files; recovered tool wrappers are unreferenced and excluded from package files, with no hidden policy...
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copilot AI 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.

Pull request overview

This PR improves provider selection/activation around the Anthropic “built-in” sentinel and Claude Code OAuth, aiming to make OAuth behave like other credential-backed providers and preserve user model preferences across provider switches. It also updates model lists/canonicalization to include new Claude 5-era models and adds tests for the new behaviors.

Changes:

  • Added explicit handling for the Anthropic sentinel state (including restart env cleanup) and a helper to detect “Anthropic default is active”.
  • Expanded ProviderManager UX/state to surface Claude Code OAuth as a selectable provider and preserve first-party model settings when switching back to Anthropic.
  • Updated model options + canonicalization to include new “current” Anthropic model generations, with additional test coverage.

Reviewed changes

Copilot reviewed 76 out of 81 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/utils/providerProfiles.ts Adds Anthropic-sentinel helper and adjusts sentinel application behavior to clear leftover env reliably.
src/utils/providerProfiles.test.ts Adds regression coverage for sentinel vs leftover env keys on restart.
src/utils/model/modelOptions.ts Introduces “current Anthropic model options” list and appends it in first-party/subscriber paths.
src/utils/model/modelOptions.crossProfile.test.ts Adds coverage for current Anthropic models being exposed in relevant branches.
src/utils/model/model.ts Updates first-party model canonicalization to recognize Claude 5 generation strings first.
src/utils/model/model.canonicalization.test.ts Adds direct unit test for canonicalization behavior with current generations.
src/integrations/models/claude.ts Adds Claude Fable 5 / Opus 5 / Sonnet 5 model definitions.
src/components/StartupScreen.ts Labels persisted Claude Code OAuth sessions distinctly on the startup banner.
src/components/StartupScreen.test.ts Adds coverage for startup banner labeling based on sentinel + oauthAccount.
src/components/ProviderManager.tsx Adds Claude Code OAuth credential detection, picker/menu plumbing, and model preservation on activation.
src/components/ProviderManager.test.tsx Adds extensive ProviderManager coverage for OAuth availability/activation + a preset ordering tweak.
src/components/ConsoleOAuthFlow.tsx Adds isSuccessfulProviderSetupResult helper and broadens “success” to include activated results.
src/components/ConsoleOAuthFlow.test.tsx Adds tests for isSuccessfulProviderSetupResult.
src/services/tools/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/web-search/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/web-fetch/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/get-tools-for-mode.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/utils/soft-error.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/utils/read-summary.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/utils/path-display.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/grep/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/grep/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/grep/grep.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/grep/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/glob/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/glob/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/glob/glob.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/glob/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-file/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-file/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-file/read-file.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-file/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-directory/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-directory/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-directory/read-directory.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-directory/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-multiple-files/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-multiple-files/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-multiple-files/read-multiple-files.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/read-multiple-files/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/write-file/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/write-file/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/write-file/write-file.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/write-file/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/edit-file/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/edit-file/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/edit-file/edit-file.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/edit-file/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/shell-command/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/shell-command/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/shell-command/shell-command.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/shell-command/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/killshell/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/killshell/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/killshell/killshell.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/killshell/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/thinking/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/thinking/thinking.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/todo-write/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/todo-write/todo-write.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/skills/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/skills/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/skills/loader.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/skills/xml-generator.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/get-self-knowledge/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/get-self-knowledge/get-self-knowledge.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/get-diagnostics/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/get-diagnostics/types.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/get-diagnostics/get-diagnostics.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/get-diagnostics/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/ask-user-question/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/ask-user-question/ask-user-question.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/ask-user-question/formatter.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/agents/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/agents/manager.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/agents/loader.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/agents/execute.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/agents/defaults.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/agents/utils.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/enter-plan-mode/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
src/services/tools/exit-plan-mode/index.ts.recovered.js Recovered/bundled artifact file (should not be committed as source).
Files not reviewed (5)
  • src/services/tools/agents/defaults.ts.recovered.js: Generated file
  • src/services/tools/ask-user-question/index.ts.recovered.js: Generated file
  • src/services/tools/edit-file/index.ts.recovered.js: Generated file
  • src/services/tools/enter-plan-mode/index.ts.recovered.js: Generated file
  • src/services/tools/exit-plan-mode/index.ts.recovered.js: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 2259 to +2267
onChange={(value: string) => {
if (value === 'skip') {
closeWithCancelled('Provider setup skipped')
return
}
if (value === ANTHROPIC_DEFAULT_PROFILE_ID) {
void activateSelectedProvider(value)
return
}
Comment on lines +2196 to +2205
if (hasClaudeAiOAuthCredentials) {
const anthropicIndex = options.findIndex(
option => option.value === 'anthropic',
)
options.splice(anthropicIndex >= 0 ? anthropicIndex + 1 : options.length, 0, {
value: ANTHROPIC_DEFAULT_PROFILE_ID,
label: CLAUDE_OAUTH_PROVIDER_NAME,
description: 'Use your authenticated Claude Code subscription',
})
}
Comment on lines +1 to +42
/*
Recovered module wrapper
Original path: src/tools/index.ts
Init symbol: rv
Statement range: 628773-629496
Wrapper range: 628780-629495
Approximate segment: ../../../segments/0197__src-tools-index.ts.mjs
Resolved init dependencies:
- src/tools/grep/index.ts
- src/tools/web-fetch/index.ts
- src/mcp/client/tool-adapter.ts
- src/tools/glob/index.ts
- src/tui/vscode-context/ipc-client.ts
- src/tools/get-tools-for-mode.ts
- ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js
- src/tools/killshell/index.ts
- src/tools/thinking/index.ts
- src/tools/agents/index.ts
- src/tools/get-diagnostics/index.ts
- src/tools/web-search/index.ts
- src/tools/exit-plan-mode/index.ts
- src/utils/telemetry/telemetry.ts
- src/tools/read-file/index.ts
- src/tools/shell-command/index.ts
- src/tools/enter-plan-mode/index.ts
- src/mcp/client/connection-manager.ts
- src/tools/read-multiple-files/index.ts
- ../shared/src/constants/tools.ts
- src/tools/edit-file/index.ts
- src/tools/todo-write/index.ts
- src/tools/write-file/index.ts
- src/tools/read-directory/index.ts
- src/tools/ask-user-question/index.ts
- src/tools/get-self-knowledge/index.ts
- src/utils/taste-path-validator.ts

Note:
The larger segment file usually contains hoisted declarations that belonged to this source file before bundling.
This file preserves the exact __esm wrapper slice for quick per-path inspection.
*/

__esm({"src/tools/index.ts"(){Ht(),Ow(),eS(),iS(),hS(),_S(),$S(),BS(),QS(),JS(),eb(),ib(),Ib(),Nb(),Rb(),Mb(),$b(),Kb(),nE(),Db(),aw(),AE(),TE(),KC(),nv(),No(),FC(),YC=[Nw,Yw,rS,cS,wS,IS,OS,HS,KS,XS,nb,cb,ub,db,Fb,Jb],JC=[mb,pb],XC=new Map(YC.map(e=>[e.name,e])),ZC=new Set([...YC.map(e=>e.name),...JC.map(e=>e.name)]),__name(isAgentTool,"isAgentTool"),__name(executeTool,"executeTool"),__name(getToolSchemas,"getToolSchemas"),__name(toPascalCase,"toPascalCase"),ev={},YC.forEach(e=>{ev[e.name]=toPascalCase(e.name)}),JC.forEach(e=>{ev[e.name]=toPascalCase(e.name)}),tv={},Object.entries(ev).forEach(([e,t])=>{tv[t]=e}),initializeAgentManager({clientTools:YC,serverTools:JC,toolsMap:XC,displayNameToToolName:tv})}})

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ConsoleOAuthFlow.test.tsx`:
- Around line 130-150: Extend the test for isSuccessfulProviderSetupResult to
cover saved results with a missing message and with an empty-string message,
asserting both are rejected. Keep the existing valid saved, activated,
cancelled, and undefined cases, and run the targeted ConsoleOAuthFlow test.

In `@src/components/ConsoleOAuthFlow.tsx`:
- Around line 33-42: Update isSuccessfulProviderSetupResult to return the type
predicate result is ProviderManagerResult & { message: string } instead of
boolean, while preserving its existing success checks so callers can safely
narrow result.message to a non-optional string.

In `@src/components/ProviderManager.test.tsx`:
- Around line 3007-3027: Ensure both tests isolate environment state: in
src/components/ProviderManager.test.tsx lines 3007-3027, wrap the body of the
“ProviderManager hides Claude Code OAuth in bare mode” test in try/finally and
delete process.env.CLAUDE_CODE_SIMPLE in finally; in
src/components/StartupScreen.test.ts lines 238-259, add a describe-scoped
afterEach that restores the captured original process.env.ANTHROPIC_MODEL value.
- Around line 2689-2692: Replace both hardcoded three-press j loops in the OAuth
navigation tests with navigation derived from PRESET_ORDER using the existing
navigateToPreset helper, targeting the Claude Code OAuth preset. Ensure both
tests select the correct row regardless of presets inserted before Anthropic,
then validate with the specified Bun test.

In `@src/components/ProviderManager.tsx`:
- Around line 2196-2205: Use CLAUDE_OAUTH_OPTION_VALUE for the Claude OAuth
preset option value in the options insertion near hasClaudeAiOAuthCredentials,
and update the corresponding activateSelectedProvider handling and first-run
tests to select that value while preserving its mapping to
ANTHROPIC_DEFAULT_PROFILE_ID.

In `@src/integrations/models/claude.ts`:
- Around line 4-19: Add contextWindow set to 1_000_000 and maxOutputTokens set
to 128_000 on each of the three Claude 5 model descriptors defined alongside
claude-fable-5. Add focused metadata assertions verifying both fields for all
three descriptors, preserving route and environment override behavior.

In `@src/services/tools/shell-command/types.ts.recovered.js`:
- Line 16: Update the FS runtime schema’s timeout field to use strict numeric
conversion that rejects malformed strings such as “100abc”, then enforce the
documented inclusive 100–300000 ms range with minimum and maximum validation.
Update the advertised shell-command schema to expose the same minimum and
maximum constraints, and add tests covering both boundaries and out-of-range
values.

In `@src/utils/model/modelOptions.ts`:
- Around line 194-215: Update getCurrentAnthropicModelOptions and the related
subscriber/first-party PAYG option-selection branches to include claude-fable-5
only when the account has the Fable-specific entitlement or availability flag;
retain the existing options for ineligible accounts and preserve the optional
allowlist behavior. Add tests covering eligible and ineligible accounts across
the affected branches.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 17554ce2-607f-487c-bc97-23798110cccb

📥 Commits

Reviewing files that changed from the base of the PR and between 6277bfa and e5c75aa.

📒 Files selected for processing (81)
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/components/ConsoleOAuthFlow.tsx
  • src/components/ProviderManager.test.tsx
  • src/components/ProviderManager.tsx
  • src/components/StartupScreen.test.ts
  • src/components/StartupScreen.ts
  • src/integrations/models/claude.ts
  • src/services/tools/agents/defaults.ts.recovered.js
  • src/services/tools/agents/execute.ts.recovered.js
  • src/services/tools/agents/index.ts.recovered.js
  • src/services/tools/agents/loader.ts.recovered.js
  • src/services/tools/agents/manager.ts.recovered.js
  • src/services/tools/agents/utils.ts.recovered.js
  • src/services/tools/ask-user-question/ask-user-question.ts.recovered.js
  • src/services/tools/ask-user-question/formatter.ts.recovered.js
  • src/services/tools/ask-user-question/index.ts.recovered.js
  • src/services/tools/edit-file/edit-file.ts.recovered.js
  • src/services/tools/edit-file/formatter.ts.recovered.js
  • src/services/tools/edit-file/index.ts.recovered.js
  • src/services/tools/edit-file/types.ts.recovered.js
  • src/services/tools/enter-plan-mode/index.ts.recovered.js
  • src/services/tools/exit-plan-mode/index.ts.recovered.js
  • src/services/tools/get-diagnostics/formatter.ts.recovered.js
  • src/services/tools/get-diagnostics/get-diagnostics.ts.recovered.js
  • src/services/tools/get-diagnostics/index.ts.recovered.js
  • src/services/tools/get-diagnostics/types.ts.recovered.js
  • src/services/tools/get-self-knowledge/get-self-knowledge.ts.recovered.js
  • src/services/tools/get-self-knowledge/index.ts.recovered.js
  • src/services/tools/get-tools-for-mode.ts.recovered.js
  • src/services/tools/glob/formatter.ts.recovered.js
  • src/services/tools/glob/glob.ts.recovered.js
  • src/services/tools/glob/index.ts.recovered.js
  • src/services/tools/glob/types.ts.recovered.js
  • src/services/tools/grep/formatter.ts.recovered.js
  • src/services/tools/grep/grep.ts.recovered.js
  • src/services/tools/grep/index.ts.recovered.js
  • src/services/tools/grep/types.ts.recovered.js
  • src/services/tools/index.ts.recovered.js
  • src/services/tools/killshell/formatter.ts.recovered.js
  • src/services/tools/killshell/index.ts.recovered.js
  • src/services/tools/killshell/killshell.ts.recovered.js
  • src/services/tools/killshell/types.ts.recovered.js
  • src/services/tools/read-directory/formatter.ts.recovered.js
  • src/services/tools/read-directory/index.ts.recovered.js
  • src/services/tools/read-directory/read-directory.ts.recovered.js
  • src/services/tools/read-directory/types.ts.recovered.js
  • src/services/tools/read-file/formatter.ts.recovered.js
  • src/services/tools/read-file/index.ts.recovered.js
  • src/services/tools/read-file/read-file.ts.recovered.js
  • src/services/tools/read-file/types.ts.recovered.js
  • src/services/tools/read-multiple-files/formatter.ts.recovered.js
  • src/services/tools/read-multiple-files/index.ts.recovered.js
  • src/services/tools/read-multiple-files/read-multiple-files.ts.recovered.js
  • src/services/tools/read-multiple-files/types.ts.recovered.js
  • src/services/tools/shell-command/formatter.ts.recovered.js
  • src/services/tools/shell-command/index.ts.recovered.js
  • src/services/tools/shell-command/shell-command.ts.recovered.js
  • src/services/tools/shell-command/types.ts.recovered.js
  • src/services/tools/skills/index.ts.recovered.js
  • src/services/tools/skills/loader.ts.recovered.js
  • src/services/tools/skills/types.ts.recovered.js
  • src/services/tools/skills/xml-generator.ts.recovered.js
  • src/services/tools/thinking/index.ts.recovered.js
  • src/services/tools/thinking/thinking.ts.recovered.js
  • src/services/tools/todo-write/index.ts.recovered.js
  • src/services/tools/todo-write/todo-write.ts.recovered.js
  • src/services/tools/utils/path-display.ts.recovered.js
  • src/services/tools/utils/read-summary.ts.recovered.js
  • src/services/tools/utils/soft-error.ts.recovered.js
  • src/services/tools/web-fetch/index.ts.recovered.js
  • src/services/tools/web-search/index.ts.recovered.js
  • src/services/tools/write-file/formatter.ts.recovered.js
  • src/services/tools/write-file/index.ts.recovered.js
  • src/services/tools/write-file/types.ts.recovered.js
  • src/services/tools/write-file/write-file.ts.recovered.js
  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/utils/model/modelOptions.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/providerProfiles.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not add new Python code, Python provider paths, or Python dependencies without explicit maintainer approval.

**/*.{ts,tsx,js,jsx}: Follow the existing code style in touched source files, prefer small readable changes, avoid unrelated reformatting, and keep comments useful and concise.
Preserve existing repository patterns unless intentionally refactoring them, and avoid broad rewrites or unnecessary generated changes.
Review AI-assisted code for correctness, style consistency, unnecessary changes, and adherence to project architecture before submitting it.

Files:

  • src/services/tools/agents/utils.ts.recovered.js
  • src/services/tools/skills/xml-generator.ts.recovered.js
  • src/services/tools/edit-file/formatter.ts.recovered.js
  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/services/tools/grep/grep.ts.recovered.js
  • src/services/tools/agents/index.ts.recovered.js
  • src/services/tools/agents/defaults.ts.recovered.js
  • src/services/tools/ask-user-question/ask-user-question.ts.recovered.js
  • src/services/tools/utils/path-display.ts.recovered.js
  • src/services/tools/skills/loader.ts.recovered.js
  • src/services/tools/skills/types.ts.recovered.js
  • src/services/tools/read-directory/formatter.ts.recovered.js
  • src/services/tools/thinking/index.ts.recovered.js
  • src/services/tools/killshell/formatter.ts.recovered.js
  • src/services/tools/get-diagnostics/types.ts.recovered.js
  • src/services/tools/read-file/formatter.ts.recovered.js
  • src/services/tools/agents/loader.ts.recovered.js
  • src/services/tools/write-file/formatter.ts.recovered.js
  • src/services/tools/utils/read-summary.ts.recovered.js
  • src/services/tools/agents/manager.ts.recovered.js
  • src/services/tools/read-file/read-file.ts.recovered.js
  • src/services/tools/read-directory/read-directory.ts.recovered.js
  • src/services/tools/web-search/index.ts.recovered.js
  • src/services/tools/get-self-knowledge/index.ts.recovered.js
  • src/services/tools/ask-user-question/index.ts.recovered.js
  • src/services/tools/shell-command/types.ts.recovered.js
  • src/services/tools/write-file/types.ts.recovered.js
  • src/services/tools/grep/index.ts.recovered.js
  • src/services/tools/glob/index.ts.recovered.js
  • src/services/tools/read-multiple-files/index.ts.recovered.js
  • src/services/tools/read-file/index.ts.recovered.js
  • src/services/tools/read-multiple-files/formatter.ts.recovered.js
  • src/components/StartupScreen.ts
  • src/services/tools/thinking/thinking.ts.recovered.js
  • src/services/tools/grep/formatter.ts.recovered.js
  • src/integrations/models/claude.ts
  • src/services/tools/glob/glob.ts.recovered.js
  • src/services/tools/get-tools-for-mode.ts.recovered.js
  • src/services/tools/edit-file/types.ts.recovered.js
  • src/services/tools/get-diagnostics/get-diagnostics.ts.recovered.js
  • src/services/tools/killshell/killshell.ts.recovered.js
  • src/services/tools/ask-user-question/formatter.ts.recovered.js
  • src/services/tools/edit-file/index.ts.recovered.js
  • src/services/tools/get-diagnostics/index.ts.recovered.js
  • src/services/tools/shell-command/shell-command.ts.recovered.js
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/services/tools/agents/execute.ts.recovered.js
  • src/services/tools/glob/formatter.ts.recovered.js
  • src/services/tools/index.ts.recovered.js
  • src/services/tools/read-directory/index.ts.recovered.js
  • src/services/tools/glob/types.ts.recovered.js
  • src/services/tools/get-diagnostics/formatter.ts.recovered.js
  • src/services/tools/write-file/index.ts.recovered.js
  • src/services/tools/skills/index.ts.recovered.js
  • src/services/tools/web-fetch/index.ts.recovered.js
  • src/services/tools/read-multiple-files/read-multiple-files.ts.recovered.js
  • src/services/tools/get-self-knowledge/get-self-knowledge.ts.recovered.js
  • src/services/tools/shell-command/formatter.ts.recovered.js
  • src/services/tools/enter-plan-mode/index.ts.recovered.js
  • src/utils/providerProfiles.test.ts
  • src/services/tools/todo-write/index.ts.recovered.js
  • src/services/tools/exit-plan-mode/index.ts.recovered.js
  • src/services/tools/todo-write/todo-write.ts.recovered.js
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/ConsoleOAuthFlow.tsx
  • src/services/tools/killshell/types.ts.recovered.js
  • src/services/tools/utils/soft-error.ts.recovered.js
  • src/services/tools/read-multiple-files/types.ts.recovered.js
  • src/services/tools/shell-command/index.ts.recovered.js
  • src/services/tools/grep/types.ts.recovered.js
  • src/services/tools/edit-file/edit-file.ts.recovered.js
  • src/utils/providerProfiles.ts
  • src/utils/model/modelOptions.ts
  • src/services/tools/read-file/types.ts.recovered.js
  • src/services/tools/read-directory/types.ts.recovered.js
  • src/components/StartupScreen.test.ts
  • src/services/tools/write-file/write-file.ts.recovered.js
  • src/services/tools/killshell/index.ts.recovered.js
  • src/components/ProviderManager.tsx
  • src/components/ProviderManager.test.tsx
**/*

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update documentation when setup, commands, or user-facing behavior changes.

Files:

  • src/services/tools/agents/utils.ts.recovered.js
  • src/services/tools/skills/xml-generator.ts.recovered.js
  • src/services/tools/edit-file/formatter.ts.recovered.js
  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/services/tools/grep/grep.ts.recovered.js
  • src/services/tools/agents/index.ts.recovered.js
  • src/services/tools/agents/defaults.ts.recovered.js
  • src/services/tools/ask-user-question/ask-user-question.ts.recovered.js
  • src/services/tools/utils/path-display.ts.recovered.js
  • src/services/tools/skills/loader.ts.recovered.js
  • src/services/tools/skills/types.ts.recovered.js
  • src/services/tools/read-directory/formatter.ts.recovered.js
  • src/services/tools/thinking/index.ts.recovered.js
  • src/services/tools/killshell/formatter.ts.recovered.js
  • src/services/tools/get-diagnostics/types.ts.recovered.js
  • src/services/tools/read-file/formatter.ts.recovered.js
  • src/services/tools/agents/loader.ts.recovered.js
  • src/services/tools/write-file/formatter.ts.recovered.js
  • src/services/tools/utils/read-summary.ts.recovered.js
  • src/services/tools/agents/manager.ts.recovered.js
  • src/services/tools/read-file/read-file.ts.recovered.js
  • src/services/tools/read-directory/read-directory.ts.recovered.js
  • src/services/tools/web-search/index.ts.recovered.js
  • src/services/tools/get-self-knowledge/index.ts.recovered.js
  • src/services/tools/ask-user-question/index.ts.recovered.js
  • src/services/tools/shell-command/types.ts.recovered.js
  • src/services/tools/write-file/types.ts.recovered.js
  • src/services/tools/grep/index.ts.recovered.js
  • src/services/tools/glob/index.ts.recovered.js
  • src/services/tools/read-multiple-files/index.ts.recovered.js
  • src/services/tools/read-file/index.ts.recovered.js
  • src/services/tools/read-multiple-files/formatter.ts.recovered.js
  • src/components/StartupScreen.ts
  • src/services/tools/thinking/thinking.ts.recovered.js
  • src/services/tools/grep/formatter.ts.recovered.js
  • src/integrations/models/claude.ts
  • src/services/tools/glob/glob.ts.recovered.js
  • src/services/tools/get-tools-for-mode.ts.recovered.js
  • src/services/tools/edit-file/types.ts.recovered.js
  • src/services/tools/get-diagnostics/get-diagnostics.ts.recovered.js
  • src/services/tools/killshell/killshell.ts.recovered.js
  • src/services/tools/ask-user-question/formatter.ts.recovered.js
  • src/services/tools/edit-file/index.ts.recovered.js
  • src/services/tools/get-diagnostics/index.ts.recovered.js
  • src/services/tools/shell-command/shell-command.ts.recovered.js
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/services/tools/agents/execute.ts.recovered.js
  • src/services/tools/glob/formatter.ts.recovered.js
  • src/services/tools/index.ts.recovered.js
  • src/services/tools/read-directory/index.ts.recovered.js
  • src/services/tools/glob/types.ts.recovered.js
  • src/services/tools/get-diagnostics/formatter.ts.recovered.js
  • src/services/tools/write-file/index.ts.recovered.js
  • src/services/tools/skills/index.ts.recovered.js
  • src/services/tools/web-fetch/index.ts.recovered.js
  • src/services/tools/read-multiple-files/read-multiple-files.ts.recovered.js
  • src/services/tools/get-self-knowledge/get-self-knowledge.ts.recovered.js
  • src/services/tools/shell-command/formatter.ts.recovered.js
  • src/services/tools/enter-plan-mode/index.ts.recovered.js
  • src/utils/providerProfiles.test.ts
  • src/services/tools/todo-write/index.ts.recovered.js
  • src/services/tools/exit-plan-mode/index.ts.recovered.js
  • src/services/tools/todo-write/todo-write.ts.recovered.js
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/ConsoleOAuthFlow.tsx
  • src/services/tools/killshell/types.ts.recovered.js
  • src/services/tools/utils/soft-error.ts.recovered.js
  • src/services/tools/read-multiple-files/types.ts.recovered.js
  • src/services/tools/shell-command/index.ts.recovered.js
  • src/services/tools/grep/types.ts.recovered.js
  • src/services/tools/edit-file/edit-file.ts.recovered.js
  • src/utils/providerProfiles.ts
  • src/utils/model/modelOptions.ts
  • src/services/tools/read-file/types.ts.recovered.js
  • src/services/tools/read-directory/types.ts.recovered.js
  • src/components/StartupScreen.test.ts
  • src/services/tools/write-file/write-file.ts.recovered.js
  • src/services/tools/killshell/index.ts.recovered.js
  • src/components/ProviderManager.tsx
  • src/components/ProviderManager.test.tsx

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/services/tools/agents/utils.ts.recovered.js
  • src/services/tools/skills/xml-generator.ts.recovered.js
  • src/services/tools/edit-file/formatter.ts.recovered.js
  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/services/tools/grep/grep.ts.recovered.js
  • src/services/tools/agents/index.ts.recovered.js
  • src/services/tools/agents/defaults.ts.recovered.js
  • src/services/tools/ask-user-question/ask-user-question.ts.recovered.js
  • src/services/tools/utils/path-display.ts.recovered.js
  • src/services/tools/skills/loader.ts.recovered.js
  • src/services/tools/skills/types.ts.recovered.js
  • src/services/tools/read-directory/formatter.ts.recovered.js
  • src/services/tools/thinking/index.ts.recovered.js
  • src/services/tools/killshell/formatter.ts.recovered.js
  • src/services/tools/get-diagnostics/types.ts.recovered.js
  • src/services/tools/read-file/formatter.ts.recovered.js
  • src/services/tools/agents/loader.ts.recovered.js
  • src/services/tools/write-file/formatter.ts.recovered.js
  • src/services/tools/utils/read-summary.ts.recovered.js
  • src/services/tools/agents/manager.ts.recovered.js
  • src/services/tools/read-file/read-file.ts.recovered.js
  • src/services/tools/read-directory/read-directory.ts.recovered.js
  • src/services/tools/web-search/index.ts.recovered.js
  • src/services/tools/get-self-knowledge/index.ts.recovered.js
  • src/services/tools/ask-user-question/index.ts.recovered.js
  • src/services/tools/shell-command/types.ts.recovered.js
  • src/services/tools/write-file/types.ts.recovered.js
  • src/services/tools/grep/index.ts.recovered.js
  • src/services/tools/glob/index.ts.recovered.js
  • src/services/tools/read-multiple-files/index.ts.recovered.js
  • src/services/tools/read-file/index.ts.recovered.js
  • src/services/tools/read-multiple-files/formatter.ts.recovered.js
  • src/components/StartupScreen.ts
  • src/services/tools/thinking/thinking.ts.recovered.js
  • src/services/tools/grep/formatter.ts.recovered.js
  • src/integrations/models/claude.ts
  • src/services/tools/glob/glob.ts.recovered.js
  • src/services/tools/get-tools-for-mode.ts.recovered.js
  • src/services/tools/edit-file/types.ts.recovered.js
  • src/services/tools/get-diagnostics/get-diagnostics.ts.recovered.js
  • src/services/tools/killshell/killshell.ts.recovered.js
  • src/services/tools/ask-user-question/formatter.ts.recovered.js
  • src/services/tools/edit-file/index.ts.recovered.js
  • src/services/tools/get-diagnostics/index.ts.recovered.js
  • src/services/tools/shell-command/shell-command.ts.recovered.js
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/services/tools/agents/execute.ts.recovered.js
  • src/services/tools/glob/formatter.ts.recovered.js
  • src/services/tools/index.ts.recovered.js
  • src/services/tools/read-directory/index.ts.recovered.js
  • src/services/tools/glob/types.ts.recovered.js
  • src/services/tools/get-diagnostics/formatter.ts.recovered.js
  • src/services/tools/write-file/index.ts.recovered.js
  • src/services/tools/skills/index.ts.recovered.js
  • src/services/tools/web-fetch/index.ts.recovered.js
  • src/services/tools/read-multiple-files/read-multiple-files.ts.recovered.js
  • src/services/tools/get-self-knowledge/get-self-knowledge.ts.recovered.js
  • src/services/tools/shell-command/formatter.ts.recovered.js
  • src/services/tools/enter-plan-mode/index.ts.recovered.js
  • src/utils/providerProfiles.test.ts
  • src/services/tools/todo-write/index.ts.recovered.js
  • src/services/tools/exit-plan-mode/index.ts.recovered.js
  • src/services/tools/todo-write/todo-write.ts.recovered.js
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/ConsoleOAuthFlow.tsx
  • src/services/tools/killshell/types.ts.recovered.js
  • src/services/tools/utils/soft-error.ts.recovered.js
  • src/services/tools/read-multiple-files/types.ts.recovered.js
  • src/services/tools/shell-command/index.ts.recovered.js
  • src/services/tools/grep/types.ts.recovered.js
  • src/services/tools/edit-file/edit-file.ts.recovered.js
  • src/utils/providerProfiles.ts
  • src/utils/model/modelOptions.ts
  • src/services/tools/read-file/types.ts.recovered.js
  • src/services/tools/read-directory/types.ts.recovered.js
  • src/components/StartupScreen.test.ts
  • src/services/tools/write-file/write-file.ts.recovered.js
  • src/services/tools/killshell/index.ts.recovered.js
  • src/components/ProviderManager.tsx
  • src/components/ProviderManager.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode and ESM imports throughout the source code.

Run bun run typecheck and bun run typecheck:type-tests for TypeScript changes when applicable.

Files:

  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/components/StartupScreen.ts
  • src/integrations/models/claude.ts
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/utils/providerProfiles.test.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/ConsoleOAuthFlow.tsx
  • src/utils/providerProfiles.ts
  • src/utils/model/modelOptions.ts
  • src/components/StartupScreen.test.ts
  • src/components/ProviderManager.tsx
  • src/components/ProviderManager.test.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use React and Ink patterns for terminal UI components.

Files:

  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/components/StartupScreen.ts
  • src/integrations/models/claude.ts
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/utils/providerProfiles.test.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/ConsoleOAuthFlow.tsx
  • src/utils/providerProfiles.ts
  • src/utils/model/modelOptions.ts
  • src/components/StartupScreen.test.ts
  • src/components/ProviderManager.tsx
  • src/components/ProviderManager.test.tsx
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Prefer existing service, provider, settings, permission, and UI patterns over introducing new abstractions.
Use chalk for terminal color and execa for child-process execution when those capabilities are needed.

Files:

  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/components/StartupScreen.ts
  • src/integrations/models/claude.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/utils/providerProfiles.ts
  • src/utils/model/modelOptions.ts
  • src/components/StartupScreen.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Add or update tests when behavior changes, and run the narrowest useful focused test checks.

Files:

  • src/utils/model/model.canonicalization.test.ts
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/utils/providerProfiles.test.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/StartupScreen.test.ts
  • src/components/ProviderManager.test.tsx
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{test,spec}.{ts,tsx,js,jsx}: Add or update tests when a code change affects behavior.
Use focused tests such as bun test ./path/to/test-file.test.ts when validating a narrowly scoped change.

Files:

  • src/utils/model/model.canonicalization.test.ts
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/utils/providerProfiles.test.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/StartupScreen.test.ts
  • src/components/ProviderManager.test.tsx
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/utils/model/model.canonicalization.test.ts
  • src/utils/model/model.ts
  • src/integrations/models/claude.ts
  • src/utils/providerProfiles.test.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/utils/providerProfiles.ts
  • src/utils/model/modelOptions.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/utils/model/model.canonicalization.test.ts
  • src/components/ConsoleOAuthFlow.test.tsx
  • src/utils/providerProfiles.test.ts
  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/StartupScreen.test.ts
  • src/components/ProviderManager.test.tsx
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: .github/pull_request_template.md:0-0
Timestamp: 2026-06-17T03:03:30.391Z
Learning: Pull request descriptions should include a Notes section documenting provider/model paths tested, screenshots (if UI changed), and follow-up work or known limitations
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: .github/pull_request_template.md:0-0
Timestamp: 2026-06-04T22:10:36.124Z
Learning: Pull request descriptions should include a Notes section documenting provider/model paths tested, screenshots (if UI changed), and follow-up work or known limitations
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2026-08-07T01:57:16.417Z
Learning: Applies to **/* : Update documentation when setup, commands, or user-facing behavior changes.
📚 Learning: 2026-06-03T16:06:37.928Z
Learnt from: beardthelion
Repo: Gitlawb/openclaude PR: 1407
File: scripts/build.ts:990-995
Timestamp: 2026-06-03T16:06:37.928Z
Learning: In Bun's bundler output, every virtual/namespaced module (e.g. those resolved via `build.onResolve` returning a custom `namespace`) is prefixed in the bundle with a boundary comment of the form `// <namespace>:<resolved-path>`. This means that in `scripts/build.ts`, the regex `bundleText.matchAll(/\/\/\s*missing-module-stub:(\S+)/g)` correctly finds all `missing-module-stub`-namespaced modules in `dist/cli.mjs` without requiring the `onLoad` handler to emit any marker comment itself — Bun emits those automatically. Adding a duplicate `// missing-module-stub:${args.path}` line in the loader stub would be redundant.

Applied to files:

  • src/services/tools/agents/utils.ts.recovered.js
  • src/services/tools/edit-file/formatter.ts.recovered.js
  • src/services/tools/utils/path-display.ts.recovered.js
  • src/services/tools/skills/loader.ts.recovered.js
  • src/services/tools/read-directory/formatter.ts.recovered.js
  • src/services/tools/killshell/formatter.ts.recovered.js
  • src/services/tools/get-diagnostics/types.ts.recovered.js
  • src/services/tools/read-file/formatter.ts.recovered.js
  • src/services/tools/agents/loader.ts.recovered.js
  • src/services/tools/write-file/formatter.ts.recovered.js
  • src/services/tools/utils/read-summary.ts.recovered.js
  • src/services/tools/read-directory/read-directory.ts.recovered.js
  • src/services/tools/glob/index.ts.recovered.js
  • src/services/tools/read-multiple-files/formatter.ts.recovered.js
  • src/services/tools/grep/formatter.ts.recovered.js
  • src/services/tools/glob/glob.ts.recovered.js
  • src/services/tools/get-diagnostics/get-diagnostics.ts.recovered.js
  • src/services/tools/shell-command/shell-command.ts.recovered.js
  • src/services/tools/glob/formatter.ts.recovered.js
  • src/services/tools/glob/types.ts.recovered.js
  • src/services/tools/get-diagnostics/formatter.ts.recovered.js
  • src/services/tools/web-fetch/index.ts.recovered.js
  • src/services/tools/todo-write/index.ts.recovered.js
  • src/services/tools/todo-write/todo-write.ts.recovered.js
  • src/services/tools/grep/types.ts.recovered.js
📚 Learning: 2026-08-07T01:57:07.096Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-07T01:57:07.096Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode and ESM imports throughout the source code.

Applied to files:

  • src/services/tools/skills/types.ts.recovered.js
  • src/services/tools/get-tools-for-mode.ts.recovered.js
  • src/services/tools/glob/types.ts.recovered.js
  • src/services/tools/todo-write/index.ts.recovered.js
  • src/services/tools/read-multiple-files/types.ts.recovered.js
  • src/services/tools/grep/types.ts.recovered.js
  • src/services/tools/read-directory/types.ts.recovered.js
📚 Learning: 2026-08-07T01:57:07.096Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-07T01:57:07.096Z
Learning: Applies to src/commands/**/*.ts : Use `commander` for CLI argument parsing and follow existing CLI command patterns.

Applied to files:

  • src/services/tools/shell-command/types.ts.recovered.js
  • src/services/tools/shell-command/index.ts.recovered.js
📚 Learning: 2026-08-07T01:57:07.096Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-07T01:57:07.096Z
Learning: Applies to **/*.{tsx,ts} : Use React and Ink patterns for terminal UI components.

Applied to files:

  • src/components/ConsoleOAuthFlow.test.tsx
  • src/components/ProviderManager.test.tsx
📚 Learning: 2026-08-07T01:57:07.096Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-07T01:57:07.096Z
Learning: Applies to web/src/data/releases.ts : Do not edit `web/src/data/releases.ts` in ordinary feature or bugfix PRs; it is owned by the release/web process.

Applied to files:

  • src/services/tools/web-fetch/index.ts.recovered.js
📚 Learning: 2026-08-07T01:57:16.417Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2026-08-07T01:57:16.417Z
Learning: Applies to web/src/data/releases.ts : Do not edit `web/src/data/releases.ts` during ordinary feature or bug-fix work; only modify it in an explicit release/web changelog PR.

Applied to files:

  • src/services/tools/web-fetch/index.ts.recovered.js
📚 Learning: 2026-08-07T01:57:07.096Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-07T01:57:07.096Z
Learning: When modifying provider behavior, test the exact provider/model path changed when possible and avoid breaking third-party providers.

Applied to files:

  • src/utils/model/modelOptions.crossProfile.test.ts
  • src/components/ProviderManager.test.tsx
📚 Learning: 2026-08-07T01:57:07.096Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-07T01:57:07.096Z
Learning: Applies to src/**/*.ts : Use `chalk` for terminal color and `execa` for child-process execution when those capabilities are needed.

Applied to files:

  • src/services/tools/shell-command/index.ts.recovered.js
📚 Learning: 2026-08-07T01:57:16.417Z
Learnt from: CR
Repo: Gitlawb/openclaude PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2026-08-07T01:57:16.417Z
Learning: When changing provider behavior, explicitly identify the affected provider path and test the exact provider/model path when possible.

Applied to files:

  • src/components/ProviderManager.test.tsx
🔇 Additional comments (44)
src/components/ConsoleOAuthFlow.tsx (1)

577-577: LGTM!

src/components/ProviderManager.tsx (2)

1068-1084: LGTM!

Also applies to: 1143-1158, 1370-1380, 1442-1452, 3046-3063


257-267: 🎯 Functional Correctness

No change needed.

MODEL_ALIASES contains only first-party Claude aliases, so isModelAlias cannot admit a non-Claude alias.

			> Likely an incorrect or invalid review comment.
src/components/StartupScreen.ts (1)

20-20: LGTM!

Also applies to: 166-179

src/components/StartupScreen.test.ts (1)

70-71: LGTM!

Also applies to: 82-83, 92-93, 261-278

src/utils/providerProfiles.ts (2)

866-878: LGTM!


1162-1177: 🗄️ Data Integrity & Integration

Keep the Anthropic sentinel precedence over third-party environment variables.

Complete shell selections intentionally yield to the sentinel. Saved profiles retain separate explicit-environment precedence.

			> Likely an incorrect or invalid review comment.
src/utils/providerProfiles.test.ts (1)

1651-1674: LGTM!

Also applies to: 2497-2580

src/components/ProviderManager.test.tsx (1)

4-4: LGTM!

Also applies to: 131-131, 193-208, 329-334, 356-356, 387-390, 429-433, 2618-2650, 2711-2797, 2799-2849, 2851-2901, 2903-2935, 2937-3005

src/services/tools/edit-file/edit-file.ts.recovered.js (1)

1-20: LGTM!

src/services/tools/edit-file/formatter.ts.recovered.js (1)

1-16: LGTM!

src/services/tools/edit-file/index.ts.recovered.js (1)

1-19: LGTM!

src/services/tools/read-directory/read-directory.ts.recovered.js (1)

1-17: LGTM!

src/services/tools/read-directory/types.ts.recovered.js (1)

1-16: LGTM!

src/services/tools/read-file/formatter.ts.recovered.js (1)

1-17: LGTM!

src/services/tools/read-file/index.ts.recovered.js (1)

1-19: LGTM!

src/services/tools/read-file/read-file.ts.recovered.js (1)

1-18: LGTM!

src/services/tools/read-file/types.ts.recovered.js (1)

16-16: 🎯 Functional Correctness

Do not change the recovered tool schemas.

The runtime uses src/tools/FileReadTool and src/tools/FileEditTool, not the recovered service modules. FileEditTool has no replacementCount, and FileReadTool uses its own semanticNumber-based schema.

			> Likely an incorrect or invalid review comment.
src/services/tools/get-diagnostics/formatter.ts.recovered.js (1)

16-16: 🩺 Stability & Availability

No runtime exclusion change is needed. These .recovered.js files are not imported, are not scanned by the build’s .ts/.tsx walkers, and are excluded from the published package.

			> Likely an incorrect or invalid review comment.
src/services/tools/glob/glob.ts.recovered.js (1)

19-19: 🩺 Stability & Availability

Do not block this change on recovered wrappers. No runtime code references *.recovered.js; the package and build use explicit entry points. Direct execution fails, but no production import path exists.

			> Likely an incorrect or invalid review comment.
src/utils/model/model.ts (1)

472-481: LGTM!

src/utils/model/model.canonicalization.test.ts (1)

1-10: LGTM!

src/utils/model/modelOptions.crossProfile.test.ts (1)

172-180: 🎯 Functional Correctness

No override reset is required.

beforeEach and afterEach reset activeApiProviderOverride, activeProfilesOverride, and activeSubscriberOverride. Each test exercises the intended branch independently.

			> Likely an incorrect or invalid review comment.
src/services/tools/ask-user-question/ask-user-question.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/ask-user-question/formatter.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/enter-plan-mode/index.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/thinking/index.ts.recovered.js (1)

17-17: LGTM!

src/services/tools/thinking/thinking.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/todo-write/index.ts.recovered.js (1)

17-17: LGTM!

src/services/tools/todo-write/todo-write.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/ask-user-question/index.ts.recovered.js (1)

18-18: 🗄️ Data Integrity & Integration

Keep this recovered artifact unchanged. The active CLI and SDK bundles use AskUserQuestionTool, whose Zod schema validates counts and uniqueness before tool.call. This recovered file has no active references.

			> Likely an incorrect or invalid review comment.
src/services/tools/exit-plan-mode/index.ts.recovered.js (1)

16-16: 🎯 Functional Correctness

Remove this finding.

The recovered files represent an old bundle snapshot. The active registry uses ExitPlanModeV2Tool, which rejects non-plan modes before prompting.

			> Likely an incorrect or invalid review comment.
src/services/tools/index.ts.recovered.js (1)

42-42: 🩺 Stability & Availability

Do not change the recovered wrappers. The CLI and SDK entry points do not import or reach any .recovered.js file, so restoring the listed initializer symbols is unnecessary.

			> Likely an incorrect or invalid review comment.
src/services/tools/killshell/index.ts.recovered.js (1)

19-19: 🩺 Stability & Availability

No runtime exclusion is required for these wrappers. The CLI and SDK builds use explicit TypeScript entry points, and the build scanner processes only .ts and .tsx files. No source file references .recovered.js, and the package files allowlist excludes all recovered wrappers.

			> Likely an incorrect or invalid review comment.
src/services/tools/shell-command/formatter.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/shell-command/shell-command.ts.recovered.js (1)

20-20: LGTM!

src/services/tools/skills/index.ts.recovered.js (1)

19-19: LGTM!

src/services/tools/skills/loader.ts.recovered.js (1)

18-18: LGTM!

src/services/tools/skills/types.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/skills/xml-generator.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/utils/path-display.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/utils/read-summary.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/utils/soft-error.ts.recovered.js (1)

16-16: LGTM!

src/services/tools/shell-command/index.ts.recovered.js (1)

21-21: 🩺 Stability & Availability

Keep recovered wrappers inspection-only. The package exports and build entrypoints exclude these files, and no tracked imports reference them.

			> Likely an incorrect or invalid review comment.

Comment on lines +130 to +150
test('first-run provider setup accepts both saved profiles and Claude Code activation', () => {
expect(
isSuccessfulProviderSetupResult({
action: 'saved',
message: 'Saved Gitlawb Opengateway',
}),
).toBe(true)
expect(
isSuccessfulProviderSetupResult({
action: 'activated',
message: 'Provider switched to Claude Code (OAuth) (claude-opus-5)',
}),
).toBe(true)
expect(
isSuccessfulProviderSetupResult({
action: 'cancelled',
message: 'Provider setup skipped',
}),
).toBe(false)
expect(isSuccessfulProviderSetupResult(undefined)).toBe(false)
})

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.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the message branches of the predicate.

The tests exercise the action check but not the message check. { action: 'saved' } with a missing message and with an empty-string message both reach the platform_setup_complete state in the old code and are exactly what the new helper rejects. Add both cases.

💚 Proposed additions
   expect(isSuccessfulProviderSetupResult(undefined)).toBe(false)
+  expect(isSuccessfulProviderSetupResult({ action: 'saved' })).toBe(false)
+  expect(
+    isSuccessfulProviderSetupResult({ action: 'activated', message: '' }),
+  ).toBe(false)
 })

Validate with bun test ./src/components/ConsoleOAuthFlow.test.tsx. As per path instructions: block when "tests assert implementation details while missing the user-visible behavior"; here the message guard drives whether the success screen renders.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('first-run provider setup accepts both saved profiles and Claude Code activation', () => {
expect(
isSuccessfulProviderSetupResult({
action: 'saved',
message: 'Saved Gitlawb Opengateway',
}),
).toBe(true)
expect(
isSuccessfulProviderSetupResult({
action: 'activated',
message: 'Provider switched to Claude Code (OAuth) (claude-opus-5)',
}),
).toBe(true)
expect(
isSuccessfulProviderSetupResult({
action: 'cancelled',
message: 'Provider setup skipped',
}),
).toBe(false)
expect(isSuccessfulProviderSetupResult(undefined)).toBe(false)
})
test('first-run provider setup accepts both saved profiles and Claude Code activation', () => {
expect(
isSuccessfulProviderSetupResult({
action: 'saved',
message: 'Saved Gitlawb Opengateway',
}),
).toBe(true)
expect(
isSuccessfulProviderSetupResult({
action: 'activated',
message: 'Provider switched to Claude Code (OAuth) (claude-opus-5)',
}),
).toBe(true)
expect(
isSuccessfulProviderSetupResult({
action: 'cancelled',
message: 'Provider setup skipped',
}),
).toBe(false)
expect(isSuccessfulProviderSetupResult(undefined)).toBe(false)
expect(isSuccessfulProviderSetupResult({ action: 'saved' })).toBe(false)
expect(
isSuccessfulProviderSetupResult({ action: 'activated', message: '' }),
).toBe(false)
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ConsoleOAuthFlow.test.tsx` around lines 130 - 150, Extend the
test for isSuccessfulProviderSetupResult to cover saved results with a missing
message and with an empty-string message, asserting both are rejected. Keep the
existing valid saved, activated, cancelled, and undefined cases, and run the
targeted ConsoleOAuthFlow test.

Source: Path instructions

Comment on lines +33 to +42
export function isSuccessfulProviderSetupResult(
result: ProviderManagerResult | undefined,
): boolean {
return (
!!result &&
(result.action === 'saved' || result.action === 'activated') &&
typeof result.message === 'string' &&
result.message.length > 0
)
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP -A6 "platform_setup_complete" src/components/ConsoleOAuthFlow.tsx | head -60
rg -nP -B2 -A12 "type OAuthStatus" src/components/ConsoleOAuthFlow.tsx

Repository: Gitlawb/openclaude

Length of output: 2546


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- ProviderManagerResult definitions and usages ---'
rg -n -C 5 "ProviderManagerResult" src

printf '%s\n' '--- Helper and call-site context ---'
sed -n '1,90p' src/components/ConsoleOAuthFlow.tsx
sed -n '510,600p' src/components/ConsoleOAuthFlow.tsx

printf '%s\n' '--- TypeScript configuration and scripts ---'
rg -n -C 3 '"typecheck|typecheck:type-tests"' package.json
fd -a 'tsconfig*.json' . -x sh -c 'echo "--- $1"; sed -n "1,180p" "$1"' sh {}

Repository: Gitlawb/openclaude

Length of output: 12430


Return a type predicate from isSuccessfulProviderSetupResult.

OAuthStatus requires message: string for platform_setup_complete, but ProviderManagerResult.message is optional. A boolean return does not narrow result.message, so strict TypeScript rejects this state transition. Use result is ProviderManagerResult & { message: string }.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ConsoleOAuthFlow.tsx` around lines 33 - 42, Update
isSuccessfulProviderSetupResult to return the type predicate result is
ProviderManagerResult & { message: string } instead of boolean, while preserving
its existing success checks so callers can safely narrow result.message to a
non-optional string.

Source: Coding guidelines

Comment on lines +2689 to +2692
for (let i = 0; i < 3; i++) {
mounted.stdin.write('j')
await Bun.sleep(25)
}

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.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Derive the OAuth row position instead of hardcoding three key presses.

Three j presses assume the Claude Code OAuth row sits at index 3, directly after Gitlawb Opengateway, aimlapi.com, and Anthropic. Line 131 shows the preset list already grows. Any preset added before Anthropic moves the cursor to a different provider, and the test then exercises the wrong path. The file already has PRESET_ORDER and navigateToPreset for this. The same hardcoded loop appears at lines 2759-2762.

♻️ Proposed navigation
-    for (let i = 0; i < 3; i++) {
-      mounted.stdin.write('j')
-      await Bun.sleep(25)
-    }
+    // Claude Code OAuth is inserted directly below the Anthropic preset.
+    await navigateToPreset(mounted.stdin, 'Anthropic')
+    mounted.stdin.write('j')
+    await Bun.sleep(25)
     mounted.stdin.write('\r')

Validate with bun test ./src/components/ProviderManager.test.tsx.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (let i = 0; i < 3; i++) {
mounted.stdin.write('j')
await Bun.sleep(25)
}
// Claude Code OAuth is inserted directly below the Anthropic preset.
await navigateToPreset(mounted.stdin, 'Anthropic')
mounted.stdin.write('j')
await Bun.sleep(25)
mounted.stdin.write('\r')
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ProviderManager.test.tsx` around lines 2689 - 2692, Replace
both hardcoded three-press j loops in the OAuth navigation tests with navigation
derived from PRESET_ORDER using the existing navigateToPreset helper, targeting
the Claude Code OAuth preset. Ensure both tests select the correct row
regardless of presets inserted before Anthropic, then validate with the
specified Bun test.

Comment on lines +3007 to +3027
test('ProviderManager hides Claude Code OAuth in bare mode', async () => {
process.env.CLAUDE_CODE_SIMPLE = '1'

const claudeAiOAuthAsyncRead = mock(async () => ({
accessToken: 'stored-oauth-token',
}))
mockProviderManagerDependencies(mock(() => undefined), mock(async () => undefined), {
claudeAiOAuthAsyncRead,
})

const nonce = `${Date.now()}-${Math.random()}`
const { ProviderManager } = await import(`./ProviderManager.js?ts=${nonce}`)
const output = await renderProviderManagerFrame(ProviderManager, {
mode: 'first-run',
waitForOutput: frame =>
frame.includes('Set up provider') && frame.includes('Anthropic'),
})

expect(output).not.toContain('Claude Code (OAuth)')
expect(claudeAiOAuthAsyncRead).not.toHaveBeenCalled()
})

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Two new tests mutate process.env without restoring it. Both tests set a provider-affecting environment variable and rely on later tests deleting it themselves. That ordering dependency breaks as soon as a test is appended.

  • src/components/ProviderManager.test.tsx#L3007-L3027: wrap the body in try/finally and delete process.env.CLAUDE_CODE_SIMPLE in the finally.
  • src/components/StartupScreen.test.ts#L238-L259: add an afterEach in this describe that restores the captured original value of process.env.ANTHROPIC_MODEL.

As per path instructions: review tests for "isolation of global/env/config state".

📍 Affects 2 files
  • src/components/ProviderManager.test.tsx#L3007-L3027 (this comment)
  • src/components/StartupScreen.test.ts#L238-L259
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ProviderManager.test.tsx` around lines 3007 - 3027, Ensure
both tests isolate environment state: in src/components/ProviderManager.test.tsx
lines 3007-3027, wrap the body of the “ProviderManager hides Claude Code OAuth
in bare mode” test in try/finally and delete process.env.CLAUDE_CODE_SIMPLE in
finally; in src/components/StartupScreen.test.ts lines 238-259, add a
describe-scoped afterEach that restores the captured original
process.env.ANTHROPIC_MODEL value.

Source: Path instructions

Comment on lines +2196 to +2205
if (hasClaudeAiOAuthCredentials) {
const anthropicIndex = options.findIndex(
option => option.value === 'anthropic',
)
options.splice(anthropicIndex >= 0 ? anthropicIndex + 1 : options.length, 0, {
value: ANTHROPIC_DEFAULT_PROFILE_ID,
label: CLAUDE_OAUTH_PROVIDER_NAME,
description: 'Use your authenticated Claude Code subscription',
})
}

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.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use CLAUDE_OAUTH_OPTION_VALUE in the preset picker for consistency.

Lines 249-253 state the distinct option value exists so Claude Code OAuth never collides with the built-in Anthropic entry. The preset picker still emits ANTHROPIC_DEFAULT_PROFILE_ID as the option value, and the handler at line 2264 matches that sentinel. Behavior is correct today because the preset list has no separate built-in Anthropic row. The mixed convention is a trap for the next edit: adding such a row here would silently merge the two entries.

♻️ Proposed alignment
       options.splice(anthropicIndex >= 0 ? anthropicIndex + 1 : options.length, 0, {
-        value: ANTHROPIC_DEFAULT_PROFILE_ID,
+        value: CLAUDE_OAUTH_OPTION_VALUE,
         label: CLAUDE_OAUTH_PROVIDER_NAME,
         description: 'Use your authenticated Claude Code subscription',
       })
-            if (value === ANTHROPIC_DEFAULT_PROFILE_ID) {
+            if (value === CLAUDE_OAUTH_OPTION_VALUE) {
               void activateSelectedProvider(value)
               return
             }

activateSelectedProvider already maps CLAUDE_OAUTH_OPTION_VALUE to the sentinel, so activation stays identical. Update the first-run tests that select this row.

Also applies to: 2264-2267

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ProviderManager.tsx` around lines 2196 - 2205, Use
CLAUDE_OAUTH_OPTION_VALUE for the Claude OAuth preset option value in the
options insertion near hasClaudeAiOAuthCredentials, and update the corresponding
activateSelectedProvider handling and first-run tests to select that value while
preserving its mapping to ANTHROPIC_DEFAULT_PROFILE_ID.

Comment on lines +4 to +19
defineModel({
id: 'claude-fable-5',
label: 'Claude Fable 5',
brandId: 'claude',
vendorId: 'anthropic',
classification: ['chat', 'reasoning', 'vision', 'coding'],
defaultModel: 'claude-fable-5',
capabilities: {
supportsVision: true,
supportsStreaming: true,
supportsFunctionCalling: true,
supportsJsonMode: true,
supportsReasoning: true,
supportsPreciseTokenCount: false,
},
}),

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 5 \
  'type ModelDescriptor|interface ModelDescriptor|contextWindow|maxOutputTokens' \
  src --glob '*.ts'

rg -n -C 5 \
  'supportsReasoning|contextWindow|maxOutputTokens' \
  src --glob '*.ts'

Repository: Gitlawb/openclaude

Length of output: 50375


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- Claude model descriptors ---'
cat -n src/integrations/models/claude.ts | sed -n '1,90p'

printf '%s\n' '--- Descriptor type and registration ---'
rg -n -C 8 'interface ModelDescriptor|type ModelDescriptor|function defineModel|const defineModel' src/integrations src --glob '*.ts' \
  | head -n 240

printf '%s\n' '--- Runtime-limit resolution and model consumers ---'
rg -n -C 6 'resolveModelRuntimeLimits|contextWindow|maxOutputTokens' src/utils src/integrations src/commands --glob '*.ts' \
  | head -n 320

printf '%s\n' '--- Focused model metadata tests ---'
git ls-files '*test.ts' '*test.tsx' | xargs -r rg -n -C 5 'claude-(fable|opus|sonnet)-5|integrations/models/claude|ModelDescriptor' \
  | head -n 240

Repository: Gitlawb/openclaude

Length of output: 48331


🌐 Web query:

Anthropic Claude Fable 5 Opus 5 Sonnet 5 context window 1,000,000 maximum output tokens 128,000 official model documentation

💡 Result:

As of August 12, 2026, the official technical specifications for the requested Anthropic Claude models (Fable 5, Opus 5, and Sonnet 5) confirm that they all support a 1,000,000 (1M) token context window and a 128,000 token maximum output limit for standard API requests [1][2][3]. Detailed Model Specifications: Model | Context Window | Maximum Output Tokens --- | --- | --- Claude Fable 5 | 1,000,000 | 128,000 [2][4] Claude Opus 5 | 1,000,000 | 128,000 [2] Claude Sonnet 5 | 1,000,000 | 128,000 [2] These models are available through the Anthropic API, Amazon Bedrock, Google Cloud, and Microsoft Foundry [2]. Note that for specific batch processing use cases, there is an option to enable up to 300,000 output tokens using the output-300k-2026-03-24 beta header [1][4].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

path = Path("src/integrations/models/claude.ts")
text = path.read_text()
ids = ["claude-fable-5", "claude-opus-5", "claude-sonnet-5"]

for model_id in ids:
    start = text.find("defineModel({", text.find(f"id: '{model_id}'") - 200)
    end = text.find("}),", start)
    block = text[start:end + 3]
    fields = {}
    for name in ("id", "defaultModel", "contextWindow", "maxOutputTokens"):
        match = re.search(rf"\b{name}:\s*([^,\n]+)", block)
        fields[name] = match.group(1).strip() if match else "<missing>"
    print(fields)
PY

Repository: Gitlawb/openclaude

Length of output: 517


🌐 Web query:

site:docs.anthropic.com Claude models context window maximum output tokens 2026

💡 Result:

As of August 12, 2026, the maximum output token limit for the latest Claude models is 128,000 tokens [1][2][3]. This maximum output limit applies to models with a 1 million token context window, which includes Claude Opus 5, Claude Sonnet 5, Claude Fable 5, and Claude Mythos 5 [2][3]. For these models, the 128k output limit acts as a hard limit on total output, which encompasses both the model's generated response text and any tokens used for internal reasoning (thinking) processes [4][5][6]. For models with a smaller 200,000 token context window, such as earlier versions like Claude Haiku 4.5, the maximum output limit is 64,000 tokens [1][3]. Users should be aware that when using models with thinking enabled, the thinking process consumes part of the total max_tokens budget [5][6]. Additionally, when migrating to newer models with different tokenizers (such as Claude Sonnet 5), token counts may differ from previous versions, making it advisable to revisit and adjust max_tokens settings for specific workloads [4].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- ModelDescriptor runtime fields ---'
sed -n '345,385p' src/integrations/descriptors.ts

printf '%s\n' '--- Runtime metadata resolver ---'
fd -t f 'runtimeMetadata' src | xargs -r -n1 sh -c 'echo "--- $0"; cat -n "$0" | sed -n "1,260p"'

printf '%s\n' '--- Claude descriptor consumers and tests ---'
rg -n -C 8 \
  'claude-fable-5|claude-opus-5|claude-sonnet-5|defaultContextWindow|defaultMaxOutputTokens|runtimeLimits' \
  src/integrations src/utils src/components --glob '*.ts' --glob '*.tsx' \
  | head -n 420

Repository: Gitlawb/openclaude

Length of output: 50374


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

text = Path("src/integrations/models/claude.ts").read_text()
ids = ["claude-fable-5", "claude-opus-5", "claude-sonnet-5"]

for model_id in ids:
    match = re.search(
        rf"defineModel\(\{{(?:(?!\n\s*defineModel\(\{{).)*?\bid:\s*'{re.escape(model_id)}'.*?\n\s*\}}\),",
        text,
        re.S,
    )
    if not match:
        raise SystemExit(f"descriptor not found: {model_id}")
    block = match.group(0)
    fields = {}
    for name in ("id", "defaultModel", "contextWindow", "maxOutputTokens"):
        field = re.search(rf"\b{name}:\s*([^,\n]+)", block)
        fields[name] = field.group(1).strip() if field else None
    print(model_id, fields)
PY

Repository: Gitlawb/openclaude

Length of output: 534


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- First-party context and output limit resolution ---'
sed -n '180,305p' src/utils/context.ts
sed -n '340,455p' src/utils/context.ts

printf '%s\n' '--- Descriptor runtime-limit use ---'
rg -n -C 10 'getModel\(.*\)|\.contextWindow|\.maxOutputTokens|modelDescriptor' \
  src/integrations/runtimeMetadata.ts src/integrations/registry.ts src/utils/context.ts \
  | head -n 360

printf '%s\n' '--- Claude model limit helpers ---'
rg -n -C 12 'has1mContext|claude-opus-5|claude-sonnet-5|claude-fable-5|opus-4-8|sonnet-4-6' \
  src/utils src/integrations --glob '*.ts' \
  | head -n 360

Repository: Gitlawb/openclaude

Length of output: 48146


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

text = Path("src/utils/context.ts").read_text()
for name in ("getContextWindowForModel", "getMaxOutputTokens"):
    match = re.search(rf"export function {name}\b", text)
    if not match:
        raise SystemExit(f"{name} not found")
    start = match.start()
    next_export = text.find("\nexport ", start + 1)
    end = len(text) if next_export < 0 else next_export
    print(f"--- {name} ---")
    print(text[start:end])
PY

Repository: Gitlawb/openclaude

Length of output: 2757


Add provider token limits to all three Claude 5 descriptors. Set contextWindow to 1_000_000 and maxOutputTokens to 128_000. resolveModelRuntimeLimits uses these descriptor fields when no route or environment override exists, so omitting them causes fallback limits for OpenAI-compatible and Anthropic-proxy routes. Add focused metadata assertions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/integrations/models/claude.ts` around lines 4 - 19, Add contextWindow set
to 1_000_000 and maxOutputTokens set to 128_000 on each of the three Claude 5
model descriptors defined alongside claude-fable-5. Add focused metadata
assertions verifying both fields for all three descriptors, preserving route and
environment override behavior.

Sources: Coding guidelines, Path instructions

This file preserves the exact __esm wrapper slice for quick per-path inspection.
*/

__esm({"src/tools/shell-command/types.ts"(){Ht(),FS=f.object({command:f.string().min(1,"Command cannot be empty"),args:f.preprocess(e=>{if("string"==typeof e){try{const t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return[e]}return e},f.array(f.string()).optional()),directory:f.string().optional(),timeout:f.preprocess(e=>"string"==typeof e?parseInt(e,10):e,f.number().optional())}),qS=class extends Error{static{__name(this,"ShellCommandError")}code;exitCode;signal;stdout;stderr;duration;constructor(e,t,n,r,o,s,i){super(e),this.name="ShellCommandError",this.code=t,this.exitCode=n,this.signal=r,this.stdout=o,this.stderr=s,this.duration=i}}}})

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(AGENTS\.md|types\.ts(\.recovered\.js)?$|index\.ts(\.recovered\.js)?$|shell-command|package\.json|.*test.*|.*spec.*)$' | head -200
printf '%s\n' '--- guidance ---'
find .. -name AGENTS.md -print
printf '%s\n' '--- timeout references ---'
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' 'timeout|300000|Command cannot be empty|ShellCommandError' src test tests 2>/dev/null | head -300

Repository: Gitlawb/openclaude

Length of output: 34889


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- exact paths ---'
find . -type f \( -name 'types.ts.recovered.js' -o -name 'index.ts.recovered.js' -o -path '*shell-command*' \) -print | head -200
printf '%s\n' '--- identifiers ---'
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
  'src/services/tools/shell-command|src/tools/shell-command/types\.ts|ShellCommandError|Command cannot be empty|maximum: 300000|minimum: 100' . | head -300
printf '%s\n' '--- AGENTS.md ---'
cat -n AGENTS.md

Repository: Gitlawb/openclaude

Length of output: 7974


🏁 Script executed:

#!/bin/bash
set -e
for f in \
  src/services/tools/shell-command/types.ts.recovered.js \
  src/services/tools/shell-command/index.ts.recovered.js \
  src/services/tools/shell-command/shell-command.ts.recovered.js \
  src/services/tools/shell-command/formatter.ts.recovered.js
do
  echo "--- $f ($(wc -l < "$f") lines) ---"
  cat -n "$f"
done
printf '%s\n' '--- recovered artifact references ---'
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
  'services/tools/shell-command|tools/shell-command|ShellCommand|shell_command|shell-command' src package.json | head -300
printf '%s\n' '--- git status and tracked state ---'
git status --short
git ls-files --stage src/services/tools/shell-command

Repository: Gitlawb/openclaude

Length of output: 37700


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- segment candidates ---'
find . -type f | rg '(^|/)(segments|.*016[0-9].*\.mjs$|.*shell-command.*\.(ts|js|mjs)$)' | head -300
printf '%s\n' '--- timeout implementation terms ---'
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
  'executeShellCommand|setTimeout|timeout\s*\?\?|timeout\s*[:=]|SIGTERM|spawn' \
  src/services src/tools src/utils | head -400
printf '%s\n' '--- dependency availability ---'
test -d node_modules && echo node_modules-present || echo node_modules-absent
rg -n '"zod"|"valibot"|"@.*schema' package.json bun.lock* package-lock.json yarn.lock 2>/dev/null | head -100

Repository: Gitlawb/openclaude

Length of output: 48558


🏁 Script executed:

#!/bin/bash
set -e
node - <<'JS'
const inputs = ['0', '-1', '100', '300000', '300001', '100abc', 'abc100', '', ' 100 ', '100.5', 'Infinity'];
for (const value of inputs) {
  const parsedInt = Number.parseInt(value, 10);
  const strict = Number(value);
  const acceptedRange = n => typeof n === 'number' && Number.isFinite(n) && n >= 100 && n <= 300000;
  console.log(JSON.stringify({ value, parseInt: parsedInt, number: strict, parseIntInRange: acceptedRange(parsedInt), numberInRange: acceptedRange(strict) }));
}
JS
python3 - <<'PY'
from pathlib import Path
text = Path("src/services/tools/shell-command/index.ts.recovered.js").read_text()
needle = 'timeout:{type:"number"'
start = text.index(needle)
end = text.index('}},required:["command"]', start)
print("advertised_timeout_schema=" + text[start:end+1])
types = Path("src/services/tools/shell-command/types.ts.recovered.js").read_text()
needle = 'timeout:f.preprocess'
start = types.index(needle)
print("runtime_timeout_schema=" + types[start:types.index('})}),qS=', start)])
PY

Repository: Gitlawb/openclaude

Length of output: 1823


Enforce the documented timeout range before execution.

FS.parse accepts values outside 100–300000 ms, and parseInt accepts prefixes such as "100abc". Use strict numeric conversion with matching min(100) and max(300000) bounds in the runtime schema. Add minimum and maximum to the advertised schema and add boundary tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/tools/shell-command/types.ts.recovered.js` at line 16, Update
the FS runtime schema’s timeout field to use strict numeric conversion that
rejects malformed strings such as “100abc”, then enforce the documented
inclusive 100–300000 ms range with minimum and maximum validation. Update the
advertised shell-command schema to expose the same minimum and maximum
constraints, and add tests covering both boundaries and out-of-range values.

Comment on lines +194 to +215
const CURRENT_ANTHROPIC_MODEL_OPTIONS: ModelOption[] = [
{
value: 'claude-fable-5',
label: 'Fable 5',
description: 'Claude Fable 5',
},
{
value: 'claude-opus-5',
label: 'Opus 5',
description: 'Claude Opus 5',
},
{
value: 'claude-sonnet-5',
label: 'Sonnet 5',
description: 'Claude Sonnet 5',
},
]

function getCurrentAnthropicModelOptions(): ModelOption[] {
return CURRENT_ANTHROPIC_MODEL_OPTIONS.map(option => ({ ...option }))
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 6 \
  'CURRENT_ANTHROPIC_MODEL_OPTIONS|check[A-Za-z]+Access|Fable|availability|entitlement|usage' \
  src --glob '*.ts'

rg -n -C 5 \
  'claude-fable-5|getModelOptions' \
  src --glob '*.{test,spec}.ts'

Repository: Gitlawb/openclaude

Length of output: 50377


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- modelOptions symbols ---'
rg -n -C 12 'CURRENT_ANTHROPIC_MODEL_OPTIONS|getCurrentAnthropicModelOptions|claude-fable-5|checkSonnet1mAccess|checkOpus1mAccess' src/utils/model/modelOptions.ts

printf '%s\n' '--- exact Fable references ---'
rg -n -C 8 'claude-fable-5|Fable 5|CURRENT_ANTHROPIC_MODEL_OPTIONS|getCurrentAnthropicModelOptions' src --glob '*.{ts,tsx,js,jsx}' --glob '!src/utils/model/modelOptions.ts'

printf '%s\n' '--- model option tests ---'
fd -i 'modelOptions' src
rg -n -C 8 'claude-fable-5|Fable 5|getModelOptions|model options|ModelOption' src --glob '*.{test,spec}.{ts,tsx}'

Repository: Gitlawb/openclaude

Length of output: 50375


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- exact modelOptions matches ---'
rg -n 'CURRENT_ANTHROPIC_MODEL_OPTIONS|getCurrentAnthropicModelOptions|claude-fable-5|checkSonnet1mAccess|checkOpus1mAccess|subscriber|PAYG|firstParty' src/utils/model/modelOptions.ts

printf '%s\n' '--- focused implementation ---'
sed -n '150,260p' src/utils/model/modelOptions.ts
sed -n '620,760p' src/utils/model/modelOptions.ts

printf '%s\n' '--- exact Fable matches in source and tests ---'
rg -n -C 4 --glob '*.{ts,tsx,js,jsx}' 'claude-fable-5|Fable 5' src

printf '%s\n' '--- availability/filter symbols in model option path ---'
rg -n -C 4 'filterAvailableCatalogEntries|allowlist|availability|entitlement|is.*Access|Access\(' src/utils/model src/integrations src/services/api --glob '*.ts'

Repository: Gitlawb/openclaude

Length of output: 50374


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- option filtering and public builder ---'
sed -n '1200,1315p' src/utils/model/modelOptions.ts
rg -n -C 8 'export function getModelOptions|function getModelOptions|getModelOptionsBase|filterModelOptionsByAllowlist' src/utils/model/modelOptions.ts

printf '%s\n' '--- allowlist implementation ---'
sed -n '1225,1275p' src/utils/model/modelOptions.ts
sed -n '90,175p' src/utils/model/modelAllowlist.ts

printf '%s\n' '--- Fable-related option tests only ---'
rg -n -C 12 'claude-fable-5|Fable 5' src/utils/model --glob '*.{test,spec}.ts'

printf '%s\n' '--- availability metadata types and Anthropic catalog ---'
rg -n -C 8 'availableUntil|availableFrom|catalogEntryAvailable|ModelCatalogEntry|claude-fable-5' src/integrations --glob '*.ts'

Repository: Gitlawb/openclaude

Length of output: 50374


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

path = Path("src/utils/model/modelOptions.ts")
text = path.read_text()

list_match = re.search(
    r"const CURRENT_ANTHROPIC_MODEL_OPTIONS: ModelOption\[\] = \[(.*?)\n\]",
    text,
    re.S,
)
assert list_match, "current Anthropic option list not found"
list_body = list_match.group(1)

spreads = list(re.finditer(r"\.\.\.getCurrentAnthropicModelOptions\(\)", text))
print("current option list contains Fable:", "value: 'claude-fable-5'" in list_body)
print("current option list contains Opus:", "value: 'claude-opus-5'" in list_body)
print("current option list contains Sonnet:", "value: 'claude-sonnet-5'" in list_body)
print("current option list spread count:", len(spreads))
for match in spreads:
    line = text.count("\n", 0, match.start()) + 1
    context = text[max(0, match.start() - 220):match.start()]
    branch = (
        "premium subscriber" if "premiumOptions" in context
        else "standard subscriber" if "standardOptions" in context
        else "first-party PAYG" if "payg1POptions" in context
        else "other"
    )
    print(f"spread line {line}: {branch}")

filter_match = re.search(
    r"function filterModelOptionsByAllowlist\(options: ModelOption\[\]\): ModelOption\[\] \{(.*?)\n\}",
    text,
    re.S,
)
assert filter_match, "allowlist filter not found"
filter_body = filter_match.group(1)
print("allowlist filter passes all options when availableModels is unset:",
      "!settings.availableModels" in filter_body)
print("allowlist filter uses server availability or entitlement API:",
      bool(re.search(r"availability|entitlement|server", filter_body, re.I)))
print("Fable-specific gating in modelOptions.ts:",
      bool(re.search(r"(if|check|is)[^\\n]*fable|fable[^\\n]*(if|check|is)", text, re.I)))
PY

Repository: Gitlawb/openclaude

Length of output: 609


Gate claude-fable-5 by availability.

The option appears in all three subscriber and first-party PAYG branches without a Fable-specific entitlement check. The optional allowlist does not enforce server availability.

Add gating and tests for eligible and ineligible accounts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/model/modelOptions.ts` around lines 194 - 215, Update
getCurrentAnthropicModelOptions and the related subscriber/first-party PAYG
option-selection branches to include claude-fable-5 only when the account has
the Fable-specific entitlement or availability flag; retain the existing options
for ineligible accounts and preserve the optional allowlist behavior. Add tests
covering eligible and ineligible accounts across the affected branches.

Sources: Coding guidelines, Path instructions

@jatmn

jatmn commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

please read and follow contributing.md

@jatmn jatmn closed this Aug 13, 2026
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.

3 participants