Skip to content

feat: unified Claude API key and profile system with z.AI, MiniMax, OpenRouter support#600

Merged
stefandevo merged 32 commits intoAutoMaker-Org:v0.13.0rcfrom
stefandevo:feature/claude-code-max-glm-api-keys
Jan 19, 2026
Merged

feat: unified Claude API key and profile system with z.AI, MiniMax, OpenRouter support#600
stefandevo merged 32 commits intoAutoMaker-Org:v0.13.0rcfrom
stefandevo:feature/claude-code-max-glm-api-keys

Conversation

@stefandevo
Copy link
Copy Markdown
Collaborator

@stefandevo stefandevo commented Jan 19, 2026

Summary

This PR implements a unified Claude API key and profile system that allows flexible configuration of how API keys are resolved, plus per-project profile overrides. Adds support for alternative Claude-compatible providers like z.AI GLM, MiniMax, and OpenRouter.

Key Features

  • Flexible API Key Sourcing: Profiles can now source their API key from:

    • inline - Key stored directly in the profile (for alternative providers)
    • credentials - Uses the Anthropic key from Settings → API Keys
    • env - Uses ANTHROPIC_API_KEY environment variable
  • Per-Project Profile Overrides: Each project can override the global Claude API profile, enabling:

    • Experimentation with z.AI GLM or MiniMax on specific projects
    • Cost optimization using different endpoints per project
    • Regional compliance with China-specific endpoints
  • New Provider Templates:

    • Direct Anthropic - Standard Anthropic API with credentials support
    • OpenRouter - Access Claude and 300+ models via unified API
    • z.AI GLM - 3× usage at fraction of cost via GLM Coding Plan
    • MiniMax - M2.1 coding model with extended context
    • MiniMax (China) - China-region endpoint
  • UX Improvements:

    • Duplicate profile name validation
    • Contextual info box explaining API key and profile relationship
    • Project Settings → Claude section for per-project profile selection

Documentation

See docs/UNIFIED_API_KEY_PROFILES.md for complete implementation details including:

  • Type changes and interfaces
  • Server-side API key resolution logic
  • UI component structure
  • Migration strategy for existing users
  • Per-project override implementation

Changes

Types (libs/types/src/settings.ts)

  • Added ApiKeySource type ('inline' | 'env' | 'credentials')
  • Added apiKeySource field to ClaudeApiProfile
  • Added activeClaudeApiProfileId to ProjectSettings
  • Added provider templates (Direct Anthropic, OpenRouter, z.AI GLM, MiniMax)

Server

  • Updated getActiveClaudeApiProfile() to check project settings first
  • Added projectPath parameter to all 16 Claude API call sites
  • Protected claudeApiProfiles from accidental empty array overwrites
  • Auto-migration creates "Direct Anthropic" profile for existing users

UI

  • New ProjectClaudeSection component for per-project profile selection
  • API Key Source selector in profile form
  • Duplicate name validation for profiles
  • Contextual info box in API Keys section
  • Settings sync includes claudeApiProfiles and activeClaudeApiProfileId

Testing

  1. Profile creation: Create profiles with different API key sources
  2. Per-project override: Set different profiles for different projects
  3. Global fallback: Verify "Use Global Setting" properly clears override
  4. Persistence: Profiles survive browser refresh and app restart
  5. Migration: Existing users with Anthropic key get auto-created profile

Screenshots

image image image image image image

Summary by CodeRabbit

  • New Features

    • Claude API Profiles: manage multiple Claude/Anthropic endpoints and choose API key source (inline/env/credentials).
    • Per-project overrides: set a project-specific Claude profile that can fall back to global.
    • UI additions: new Claude section in Project Settings and a profiles management panel; title/enhance features accept optional project context.
  • Chores

    • Settings migration: automatic creation of a Direct Anthropic profile when applicable.
  • Documentation

    • Added guide for unified API key profiles and usage.

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

