关于 claude-permissions
通过 Dippy 和设置文件管理 Claude Code 权限的技能,说明命令与 MCP 工具规则、权限状态及自动模式包装脚本,供维护者检查、调整和排查访问行为。
主要功能
- 01管理 Bash 与 MCP 工具规则
- 02配置读取和网页访问权限
- 03说明 ACTIVE、ALLOW-ONLY、DISABLED 状态
- 04处理自动模式下的权限提示
- 05查看配置优先级与规则匹配
- 06排查权限行为
适用场景
- 01添加或更改命令及 MCP 权限
- 02审查不同权限状态的影响
- 03调查异常的批准或拒绝行为
MCP 相关
该技能介绍 Dippy 对 MCP 工具的允许、询问和阻止规则,包括 Claude Code 自动模式下的行为。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vtmocanu/ skills --skill claude-permissions安装后在 Claude Code 中输入/claude-permissions确认已加载。
附带文件config.exampledippy-with-auto-fallback.sh
详细介绍
Claude Code 权限管理
文档位置
本文档位于:~/stuff/gitrepos/gh/vtmocanu/skills/claude-permissions/SKILL.md(公开仓库:github.com/vtmocanu/skills)
注意:这是事实来源。通过
npx skills包管理器从此文件派生出安装副本~/.claude/skills/claude-permissions/SKILL.md;请在此处编辑,然后运行npx skills update重新拉取。切勿编辑安装副本。
Dippy 文档:配置语法和行为记录在 https://github.com/ldayton/Dippy/wiki。如果遇到不确定的语法,请先获取相应的 wiki 页面并核实,再进行更改。关键页面:配置、MCP 工具、文件编辑、事后处理、处理程序模型、安全模型。
入口
未收到具体指示时,询问用户想要做什么:
- 允许新的命令或 MCP 工具?(Dippy 配置)
- 允许新的 Read/WebFetch/Skill 条目?(settings.json)
- 检查当前权限?
- 排查权限错误?
- 清理过时的权限?
- 其他事项?
架构概览
权限分为两个系统管理:
| 权限类型 | 管理方 | 配置文件 |
|---|---|---|
| Bash 命令 | Dippy | ~/.dippy/config(全局),.dippy(项目) |
| MCP 工具 | Dippy | ~/.dippy/config(全局),.dippy(项目) |
| 文件重定向 | Dippy | ~/.dippy/config(全局),.dippy(项目) |
| Read、WebFetch、WebSearch、Skill | settings.json | ~/mackup/confs/claude/settings.json(全局),.claude/settings.local.json(项目) |
Dippy 通过 PreToolUse 钩子运行(在 settings.json 中配置),用于 Bash 和 mcp__.* 匹配器。PostToolUse 钩子则用于启用事后处理。
关键:Dippy 通过包装脚本调用,而非直接调用。 settings.json 中的钩子命令是
~/stuff/gitrepos/gh/vtmocanu/skills/claude-permissions/dippy-with-auto-fallback.sh,而不是单独的dippy。该包装脚本会改变ask判定在自动模式下的行为(自主运行以及派生 Agent/队友所使用的权限模式)。请参阅下方的自动模式回退包装脚本。这是此配置中最令人意外的一点:在自动模式下,普通的ask规则不会向用户发出询问。
自动模式回退包装器
包装器会从 hook 负载中读取 permission_mode 并进行分支处理(这是默认 ACTIVE 状态下的行为;有关优先于它的两种标记文件状态,请参阅三种状态):
-
非自动模式(
default、acceptEdits、plan等):负载会直接传递给dippy。这是正常行为,ask规则会向用户显示交互式提示。 -
auto模式:包装器会运行dippy、检查判定结果,并且只转发:allow/deny判定(始终执行白名单 + 阻止列表),以及permissionDecisionReason中包含字面标记[ASK]的ask判定。
其他任何
ask(没有[ASK]标记)都会被丢弃(包装器不输出任何内容并执行exit 0),从而将判定交给自动模式自己的分类器;该分类器通常会不经人工提示就运行常规命令。
结果:在自动模式下,只有消息中带有 [ASK] 标记的 ask 规则才会升级为向用户询问。dippy 会询问的其他所有事项都会被静默地自动处理。因此,[ASK] 前缀是一项真正影响行为的约定,而非装饰:任何即使在自主/Agent 运行期间也需要人工提示的操作,都应使用它。
| Dippy 判定 | 原因中是否有 [ASK]? | 非自动模式 | 自动模式 |
|---|---|---|---|
allow | 不适用 | 运行,不提示 | 运行,不提示 |
deny | 不适用 | 已阻止 | 已阻止 |
ask | 是 | 提示用户 | 提示用户 |
ask | 否 | 提示用户 | 丢弃,由自动分类器判定(通常会运行,不提示) |
当前配置中的示例:ask git push "[ASK] Confirm push target"(包含 [ASK])即使在自动模式下也会提示用户;而 ask git commit "Confirm commit" 和 ask git add "Confirm staging"(不含 [ASK])在自动模式下会由自动分类器静默处理,不会提示。编写新的 ask 规则时,应慎重决定是否需要 [ASK]:必须始终交由人工确认的写入/破坏性操作应带上它。
三种状态:ACTIVE / ALLOW-ONLY / DISABLED
dippy 本身没有启用/禁用标志(dippy --help,v0.2.7)。状态由包装器在每次调用时检查的两个标记文件决定:
| 状态 | 标记 | 包装器转发的内容 | 实际效果 |
|---|---|---|---|
| ACTIVE(默认) | 无 | allow、deny 和 ask(按照上表,自动模式下会过滤普通 ask) | 完整规则集,完整防护措施 |
| ALLOW-ONLY | ~/.dippy/ALLOW_ONLY | 仅 allow | 白名单会跳过主机的自动分类器;其他所有内容均由它判定 |
| DISABLED | ~/.dippy/OFF | 对所有事件均不转发任何内容 | 完全绕过 Dippy |
如果两个标记同时存在,以 OFF 为准。~/.dippy 是指向 mackup 仓库的符号链接,因此标记会放在 confs/.dippy/ 中;两者都会被 git 忽略,这是有意为之(机器本地状态,不会同步配置)。
切换状态无需重启:Claude Code 会在启动时缓存 settings.json 中的 hook 命令,但每次调用时都会重新读取 脚本,因此切换会立即应用于正在运行的会话。(相比之下,编辑 settings.json 中的 hook 条目则需要重启。)
在这台 Mac 上,建议使用 mackup/scripts/dippy-toggle.sh(通过 ~/scripts 添加到 PATH),而不是手动修改标记文件。它会报告状态,确保两个标记互斥,并在 settings.json 不再将 hook 路由到 dippy-with-auto-fallback.sh,或者它指向的包装器是没有 ALLOW_ONLY 分支的过期克隆时发出警告(这两种情况下,标记都不会生效):
dippy-toggle.sh # status (default)
dippy-toggle.sh on # ACTIVE - full dippy (clears both markers)
dippy-toggle.sh allow-only # ALLOW-ONLY - whitelist only
dippy-toggle.sh off # DISABLED - bypass dippy
dippy-toggle.sh toggle # flip on <-> off
dippy-toggle.sh cycle # rotate active -> allow-only -> off -> active
ALLOW-ONLY:仅白名单,一种降噪过滤器
包装器运行 dippy,仅在判定结果为 allow 时转发,否则不输出任何内容:
[ -f "${HOME}/.dippy/ALLOW_ONLY" ] && forward only `allow`
钩子 allow 会短路宿主的权限流程,因此白名单中的命令永远不会进入自动分类器——这正是该状态的目的。白名单之外的所有内容都会交由宿主原本的处理流程:在 auto 模式下交给分类器,在其他模式下则触发普通提示。
此状态下不会触发 deny 规则和 [ASK] 升级。 已于 2026-08-04 使用 dippy 0.2.7 验证:
| 命令 | ACTIVE 判定 | ALLOW-ONLY:Claude 看到的内容 |
|---|---|---|
cat /etc/hosts | allow | allow — 已跳过分类器 |
kubectl get pods | allow | allow — 已跳过分类器 |
helm install foo bar | deny("Use GitOps…") | 无内容 — 由分类器决定 |
brew install foo | ask [ASK] | 无内容 — 由分类器决定 |
some-unknown-tool --wat | ask | 无内容 — 由分类器决定 |
在 ALLOW-ONLY 状态下,PostToolUse 事后提示仍会触发(它们是指导文本,而不是权限判定;事件检查会在过滤器之前运行)。
DISABLED:关闭安全机制的开关,而非降噪过滤器
只要 ~/.dippy/OFF 存在,包装器就会对每个事件不输出任何内容并执行 exit 0,因此:
- 不会执行
deny阻止列表——rm -rf、git push --force、deny-redirect秘密路径防护和deny-mcp规则都会停止触发。 allow规则也会停止触发,因此在非自动模式下,常规命令会开始触发提示(提示会更多,而不是更少)。在auto模式下,所有内容都会交由自动模式自己的分类器处理,而该分类器通常会在不提示的情况下运行命令。- 事后提示也会停止,因为终止开关会在事件检查之前触发。
适用时,优先选择范围更窄的替代方案:
| 目标 | 比终止开关更好的工具 |
|---|---|
| 保留快速通道允许规则,但停止所有 dippy 提示 | dippy-toggle.sh allow-only(注意:也会停用 deny) |
| 停止某个仓库中的提示 | 在该仓库的 .dippy 中设置 set default allow(全局 deny 规则仍会触发) |
| 停止某个命令的提示 | 在项目 .dippy 中添加 allow <cmd> 规则 |
| 本次运行使用另一套完整规则 | DIPPY_CONFIG=/path/to/other-config claude |
验证当前状态:
# which state? (or just: dippy-toggle.sh status)
ls -la ~/.dippy/OFF ~/.dippy/ALLOW_ONLY 2>/dev/null
# end-to-end check — a denied command (empty = bypassed or allow-only; JSON deny = active)
printf '%s' '{"permission_mode":"default","tool_name":"Bash","tool_input":{"command":"helm install foo bar"}}' \
| ~/stuff/gitrepos/gh/vtmocanu/skills/claude-permissions/dippy-with-auto-fallback.sh
# end-to-end check — a whitelisted command (JSON allow = active or allow-only; empty = bypassed)
printf '%s' '{"permission_mode":"default","tool_name":"Bash","tool_input":{"command":"cat /etc/hosts"}}' \
| ~/stuff/gitrepos/gh/vtmocanu/skills/claude-permissions/dippy-with-auto-fallback.sh
注意:原生 settings.json 功能(仅供参考,不建议使用):settings.json 自 v2.1.0(2026 年 1 月)起支持任意位置的通配符,提供 allow/ask/deny 指令、通过
settings.local.json进行项目级覆盖,以及 MCP 工具权限。Dippy 的独特优势:ask/deny 规则中的指导消息、后匹配优先顺序(而非固定的 deny>ask>allow 优先级)、带注释的纯文本配置,以及文件重定向控制(deny-redirect)。
关键位置
| 文件 | 范围 | 路径 | 管理内容 |
|---|---|---|---|
| 全局 Dippy 配置 | 所有项目 | ~/mackup/confs/.dippy/config(符号链接至 ~/.dippy/config) | Bash、MCP、重定向 |
| 项目 Dippy 配置 | 单个项目 | 项目根目录中的 .dippy | Bash、MCP 覆盖 |
| 全局 settings.json | 所有项目 | ~/mackup/confs/claude/settings.json | Read、WebFetch、Skill、钩子 |
| 项目 settings.local.json | 单个项目 | .claude/settings.local.json | Read、WebFetch 覆盖 |
Dippy 配置优先级(从高到低):
$DIPPY_CONFIG环境变量(如果已设置)- 项目根目录中的
.dippy(像.git一样向上搜索) - 全局配置
~/.dippy/config
在配置文件内部:最后匹配的规则优先。先写宽泛的允许规则,再写具体的拒绝规则。
项目 .dippy 会与全局 ~/.dippy/config 合并。两个文件中的规则会一起评估,最后匹配的规则优先。项目规则可以针对相同的命令模式覆盖全局规则。
Dippy 配置格式
此技能附带一份可直接调整的入门配置 config.example — 通用安全默认值(允许只读操作,对写入/破坏性操作使用 ask/deny,使用 deny-redirect 防护秘密写入,禁止使用解释器,并采用自动模式下的 [ASK] 约定)。将其复制到 ~/.dippy/config(或项目的 .dippy),并根据你的工具链进行调整。
指令参考
| 指令 | 语法 | 行为 |
|---|---|---|
allow | allow <pattern> | 自动批准匹配的命令 |
ask | ask <pattern> "message" | 提示用户批准 |
deny | deny <pattern> "message" | 阻止并说明原因 |
allow-redirect | allow-redirect <path-pattern> | 允许向路径写入文件 |
deny-redirect | deny-redirect <path-pattern> "message" | 阻止向路径写入文件 |
allow-mcp | allow-mcp <tool-pattern> | 自动批准 MCP 工具 |
ask-mcp | ask-mcp <tool-pattern> "message" | 提示用户批准 MCP 工具 |
deny-mcp | deny-mcp <tool-pattern> "message" | 阻止 MCP 工具 |
after | after <pattern> "message" | 执行后的反馈(需要 PostToolUse hook) |
after-mcp | after-mcp <pattern> "message" | 执行后的 MCP 反馈 |
alias | alias <source> <target> | 将包装脚本映射到规范名称 |
set default | set default allow / set default ask | 未知命令的默认处理方式 |
set log | set log <path> | 启用审计日志 |
set log-full | set log-full | 在日志中包含完整命令文本 |
模式匹配
- 前缀匹配(默认):
allow git status匹配git status、git status -s等。 - 精确匹配:添加
|锚点:allow git status|只匹配字面命令 - 通配符:
*(任意内容,包括空格)、?(一个字符)、[abc](字符类) - 路径模式(重定向):
**递归匹配,*匹配单个目录层级
注意:包含 glob 字符(
*、?、[)的模式不会进行隐式前缀匹配。 只有在模式不含任何 glob 字符时,Dippy 才会添加尾随的*进行前缀匹配。如果模式包含任何 glob 字符,就必须通过fnmatch匹配整个命令字符串。例如,ask tea issue* close匹配tea issues close,但不匹配tea issues close 42。v0.2.7 修复:尾随的
*现在也能匹配空字符串(不带参数的命令)。因此,ask tea issue* close *同时匹配tea issues close和tea issues close 42。对于需要在带或不带额外参数时都匹配的 glob 模式,务必添加尾随的*。对
curl模式的推论: 匹配标志后务必使用尾随的*:ask curl * -X POST *可匹配curl url -X POST和curl url -X POST -d '{}'。不加尾随的*时,只有 POST 是最后一个词元时才会匹配。注意:模式词元与命令词元一一对应,因此路径规则需要为标志留出
-*位置。 这是规则看起来正确却始终不生效的最大原因。ask rm /*.git/*匹配rm /repo/.git/config,但不匹配rm -rf /repo/.git/config——-rf占用了模式中未预留的位置。请分别编写两种形式,或在模式开头添加-*:ask rm /*.git/* "deletes git internals" # rm <path> ask rm -* /*.git/* "deletes git internals" # rm -rf <path>推论——路径模式词元必须是绝对路径。 不含
/的词元(*.git、*objects)是普通 glob,会匹配命令的剩余部分。含/的词元会针对单个参数进行匹配,而相对路径永远无法匹配绝对路径参数。在这类词元中,*可以跨越斜杠,因此能在任意深度匹配。于 2026-08-02 使用隔离的DIPPY_CONFIG,针对目标rm -rf /Users/me/repo/.git/objects,在 v0.2.7 上验证:
模式 匹配? 原因 ask rm -* /*.git/*是 绝对路径词元, *可跨越/ask rm -* /*/.git/*是 同上 ask rm *.git是 不含斜杠 → 普通 glob,可匹配整个命令;仅在 .git结尾时匹配ask rm *.git/*否 含斜杠 → 路径词元,但路径是相对路径 ask rm */.git/*否 同上 ask rm /*.git/*否 是绝对路径,但未为 -rf留出-*位置ask rm **/.git/*否 **仅用于重定向模式语法重定向使用不同的匹配器,不受影响:
deny-redirect **/.env*按文档所述正常工作。每条规则都要单独测试: 执行
printf 'set default allow\nask rm <pattern> "HIT"\n' > /tmp/p.dippy,然后通过DIPPY_CONFIG=/tmp/p.dippy dippy --claude将钩子负载传入管道。set default deny是无效语法(仅支持allow/ask),并会静默生成空规则集,看起来就像“DIPPY_CONFIG被忽略了”;配置路径不存在时,也会在不发出警告的情况下回退到全局文件。安全:绝不要
allow解释器命令。allow bash、allow python3、allow node这类规则会进行前缀匹配,从而自动批准bash -c '...'、python3 -c '...'、node -e '...',绕过所有内部命令规则。Dippy 不会追踪-c/-e参数中的命令(仅执行一层)。请移除这些规则,让命令落入set default ask的处理范围。
MCP 工具命名
MCP 工具遵循以下格式:mcp__<server>__<action>。例如:
allow-mcp mcp__grafana__*- 所有 Grafana 工具deny-mcp mcp__*__delete_*- 所有服务中的所有删除操作allow-mcp mcp__context7__query-docs- 特定工具
注释
支持整行注释(# comment)和行内注释(allow git # comment)。
settings.json 格式(仅限 Read/WebFetch/Skill)
权限存放在 permissions.allow(字符串数组)中:
{
"permissions": {
"allow": [
"Read(*)", // allow reading any file
"Read(~/**)", // path-specific
"WebSearch", // no pattern needed
"WebFetch",
"WebFetch(domain:github.com)", // domain-scoped
"Skill(docx)" // specific skill
]
}
}
| 工具 | 模式语法 | 示例 |
|---|---|---|
Read | Read(glob) - 文件路径 glob | Read(~/**) |
WebFetch | WebFetch(domain:host) 或仅使用 WebFetch | WebFetch(domain:example.com) |
WebSearch | WebSearch | WebSearch |
Skill | Skill(name) | Skill(docx) |
重要:不要向 settings.json 添加
Bash(...)或mcp__*条目。这些条目仅由 Dippy 管理。
工作流:允许执行 Bash 命令
关键规则:绝不运行该命令,只更新权限。
- 分析用户想要允许执行的命令
- 确定范围:全局(
~/.dippy/config)还是项目(.dippy)?- 不明确时,默认选择全局
- 检查重复项后再添加:
- 读取目标 Dippy 配置
- 检查该命令是否已被更宽泛的规则覆盖(例如,
allow git已覆盖git status) - 检查是否已存在可能冲突的更具体规则
- 如果发现重复项,告知用户并跳过
- 拆分链式命令:管道中的每个命令都需要各自的规则
- 应用安全默认值(参见下方“安全”部分)
- 在配置的正确部分添加规则(按类别整理)
- 向用户准确展示添加的内容及其位置
- 询问用户是否要测试新允许执行的命令
重复项检查逻辑
添加任何规则之前:
- 是否已被全局规则覆盖? 如果全局配置中有
allow git,则不要在任何位置添加allow git status - 项目中是否已有? 不要添加项目
.dippy中已存在的规则 - 是否有更宽泛的项目规则? 如果项目中有
allow kubectl,则不要添加allow kubectl get - 项目规则是否会覆盖全局 deny? 如果全局配置中有
deny git push --force,在项目.dippy中添加allow git push --force会覆盖该规则。请警告用户。
工作流:允许使用 MCP 工具
- 识别工具名称:
mcp__<server>__<action> - 确定范围:全局还是项目
- 检查重复项(逻辑与 Bash 命令相同,使用
allow-mcp/deny-mcp) - 添加
allow-mcp规则 - 验证 settings.json 中是否存在
mcp__.*PreToolUse hook 匹配器(Dippy 拦截 MCP 调用所必需)
工作流:允许使用 Read/WebFetch/Skill
这些仍使用 settings.json,因为 Dippy 不处理它们:
- 确定范围:全局(
~/mackup/confs/claude/settings.json)还是项目(.claude/settings.local.json) - 读取目标 settings 文件
- 将权限条目添加到
permissions.allow - 验证 JSON:
jq . <settings-file> > /dev/null && echo "JSON valid" - 向用户展示添加的内容
安全:默认只读
默认情况下,仅允许读取操作。对于会产生写入效果的命令,请先征求用户确认。
自动允许(只读,可安全地 allow)
| 类别 | 命令 |
|---|---|
| Kubernetes | kubectl get/describe/logs/explain/events/top/diff/cluster-info/api-resources |
| Git | git status/log/diff/fetch/remote/branch(列出信息) |
| Helm | helm template/show/list/get/search/history/pull |
| Flux | flux get/check/diff/logs/build |
| Docker | docker ps/images/logs/inspect/info |
| 基础设施 | tofu plan/show/state(通过 infisical 包装器) |
| CLI 工具 | ls、cat、jq、grep、rg、fd、tree、eza、curl -s -X GET |
绝不自动允许解释器:
bash、python3、node、sh、ruby、perl。对这些命令使用前缀匹配会自动批准-c/-e标志,从而绕过所有内部命令规则。应让这些命令继续执行到set default ask。
需要确认(写入/破坏性操作,使用 deny 或 ask)
kubectl apply/delete/edit/patch/rollout restart/scale/draingit push/commit/rebase/reset --hard/clean -fhelm install/upgrade/uninstall/rollback(对于 GitOps 工作流,建议使用deny并提供指引:deny helm install "Use GitOps: create/edit the HelmRelease in your GitOps repo instead")flux suspend/resume/deletedocker rm/rmi/system prunetofu apply/destroyrm -rf、rm -r、sudo、chown- 使用 POST/PUT/PATCH/DELETE 方法、
-d/--data、-F/--form、-T/--upload-file的curl - 重要:使用通配符
*,无论写入标志位于何处都能匹配;末尾添加*以匹配其他参数:ask curl * -X POST *(而不是ask curl -X POST)。URL 通常位于方法标志之前,之后也可能还有其他标志。
当命令会产生写入效果时,请提供以下选项:
“此命令可能会修改状态。建议:
- 添加为
ask规则(执行前提示,更安全)- 添加为
allow规则(自动批准,需经你确认)- 添加为带有指引消息的
deny规则(阻止执行并说明原因)”
工作流:审核权限
# Show global Dippy config
cat ~/.dippy/config
# Show project Dippy config (if exists)
cat .dippy 2>/dev/null || echo "No project .dippy"
# Show settings.json permissions (Read/WebFetch/Skill)
jq '.permissions.allow' ~/mackup/confs/claude/settings.json
# Show project settings.local.json
jq '.permissions.allow' .claude/settings.local.json 2>/dev/null || echo "No project settings"
# List all project .dippy files across repos
fd -H -t f '^\\.dippy$' ~/stuff/gitrepos/wxs/
工作流:清理过时权限
- 读取 Dippy 配置(全局和/或项目配置)
- 找出不再使用的工具/命令规则
- 删除任何条目前先询问用户
- 删除已确认的条目
- 修改 settings.json 后,验证 JSON
故障排除
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| Bash 命令意外提示确认 | Dippy 配置中缺少 allow 规则 | 在 ~/.dippy/config 或 .dippy 中添加规则 |
| 命令被拒绝并显示消息 | 命中了 deny 规则 | 检查规则顺序(最后匹配的规则优先生效) |
| MCP 工具意外提示确认 | 缺少 allow-mcp 规则 | 在 Dippy 配置中添加 allow-mcp 规则 |
| MCP 规则完全被忽略 | 缺少 mcp__.* hook 匹配器 | 在 settings.json 中添加 PreToolUse 匹配器 |
| 已添加权限但仍被拒绝 | 规则顺序问题:后面的 deny 会覆盖 allow | 将 allow 移到 deny 后面,或让 deny 更具体 |
| 在一个项目中有效,在另一个项目中无效 | 项目 .dippy 规则可能覆盖全局规则(最后匹配的规则优先生效) | 检查全局和项目配置中是否存在冲突规则 |
| Read/WebFetch 被拒绝 | settings.json 中缺少条目(不是 Dippy) | 在 settings.json 的 permissions.allow 中添加条目 |
| 编辑设置后出现 JSON 解析错误 | JSON 格式错误 | 运行 jq . 查找语法错误 |
| 事后提示未触发 | 缺少 PostToolUse hook | 在 settings.json 中添加 PostToolUse Bash 匹配器 |
所有规则都未触发:deny 被忽略,指导消息消失 | 紧急停用开关仍处于开启状态——~/.dippy/OFF 存在,包装器在运行 dippy 前就退出了 | 运行 dippy-toggle.sh on(或 rm ~/.dippy/OFF;参见三种状态);立即生效,无需重启 |
allow 规则会触发,但 deny 和 [ASK] 不会触发,且事后提示仍有效 | 紧急仅允许状态仍处于开启状态——~/.dippy/ALLOW_ONLY 存在,包装器只转发 allow | 运行 dippy-toggle.sh on 恢复完整防护;dippy-toggle.sh status 会报告状态 |
dippy-toggle.sh allow-only 报告处于 ALLOW-ONLY 状态,但 deny 规则仍会阻止命令 | settings.json 指向的包装器副本早于 ALLOW_ONLY 分支(该分支于 2026-08-04 添加) | 更新 dippy-with-auto-fallback.sh 的副本;dippy-toggle.sh status 会自动对此发出警告 |
| 仅在自动模式下事后提示未触发 | 包装器早于 hook_event_name 检查:其自动模式筛选器只转发带 allow/deny/[ASK] 标记的 ask,而 dippy 发出的事后提示是纯文本,没有 permissionDecision,因此被丢弃。此问题已于 2026-07-26 修复——现在包装器会将任何非 PreToolUse 事件直接传给 dippy,因此将 PostToolUse 指向包装器或直接指向 dippy 均可正常工作 | 更新 dippy-with-auto-fallback.sh 的副本 |
| 带有 glob 字符的规则无法匹配带额外参数的命令 | 包含 */?/[ 的模式会失去隐式的尾随 * 前缀匹配;必须匹配完整命令 | 在 glob 模式末尾显式添加 *(v0.2.7+ 也能匹配不带参数的命令) |
bash -c / python3 -c 绕过规则 | allow bash 会对所有 bash -c '...' 命令进行前缀匹配;Dippy 不会追踪 -c 参数 | 移除 allow bash/allow python3/allow node;让这些命令落入 set default ask 规则 |
Hook 配置参考
Dippy 要正常工作,~/mackup/confs/claude/settings.json 中必须存在以下 hooks。PreToolUse Bash + mcp__.* 匹配器会调用自动回退包装脚本(随此技能提供的 dippy-with-auto-fallback.sh),而非裸 dippy,以便按自动模式回退包装脚本中的说明处理自动模式下的 ask。PostToolUse hook(事后检查)则直接调用 dippy。
Hook 命令路径必须使用绝对路径。 Claude Code 不会在 hook 的
command字符串中展开~——下方显示的~/...路径仅为便于阅读;在实际的settings.json中,请使用完整路径(例如/home/you/stuff/gitrepos/gh/vtmocanu/skills/claude-permissions/dippy-with-auto-fallback.sh)。请将 hook 指向此仓库的本地克隆,而不是已安装的~/.claude/skills/claude-permissions/副本(每次运行npx skills update时,该目录都会被覆盖)。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "~/stuff/gitrepos/gh/vtmocanu/skills/claude-permissions/dippy-with-auto-fallback.sh" }
]
},
{
"matcher": "mcp__.*",
"hooks": [
{ "type": "command", "command": "~/stuff/gitrepos/gh/vtmocanu/skills/claude-permissions/dippy-with-auto-fallback.sh" }
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "dippy" }
]
}
]
}
}
此包装脚本随此技能提供,路径为 ./dippy-with-auto-fallback.sh。需要了解其确切逻辑时,请直接阅读该文件——它是上文自动模式回退包装脚本中所概述自动模式行为的权威来源。要使用它,请在本地克隆此仓库,并将两个 PreToolUse hook 命令都指向克隆中的副本(根据上文说明,使用绝对路径)。
注意:
mcp__.*匹配器使用正则表达式(而非 glob)。其他 PreToolUse hooks(zellaude、clawd、dot-agent-deck)会与包装脚本同时运行,但与权限无关。