零运行时依赖
package.json 里只有 devDependencies,跑起来不下载任何东西。
实现细节:七个设计决定、六个模块与那条链、权限规则的写法、十阶段路线图、九条已知限制。 它是什么、怎么装、怎么用,看 首页。
7 条
package.json 里只有 devDependencies,跑起来不下载任何东西。
固定优先级 deny > ask > allow,与写在哪一层、排第几都无关。
非 TTY 默认拒绝;不认识的工具拒绝;tool.check 走到链尾无人应答也是 deny。
--yes写盘与执行命令都要有人按一次 y。
contract/ 不许 import 任何东西,builtins/ 只许 import contract/。
每次请求都带着工具清单,/context 的合计一度只算了系统提示与消息 ——
实测某一轮真切发出去约 448 token,账本报 11,其中 97.5% 是漏掉的工具。
八个工具走同一条接口:清单来自注册面上 tool.call 的 matcher 取值,
再过白名单与 hidden 两道。core/tool-list.ts 是这一份清单的唯一算法。
6 个模块 · 1 条链
每个调用点抛出一个事件,插件把自己的 hook 注册成中间件,按 tier 权威序串成一条链。 一个 hook 可以应答 / 改写 / 拒绝 / 委托下层。下面是这条链上的六个模块。
engine.dispatch —— 每个调用点抛出一个事件prepend → user → append → builtin → corenext(e) 是 Koa 式续体,不是事件发射器 —— 链尾只有一处,没有第二个地方可以漏user → project → local → flag → policydeny > ask > allow —— 与写在哪一层、在同一数组里排第几都无关allow 的效力上限是把 ask 变成 allow;托管层能收紧,不能放宽tool.check(预览后停下等一个答案:y 这一次 / a 本次会话这一类 / 其余算拒绝)→ sandbox(只有 Bash,路径闸)→ 真进程 / 真文件deny · 不认识的工具 = denyallow 规则都绕不过它AGENTS.md × 5 层拼进系统提示(每轮重算,改了当场生效)—— 五层里只有托管层能写--resume 接上一次会话~/.deepcode/history;/context 看账本(不报「还剩多少」),/compact 手动压、自动压缩默认关Task / Skill(第一方插件给的)pnpm lint 直接红 —— 不靠自觉telemetry.jsonl,没有网络上报src/ contract/ 事件目录与契约类型 —— 不 import 任何东西 core/ 引擎:dispatch、链、tier → contract providers/ anthropic / openai 两种协议 → contract builtins/ 六个内建工具 → contract cli/ 装配、REPL、渲染、设置、权限解析 → 上面全部 mods/ 四个内建 mod(与第三方插件同一个接口) → node: 内建 + contract + 自己 plugins/ 第三方插件 —— 不 import 内核,只拿到注册回调
这张表就是 scripts/check-boundaries.mjs 里的规则表;破坏边界
pnpm lint 直接红。
42 个事件已声明,23 个已实现;八个工具里六个内建、两个由第一方插件提供
(Task / Skill)。其余 19 个事件用到时会抛
NotImplementedError。
5 层来源 · 3 组数组
配置管连接(config.json),权限是另一套(.deepcode/settings.json),
三组数组 allow / ask / deny 都可以省略。五个来源从低到高:
user → project → local → flag
(--settings=)→ policy(托管)。
| 写法 | 含义 |
|---|---|
Bash | 该工具的所有调用 |
Bash(git push:*) | 命令行以 git push 开头,按空白 token 边界 ——
git pushup ✗ |
Read(~/.ssh/**) | file_path 按 glob 匹配:* 单段、
** 跨段 |
| 其它工具带括号 | 不支持:不命中,且启动时警告一次 |
: 是 token 边界,不是通配符;路径按绝对路径匹配(~ 会展开),
相对路径不会命中。
确认提示上除了 y(这一次)还有 a(本次会话的这一类)。
Bash 按归一后的那一条命令记,其余工具按整个工具记 ——
记住什么,按下的那一刻就打在屏幕上;只活在进程内存里,/permissions forget 一句话忘掉。
它与 settings 里的 allow 走同一条判定,所以一样掀不翻 deny。
前缀匹配不懂 shell 语法,「藏在后面」的命令它看不见。
Bash(git push:*) 拦得住 git push origin main; rm -rf ~,
但拦不住 true && git push origin main。所以 deny 是给手滑与误操作
加的一道闸,不是反对抗手段。
个人规则掀不翻任何一条 deny(allow 的效力上限是把
ask 变成 allow),会话里用 /permissions 看每条规则的来源。
全部完成
十个阶段全部完成。每阶段的出口标准与偏差记在 变更记录里。
「读 → 改 → 跑测试」的闭环;安全底线是每个会写盘或执行命令的动作按一次 y
会话与体验:--resume 接上上次会话、/diff、OpenAI 兼容 provider
安全与策略:五层设置来源、规则内核、托管策略掀不翻
扩展面:不改引擎的插件、classic 钩子、只能拧紧不能拧松
组合面:Task / Skill、沙箱、会话压缩、marketplace、遥测
内建与分发:四个内建 mod、指令文件五层、托管三通道
界面与交互:开场屏、活动区、内容面、两份账、历史与补全(全是行内增强,不占整屏)
记忆与上下文:/context 账本(明说不报「还剩多少」)、系统提示每轮重算、/compact 能带一句说明、压缩后重新附上目录约定、两道断电器
执行循环的收场:停止原因收敛成七个产品字面量、被截断就接着往下写(≤ 3 次,每次出声)、空步与炸在中途都不丢内容、两侧统一按白名单判「做完了没有」
工具清单:一条清单三个消费者(模型请求 / /help / /tools)收敛到一个函数;/context 把工具算进合计;/tools 说清每个工具来自哪个插件、以及哪些没进来、为什么
子代理的边界:子代理看得见哪些工具、能派多深,从调用方按「会话的全部」算挪进内核按「当前这一轮」算:嵌套一层拿不回被扣掉的面,深度上限(3 层)对 Task 与插件直派共用同一个数
9 条
六个工具能碰到你进程权限内的任何路径,不限工作目录 —— 确认提示拦的是「要不要动手」,不是「动哪里」。
Bash 有一道可选的路径闸,但它靠切分 token 判路径,不是解析 shell:
rm $(echo /etc/passwd) 绕得过去。
界面是逐行的纯文本流,markdown 只认一个子集,也不走 ui.render 事件。
算术写错、正则编译不过、钩子进程崩了 —— 一律非零退出,而 PreToolUse 上的非零就是
deny:Write / Edit / Bash 全部被拒绝,直到修好它。
子代理的系统提示只有 agent 文件里那段正文(为空时回落到会话的基础提示)——
AGENTS.md / CLAUDE.md 一个字都不进,工具面也只能是父级那一轮的子集。
会话落成 JSONL,放在用户级目录(不进项目目录),权限 0600。
删掉那个文件就等于删掉那次会话 —— 没有别的副本。
回答撞上输出长度上限时会自动接着往下写,最多 3 次 —— 每一次都是一次真的模型请求。 这个 3 是我们自己定的数,不是测出来的。
/context 按 4 字符 1 token 粗估,中英混排会失真;工具那一行算的是
名字 + 描述 + schema 的字符数,不等于适配器真正发出的字节数。
plugin add 从一份本地索引拷插件进落点:不 fetch、不 clone、没有签名与校验和,
也没有版本与升级。