feat: Add setting to use Claude subscription when API key is detected (#1229)

* feat: Add setting to use Claude subscription when API key is detected

This commit adds a new optional setting `use_claude_subscription` to the ClaudeCode
executor configuration. When enabled, this setting removes the ANTHROPIC_API_KEY
environment variable before spawning the Claude Code agent, ensuring that users with
Claude Pro/Team subscriptions can opt to use their subscription instead of being
charged API fees.

## Changes

- Added `use_claude_subscription` optional field to the `ClaudeCode` struct
- Implemented logic in `spawn_internal` to conditionally remove `ANTHROPIC_API_KEY`
  from the environment when the setting is enabled
- Added tracing log when API key is removed for better debugging

## Implementation Details

- The field is optional (`Option<bool>`) and defaults to `false` when not set,
  maintaining backward compatibility
- Uses `#[serde(skip_serializing_if = "Option::is_none")]` to keep JSON clean
- The setting is automatically exposed in the frontend via the JSON Schema
  auto-generation from Rust structs
- TypeScript bindings are auto-generated via the `#[derive(TS)]` macro

## Benefits

- Prevents unexpected API charges for users with Claude subscriptions
- Gives users explicit control over authentication method
- Backward compatible - existing configurations continue to work unchanged
- No frontend changes needed - the setting appears automatically in the
  ExecutorConfigForm

## Related

- Addresses feature request in discussion #1228
- Design document: https://github.com/potable-anarchy/vibe-kanban-launcher/blob/main/DESIGN_PROPOSAL.md

* cleanups

rename the config parameter to `disable_api_key`.
regenerate type bindings.

* suggest using the setting in the api-key warning

---------

Co-authored-by: Solomon <abcpro11051@disroot.org>
This commit is contained in:
potable-anarchy
2025-11-26 02:38:23 -08:00
committed by GitHub
parent 9dabff0752
commit 14fe26f72d
3 changed files with 18 additions and 3 deletions

View File

@@ -59,6 +59,8 @@ pub struct ClaudeCode {
pub model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dangerously_skip_permissions: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub disable_api_key: Option<bool>,
#[serde(flatten)]
pub cmd: CmdOverrides,
@@ -231,6 +233,12 @@ impl ClaudeCode {
.current_dir(current_dir)
.args(&args);
// Remove ANTHROPIC_API_KEY if disable_api_key is enabled
if self.disable_api_key.unwrap_or(false) {
command.env_remove("ANTHROPIC_API_KEY");
tracing::info!("ANTHROPIC_API_KEY removed from environment");
}
let mut child = command.group_spawn()?;
let child_stdout = child.inner().stdout.take().ok_or_else(|| {
ExecutorError::Io(std::io::Error::other("Claude Code missing stdout"))
@@ -444,7 +452,7 @@ impl ClaudeLogProcessor {
timestamp: None,
entry_type: NormalizedEntryType::ErrorMessage { error_type: NormalizedEntryError::Other,
},
content: "Claude Code + ANTHROPIC_API_KEY detected. Usage will be billed via Anthropic pay-as-you-go instead of your Claude subscription.".to_string(),
content: "Claude Code + ANTHROPIC_API_KEY detected. Usage will be billed via Anthropic pay-as-you-go instead of your Claude subscription. If this is unintended, please select the `disable_api_key` checkbox in the conding-agent-configurations settings page.".to_string(),
metadata: None,
})
}
@@ -1987,6 +1995,7 @@ mod tests {
additional_params: None,
},
approvals_service: None,
disable_api_key: None,
};
let msg_store = Arc::new(MsgStore::new());
let current_dir = std::path::PathBuf::from("/tmp/test-worktree");
@@ -2260,7 +2269,7 @@ mod tests {
));
assert_eq!(
entries[0].content,
"Claude Code + ANTHROPIC_API_KEY detected. Usage will be billed via Anthropic pay-as-you-go instead of your Claude subscription."
"Claude Code + ANTHROPIC_API_KEY detected. Usage will be billed via Anthropic pay-as-you-go instead of your Claude subscription. If this is unintended, please select the `disable_api_key` checkbox in the conding-agent-configurations settings page."
);
// Test with managed API key source - should not generate warning