Skip to content

Conversation

@aw338WoWmUI
Copy link

@aw338WoWmUI aw338WoWmUI commented Jan 3, 2026

Summary

This PR adds two important features for flexibility in Auto Claude configuration:

1. Third-party API Provider Support (auth.py)

  • Read environment variables from active profile's settings.json (via configDir/settings.json)
  • Support ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, and model overrides
  • Enable usage of Minimax, OpenRouter, and other Claude-compatible APIs
  • Maintain full backward compatibility with existing OAuth flow

Supported profile env vars:

  • ANTHROPIC_BASE_URL
  • ANTHROPIC_AUTH_TOKEN
  • ANTHROPIC_MODEL
  • ANTHROPIC_SMALL_FAST_MODEL
  • ANTHROPIC_DEFAULT_SONNET_MODEL
  • ANTHROPIC_DEFAULT_OPUS_MODEL
  • ANTHROPIC_DEFAULT_HAIKU_MODEL
  • API_TIMEOUT_MS
  • CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC

2. Project-level DEFAULT_BRANCH (worktree.py)

  • Read DEFAULT_BRANCH from project's .auto-claude/.env file
  • System environment variable still takes priority
  • Allows per-project branch configuration without modifying system env

Priority order for DEFAULT_BRANCH:

  1. System environment variable
  2. Project's .auto-claude/.env file
  3. Auto-detect main/master
  4. Current branch (fallback)

Priority order for auth token:

  1. System env (CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_AUTH_TOKEN)
  2. Profile settings.json env section
  3. System credential store (Keychain/Credential Manager)

Motivation

  • Some users want to use third-party Claude-compatible APIs (Minimax, OpenRouter, etc.) with Auto Claude
  • The current auth.py only reads from system environment variables, ignoring profile settings
  • Projects may need different default branches (e.g., develop instead of main), but setting system env affects all projects

Test Plan

  • Tested with Minimax M2.1 API via profile settings.json
  • Tested DEFAULT_BRANCH reading from .auto-claude/.env
  • Verified backward compatibility with existing OAuth flow
  • Verified system env vars still take priority

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Profiles can now store authentication tokens and environment variables in their settings.
    • Project-level .env files are now recognized for configuration defaults.
    • Enhanced support for third-party AI provider authentication through profile settings.

✏️ Tip: You can customize this high-level summary in your review settings.

This commit adds two important features:

1. Third-party API Provider Support (auth.py):
   - Read env vars from active profile's settings.json (configDir/settings.json)
   - Support ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, and model overrides
   - Enable usage of Minimax, OpenRouter, and other Claude-compatible APIs
   - Maintain backward compatibility with existing OAuth flow

2. Project-level DEFAULT_BRANCH (worktree.py):
   - Read DEFAULT_BRANCH from project's .auto-claude/.env file
   - System environment variable still takes priority
   - Allows per-project branch configuration without modifying system env

Priority order for DEFAULT_BRANCH:
  1. System environment variable
  2. Project's .auto-claude/.env file
  3. Auto-detect main/master
  4. Current branch (fallback)

Priority order for auth token:
  1. System env (CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_AUTH_TOKEN)
  2. Profile settings.json env section
  3. System credential store (Keychain/Credential Manager)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Spark seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 3, 2026

📝 Walkthrough

Walkthrough

This pull request introduces profile-aware environment configuration to the authentication system. New helper functions read the active UI profile's settings to source environment variables for authentication tokens and third-party provider configuration. Additionally, base-branch detection now checks project-level .env files before falling back to auto-detection.

Changes

Cohort / File(s) Summary
Profile-aware authentication
apps/backend/core/auth.py
Introduces profile-based configuration sourcing: adds _locate_ui_config(), _load_active_profile(), and _read_profile_env_vars() helpers; creates PROFILE_ENV_VARS constant listing supported variables; modifies get_auth_token(), get_auth_token_source(), and get_sdk_env_vars() to prioritize profile-derived environment variables before system env; adds get_active_profile_info() public function returning profile metadata and derived third-party provider info.
Project environment loading
apps/backend/core/worktree.py
Adds _load_env_file() helper to parse key=value pairs from .env files; updates _detect_base_branch() to load and check DEFAULT_BRANCH from project .auto-claude/.env after checking system environment and before git auto-detection.

Sequence Diagram(s)