webdevcody and others added 28 commits January 17, 2026 18:43
Introduce APP_HOST variable to allow custom hostname configuration for the web server. Default to localhost if VITE_HOSTNAME is not set. Update relevant URLs and CORS origins to use APP_HOST, enhancing flexibility for local development and deployment.

This change improves the application's adaptability to different environments.
Updated the process termination logic in ClaudeUsageService to handle Windows environments correctly. The code now checks the operating system and calls the appropriate kill method, ensuring consistent behavior across platforms.
Refactored the process termination logic in both ClaudeUsageService and TerminalService to use a centralized method for killing PTY processes. This ensures consistent handling of process termination across Windows and Unix-like systems, improving reliability and maintainability of the code.
…ests

Added a mock for the Unix platform in the SIGTERM test case to ensure proper behavior during testing on non-Windows systems. This change enhances the reliability of the tests by simulating the expected environment for process termination.
Add support for managing multiple Claude-compatible API endpoints
(z.AI GLM, AWS Bedrock, etc.) through provider profiles in settings.

Features:
- New ClaudeApiProfile type with base URL, API key, model mappings
- Pre-configured z.AI GLM template with correct model names
- Profile selector in Settings > Claude > API Profiles
- Clean switching between profiles and direct Anthropic API
- Immediate persistence to prevent data loss on restart

Profile support added to all execution paths:
- Agent service (chat)
- Ideation service
- Auto-mode service (feature agents, enhancements)
- Simple query service (title generation, descriptions, etc.)
- Backlog planning, commit messages, spec generation
- GitHub issue validation, suggestions

Environment variables set when profile is active:
- ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN/API_KEY
- ANTHROPIC_DEFAULT_HAIKU/SONNET/OPUS_MODEL
- API_TIMEOUT_MS, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
Resolved conflict in terminal-service.ts by accepting upstream
Electron detection properties alongside local Windows termination fixes.
…upport

The `./start-automaker.sh` script doesn't work when invoked from Windows
CMD or PowerShell because:
1. The `./` prefix is Unix-style path notation
2. Windows shells don't execute .sh files directly

This adds a Node.js launcher (`start-automaker.mjs`) that:
- Detects the platform and finds bash (Git Bash, MSYS2, Cygwin, or WSL)
- Converts Windows paths to Unix-style for bash compatibility
- Passes all arguments through to the original bash script
- Provides helpful error messages if bash isn't found

The npm scripts now use `node start-automaker.mjs` which works on all
platforms while preserving the full functionality of the bash TUI launcher.
- Remove duplicate killPtyProcess method in claude-usage-service.ts
- Import and use spawnSync correctly instead of spawn.sync
- Fix misleading comment about shell option and signal handling
- Add convertPathForBash() function that detects bash variant:
  - Cygwin: /cygdrive/c/path
  - WSL: /mnt/c/path
  - MSYS/Git Bash: /c/path
- Update exit handler to properly handle signal termination
  (exit code 1 when killed by signal vs code from child)

Addresses remaining CodeRabbit PR AutoMaker-Org#586 recommendations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added handlers for theme submenu to manage mouse enter/leave events with a delay, preventing premature closure.
- Implemented dynamic positioning for the submenu to avoid viewport overflow, ensuring better visibility.
- Updated styles to accommodate new positioning logic and added scroll functionality for theme selection.

These changes improve user experience by making the theme selection process more intuitive and visually accessible.
- Add detectBashVariant() that checks $OSTYPE for reliable WSL/MSYS/Cygwin
  detection instead of relying solely on executable path
- Add input validation to convertPathForBash() to catch null/undefined args
- Add validate_port() function in bash script to reject invalid port input
  (non-numeric, out of range) with clear error messages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Collect web and server port inputs first, then validate both before
assigning to global variables. This prevents WEB_PORT from being
modified when SERVER_PORT validation subsequently fails.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…roject-theme-ui-overlap

