Dropstone CLI

权限

控制哪些操作需要批准才能运行。

Dropstone 使用 permission 配置来决定某个操作是自动运行、提示你,还是被阻止。

旧的 tools 布尔配置已弃用;它已合并到 permission 中。旧的 tools 配置仍然支持,以保持向后兼容。


操作

每个权限规则解析为以下之一:

  • "allow":无需批准即可运行
  • "ask":提示请求批准
  • "deny":阻止该操作

配置

你可以全局设置权限(使用 *),并覆盖特定工具。

{
  "$schema": "https://dropstone.io/schema/config.json",
  "permission": {
    "*": "ask",
    "bash": "allow",
    "edit": "deny"
  }
}

你也可以一次性设置所有权限:

{
  "$schema": "https://dropstone.io/schema/config.json",
  "permission": "allow"
}

细粒度规则(对象语法)

对于大多数权限,你可以使用对象根据工具输入应用不同的操作。

{
  "$schema": "https://dropstone.io/schema/config.json",
  "permission": {
    "bash": {
      "*": "ask",
      "git *": "allow",
      "npm *": "allow",
      "rm *": "deny",
      "grep *": "allow"
    },
    "edit": {
      "*": "deny",
      "packages/web/src/content/docs/*.mdx": "allow"
    }
  }
}

规则通过模式匹配进行评估,最后匹配的规则生效。常见模式是将通配符 "*" 规则放在前面,更具体的规则放在后面。

通配符

权限模式使用简单的通配符匹配:

  • * 匹配零个或多个任意字符
  • ? 匹配恰好一个字符
  • 所有其他字符按字面匹配

主目录展开

