Summary
The Claude Agent SDK (@anthropic-ai/claude-agent-sdk@^0.2.96, which happy already depends on) supports six PermissionMode values:
// node_modules/@anthropic-ai/claude-agent-sdk/sdk.d.ts:1489
export declare type PermissionMode =
'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk' | 'auto';
Happy currently only plumbs through the first four (plus Codex-specific read-only | safe-yolo | yolo). The newer auto mode (model decides whether to prompt) and dontAsk (SDK auto-approve without prompts) are not reachable from the app.
Side note: dontAsk is already listed in packages/happy-app/sources/components/modelModeOptions.ts:52 and its i18n strings, but the wire enum in packages/happy-wire/src/messageMeta.ts rejects it — so even selecting it in the UI fails validation before reaching the CLI. dontAsk is effectively dead UI today.
User impact
Users on recent Claude Code versions cannot select the auto mode that the CLI natively offers. They are stuck choosing between hard bypass (bypassPermissions) and default prompting, with no middle-ground model-driven behavior. The half-wired dontAsk is also a papercut.
Proposed implementation path
Changes isolated to Happy — no SDK change needed.
packages/happy-wire/src/messageMeta.ts: add 'auto' (and 'dontAsk' if we're also finishing that feature) to the permissionMode zod enum.
packages/happy-cli/src/api/types.ts:35: extend PermissionMode union to include 'auto'. Update doc comment.
packages/happy-cli/src/claude/utils/permissionMode.ts:
- Add
'auto' to VALID_PERMISSION_MODES.
mapToClaudeMode: auto is identity passthrough (SDK native).
packages/happy-cli/src/claude/runClaude.ts:80: ensure dangerouslySkipPermissions is NOT set for auto (should only cover bypassPermissions / yolo / sandbox).
packages/happy-cli/src/claude/utils/permissionHandler.ts: no new branch needed at handleToolCall — auto should fall through to the SDK's own gating (i.e. canCallTool runs normally; what matters is the mode value passed to the SDK).
packages/happy-cli/src/codex/executionPolicy.ts: add defensive mapping for Codex fallback (e.g. auto → approvalPolicy: 'on-request', sandbox: 'workspace-write'), or leave on defaults.
packages/happy-app/sources/components/modelModeOptions.ts:48: add { key: 'auto', name: translate('agentInput.permissionMode.auto'), ... } to getClaudePermissionModes.
packages/happy-app/sources/text/_default.ts + all translations/*.ts: add agentInput.permissionMode.auto strings.
Release coordination
happy-wire ships as a separate npm package that happy-server also depends on. Adding values to the permissionMode enum is a coordinated release: clients sending 'auto' to a server with the old enum will be rejected at validation. Sequence: publish wire, upgrade server, then ship CLI + app simultaneously (or gate the UI option behind a feature flag until rollout is complete).
Acceptance criteria
- User can select
auto in the Claude permission-mode selector on mobile/web.
- Outbound messages carry
meta.permissionMode: 'auto'.
- CLI forwards to the Claude SDK as
permissionMode: 'auto' and session behaves as native Claude Code auto mode.
--permission-mode auto via claudeArgs is also honored.
- No regression for the existing 7 modes.
Out of scope
- Finishing
dontAsk end-to-end — can ride with this PR or split; I'd suggest same PR for consistency since the plumbing is identical.
- Gemini / Codex native
auto support — neither agent has it natively; only defensive mapping is required.
Related
Summary
The Claude Agent SDK (
@anthropic-ai/claude-agent-sdk@^0.2.96, which happy already depends on) supports sixPermissionModevalues:Happy currently only plumbs through the first four (plus Codex-specific
read-only | safe-yolo | yolo). The newerautomode (model decides whether to prompt) anddontAsk(SDK auto-approve without prompts) are not reachable from the app.Side note:
dontAskis already listed inpackages/happy-app/sources/components/modelModeOptions.ts:52and its i18n strings, but the wire enum inpackages/happy-wire/src/messageMeta.tsrejects it — so even selecting it in the UI fails validation before reaching the CLI.dontAskis effectively dead UI today.User impact
Users on recent Claude Code versions cannot select the
automode that the CLI natively offers. They are stuck choosing between hard bypass (bypassPermissions) and default prompting, with no middle-ground model-driven behavior. The half-wireddontAskis also a papercut.Proposed implementation path
Changes isolated to Happy — no SDK change needed.
packages/happy-wire/src/messageMeta.ts: add'auto'(and'dontAsk'if we're also finishing that feature) to thepermissionModezod enum.packages/happy-cli/src/api/types.ts:35: extendPermissionModeunion to include'auto'. Update doc comment.packages/happy-cli/src/claude/utils/permissionMode.ts:'auto'toVALID_PERMISSION_MODES.mapToClaudeMode:autois identity passthrough (SDK native).packages/happy-cli/src/claude/runClaude.ts:80: ensuredangerouslySkipPermissionsis NOT set forauto(should only coverbypassPermissions/yolo/ sandbox).packages/happy-cli/src/claude/utils/permissionHandler.ts: no new branch needed athandleToolCall—autoshould fall through to the SDK's own gating (i.e.canCallToolruns normally; what matters is the mode value passed to the SDK).packages/happy-cli/src/codex/executionPolicy.ts: add defensive mapping for Codex fallback (e.g.auto → approvalPolicy: 'on-request', sandbox: 'workspace-write'), or leave on defaults.packages/happy-app/sources/components/modelModeOptions.ts:48: add{ key: 'auto', name: translate('agentInput.permissionMode.auto'), ... }togetClaudePermissionModes.packages/happy-app/sources/text/_default.ts+ alltranslations/*.ts: addagentInput.permissionMode.autostrings.Release coordination
happy-wireships as a separate npm package that happy-server also depends on. Adding values to thepermissionModeenum is a coordinated release: clients sending'auto'to a server with the old enum will be rejected at validation. Sequence: publish wire, upgrade server, then ship CLI + app simultaneously (or gate the UI option behind a feature flag until rollout is complete).Acceptance criteria
autoin the Claude permission-mode selector on mobile/web.meta.permissionMode: 'auto'.permissionMode: 'auto'and session behaves as native Claude Codeautomode.--permission-mode autoviaclaudeArgsis also honored.Out of scope
dontAskend-to-end — can ride with this PR or split; I'd suggest same PR for consistency since the plumbing is identical.autosupport — neither agent has it natively; only defensive mapping is required.Related
@anthropic-ai/claude-agent-sdk@0.2.96→sdk.d.ts:1489