fix: enhance project context menu with theme submenu improvements
…r-compatibility

fix: add cross-platform Node.js launcher for Windows CMD/PowerShell support
- Add ApiKeySource type ('inline' | 'env' | 'credentials') to ClaudeApiProfile
- Allow profiles to source API keys from credentials.json or environment variables
- Add provider templates: OpenRouter, MiniMax, MiniMax (China)
- Auto-migrate existing users with Anthropic key to "Direct Anthropic" profile
- Update all API call sites to pass credentials for key resolution
- Add API key source selector to profile creation UI
- Increment settings version to 5 for migration support

This allows users to:
- Share a single API key across multiple profile configurations
- Use environment variables for CI/CD deployments
- Easily switch between providers without re-entering keys
Allow users to override the global Claude API profile on a per-project
basis. This enables experimentation with alternative providers (z.AI GLM,
MiniMax, etc.) on specific projects while keeping others on Direct Anthropic.

Changes:
- Add activeClaudeApiProfileId to ProjectSettings type
- Update getActiveClaudeApiProfile() to check project settings first
- Pass projectPath to all server call sites (14 files)
- Add Claude section to Project Settings UI with profile selector
- Add setProjectClaudeApiProfile store action with server persistence
- Update project settings loader to restore per-project profile
- Document per-project override in UNIFIED_API_KEY_PROFILES.md

Note: This only affects Claude model calls. When using Codex, OpenCode,
or Cursor models, the Claude API profile setting has no effect.
Keep DATA_DIR export from feature branch and adopt improved
CORS_ORIGINS handling from main that ensures localhost and
127.0.0.1 are always included for local development.
Updated enhance-prompt and generate-title endpoints to accept and use
projectPath, ensuring per-project Claude API profile selection works
correctly for these operations.

Changes:
- enhance.ts: Accept projectPath in request body, pass to getActiveClaudeApiProfile
- generate-title.ts: Accept projectPath in request body, pass to getActiveClaudeApiProfile
- http-api-client.ts: Update both API calls to accept projectPath
- electron.ts: Update interface for both endpoints
- enhance-with-ai.tsx: Get currentProject.path from store and pass it
- use-board-actions.ts: Pass projectPath to generateTitle call

All 16 call sites now pass project context to getActiveClaudeApiProfile().
Added claudeApiProfiles and activeClaudeApiProfileId to the
buildSettingsUpdateFromStore() function so that Claude API
profiles are properly persisted to the server settings file.

Previously, profiles were only stored in Zustand state but not
synced to the server, causing them to be lost on hot reload.
Two issues were preventing Claude API profiles from persisting:

1. Server: claudeApiProfiles was not protected against accidental empty
   array overwrites - added to ignoreEmptyArrayOverwrite list

2. UI: hydrateStoreFromSettings() was not loading claudeApiProfiles and
   activeClaudeApiProfileId from server settings into Zustand store

Now profiles will properly survive browser refreshes and hot reloads.
When setting activeClaudeApiProfileId to undefined (meaning "use global"),
the JavaScript spread operator was ignoring it, keeping the old value.

Now explicitly delete the key when undefined is passed, so the project
properly falls back to the global setting.
JavaScript/JSON doesn't serialize undefined values, so when the UI tried
to send {activeClaudeApiProfileId: undefined} to clear the project override,
the key was simply not included in the request.

Solution: Use "__USE_GLOBAL__" marker string when selecting "Use Global Setting".
The server detects this marker and deletes the key from project settings,
properly falling back to global configuration.
Prevent users from creating profiles with duplicate names (case-insensitive).
Shows an error message under the name field and disables the save button
when a duplicate is detected.
Added an info box below the Anthropic API Key field explaining:
- How to use this key with Claude API Profiles (credentials source)
- How to configure alternative providers (inline key source)

This helps users understand the relationship between the API Keys
section and the Claude API Profiles feature.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 19, 2026

Warning

