Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/providers/claude-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ export class ClaudeProvider implements LLMProvider {
this._cwd = options.cwd ?? process.cwd();
this._systemPrompt = options.systemPrompt ?? '';
this._allowedTools = options.allowedTools ?? [];
this._permissionMode = options.permissionMode ?? 'bypassPermissions';
// Read permission_mode from provider config, falling back to options, then default.
// 'bypassPermissions' fails when running as root in Docker, so containers
// should set permission_mode = "acceptEdits" in config.toml.
this._permissionMode = config.permission_mode
?? options.permissionMode
?? 'bypassPermissions';
Comment on lines +178 to +183

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.

medium

Programmatic options typically take precedence over configuration file settings to allow for runtime overrides. The current implementation prioritizes config.permission_mode over options.permissionMode. Swapping the order ensures that explicit overrides provided during instantiation are respected.

Suggested change
// Read permission_mode from provider config, falling back to options, then default.
// 'bypassPermissions' fails when running as root in Docker, so containers
// should set permission_mode = "acceptEdits" in config.toml.
this._permissionMode = config.permission_mode
?? options.permissionMode
?? 'bypassPermissions';
// Read permission_mode from options (programmatic override) or provider config, falling back to default.
// 'bypassPermissions' fails when running as root in Docker, so containers
// should set permission_mode = "acceptEdits" in config.toml.
this._permissionMode = options.permissionMode
?? config.permission_mode
?? 'bypassPermissions';

@josephfung josephfung Apr 23, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I get the general principle - programmatic options should normally beat config file settings.

However, in this codebase the orchestrator always passes permissionMode: 'default' explicitly when constructing ClaudeProviderOptions (see src/orchestrator/orchestrator.ts), so options.permissionMode is never undefined. With the order suggested, config.permission_mode would never be reached, making the feature silently non-functional.

The intent here is that config.permission_mode is the user's override lever (the only one they have), while options.permissionMode is the orchestrator's internal default. So config should win over the orchestrator default, which is what the current order achieves.

If there's a future need for a true programmatic override that beats the config, the right fix would be a distinct field (e.g., options.permissionModeOverride) that the orchestrator sets only when explicitly requested rather than conflating it with the fallback default.

this._circuitBreaker = new CircuitBreaker();

// Dependency injection: use provided queryFn or lazy-load the real SDK
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,9 @@ export interface ClaudeProviderConfig extends BaseProviderConfig {
type: 'claude-sdk';
auth_method?: 'mac_session' | 'api_key';
api_key_env?: string;
/** Permission mode for the Claude Code subprocess.
* 'bypassPermissions' fails as root in Docker — use 'acceptEdits' instead. */
permission_mode?: 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan';
}

/** TYPE-04: Gemini CLI provider config */
Expand Down Expand Up @@ -454,6 +457,9 @@ export interface ProviderConfig {
cli_path?: string;
api_key_env?: string;
endpoint?: string;
/** Permission mode for the Claude Code subprocess.
* 'bypassPermissions' fails as root in Docker — use 'acceptEdits' instead. */
permission_mode?: 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan';
}

/** TYPE-04: Typed provider config discriminated union */
Expand Down