你可以在模式开头使用 ~$HOME 来引用你的主目录。这对于 external_directory 规则特别有用。

  • ~/projects/* -> /Users/username/projects/*
  • $HOME/projects/* -> /Users/username/projects/*
  • ~ -> /Users/username

外部目录

使用 external_directory 允许工具调用触及 Dropstone 启动时工作目录之外的路径。这适用于任何接受路径作为输入的工具(例如 readeditglobgrep 以及许多 bash 命令)。

主目录展开(如 ~/...)只影响模式的书写方式。它不会使外部路径成为当前工作区的一部分,因此工作目录之外的路径仍然必须通过 external_directory 允许。

例如,这允许访问 ~/projects/personal/ 下的所有内容:

{
  "$schema": "https://dropstone.io/schema/config.json",
  "permission": {
    "external_directory": {
      "~/projects/personal/**": "allow"
    }
  }
}

此处允许的任何目录都继承与当前工作区相同的默认值。由于 read 默认为 allow,除非被覆盖,否则 external_directory 下的条目的读取也被允许。当工具在这些路径中应受到限制时,添加显式规则,例如阻止编辑同时保留读取:

{
  "$schema": "https://dropstone.io/schema/config.json",
  "permission": {
    "external_directory": {
      "~/projects/personal/**": "allow"
    },
    "edit": {
      "~/projects/personal/**": "deny"
    }
  }
}

保持列表集中在受信任的路径上,并根据需要为其他工具(例如 bash)添加额外的允许或拒绝规则。


可用权限

Dropstone 权限按工具名称键控,外加几个安全防护:

  • read:读取文件(匹配文件路径)
  • edit:所有文件修改(涵盖 editwritepatch
  • glob:文件通配(匹配 glob 模式)
  • grep:内容搜索(匹配正则表达式模式)
  • bash:运行 shell 命令(匹配解析后的命令,如 git status --porcelain
  • task:启动子代理(匹配子代理类型)
  • skill:加载技能(匹配技能名称)
  • lsp:运行 LSP 查询(目前不可细粒度)
  • question:在执行期间向用户提问
  • webfetch:获取 URL(匹配 URL)
  • websearch:网络搜索(匹配查询)
  • external_directory:当工具触及项目工作目录之外的路径时触发
  • doom_loop:当相同的工具调用以相同的输入重复 3 次时触发

默认值

如果你不指定任何内容,默认的 build 代理会在所有操作前询问。批准是默认行为,而不是例外:

{
  "permission": {
    "*": "ask",
    "read": {
      "*": "ask",
      "*.env": "ask",
      "*.env.*": "ask",
      "*.env.example": "ask"
    },
    "external_directory": { "*": "ask" },
    "question": "deny",
    "plan_enter": "deny",
    "plan_exit": "deny",
    "mode_switch": "deny"
  }
}

你已经批准的目录会在会话的剩余时间内添加到 external_directory 中作为 "allow"

你的配置会叠加在这些默认值之上,你的规则优先。它不会替换默认值:将 edit 设置为 "allow" 会使 read 保持为 "ask",因此请明确列出你打算更改的每个权限。

accept all 代理则从 "*": "allow" 开始,external_directory 完全允许。对 .env.env.* 的读取仍然会询问,理由是自动批准运行并不等同于同意交出机密。


无头模式和服务端模式

在交互模式下,"ask" 是无害的:你会收到提示并批准。在 dropstone serve 下、CI 中或任何其他没有人在键盘前的地方,没有人可以询问,因此调用会停留在 "status": "running" 状态,请求会挂起而不是失败。没有超时,也没有可捕获的错误。

由于 build 代理在所有操作前询问,这是默认结果而不是边缘情况。部分配置也救不了你:允许 edit 会使 read 保持为 "ask",代理第一次打开文件时运行就会挂起。

有两种修复方法。要么运行 accept all 代理,它从 "*": "allow" 开始:

curl -X POST ".../session/$SID/message" -d '{ "agent": "accept all", ... }'

要么继续使用 build 并明确列出完整的允许列表,默认拒绝,这样后续版本中添加的工具不会悄悄开始挂起你的运行:

{
  "$schema": "https://dropstone.io/schema/config.json",
  "permission": {
    "*": "deny",
    "read": "allow",
    "edit": "allow",
    "glob": "allow",
    "grep": "allow",
    "bash": "allow"
  }
}

将其缩小到任务实际需要的范围。只读取和报告的代理没有理由持有 editbash

请注意,accept all 在读取 .env.env.* 之前仍然会询问。如果无人值守的运行必须读取其中一个,请明确允许它并慎重考虑。

Note

如果无头运行停止产生输出并且从不返回,请使用 GET /session/:id/message 检查会话中的最后一条消息。工具部分卡在 "status": "running" 就是这个问题的表现,而不是模型速度慢。


"Ask" 的作用

当 Dropstone 提示批准时,界面提供三种结果:

  • once:仅批准此请求
  • always:批准与建议模式匹配的未来请求(在当前 Dropstone 会话的剩余时间内)
  • reject:拒绝该请求

always 将批准的模式集由工具提供(例如,bash 批准通常白名单安全命令前缀,如 git status*)。


代理

你可以按代理覆盖权限。代理权限与全局配置合并,代理规则优先。了解更多 关于代理权限的信息。

Note

请参阅上面的 细粒度规则(对象语法) 部分,了解更详细的模式匹配示例。

{
  "$schema": "https://dropstone.io/schema/config.json",
  "permission": {
    "bash": {
      "*": "ask",
      "git *": "allow",
      "git commit *": "deny",
      "git push *": "deny",
      "grep *": "allow"
    }
  },
  "agent": {
    "build": {
      "permission": {
        "bash": {
          "*": "ask",
          "git *": "allow",
          "git commit *": "ask",
          "git push *": "deny",
          "grep *": "allow"
        }
      }
    }
  }
}

你也可以在 Markdown 中配置代理权限:

---
description: 代码审查,不进行编辑
mode: subagent
permission:
  edit: deny
  bash: ask
  webfetch: deny
---

只分析代码并提出建议。

Tip

对带参数的命令使用模式匹配。"grep *" 允许 grep pattern file.txt,而单独的 "grep" 会阻止它。像 git status 这样的命令适用于默认行为,但在传递参数时需要显式权限(如 "git status *")。

Ctrl+I