Skip to content

confirm-deploy PreToolUse hook hard-blocks non-deploy Bash commands (incl. /lua-doctor's own 'lua agents' probe) #2

Description

@Nelnamara

Summary

The confirm-deploy PreToolUse Bash hook intermittently hard-blocks legitimate Bash commands that do not invoke lua deploy — including the plugin's own /lua-doctor Step 4 probe (lua agents --json --ci). Because confirm-deploy.decide() blocks anything that isn't a prefixed lua deploy, any command whose if scoping is mis-matched is rejected with DEPLOY_DENIED_BARE.

Environment

  • Claude Code on Windows 11 (Git Bash shell)
  • Plugin lua-agent-builder 1.0.0 (claude-code-lua-plugin marketplace)
  • lua-cli 3.18.0, Node v24.16.0, npm 11.13.0

Relevant hooks/hooks.json

{ "matcher": "Bash",
  "hooks": [{ "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/confirm-deploy.mjs",
              "if": "Bash(*lua deploy*)" }] }

Observed

Command Result
node --version ✓ passes
lua --version ✓ passes
lua agents --json --ci blocked (DEPLOY_DENIED_BARE)
multi-line ls … && ls … && … (no lua token at all) blocked

The blocked commands contain no lua deploy substring. Simple single-token commands pass; commands with an env prefix (PATH=… lua agents), pipes, && chains, or spaces in paths appear to trip the if scoping into firing.

Why allow rules don't save it

The user's settings.json explicitly allows Bash(lua agents *), but PreToolUse hooks run regardless of permissions.allow, so the misfiring hook overrides the allow rule. The result is a hard block with no way to proceed except routing the command through a different shell (PowerShell).

Impact

  • Legitimate lua subcommands and general Bash are intermittently hard-blocked.
  • /lua-doctor cannot complete Step 4 — its own lua agents auth probe is blocked by the plugin's own hook.

Suggested fix

  • Tighten the if matcher to anchor on an actual lua deploy invocation (token / word-boundary match) rather than the substring glob Bash(*lua deploy*), or
  • Make confirm-deploy.decide() return null (allow) unless the command actually invokes the deploy subcommand, instead of blocking every non-prefixed-deploy command it sees.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions