487487# that should never trigger the overlay. Pass them through unconditionally.
488488if [ " $MATCHED " != " ask" ]; then
489489 case " $TOOL_NAME " in
490- ToolSearch|TaskCreate|TaskUpdate|TaskGet|TaskList|TaskOutput|TaskStop|\
490+ ToolSearch|Skill| TaskCreate|TaskUpdate|TaskGet|TaskList|TaskOutput|TaskStop|\
491491 AskUserQuestion|SendMessage|EnterPlanMode|ExitPlanMode|ScheduleWakeup|\
492492 CronCreate|CronDelete|CronList|Monitor|LSP|RemoteTrigger|\
493493 EnterWorktree|ExitWorktree|TeamCreate|TeamDelete)
@@ -497,12 +497,38 @@ if [ "$MATCHED" != "ask" ]; then
497497 esac
498498fi
499499
500- # --- 8. Overlay path -------------------------------------------------------
501- # Passthru handles ALL non-internal tool calls. There is no mode-based
502- # auto-allow shortcut. Every unmatched call goes to the overlay so the user
503- # always sees a prompt. CC's native dialog only fires as a fallback when the
504- # user explicitly cancels the overlay (Esc) or the overlay is unavailable.
505- #
500+ # --- 8. Mode-based auto-allow -----------------------------------------------
501+ # Replicate CC's per-mode auto-allow logic within passthru. Calls that CC
502+ # would silently approve (e.g. Read inside cwd in default mode, Write inside
503+ # cwd in acceptEdits mode) get an explicit allow from passthru so the overlay
504+ # does not fire for routine operations. Passthru emits allow (not continue),
505+ # keeping the decision on our side rather than falling through to CC.
506+ if [ " $MATCHED " != " ask" ]; then
507+ if permission_mode_auto_allows " $PERMISSION_MODE " " $TOOL_NAME " " $TOOL_INPUT " " $CC_CWD " 2> /dev/null; then
508+ MSG=" passthru mode-allow: ${PERMISSION_MODE:- default} "
509+ emit_decision " allow" " $MSG "
510+ audit_write_line " allow" " $TOOL_NAME " " mode:${PERMISSION_MODE:- default} " " " " " " $TOOL_USE_ID " " passthru-mode"
511+ exit 0
512+ fi
513+ fi
514+
515+ # --- 9. Write tools -> native dialog (for diff rendering) ------------------
516+ # Write/Edit/NotebookEdit that weren't mode-auto-allowed (step 8) should
517+ # fall through to CC's native dialog which renders diffs. The overlay can't
518+ # show diffs, so forcing Esc for every edit is bad UX. An explicit ask-rule
519+ # match still routes to the overlay (user opted in).
520+ if [ " $MATCHED " != " ask" ]; then
521+ case " $TOOL_NAME " in
522+ Write|Edit|NotebookEdit|MultiEdit)
523+ emit_decision " ask" " passthru: write tool, deferring to native dialog for diff"
524+ audit_write_line " ask" " $TOOL_NAME " " write-tool native fallback" " " " " " $TOOL_USE_ID "
525+ audit_write_breadcrumb " $TOOL_USE_ID " " $TOOL_NAME " " $TOOL_INPUT "
526+ exit 0
527+ ;;
528+ esac
529+ fi
530+
531+ # --- 10. Overlay path ------------------------------------------------------
506532# Reached when either:
507533# * an ask[] rule matched, or
508534# * no rule matched AND mode did NOT auto-allow.
582608export PASSTHRU_OVERLAY_RESULT_FILE=" $OVERLAY_RESULT "
583609export PASSTHRU_OVERLAY_TOOL_NAME=" $TOOL_NAME "
584610export PASSTHRU_OVERLAY_TOOL_INPUT_JSON=" $TOOL_INPUT "
611+ export PASSTHRU_OVERLAY_CWD=" $CC_CWD "
585612
586613# Invoke the overlay and capture its exit code. We have an ERR trap in place
587614# (converts unexpected errors to fail-open passthrough), so we cannot rely on
0 commit comments