Rate limit exceeded

@stefandevo has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 20 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 61eb548 and 78ab646.

📒 Files selected for processing (6)
  • apps/server/src/services/auto-mode-service.ts
  • apps/ui/src/components/layout/project-switcher/components/project-context-menu.tsx
  • apps/ui/src/components/views/board-view/hooks/use-board-actions.ts
  • apps/ui/src/components/views/settings-view/providers/claude-settings-tab/api-profiles-section.tsx
  • apps/ui/src/hooks/use-settings-migration.ts
  • apps/ui/src/store/app-store.ts

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a Claude API profile system: types, settings migration, profile resolution (project override → global → direct Anthropic), credential sourcing (inline/env/credentials), UI for managing profiles, and threads profile+credentials through provider, routes, and services.

Changes

Cohort / File(s) Summary
Type Definitions
libs/types/src/settings.ts, libs/types/src/provider.ts, libs/types/src/index.ts
New ApiKeySource, ClaudeApiProfile, ClaudeApiProfileTemplate, CLAUDE_API_PROFILE_TEMPLATES; add claudeApiProfiles and activeClaudeApiProfileId to settings; bump settings version; extend ExecuteOptions with claudeApiProfile? and credentials?.
Settings Helper
apps/server/src/lib/settings-helpers.ts
New getActiveClaudeApiProfile() returns { profile?, credentials? }, resolves project override then global, logs decisions and handles errors.
Provider & Query Surface
apps/server/src/providers/claude-provider.ts, apps/server/src/providers/simple-query-service.ts
buildEnv(profile?, credentials?) added/updated to resolve env from profile or direct credentials/env; ExecuteOptions / SimpleQueryOptions now accept claudeApiProfile and credentials and are threaded into provider calls.
Settings Service & Migration
apps/server/src/services/settings-service.ts, apps/ui/src/hooks/use-settings-migration.ts, apps/ui/src/hooks/use-settings-sync.ts
v4→v5 migration to auto-create Direct Anthropic profile when appropriate; persist claudeApiProfiles and activeClaudeApiProfileId; special __USE_GLOBAL__ sentinel handling for project overrides.
Route Handlers (server)
apps/server/src/routes/.../*.ts (e.g., app-spec/*, backlog-plan/*, context/*, enhance-prompt/*, features/*, github/*, suggestions/*, worktree/*)
Import and call getActiveClaudeApiProfile(...) (often with optional projectPath), pass claudeApiProfile and credentials into streaming/simpleQuery/execute calls; generate-commit-message consolidated to provider-based streaming.
Backend Services
apps/server/src/services/{agent-service,auto-mode-service,ideation-service}.ts
Fetch active profile early in flows and propagate claudeApiProfile and credentials via ExecuteOptions to provider/agent executions.
UI - App Store & Sync
apps/ui/src/store/app-store.ts, apps/ui/src/hooks/use-project-settings-loader.ts, apps/ui/src/hooks/use-settings-sync.ts
Add claudeApiProfiles and activeClaudeApiProfileId to store; CRUD actions add/update/delete/setActive + setProjectClaudeApiProfile() (persists using __USE_GLOBAL__ marker); hydration/sync updated.
UI - Profile Management
apps/ui/src/components/views/settings-view/providers/claude-settings-tab/api-profiles-section.tsx, apps/ui/src/components/views/settings-view/providers/claude-settings-tab.tsx, apps/ui/src/components/views/settings-view/api-keys-section.tsx
New ApiProfilesSection component: create/edit/delete profiles, API key source selector (inline/env/credentials), templates, active-profile control; contextual info in API Keys section; integrated into Claude settings tab.
UI - Project Settings
apps/ui/src/components/views/project-settings-view/project-claude-section.tsx, .../project-settings-view.tsx, .../config/navigation.ts, .../hooks/use-project-settings-view.ts
New ProjectClaudeSection UI and 'claude' view; per-project selection (Global / Direct / profile), displays status and persists overrides.
UI - Integration & Calls
apps/ui/src/lib/http-api-client.ts, apps/ui/src/lib/electron.ts, apps/ui/src/components/.../enhance-with-ai.tsx, apps/ui/src/components/views/board-view/hooks/use-board-actions.ts
generateTitle and enhance APIs accept optional projectPath; frontend passes current project path into enhancement/title flows.
UI - Theme Submenu & Misc
apps/ui/src/components/layout/project-switcher/..., apps/ui/src/components/layout/sidebar/..., apps/ui/src/components/layout/sidebar/constants.ts
Add THEME_SUBMENU_CONSTANTS, improved theme submenu UX/positioning, exposed extra props for project picker control.
Startup / Scripts
start-automaker.mjs, start-automaker.sh, package.json
Add cross-platform Node launcher start-automaker.mjs, update npm scripts to use it; shell script adds port validation and APP_HOST/CORS improvements.
Documentation
docs/UNIFIED_API_KEY_PROFILES.md
Comprehensive docs for profiles, apiKeySource semantics, migration, templates, and usage across server/UI.

Sequence Diagram(s)

sequenceDiagram
    participant Route as Route Handler
    participant Helper as getActiveClaudeApiProfile
    participant Settings as SettingsService
    participant Store as App Store
    participant Provider as Claude Provider

    Route->>Helper: getActiveClaudeApiProfile(settingsService, logPrefix, projectPath)
    Helper->>Settings: getProjectSettings(projectPath)
    Settings-->>Helper: projectSettings
    alt project override exists
        Helper->>Store: lookup profile by project.activeClaudeApiProfileId
        Store-->>Helper: ClaudeApiProfile
    else fallback to global
        Helper->>Settings: getGlobalSettings()
        Settings-->>Helper: globalSettings
        Helper->>Store: lookup profile by global.activeClaudeApiProfileId
        Store-->>Helper: ClaudeApiProfile
    end
    alt profile found
        Helper->>Helper: resolve credentials (inline/env/credentials) using credentials arg
        Helper-->>Route: { profile, credentials }
    else no profile
        Helper-->>Route: { profile: undefined, credentials }
    end
    Route->>Provider: executeQuery({ claudeApiProfile, credentials, ... })
    Provider->>Provider: buildEnv(claudeApiProfile, credentials)
    Note over Provider: construct env vars (API key, base URL, timeout, models)
    Provider-->>Route: response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Suggested labels

Enhancement

Suggested reviewers

  • Shironex

Poem

🐰 A rabbit finds the profile tree,

Global, project, keys for me.
Inline, env, or shared credentials flow,
Profiles pick the endpoints we go.
Hops of joy—configured, neat, and free!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main feature: unified Claude API key and profile system with support for multiple providers (z.AI, MiniMax, OpenRouter).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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
Copy Markdown
Contributor

Summary of Changes

Hello @stefandevo, 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 flexibility and management of Claude API access by introducing a unified system for API key sourcing and per-project profile overrides. It allows users to configure how API keys are resolved (inline, environment variable, or global credentials) and provides the ability to assign different Claude-compatible API endpoints to individual projects. This change aims to improve experimentation, cost optimization, and regional compliance by making it easier to switch between various providers like z.AI GLM, MiniMax, and OpenRouter, all while maintaining a consistent and user-friendly experience.

Highlights

  • Unified Claude API Key and Profile System: Introduced a flexible apiKeySource field for Claude API profiles, allowing API keys to be sourced from inline (directly in profile), env (environment variable ANTHROPIC_API_KEY), or credentials (from global API Keys settings). This enables sharing a single API key across multiple configurations and supports various deployment scenarios.
  • Per-Project Profile Overrides: Projects can now override the global Claude API profile, enabling specific projects to use different endpoints or configurations. This is configurable in 'Project Settings → Claude' and supports options like 'Use Global Setting', 'Direct Anthropic API', or a specific custom profile.
  • New Provider Templates: Added predefined templates for alternative Claude-compatible providers, including 'Direct Anthropic', 'OpenRouter', 'z.AI GLM', 'MiniMax', and 'MiniMax (China)', simplifying setup for these services.
  • Automatic Migration for Existing Users: Implemented an automatic migration (v4 to v5) that creates a 'Direct Anthropic' profile for existing users who have an Anthropic API key configured but no existing profiles, ensuring a seamless transition.
  • Enhanced UX for API Key Management: Improved the user interface with duplicate profile name validation, a contextual information box in the API Keys section explaining the relationship with profiles, and a dedicated 'Claude' section in Project Settings for per-project profile selection.
  • Cross-Platform Launcher Script: Replaced the start-automaker.sh script with a new cross-platform start-automaker.mjs launcher, improving compatibility and robustness across different operating systems, especially Windows.

🧠 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
Copy Markdown
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 is an impressive and extensive pull request that successfully implements a unified API key and profile system for Claude. The introduction of flexible API key sourcing, per-project profile overrides, and support for alternative providers like z.AI, MiniMax, and OpenRouter is a significant architectural improvement. The code is well-structured, and the addition of documentation and a settings migration path shows great attention to detail.

I've identified one critical issue in the API key resolution logic on the server and one high-severity issue in the UI that could cause a crash. Once these are addressed, this will be an excellent addition to the codebase.

Comment thread apps/server/src/providers/claude-provider.ts Outdated
Update buildEnv() to pass through ANTHROPIC_BASE_URL from process.env
when no API profile is configured. This maintains backward compatibility
for users who set custom endpoints via environment variables without
creating a profile.

Also fix prettier formatting in use-project-creation.ts from merge.
1. Critical: Use credentials file API key when no profile is active
   - buildEnv() now prioritizes credentials.apiKeys.anthropic over
     process.env.ANTHROPIC_API_KEY when no profile is configured
   - This ensures API keys saved in the UI settings are used correctly

2. High: Handle undefined API key in maskApiKey function
   - maskApiKey() now accepts optional string parameter
   - Returns masked placeholder for undefined/short keys
   - Prevents runtime error for profiles with non-inline key sources
Copy link
Copy Markdown
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: 6

Caution

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

⚠️ Outside diff range comments (1)
apps/ui/src/components/views/board-view/hooks/use-board-actions.ts (1)

210-252: Add projectPath to the useCallback dependency array.

Line 215 uses projectPath in the generateTitle call, but it's missing from the dependency array. If the user switches projects, the callback will continue using the stale projectPath value.

🔧 Suggested fix
     [
       addFeature,
       persistFeatureCreate,
       persistFeatureUpdate,
       updateFeature,
       saveCategory,
       currentProject,
+      projectPath,
       onWorktreeCreated,
       onWorktreeAutoSelect,
       getPrimaryWorktreeBranch,
       features,
     ]
🤖 Fix all issues with AI agents
In `@apps/server/src/routes/context/routes/describe-file.ts`:
- Around line 22-26: The per-project lookup is using the file's directory as cwd
when calling getAutoLoadClaudeMdSetting and getActiveClaudeApiProfile, causing
settings in the project root to be missed; change the code that computes cwd for
those calls to resolve the project root instead of the file's parent directory
by traversing upward from the file path and stopping on project markers (e.g.,
.git, .automaker/settings.json or similar), then pass that projectRoot into
getAutoLoadClaudeMdSetting(...) and getActiveClaudeApiProfile(...) in place of
the current cwd usage.

In `@apps/server/src/services/auto-mode-service.ts`:
- Around line 3269-3270: Nested executeQuery calls are not forwarding
credentials when apiKeySource === 'credentials', so plan revisions, per-task
executions and continuations fail; update each nested call that currently passes
claudeApiProfile (e.g., the calls around the claudeApiProfile parameter) to also
forward the active credentials from that profile (e.g., include
claudeApiProfile.credentials or a credentials field) when
claudeApiProfile.apiKeySource === 'credentials'; apply this fix to the
occurrences at the executeQuery invocations near the existing claudeApiProfile
usage and the other two locations mentioned (around lines 3415-3416 and
3510-3511) so all nested plan/task/continuation executeQuery calls receive
credentials.

In
`@apps/ui/src/components/layout/project-switcher/components/project-context-menu.tsx`:
- Around line 456-460: Clamp the computed submenu maxHeight so it never goes
negative by replacing the direct subtraction with a non-negative expression
(e.g., use Math.max(0, submenuPosition.maxHeight -
THEME_SUBMENU_CONSTANTS.SUBMENU_HEADER_HEIGHT)) and use that clamped value in
the inline style for the div; update the logic around submenuPosition and
THEME_SUBMENU_CONSTANTS.SUBMENU_HEADER_HEIGHT in project-context-menu.tsx so the
style always receives a safe, non-negative maxHeight.

In
`@apps/ui/src/components/views/settings-view/providers/claude-settings-tab/api-profiles-section.tsx`:
- Around line 50-54: maskApiKey currently assumes a string and will throw if
profile.apiKey is undefined for non-inline profiles; update maskApiKey (and
calls in the profile card rendering) to accept undefined/null and return a safe
label such as 'Environment' or 'Credentials' (or a masked placeholder like
'••••••••') when key is missing, and ensure the UI shows the apiKeySource value
as the visible source label when apiKey is not provided; reference maskApiKey
and where profile.apiKey and profile.apiKeySource are read in the profile card
rendering to implement this guard and display the source.

In `@apps/ui/src/hooks/use-settings-migration.ts`:
- Around line 674-675: parseLocalStorageSettings and mergeSettings currently
omit the new claudeApiProfiles and activeClaudeApiProfileId fields so
localStorage-stored Claude profiles get dropped during migration/fallback;
update both functions to read and include settings.claudeApiProfiles (defaulting
to [] if undefined) and settings.activeClaudeApiProfileId (defaulting to null if
undefined) when constructing the returned/merged settings object so local
profiles survive server-unreachable or first-time migration paths.

In `@apps/ui/src/store/app-store.ts`:
- Around line 2540-2550: When deleting a Claude profile in
deleteClaudeApiProfile, also scan and clear any per-project overrides that
reference the deleted id: for each project with activeClaudeApiProfileId === id
set it to '__USE_GLOBAL__' and persist via
httpClient.settings.updateProject(projectId, { activeClaudeApiProfileId:
'__USE_GLOBAL__' }); after updating the in-memory claudeApiProfiles and
activeClaudeApiProfileId, await all updateProject calls and then call
syncSettingsToServer(); also adjust imports to use the `@automaker/`* namespace
(e.g., import httpClient from '@automaker/http' or the appropriate `@automaker`
settings client) instead of '@/...'.
🧹 Nitpick comments (1)
apps/server/src/routes/enhance-prompt/routes/enhance.ts (1)

145-155: Consider using projectPath as cwd when available.

Currently, cwd is always set to process.cwd() even when projectPath is provided. While this may be intentional since prompt enhancement doesn't need filesystem access, using projectPath as cwd (when provided) would be more consistent with the profile resolution context.

💡 Optional: Use projectPath as cwd when available
       const result = await simpleQuery({
         prompt: `${systemPrompt}\n\n${userPrompt}`,
         model: resolvedModel,
-        cwd: process.cwd(), // Enhancement doesn't need a specific working directory
+        cwd: projectPath || process.cwd(), // Use project path for consistency with profile resolution
         maxTurns: 1,
         allowedTools: [],
         thinkingLevel,

Comment thread apps/server/src/routes/context/routes/describe-file.ts
Comment thread apps/server/src/services/auto-mode-service.ts
Comment thread apps/ui/src/hooks/use-settings-migration.ts
Comment thread apps/ui/src/store/app-store.ts
1. auto-mode-service.ts: Forward credentials in nested executeQuery calls
   - Plan revisions, per-task executions, and continuations now receive
     credentials for profiles using 'credentials' apiKeySource

2. app-store.ts: Clear per-project overrides when deleting profile
   - Projects referencing deleted profile are reset to "use global"
   - Persists changes via httpClient.settings.updateProject()

3. use-board-actions.ts: Add projectPath to useCallback dependency array
   - Prevents stale closure when switching projects during title generation

4. project-context-menu.tsx: Clamp submenu maxHeight to avoid negative values
   - Prevents collapsed scroll area on very small viewports

5. use-settings-migration.ts: Include Claude API profiles in localStorage migration
   - Adds claudeApiProfiles and activeClaudeApiProfileId to parseLocalStorageSettings()
   - Adds merge logic in mergeSettings() to preserve profiles during migration
Copy link
Copy Markdown
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

🤖 Fix all issues with AI agents
In
`@apps/ui/src/components/views/settings-view/providers/claude-settings-tab/api-profiles-section.tsx`:
- Around line 160-179: The timeout parsing in handleSave builds
ClaudeApiProfile.timeoutMs using parseInt on formData.timeoutMs which truncates
decimals and misparses scientific notation; replace that logic to convert via
Number(formData.timeoutMs) and validate with Number.isFinite (or isFinite) so
decimal (e.g., "123.45") and scientific ("1e3") strings produce correct numeric
values, and set timeoutMs to the numeric value only when the conversion yields a
finite number (otherwise undefined).
🧹 Nitpick comments (2)
apps/server/src/providers/claude-provider.ts (2)

26-52: Consider removing system vars from ALLOWED_ENV_VARS to reduce redundancy.

System variables (PATH, HOME, etc.) are listed in both ALLOWED_ENV_VARS (lines 42-48) and SYSTEM_ENV_VARS (line 52). Since SYSTEM_ENV_VARS is now used exclusively for adding system vars (line 153), the entries in ALLOWED_ENV_VARS are unused and potentially misleading.

♻️ Suggested cleanup
 const ALLOWED_ENV_VARS = [
   // Authentication
   'ANTHROPIC_API_KEY',
   'ANTHROPIC_AUTH_TOKEN',
   // Endpoint configuration
   'ANTHROPIC_BASE_URL',
   'API_TIMEOUT_MS',
   // Model mappings
   'ANTHROPIC_DEFAULT_HAIKU_MODEL',
   'ANTHROPIC_DEFAULT_SONNET_MODEL',
   'ANTHROPIC_DEFAULT_OPUS_MODEL',
   // Traffic control
   'CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC',
-  // System vars (always from process.env)
-  'PATH',
-  'HOME',
-  'SHELL',
-  'TERM',
-  'USER',
-  'LANG',
-  'LC_ALL',
 ];

288-300: detectInstallation() only checks environment variables, not credentials-based API keys.

The method checks process.env.ANTHROPIC_API_KEY to determine hasApiKey and authenticated status. With credentials-based keys supported in the UI settings (via buildEnv() at lines 135-136), this may report hasApiKey: false even when a valid key is configured through the credentials file.

This is an architectural limitation: detectInstallation() is called from ProviderFactory.checkAllProviders() without credentials context, since provider instances are created fresh from a factory and credentials are only available during executeQuery(). Fixing this would require passing credentials through the factory chain or storing them in the provider instance—changes that may warrant separate consideration.

…ic notation

parseInt truncates decimals and misparses scientific notation (e.g., "1e3").
Using Number() with Number.isFinite() validation correctly handles:
- Decimal values: "123.45" -> 123.45
- Scientific notation: "1e3" -> 1000
- Invalid values: "abc" -> undefined
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.

4 participants