The four modes, and what they actually do
permission_mode on ClaudeAgentOptions takes one of four values. 'default' prompts the user before any tool that has side effects. 'acceptEdits' auto-approves Write/Edit but still prompts for Bash. 'bypassPermissions' approves everything (use for trusted CI only). 'plan' puts the agent in dry-run mode — it plans actions without executing.
Pick by who is on the other end
If a developer is at the keyboard reviewing each prompt, 'acceptEdits' often hits the right tradeoff (file edits flow, shell still asks). If the agent runs unattended in a server context, 'default' with a custom permission handler is the policy posture. 'bypassPermissions' is for trusted CI runners that already pass through review elsewhere.
Write your own permission handler
Beyond the modes, you can supply a callback that decides per-tool. The callback gets the tool name, input, and a signal to allow / deny / ask. cwkPippa's setup uses a custom handler for the chat-from-WebUI path so Dad can approve dangerous commands inline rather than via the CLI's TUI.