-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Bug Description
When sandboxConfig.enabled: true is set in ~/.happy/settings.json along with a profile that has defaultPermissionMode: "bypassPermissions", the web app (app.happy.engineering) still sends permissionMode: "default" with every new session's first messages. This causes permission prompts to appear on the phone/web despite the user configuring bypass mode.
The Android app exhibits the same behavior — both platforms intermittently send "default" for new sessions.
Root Cause
The CLI's runClaude() function creates session metadata without including sandbox configuration:
// packages/happy-agent/src/index.ts (or dist/index-B3gQr6vs.mjs ~line 5000)
let metadata = {
path: workingDirectory,
host: os.hostname(),
version: packageJson.version,
os: os.platform(),
machineId,
homeDir: os.homedir(),
happyHomeDir: configuration.happyHomeDir,
happyLibDir: projectPath(),
happyToolsDir: resolve(projectPath(), "tools", "unpacked"),
startedFromDaemon: options.startedBy === "daemon",
hostPid: process.pid,
startedBy: options.startedBy || "terminal",
lifecycleState: "running",
lifecycleStateSince: Date.now(),
flavor: "claude"
};
// No sandbox field ^^^Meanwhile, the web app's permission resolution in packages/happy-app/sources/sync/messageMeta.ts checks:
function isSandboxEnabled(metadata): boolean {
const sandbox = metadata?.sandbox;
return !!sandbox && typeof sandbox === 'object' && sandbox.enabled === true;
}Since session.metadata.sandbox is never set by the CLI, isSandboxEnabled() always returns false, and the web app falls through to 'default' for every new session.
Evidence from Logs
Analyzed all ~/.happy/logs/ files across multiple sessions (v0.13.0). Pattern:
- 439 messages with
sentFrom+permissionModemetadata - Both
androidandwebintermittently send"default"(88 and 78 times respectively) - Every new session starts with
"default"until the user manually changes it - The
[loop] Permission mode updated from user message to: defaultlog confirms the CLI receives"default"from the app - Permission prompts (
sendToAllDevices "Permission Request") only occur whenpermissionMode: "default"was sent - Once the user manually switches a session to bypass mode on the app, subsequent messages correctly send
"bypassPermissions"— but this resets on every new session
Suggested Fix
Include sandbox config in session metadata when creating sessions:
const settings = await readSettings();
// ...
let metadata = {
// ... existing fields ...
sandbox: {
enabled: settings?.sandboxConfig?.enabled ?? false
}
};This would allow the web app's isSandboxEnabled() check to work as documented in docs/permission-resolution.md.
Alternatively
The defaultPermissionMode from the active profile could also be propagated — either in session metadata or via a separate mechanism — so the web/mobile apps can resolve the correct mode without relying solely on sandbox status.
Environment
- Happy CLI: v0.13.0
- Claude Code: v2.1.42
- Platform: Windows 11 Pro (win32/x64)
- Node: v24.6.0