npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pi-ast-guard

v1.1.1

Published

基于 AST 的 Pi 代理安全防护扩展 — 解析 Bash 命令,拦截危险操作(继承自 pi-damage-control)

Readme

pi-ast-guard

npm

Languages: 简体中文 | English

简介

pi-ast-guard(原名 pi-damage-control)是一款基于 AST 的代理安全防护扩展,专为 Pi 编码代理设计。 它能够在破坏性 shell 命令或文件操作执行之前进行拦截,同时避免因普通文本、markdown、heredoc 和任务描述中的内容而产生误报。

继承说明:本项目继承自 pi-damage-control(原作者 Baishampayan Ghose,原仓库已删除), 在保留原有 AST 解析方案与策略引擎的基础上继续维护与改进。

安装

pi install npm:pi-ast-guard
# 或者
# pi install git:github.com/rainmanhhh/pi-ast-guard

DNA 模式(Do Not Ask)

不想每次操作都弹窗确认?/ag:dna 一键进入 DNA 模式:遇到 ask 不再询问,而是按策略自动审批或拒绝block 规则照常拦截,安全底线不丢。

自动回答由 4 个参数决定(工作区内/外 × 读/写),外加工具黑白名单与累计违反上限,可在 settings.dna 中配置:

| 参数 | 默认 | 含义 | |------|------|------| | dna.readInside | allow | 工作区内读取 | | dna.readOutside | allow | 工作区外读取(仅读取,风险低) | | dna.writeInside | allow | 工作区内写/删/移动 | | dna.writeOutside | block | 工作区外写/删/移动(高风险,默认拒绝) | | dna.maxViolations | 3 | 本次 DNA 模式下累计自动拒绝的总上限(所有规则含工具黑白名单),达到后强制中断会话并清零(对话结束也清零) | | dna.allowTools | [] | 工具白名单(非空时启用白名单模式,仅允许名单中的工具调用) | | dna.blockTools | [] | 工具黑名单(白名单为空时启用黑名单模式,禁止名单中的工具调用) |

工作区 = cwd + settings.extraDirs。命令类 ask(如发布命令)在 DNA 模式下默认放行;自动拒绝会拦截操作并引导 AI 评估替代方案(勿绕过规则),本次模式内累计违反达到上限(dna.maxViolations,默认 3)才强制中断。

工作原理

  • 使用 just-bash 解析 Bash 命令 AST,无需正则表达式回退
  • 根据 config/default-policy.yaml 中的语义化命令规则进行评估
  • 从 Bash 命令和 Pi 文件工具中提取文件操作意图
  • 对零访问(zero-access)、只读(read-only)、禁止删除(no-delete)和工作区外写入路径应用路径策略
  • 当策略动作为 ask 时弹出四选对话框(同意一次 / 本会话允许 / 本会话拒绝 / 拒绝一次);当 UI 不可用时自动拒绝(fail-closed)

配置方式

创建项目级策略文件:

.pi/ast-guard.yml

或全局策略文件:

~/.pi/agent/ast-guard.yml

策略分层加载:全局策略(~/.pi/agent/ast-guard.yml)为基础层(缺失时用内置默认策略),项目策略(.pi/ast-guard.yml)存在时在其上合并——settings 字段级覆盖,rulesid 覆盖(同 id 项目优先),不同 id 的规则全部保留。

内置默认策略文件:config/default-policy.yaml

策略语言

顶层策略结构:

settings:
  language: auto
  parseFailure: ask
  showStatus: true
  # 额外工作区目录:与 cwd 共同构成「完整的工作区」,outsideWorkdir: true 的语义变为「在工作区目录列表之外」
  extraDirs: []
  # DNA 模式(Do Not Ask)下 ask 的自动回答
  dna:
    readInside: allow
    readOutside: allow
    writeInside: allow
    writeOutside: block
    maxViolations: 3
rules: []

settings.language 控制扩展 UI 提示的语言(zh 中文 / en 英文 / auto 跟随系统,默认 auto),包括通知、拦截/确认对话框、命令描述与默认策略规则文案;auto 通过系统区域设置探测(Windows 取系统区域,Unix-like 取 LANG/LC_ALL,无则英文)。跟随项目策略,/ag:status(已合并 reload)后生效。

路径规则

路径规则与命令规则同属顶层的 rules 列表。其 type 字段编码了路径策略的子类型:

  • path:zeroAccess — 禁止读、写、删除和移动操作
  • path:readOnly — 仅禁止写、删除和移动操作,读取允许
  • path:noDelete — 仅禁止删除和移动操作

每条路径规则示例:

- id: path-secrets-env
  type: path:zeroAccess
  action: block
  reason: 环境文件可能包含密钥信息
  match:
    path:
      any: .env*
      except: [.env.example]

match.path.any 可以是字符串或字符串列表:

match:
  path:
    any: [LICENSE, LICENSE.*, COPYING, COPYING.*]

支持的路径模式(glob 语义,* 按段匹配不跨 /** 匹配任意深度):

  • 精确匹配/文件名:README.md.env(无斜杠模式匹配任意位置的同名文件,如 ast-guard.yml 可命中 ~/.pi/ast-guard.yml
  • 目录:.git/node_modules/(含目录本身及其下所有内容)
  • 通配符:*.pemdocker-compose.*.ymldist/****/secrets/**** 段感知,**/secrets/** 命中任意深度含 secrets 段的路径)
  • 前缀:build-*/ 段结尾)
  • 当前工作目录宏:$CWD$CWD/…(工作区外用 outsideWorkdir: true
  • 相对模式解析到工作区根(cwd),~ 解析到 HOME

工作区外写入确认示例:

- id: path-outside-project-write
  type: path:readOnly
  reason: 工作区外写入需要确认
  match:
    path:
      outsideWorkdir: true
      except: [/tmp/, /dev/null]

命令规则

命令规则使用 type: command

- id: git-reset-hard
  type: command
  action: block
  reason: git reset --hard 会丢弃工作区变更
  match:
    command: git
    subcommand: reset
    flags:
      any: [--hard]

常用匹配字段:

  • command:精确的命令名称
  • commandAny:多个命令名称之一
  • subcommand:第一个非选项命令操作数
  • subcommandAny:多个子命令之一
  • argsAny:参数列表中任意一个匹配即可
  • argsAll:参数列表中全部必须匹配
  • argsNone:参数列表中不得出现任何匹配项
  • argsContainAny / argsContainAll:参数子串匹配
  • flags.any / flags.all / flags.none:语义化标志匹配
  • optionsBeforeSubcommand.value:子命令检测前的全局选项值,适用于 git -C repo ...
  • visibleTextAny / visibleTextAll / visibleTextNone:匹配可见静态文本,适用于 SQL 执行器

规则默认启用。审批对话框中的「本会话允许」会在当前会话内临时解除被触发规则的检查。

规则可配 priority(默认 0,值越大越优先):命中多条规则时只保留最高优先级的一组再按动作强度判定(block > ask > allow),因此高优先级 allow 规则可豁免低优先级 ask/block。来源偏移:项目 0 / home -0.3 / 内置默认 -0.6

动作选项:

  • allow — 放行
  • ask — 请求确认
  • block — 直接阻止

action 字段可选,省略时默认为 ask

- id: git-commit
  type: command
  action: ask
  reason: git commit 需要确认
  match:
    command: git
    subcommand: commit

完整示例:

settings:
  parseFailure: ask
  showStatus: true
rules:
  - id: path-secrets-env
    type: path:zeroAccess
    action: block
    reason: 环境文件可能包含密钥信息
    match:
      path:
        any: .env*
        except: [.env.example]
  - id: path-outside-project-write
    type: path:readOnly
    reason: 工作区外写入需要确认
    match:
      path:
        outsideWorkdir: true
        except: [/tmp/, /dev/null]
  - id: git-commit
    type: command
    action: ask
    reason: git commit 需要确认
    match:
      command: git
      subcommand: commit

审批对话框

当规则动作评估为 ask 时,弹出四选对话框(30 秒超时,超时即拒绝):

  • 同意一次 — 只放行当前这一次工具调用(单次生效,不影响下次)
  • 本会话允许 — 记录为会话级决策(决策层),当前会话内该规则在作用域内不再询问
  • 本会话拒绝 — 记录为会话级决策(决策层),当前会话内该规则在作用域内直接拦截、不再弹窗
  • 拒绝一次 — 拦截本次调用(单次生效,不影响下次)

会话级决策 = 规则匹配之上叠加的一层精确路径匹配:每条决策是 (规则, 作用域路径),查询时 deny 优先于 allow(无论新旧);同一 (规则, 作用域) 的新决策覆盖旧决策,不同作用域累积生效。

拒绝(含本会话拒绝、拒绝一次)、对话框取消/超时未应答,以及无 UI 自动拒绝,都会在拦截的同时中止当前轮(agent 停止执行,回到等待用户输入的状态);拦截消息仍作为工具结果发给 AI。

对话框被取消或超时均视为拒绝并拦截。无 UI 环境(print/JSON 模式)下,ask 决策自动拦截(fail-closed)。

作用域输入(粗粒度规则)

规则匹配域超出「工作区锚定的局部区域」(粗粒度)时,选中「本会话允许/拒绝」后额外弹一次输入框确定作用域:

| 输入 | 作用域 | |------|--------| | (空) | 仅本次触发的目标文件(父目录存在即可,容忍尚未创建的文件) | | . | 目标文件所在目录 | | ../.. | 从目标文件的上两级目录起(相对输入均相对目标文件目录解析) | | 绝对路径 | 直接以该路径为作用域 |

输入会校验:不得含通配符;作用域必须与规则的匹配域相交(如 outsideWorkdir 规则不接受工作区内的绝对路径,/etc/** 规则不接受 /var);目录作用域必须真实存在;不通过则提示并重新输入。取消输入等同取消对话框(fail-closed,中止当前轮)。

粗粒度判定(任一命中即弹输入):

  • outsideWorkdir: true
  • 根锚定绝对路径且解析后字面深度 ≤ 2(如 /etc/**/var/log//home/user/data/** 深度 ≥ 3 视为细粒度)
  • 首段为通配符或覆盖工作区及以上(**/…*/…../**..../**

无斜杠模式(ast-guard.yml*.log不弹输入:选中后自动把作用域限定为本次触发的目标文件(同名其他位置下次仍会询问)。命令面规则(无路径可锚定)与细粒度路径规则保持规则级决策(覆盖该规则所有路径)。

最近决策与按序号清除

会话级决策记录到 /ag:status 面板的「最近决策」(保留最近 10 条),每行带序号(最新在前 = 1):

最近决策
1. 14:32 本会话允许 → outside-ask → C:/tmp/x.log (touch C:/tmp/x.log)
2. 14:31 本会话拒绝 → git-commit (git commit)

单次生效的同意/拒绝不影响下次 ask,不在面板展示。执行 /ag:forget 1,3 按序号清除单条决策(逗号分隔多个);清除后序号重排,新决策到达也会使序号位移,忘记前可先执行 /ag:status 查看最新序号。

可用命令

| 命令 | 说明 | |------|------| | /ag:forget <序号...> | 按序号清除会话决策(逗号分隔多个,如 1,3),清除后序号重排 | | /ag:dna | 开启/关闭 Do Not Ask 模式 | | /ag:status | 重新加载策略并显示状态面板(含带序号的「最近决策」);再次执行刷新 |

开发

使用 Bun 作为包管理器:

bun install
bun run test        # 运行单元测试(Vitest)
bun run test:watch  # 监听模式
bun run typecheck   # TypeScript 类型检查
bun run check       # 完整检查(lint + 测试 + 类型)
bun run bench       # 性能基准(mitata)

测试位于 tests/ 目录,按模块组织(bash/rules/policy/engine/extension/intents/)。 已知问题与待优化项见 docs/known-issues.md

本地开发与验证

~/.pi/agent/settings.json 中直接指向源码(改代码即时生效):

{
  "extensions": ["E:/workspace/pi-ast-guard/src/index.ts"]
}

然后进入任意测试项目运行 pi,状态栏出现 🛡 图标即加载成功。仓库内 bun run check 通过后提交(pre-commit hook 会自动运行 bun run lint)。 也可在 ast-guard-demo 测试沙箱(含 .envdist/、自定义策略与完整验证清单)中手动验证。

鸣谢

本项目继承自 pi-damage-control(原作者 Baishampayan Ghose,原仓库已删除)。 灵感来源于 claude-code-damage-control

许可证

MIT © rainmanhhh