Add Claude Code auto permission mode as a 4th runtime mode#3628
Conversation
Claude Code's TypeScript Agent SDK exposes an "auto" PermissionMode (default | acceptEdits | bypassPermissions | plan | dontAsk | auto) that runs tool calls through a background safety classifier instead of skipping permission checks entirely. It's distinct from bypassPermissions and never requires allowDangerouslySkipPermissions, so it works in environments where an org policy blocks --dangerously-skip-permissions but still allows auto mode. - Add "auto" to the RuntimeMode contract and map it to the SDK's permissionMode in ClaudeAdapter. - Add a supportsAutoRuntimeMode provider capability flag so only Claude advertises the option; Codex falls back to its workspace-write policy defensively instead of full bypass. - Surface the option in the web composer menus and mobile runtime option lists, gated on that capability flag.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
| @@ -117,6 +117,7 @@ export type ModelSelection = typeof ModelSelection.Type; | |||
| export const RuntimeMode = Schema.Literals([ | |||
There was a problem hiding this comment.
🟡 Medium src/orchestration.ts:117
Adding "auto" to the global RuntimeMode schema makes that value valid in every persisted thread and command, not just Claude. A thread created with runtimeMode: "auto" can later have its modelSelection changed via ThreadMetaUpdateCommand to a non-Claude provider while keeping runtimeMode: "auto". Adapters that don't recognize "auto" silently misresolve it — for example CursorAdapter.resolveRequestedModeId maps any non-"approval-required" value to its implement mode, and buildOpenCodePermissionRules falls back to generic non-full-access rules. The thread then runs with wrong permission behavior instead of a normalization or validation failure. If "auto" is Claude-specific, consider narrowing it to a Claude-only field or adding adapter-level validation that rejects unrecognized modes.
🤖 Copy this AI Prompt to have your agent fix this:
In file @packages/contracts/src/orchestration.ts around line 117:
Adding `"auto"` to the global `RuntimeMode` schema makes that value valid in every persisted thread and command, not just Claude. A thread created with `runtimeMode: "auto"` can later have its `modelSelection` changed via `ThreadMetaUpdateCommand` to a non-Claude provider while keeping `runtimeMode: "auto"`. Adapters that don't recognize `"auto"` silently misresolve it — for example `CursorAdapter.resolveRequestedModeId` maps any non-`"approval-required"` value to its implement mode, and `buildOpenCodePermissionRules` falls back to generic non-full-access rules. The thread then runs with wrong permission behavior instead of a normalization or validation failure. If `"auto"` is Claude-specific, consider narrowing it to a Claude-only field or adding adapter-level validation that rejects unrecognized modes.
ApprovabilityVerdict: Needs human review 2 blocking correctness issues found. New feature adding a 4th runtime mode with multiple unresolved review comments identifying bugs: runtime mode isn't normalized when switching providers, and non-Claude adapters could silently mishandle the 'auto' value. These issues affect runtime behavior and need resolution. You can customize Macroscope's approvability policy. Learn more. |
Mobile checked providerDriver === "claudeAgent" directly, while the web composer checks the supportsAutoRuntimeMode flag reported by the provider snapshot. Those happen to agree today since Claude always sets the flag to true, but they could silently diverge if the flag is ever made conditional. Add supportsAutoRuntimeMode to ModelOption and gate on that instead, matching the web behavior.
|
Mobile gating on Global
So the worst case is a thread that shows "Auto" in its history while actually behaving like "ask before every action" on a non-Claude provider. That's a UX/labeling nit, not a permissions escalation. Codex is the one adapter where this mattered for real, since its unhandled-mode fallback was |
| flow.interactionMode, | ||
| flow.runtimeMode, | ||
| flow.selectedModelOption?.supportsAutoRuntimeMode, | ||
| providerOptionDescriptors, |
There was a problem hiding this comment.
🟡 Medium threads/NewTaskDraftScreen.tsx:241
When the selected model does not support the "auto" runtime mode (flow.selectedModelOption?.supportsAutoRuntimeMode is false), the menu hides the "auto" option but flow.runtimeMode is never normalized back to a supported value. If the user previously selected "auto" with a supporting model and then switches to an unsupported model, the options menu subtitle still labels the runtime as "Auto", and handleStart() submits runtimeMode: "auto" to createProjectThread for a provider that does not expose that mode. Consider resetting flow.runtimeMode whenever supportsAutoRuntimeMode transitions to false so the submitted runtime mode stays within the selected provider's supported set.
Also found in 1 other location(s)
apps/mobile/src/features/threads/ThreadComposer.tsx:555
The runtime menu can still present the current mode as
"Auto"after the user switches away from a provider that supports auto mode.handleModelMenuActiononly changesmodelSelection, socurrentRuntimeModestays"auto"; then the subtitle logic at lines 550-557 still renders"Auto"even whencurrentModelOption?.supportsAutoRuntimeModeis false and theAutomenu item has been removed. Trigger: pick ClaudeAuto, switch to another provider, and reopen the composer. The UI now claims the active provider is inAutomode even though that option is supposed to be hidden for non-Claude providers.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/mobile/src/features/threads/NewTaskDraftScreen.tsx around line 241:
When the selected model does not support the `"auto"` runtime mode (`flow.selectedModelOption?.supportsAutoRuntimeMode` is false), the menu hides the `"auto"` option but `flow.runtimeMode` is never normalized back to a supported value. If the user previously selected `"auto"` with a supporting model and then switches to an unsupported model, the options menu subtitle still labels the runtime as `"Auto"`, and `handleStart()` submits `runtimeMode: "auto"` to `createProjectThread` for a provider that does not expose that mode. Consider resetting `flow.runtimeMode` whenever `supportsAutoRuntimeMode` transitions to false so the submitted runtime mode stays within the selected provider's supported set.
Also found in 1 other location(s):
- apps/mobile/src/features/threads/ThreadComposer.tsx:555 -- The runtime menu can still present the current mode as `"Auto"` after the user switches away from a provider that supports auto mode. `handleModelMenuAction` only changes `modelSelection`, so `currentRuntimeMode` stays `"auto"`; then the subtitle logic at lines 550-557 still renders `"Auto"` even when `currentModelOption?.supportsAutoRuntimeMode` is false and the `Auto` menu item has been removed. Trigger: pick Claude `Auto`, switch to another provider, and reopen the composer. The UI now claims the active provider is in `Auto` mode even though that option is supposed to be hidden for non-Claude providers.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 45eddfd. Configure here.
| providerKey: fallbackModelSelection.instanceId, | ||
| providerLabel, | ||
| providerDriver: fallbackModelSelection.instanceId, | ||
| supportsAutoRuntimeMode: false, |
There was a problem hiding this comment.
Fallback options hide Auto mode
Medium Severity
Synthetic ModelOption rows from buildModelOptions always set supportsAutoRuntimeMode to false, even when the matching provider is still present in config.providers (disabled, unauthenticated, or missing from the model list). The runtime menus now gate the Auto entry on that flag instead of providerDriver, so Claude selections in those states lose Auto while drafts can still use runtimeMode "auto".
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 45eddfd. Configure here.


What Changed
Adds Claude Code's
autopermission mode as a fourth runtime mode option, alongside the existing Supervised / Auto-accept edits / Full access modes.RuntimeModecontract gains an"auto"value.ClaudeAdaptermaps it to the Agent SDK's nativepermissionMode: "auto", and never setsallowDangerouslySkipPermissionsfor it (that flag stays scoped tobypassPermissionsonly).supportsAutoRuntimeModeprovider capability flag gates the option so it only shows up for the Claude provider. Codex defensively maps an incoming"auto"to its existingworkspace-writepolicy instead of falling through to full sandbox bypass.Why
Claude Code's TypeScript Agent SDK supports six
PermissionModevalues (default | acceptEdits | bypassPermissions | plan | dontAsk | auto), but only two of those were reachable from this app's runtime mode selector.automode runs tool calls through a background safety classifier rather than skipping permission checks outright, so it's meaningfully different frombypassPermissions: it does not requireallowDangerouslySkipPermissions. That matters for orgs whose managed Claude Code settings disablebypassPermissions/--dangerously-skip-permissionsbut still allowautomode — those users currently have no way to reduce prompt fatigue in this app beyondacceptEdits.UI Changes
New "Auto" option in the runtime mode selector (web composer dropdown + compact menu), visible only when the active provider is Claude.
Checklist
Note
Add 'auto' as a fourth runtime mode for Claude Code permission handling
'auto'to theRuntimeModecontract schema and wires it through the server, mobile, and web layers.supportsAutoRuntimeMode: true; UI components (web composer, compact menu, mobile thread composer) conditionally show the 'Auto' option only when the selected provider/model supports it.'auto'maps topermissionMode: 'auto'in the Claude adapter and toon-requestapproval policy withworkspace-writesandbox in the Codex session runtime (same behavior as'auto-accept-edits').permissionMode: 'auto'to the Claude API rather than rejecting it as an unknown mode.Macroscope summarized 45eddfd.
Note
Medium Risk
Changes permission/runtime semantics for agent sessions; impact is mostly gated to Claude UI, but Codex still accepts
autoat the API layer with a conservative sandbox mapping.Overview
Introduces a fourth runtime mode,
auto, for Claude Code’s background safety-classifier permission path (distinct from fullbypassPermissions).Contracts & server:
RuntimeModeand provider snapshots gainsupportsAutoRuntimeMode. Claude declares it;ClaudeAdaptermapsauto→ SDKpermissionMode: "auto". Codex treats an incomingautolikeauto-accept-edits(workspace-write / on-request) so it never falls through to full-access sandbox.Clients: Web
ChatComposer/ compact menu and mobile new-task / thread composers add an Auto runtime choice only when the selected model’s provider supports it; mobileModelOptioncarries the flag from server config.Reviewed by Cursor Bugbot for commit 45eddfd. Bugbot is set up for automated code reviews on this repo. Configure here.