Skip to content

fix: respect Claude's defaultMode from settings.json as permission mode default#528

Closed
ye4241 wants to merge 1 commit intotiann:mainfrom
ye4241:fix/respect-claude-default-permission-mode
Closed

fix: respect Claude's defaultMode from settings.json as permission mode default#528
ye4241 wants to merge 1 commit intotiann:mainfrom
ye4241:fix/respect-claude-default-permission-mode

Conversation

@ye4241
Copy link
Copy Markdown

@ye4241 ye4241 commented Apr 26, 2026

Problem

When hapi spawns a Claude session (especially via runner), the permissionMode is hardcoded to 'default':

// runClaude.ts
let currentPermissionMode: PermissionMode = options.permissionMode ?? 'default';

This ignores the user's permissions.defaultMode configured in ~/.claude/settings.json. For example, users who set "defaultMode": "auto" in their Claude settings will find that hapi overrides it with default, causing unexpected permission prompts on every tool call.

Fix

Use the existing readClaudeSettings() utility (already imported in the codebase for includeCoAuthoredBy) to read permissions.defaultMode from Claude's settings and use it as the fallback:

const claudeSettings = readClaudeSettings();
const claudeDefaultMode = claudeSettings?.permissions?.defaultMode as PermissionMode | undefined;
let currentPermissionMode: PermissionMode = options.permissionMode ?? claudeDefaultMode ?? 'default';

Priority: explicit hapi permissionMode > Claude's defaultMode > 'default'

Test

  1. Set "permissions": { "defaultMode": "auto" } in ~/.claude/settings.json
  2. Start a session via hapi runner
  3. Verify the session runs with permissionMode=auto instead of permissionMode=default

…de default

When hapi spawns a session without an explicit permissionMode, it was
hardcoded to 'default', ignoring the user's `permissions.defaultMode`
setting in ~/.claude/settings.json (e.g. 'auto').

Now reads Claude's settings.json via the existing readClaudeSettings()
utility and uses its defaultMode as the fallback, keeping 'default' as
the final fallback for users without the setting configured.
Copilot AI review requested due to automatic review settings April 26, 2026 12:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adjusts Claude session startup so hapi can respect the user’s configured default permission mode from ~/.claude/settings.json instead of always falling back to 'default', reducing unexpected permission prompts.

Changes:

  • Import and call readClaudeSettings() during runClaude() startup.
  • Derive a claudeDefaultMode from claudeSettings?.permissions?.defaultMode.
  • Use Claude’s default mode as the fallback when options.permissionMode is not provided.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

let currentPermissionMode: PermissionMode = options.permissionMode ?? 'default';
const claudeSettings = readClaudeSettings();
const claudeDefaultMode = claudeSettings?.permissions?.defaultMode as PermissionMode | undefined;
let currentPermissionMode: PermissionMode = options.permissionMode ?? claudeDefaultMode ?? 'default';
// Forward messages to the queue
let currentPermissionMode: PermissionMode = options.permissionMode ?? 'default';
const claudeSettings = readClaudeSettings();
const claudeDefaultMode = claudeSettings?.permissions?.defaultMode as PermissionMode | undefined;
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Findings

  • [Major] Validate permissions.defaultMode before using it as a HAPI permission mode — settings.json is arbitrary JSON, but the new cast accepts any value. HAPI's Claude mode set is default | acceptEdits | bypassPermissions | plan, so values such as the PR's auto example can be forwarded as runtime permission modes and then passed to Claude as --permission-mode <value>, which can break remote startup or leave HAPI's permission handler in an unsupported mode. Evidence: cli/src/claude/runClaude.ts:156.
    Suggested fix:
    const configuredDefaultMode = claudeSettings?.permissions?.defaultMode;
    const parsedDefaultMode = PermissionModeSchema.safeParse(configuredDefaultMode);
    const claudeDefaultMode: PermissionMode | undefined =
        parsedDefaultMode.success && isPermissionModeAllowedForFlavor(parsedDefaultMode.data, 'claude')
            ? parsedDefaultMode.data as PermissionMode
            : undefined;
    If Claude settings can use aliases such as auto, normalize those aliases before this validation.

Summary

  • Review mode: initial
  • One major issue found: unsupported Claude settings values can now escape the type system and become active HAPI permission modes.

Testing

  • Not run (automation)

HAPI Bot

// Forward messages to the queue
let currentPermissionMode: PermissionMode = options.permissionMode ?? 'default';
const claudeSettings = readClaudeSettings();
const claudeDefaultMode = claudeSettings?.permissions?.defaultMode as PermissionMode | undefined;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MAJOR] Validate permissions.defaultMode before using it as a HAPI permission mode.

This cast turns arbitrary settings.json content into PermissionMode. HAPI's Claude modes are default | acceptEdits | bypassPermissions | plan, so values such as the PR's auto example can flow into the message queue and then to Claude as --permission-mode <value>. That can break remote startup or leave HAPI's permission handler in an unsupported mode.

Suggested fix:

const configuredDefaultMode = claudeSettings?.permissions?.defaultMode;
const parsedDefaultMode = PermissionModeSchema.safeParse(configuredDefaultMode);
const claudeDefaultMode: PermissionMode | undefined =
    parsedDefaultMode.success && isPermissionModeAllowedForFlavor(parsedDefaultMode.data, 'claude')
        ? parsedDefaultMode.data as PermissionMode
        : undefined;

If Claude settings can use aliases such as auto, normalize those aliases before this validation.

@ye4241
Copy link
Copy Markdown
Author

ye4241 commented Apr 26, 2026

Closing in favor of #529 which includes this backend fix along with the full permission mode selector UI feature.

@ye4241 ye4241 closed this Apr 26, 2026
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.

2 participants