Skip to content

Daemon-spawned sessions ignore ~/.claude/settings.json permissions and hooks #1396

Description

@mislaughter1989-del

Problem

When the Happy daemon spawns a new Claude session (via mobile app or happy daemon), it does not read ~/.claude/settings.json to determine the user's configured permission mode. This causes every Bash/tool call to prompt for approval, even when the user has set "defaultMode": "bypassPermissions" in their Claude settings.

Additionally, the --settings flag passed to the Agent SDK binary points to a minimal Happy-internal hook file (~/.happy/tmp/hooks/session-hook-*.json) that only contains a SessionStart forwarder. This means:

  1. User-defined hooks (PreToolUse, PostToolUse, Stop, SessionEnd, etc.) from ~/.claude/settings.json are not loaded
  2. Plugins configured in settings.json are not passed through
  3. Permission allowlists from settings.local.json are ignored
  4. Environment variables set in the env block of settings.json are not injected

Root Cause

In dist/index-q9G4ktSK.mjs (and CJS equivalent), the daemon spawn code builds args without reading Claude's permission settings:

// Line ~5371 (new session spawn)
const args = [
  agentCommand,
  "--happy-starting-mode", "remote",
  "--started-by", "daemon"
];
// No --permission-mode flag added

// Line ~5296 (tmux spawn)
const fullCommand = `node ... ${agent} --happy-starting-mode remote --started-by daemon`;
// No --permission-mode flag added

Meanwhile, readClaudeSettings() already exists and correctly reads ~/.claude/settings.json (used for includeCoAuthoredBy), but its output is never consulted for permission mode on daemon spawns. The options.permissionMode passthrough only happens for resume operations (line ~5514), not new spawns.

Expected Behavior

  • Daemon-spawned sessions should inherit permissions.defaultMode from ~/.claude/settings.json
  • Ideally, the full settings merge chain (settings.json + settings.local.json + project-level settings) should be respected, same as a direct claude CLI launch
  • At minimum: if defaultMode: "bypassPermissions" is set, daemon spawns should pass --permission-mode bypassPermissions

Workaround

Users can work around the permission issue by always launching with happy --yolo, but this doesn't help daemon-spawned sessions (the primary use case for the mobile app).

A local patch to readClaudeSettings() at the spawn sites works but is overwritten on npm update.

Environment

  • Happy CLI: 1.1.8
  • OS: Ubuntu 24.04 (Linux 6.17)
  • Claude Agent SDK: bundled in happy node_modules
  • Claude Code: 2.1.176

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions