Description
PR #17 fixed Dippy to show clean descriptions when asking for permission — git -C /some/path commit is displayed to the user as "git commit", not "git -C". This is correct, but it creates a confusing inconsistency:
- Dippy asks permission for "git commit" (global flags stripped in the description)
- User adds
allow git commit to their .dippy config based on what they saw
- Next time the same command runs, Dippy still asks for permission — because the config matcher checks against the raw tokens
git -C /some/path commit, which doesn't match the pattern git commit
In other words, the description and the config matching use different representations of the same command. The user sees "git commit" but can't write a rule that matches it when global flags are present.
This commonly happens when Claude Code works with worktrees, where git commands are invoked as git -C /path/to/worktree ....
Steps to reproduce
- Add
allow git commit to your project .dippy file
- Trigger a
git -C /some/worktree commit -m "message" command (e.g. Claude Code working in a worktree)
- Dippy shows the permission prompt as "git commit"
- Despite the config rule matching exactly what's displayed, Dippy still asks
Reproduction script
# uv run python repro.py
from dippy.core.config import Config, Rule, match_command, SimpleCommand
from pathlib import Path
cfg = Config(rules=[Rule("allow", "git commit")])
cwd = Path("/tmp")
r1 = match_command(SimpleCommand(words="git commit -m test".split()), cfg, cwd)
r2 = match_command(SimpleCommand(words="git -C /some/path commit -m test".split()), cfg, cwd)
print(f"git commit -m test -> {'MATCH' if r1 else 'NO MATCH'}")
print(f"git -C /path commit -m test -> {'MATCH' if r2 else 'NO MATCH'}")
Output:
git commit -m test -> MATCH
git -C /path commit -m test -> NO MATCH
Expected behavior
allow git commit should match git -C /some/path commit -m "test". The config matcher should recognize the same command that the description shows the user.
Root cause
_match_words() in config.py joins raw tokens into "git -C /some/path commit -m test" and tries to match against the pattern "git commit *" via fnmatch. This fails because -C /some/path sits between git and commit.
PR #17 added _find_action() to the git handler to skip global flags for description and classification purposes, but this normalization is not applied during config rule matching.
Affected handlers
Multiple CLI handlers define GLOBAL_FLAGS_WITH_ARG / GLOBAL_FLAGS_NO_ARG constants that would be affected: git, docker, auth0, ip.
Environment
- Dippy v0.2.7
- Observed when Claude Code uses worktrees (
git -C) or --work-tree
Description
PR #17 fixed Dippy to show clean descriptions when asking for permission —
git -C /some/path commitis displayed to the user as "git commit", not "git -C". This is correct, but it creates a confusing inconsistency:allow git committo their.dippyconfig based on what they sawgit -C /some/path commit, which doesn't match the patterngit commitIn other words, the description and the config matching use different representations of the same command. The user sees "git commit" but can't write a rule that matches it when global flags are present.
This commonly happens when Claude Code works with worktrees, where git commands are invoked as
git -C /path/to/worktree ....Steps to reproduce
allow git committo your project.dippyfilegit -C /some/worktree commit -m "message"command (e.g. Claude Code working in a worktree)Reproduction script
Output:
Expected behavior
allow git commitshould matchgit -C /some/path commit -m "test". The config matcher should recognize the same command that the description shows the user.Root cause
_match_words()inconfig.pyjoins raw tokens into"git -C /some/path commit -m test"and tries to match against the pattern"git commit *"viafnmatch. This fails because-C /some/pathsits betweengitandcommit.PR #17 added
_find_action()to the git handler to skip global flags for description and classification purposes, but this normalization is not applied during config rule matching.Affected handlers
Multiple CLI handlers define
GLOBAL_FLAGS_WITH_ARG/GLOBAL_FLAGS_NO_ARGconstants that would be affected:git,docker,auth0,ip.Environment
git -C) or--work-tree