sequenceDiagram
    participant App as App
    participant Auth as auth.py
    participant UIConfig as UI Config Files
    participant Profile as Active Profile
    participant Env as System Environment
    
    App->>Auth: get_auth_token()
    Auth->>Auth: Locate UI config directory
    Auth->>UIConfig: Load settings.json
    UIConfig-->>Auth: Config data
    Auth->>Profile: Extract active profile ID
    Auth->>Profile: Load profile/settings.json
    Profile-->>Auth: Profile env vars (ANTHROPIC_AUTH_TOKEN, etc.)
    
    alt Profile value found
        Auth-->>App: Return token from profile
    else Profile value not found
        Auth->>Env: Check system environment variables
        Env-->>Auth: Env var value
        Auth-->>App: Return token from system
    end
    
    rect rgb(240, 248, 255)
        note over Auth,Profile: Profile-aware configuration<br/>New prioritization: profile → system env → credential store
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 With profiles in hand and settings to read,
The auth now knows what each project will need,
From UI to token, the config flows free,
Third-party providers hop into the spree! 🌿
Environment variables, no secrets untold—
A profile-aware system, remarkably bold!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures both main features: third-party API provider support and project-level DEFAULT_BRANCH configuration. It is concise, specific, and clearly reflects the primary changes in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @aw338WoWmUI, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the configuration flexibility of Auto Claude by introducing support for third-party API providers and enabling project-specific default branch settings. These changes allow users to seamlessly integrate with alternative Claude-compatible services and tailor branch configurations to individual project needs, improving adaptability and user experience.

Highlights

  • Third-party API Provider Support: Auto Claude now supports third-party Claude-compatible API providers like Minimax and OpenRouter. This is achieved by reading environment variables such as "ANTHROPIC_BASE_URL" and "ANTHROPIC_AUTH_TOKEN" from the active profile's "settings.json" file, while maintaining backward compatibility with existing OAuth flows.
  • Project-level DEFAULT_BRANCH Configuration: Users can now define a "DEFAULT_BRANCH" at the project level by placing a ".env" file within the ".auto-claude/" directory. This allows for per-project branch configuration without affecting system-wide environment variables, with system environment variables still taking precedence.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

🎉 Thanks for your first PR!

A maintainer will review it soon. Please make sure:

  • Your branch is synced with develop
  • CI checks pass
  • You've followed our contribution guide

Welcome to the Auto Claude community!

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces valuable flexibility by adding support for third-party API providers and project-level default branch configuration. The changes are well-implemented and align with the stated goals. My review includes suggestions to enhance robustness by improving exception handling, fixing a bug related to environment variable priority, and pointing out some minor inefficiencies for potential optimization. Overall, these are solid improvements to the project.

Comment on lines 365 to 368
for var in SDK_ENV_VARS:
value = os.environ.get(var)
if value:
env[var] = value
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This logic for overriding with system environment variables is incomplete. It only iterates over SDK_ENV_VARS, which no longer includes model-related variables like ANTHROPIC_MODEL. This means if a user sets ANTHROPIC_MODEL as a system environment variable, it will be ignored, which breaks the expected priority of system environment variables over profile settings. The loop should iterate over all possible SDK-related variables to ensure system environment variables always take precedence.

Suggested change
for var in SDK_ENV_VARS:
value = os.environ.get(var)
if value:
env[var] = value
all_sdk_vars = set(SDK_ENV_VARS) | set(PROFILE_ENV_VARS)
for var in all_sdk_vars:
value = os.environ.get(var)
if value:
env[var] = value

Comment on lines +97 to +98
except (json.JSONDecodeError, KeyError, Exception):
pass
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Using a broad except Exception: pass can hide bugs and make debugging difficult. It's better to catch more specific exceptions or at least log any unexpected errors to help with troubleshooting when reading profile data.

Suggested change
except (json.JSONDecodeError, KeyError, Exception):
pass
except (json.JSONDecodeError, KeyError, Exception) as e:
# Consider logging this exception for easier debugging.
# For example: logging.warning(f"Failed to get active profile: {e}")
pass

Comment on lines +146 to +147
except (json.JSONDecodeError, KeyError, Exception):
return {}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Silently catching all exceptions with except Exception can hide underlying issues with settings.json files, such as file permission errors or malformed content. It's recommended to log the exception to make debugging easier.

Suggested change
except (json.JSONDecodeError, KeyError, Exception):
return {}
except (json.JSONDecodeError, KeyError, Exception) as e:
# Consider logging this exception for easier debugging.
# For example: logging.warning(f"Failed to get profile env vars: {e}")
return {}

Comment on lines +279 to +281
profile_env = _get_profile_env_vars()
if "ANTHROPIC_AUTH_TOKEN" in profile_env:
profile = _get_active_profile()
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

There's a small inefficiency here. The _get_profile_env_vars() function already calls _get_active_profile() internally. By calling _get_active_profile() again on line 281, you're doing redundant work (e.g., reading and parsing config files twice). This could be optimized by modifying _get_profile_env_vars to also return the profile it found, or by caching the result of _get_active_profile().

Comment on lines +395 to +399
profile = _get_active_profile()
if not profile:
return None

profile_env = _get_profile_env_vars()
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to another function in this file, there's a redundant call pattern. _get_active_profile() is called on line 395, and then _get_profile_env_vars() on line 399 calls it again internally. This results in reading and parsing configuration files twice. To improve efficiency, you could pass the profile object to a modified _get_profile_env_vars or have it return the profile along with the environment variables.

Comment on lines +57 to +58
except Exception:
pass
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The except Exception: pass is too broad and will silently ignore all errors during .env file processing, such as permission errors or encoding issues. This can make it very difficult to diagnose problems. It's better to log the exception to provide visibility into potential issues.

Suggested change
except Exception:
pass
except Exception as e:
# Consider logging the exception for debugging purposes, e.g.:
# import logging
# logging.warning(f"Error loading .env file {env_path}: {e}")
pass

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/backend/core/worktree.py (2)

137-154: Fix stale comment numbering.

The inline comments are out of sync with the updated docstring. After adding the project .env check as step 2, these comments still reference the old numbering.

🔎 Proposed fix
-        # 2. Auto-detect main/master
+        # 3. Auto-detect main/master
         for branch in ["main", "master"]:
             result = subprocess.run(
                 ["git", "rev-parse", "--verify", branch],
                 cwd=self.project_dir,
                 capture_output=True,
                 text=True,
                 encoding="utf-8",
                 errors="replace",
             )
             if result.returncode == 0:
                 return branch

-        # 3. Fall back to current branch with warning
+        # 4. Fall back to current branch with warning
         current = self._get_current_branch()

152-155: Consider updating the tip to mention both configuration options.

The tip only mentions .env but doesn't clarify which one. Since this PR adds project-level .auto-claude/.env support, the message could guide users to both options.

🔎 Proposed improvement
         print("Warning: Could not find 'main' or 'master' branch.")
         print(f"Warning: Using current branch '{current}' as base for worktree.")
-        print("Tip: Set DEFAULT_BRANCH=your-branch in .env to avoid this.")
+        print("Tip: Set DEFAULT_BRANCH in system env or .auto-claude/.env to specify the base branch.")
apps/backend/core/auth.py (1)

271-295: Minor redundancy in profile fetching.

_get_profile_env_vars() (line 279) internally calls _get_active_profile(), then line 281 calls _get_active_profile() again. This results in reading and parsing the JSON file twice. Not critical since this isn't a hot path, but could be optimized.

🔎 Proposed optimization
     # Check profile settings
-    profile_env = _get_profile_env_vars()
-    if "ANTHROPIC_AUTH_TOKEN" in profile_env:
-        profile = _get_active_profile()
-        if profile:
-            return f"Profile: {profile.get('name', profile.get('id', 'unknown'))}"
+    profile = _get_active_profile()
+    if profile:
+        profile_env = _get_profile_env_vars()
+        if "ANTHROPIC_AUTH_TOKEN" in profile_env:
+            return f"Profile: {profile.get('name', profile.get('id', 'unknown'))}"

Note: This still has redundancy since _get_profile_env_vars() calls _get_active_profile() internally. A more thorough refactor would pass the profile as a parameter or cache the result.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7177c79 and f16fb78.

📒 Files selected for processing (2)
  • apps/backend/core/auth.py
  • apps/backend/core/worktree.py
🧰 Additional context used
📓 Path-based instructions (2)
apps/backend/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

apps/backend/**/*.py: Always use the Claude Agent SDK (claude-agent-sdk package) for all AI interactions, never use the Anthropic API directly
Use the create_client() function from apps/backend/core/client.py to instantiate Claude SDK clients, not direct ClaudeSDKClient initialization

Files:

  • apps/backend/core/auth.py
  • apps/backend/core/worktree.py

⚙️ CodeRabbit configuration file

apps/backend/**/*.py: Focus on Python best practices, type hints, and async patterns.
Check for proper error handling and security considerations.
Verify compatibility with Python 3.12+.

Files:

  • apps/backend/core/auth.py
  • apps/backend/core/worktree.py
apps/backend/core/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Implement dynamic command allowlisting based on detected project stack using core/security.py for bash command validation

Files:

  • apps/backend/core/auth.py
  • apps/backend/core/worktree.py
🔇 Additional comments (7)
apps/backend/core/worktree.py (1)

26-60: LGTM! Clean .env parser implementation.

The function handles common .env file patterns well: comments, empty lines, quoted values, and missing files. The broad exception handling is acceptable here since this is configuration loading where graceful degradation is preferred.

One minor note: the quote removal logic (line 53) won't handle escaped quotes within strings (e.g., KEY="value with \" inside"), but this is likely fine for typical .env usage.

apps/backend/core/auth.py (6)

38-49: LGTM! Good security practice with allowlist.

Using an explicit allowlist of environment variables that can be loaded from profile settings is the right approach. This prevents arbitrary environment variable injection from user-controlled config files.


52-64: LGTM! Correct platform-specific config path handling.

The function properly follows platform conventions for application configuration directories.


67-100: Acceptable implementation with a note on fallback behavior.

The fallback to the first profile (lines 93-95) when activeProfileId doesn't match any profile could lead to unexpected behavior if the active profile was deleted or renamed. Consider logging a debug message when this fallback occurs to aid troubleshooting.


103-147: LGTM! Secure env var loading with proper filtering.

Good implementation:

  • Allowlist filtering via PROFILE_ENV_VARS prevents arbitrary env var injection
  • Handles type conversion for boolean and non-string values
  • Graceful error handling for malformed config files

240-268: LGTM! Clean integration of profile-based auth token resolution.

The priority order is well-documented and correctly implemented:

  1. System env vars (CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_AUTH_TOKEN)
  2. Profile settings.json
  3. System credential store

339-370: LGTM! Correct priority order for SDK environment variables.

Profile settings are loaded first (lower priority), then system environment variables override them (higher priority). This allows system-level configuration to take precedence while enabling profile-based defaults for third-party providers.

Comment on lines +388 to +408
def get_active_profile_info() -> dict | None:
"""
Get information about the currently active profile.
Returns:
Dict with profile info (id, name, configDir, isThirdParty) or None
"""
profile = _get_active_profile()
if not profile:
return None

profile_env = _get_profile_env_vars()
is_third_party = bool(profile_env.get("ANTHROPIC_BASE_URL"))

return {
"id": profile.get("id"),
"name": profile.get("name"),
"configDir": profile.get("configDir"),
"isThirdParty": is_third_party,
"baseUrl": profile_env.get("ANTHROPIC_BASE_URL", "https://api.anthropic.com"),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

LGTM with same redundancy note.

The function provides useful profile metadata. Same observation as before: _get_profile_env_vars() (line 399) will call _get_active_profile() internally, duplicating the work done on line 395.

Consider refactoring the internal functions to accept an optional pre-fetched profile to avoid repeated file I/O, but this is a nice-to-have optimization.

🤖 Prompt for AI Agents
In apps/backend/core/auth.py around lines 388 to 408, the call to
_get_profile_env_vars() duplicates work because that helper re-calls
_get_active_profile(); modify _get_profile_env_vars to accept an optional
profile argument (defaulting to None) and use the already-fetched profile when
provided, then change this function to pass the local profile into
_get_profile_env_vars(profile) to avoid redundant file I/O; update other callers
of _get_profile_env_vars as needed to preserve behavior (use existing call with
no arg or pass a pre-fetched profile) and add minimal docstring/comments noting
the new parameter.

@MikeeBuilds MikeeBuilds added feature New feature or request stability-hold Feature on hold during Stability First initiative area/backend This is backend only priority/low Nice to have, when time permits size/M Medium (100-499 lines) labels Jan 3, 2026
@AndyMik90 AndyMik90 self-assigned this Jan 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/backend This is backend only feature New feature or request priority/low Nice to have, when time permits size/M Medium (100-499 lines) stability-hold Feature on hold during Stability First initiative

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants