# pi-ignore

> 让指定 skill / MCP / 工具在指定目录或全局范围内"不生效"的 pi 平台能力，
> 类似 `.gitignore`。集成在 pi 拦截链最前端，对所有 skill 的 guard 扩展
> **自动生效、零改造、零感知**。

中文 · [English](./README.en.md)

## 快速开始

```bash
# npm 一键安装（推荐）：扩展自动注册 + postinstall 自动安装
pi install npm:pi-ignore

# 本地源码安装：
# pi install /path/to/pi-ignore
# python3 install.py                  # 安装 wrapper + 验证（幂等）

# 项目里创建规则：
echo "skill:wekan-task-manager" > .pi/.piignore   # 本项目跳过 wekan guard
echo "node_modules/"              >> .pi/.piignore # node_modules 下 guard 全跳过
```

> **如何生效**：扩展在 pi 启动时**自行加载拦截补丁**（patch.mjs），
> 无论 pi 用什么方式启动（pnpm shim / npm bin / wrapper）都生效，
> 无需改 PATH、无需重启 shell。`~/.pi/bin/pi` wrapper 是可选的双保险
> （在扩展加载前预载补丁）。

检查：`python3 install.py --check`；卸载：`python3 install.py --uninstall`。

## 使用 /piignore（交互式配置向导）

安装后**重启 pi**，在终端输入 `/piignore` 即可开始配置——**全程弹窗操作，不经过 AI 对话**：

1. **探测当前路径**：自动检测项目里的 `node_modules/`、`dist/`、`build/`、`__pycache__/`、`.venv/`、`.git/`、`*.log` 等常见忽略目标，以及可用 skills、MCP 服务器、已有规则
2. **进入向导**：确认后弹出选择器，可**多轮反复选择**多个类别与条目：
   - 📁 目录/文件（检测到的优先，如 `node_modules/`）
   - 🛡 skill 忽略（如 `skill:wekan-task-manager`）
   - 🔌 MCP / 工具（如 `mcp:github`）
   - ✍️ 自定义规则（自由输入，如 `tool:edit`）
3. **选择写入层级**：项目 `.pi/.piignore`（仅当前项目）或全局 `~/.pi/.piignore`（所有项目）
4. **预览确认**：追加写入，**不会覆盖已有规则**

其他子命令：

```bash
/piignore check <path>      # 检查某路径是否被忽略
/piignore check-tool <名称>  # 检查某工具是否被禁用
/piignore cleanup [skill]   # 清理 CLAUDE.md/AGENTS.md 里的注入块（默认按规则命中的 skill）
/piignore help              # 帮助
```

> 方向键选择、回车确认、Esc 取消；不想配置时直接在探测结果后选“否”即可。

### 注入屏蔽（skill 规则的双通道）

部分 skill（如 wekan-task-manager）会把启动指令块注入项目 `CLAUDE.md` / `AGENTS.md`，
新会话作为 system prompt 加载——运行时 guard 屏蔽拦不住它。pi-ignore 对命中
`skill:xxx` 规则的 skill 自动处理两条通道：

1. **系统提示过滤**：新会话的 system prompt 中 `<!-- xxx:start -->…<!-- xxx:end -->`
   块自动移除（动态生效，规则一删即恢复）
2. **文件清理**：`/piignore cleanup` 直接移除 CLAUDE.md/AGENTS.md 中的注入块

## 规则（.piignore 配置样例）

规则写在三个层级，支持 gitignore 语法（`*`/`**`/`/` 锚定/取反）+ `skill:`/`mcp:`/`tool:` 前缀：

```
# ── 1. 路径规则：命中即“跳过 guard”（skill 的拦截全部不执行）──
node_modules/            # 目录及子树下 guard 全跳过（目录自动递归）
*.log                    # 任意层级的 .log 文件
build/output.js          # 锚定项目根：仅项目根 build/output.js
**/test/fixtures/        # 任意层级 test/fixtures 目录

# ── 2. 取反（白名单）：被上方忽略的路径重新放回 guard 监管 ──
node_modules/            # 先忽略整个 node_modules
!node_modules/keep/      # 再放回 keep 目录（guard 重新生效）

# ── 3. skill 规则：整个 skill 失效（guard 全局跳过 + SKILL.md 不可读）──
skill:wekan-task-manager # 这个项目里 wekan 强制建卡流程失效
skill:wekan-*            # 通配：wekan 系列 skill 全部失效

# ── 4. MCP / 工具规则：直接禁用（调用即被 block，fail 给 LLM）──
mcp:github               # 禁用 github MCP 服务器全部工具
mcp:github__search_repos # 也可用工具名形式禁用单个工具
# 每行一条规则；多个前缀规则分开写即可（同一行只认一个 pattern）
```

**优先级**：项目 `.pi/.piignore` > 全局 `~/.pi/.piignore` > 能力自带
（`<skill>/.piignore`）；同层后写优先；`skill:`/`mcp:`/`tool:`（block）优先于路径（skip）。

**典型场景**：

```bash
# 场景 A：某项目不想被 wekan-task-manager 强制建卡
# （等价于 `.gitignore` 里忽略 wekan 这个“文件”）：
echo "skill:wekan-task-manager" > .pi/.piignore

# 场景 B：所有项目里 node_modules 下不要任何 guard 干扰：
echo "node_modules/" >> ~/.pi/.piignore

# 场景 C：全局禁用某个不用的 MCP 服务器：
echo "mcp:github" >> ~/.pi/.piignore

# 场景 D：项目里想保留规则但绕过某目录（白名单）：
printf 'node_modules/\n!node_modules/vendor-keep/\n' > .pi/.piignore
```

写完后可用 `/piignore` 查看生效规则，或 `/piignore check <path>` 验证具体路径。

## 工作原理

pi 扩展拦截链 first-block-wins，guard 无法被其他扩展撤销。pi-ignore 用
`node --import` 预加载补丁 monkey-patch `ExtensionRunner.prototype.emitToolCall`，
在**所有 guard 之前**仲裁（skip 放行 / block 禁用）。每次启动做健康检查
（模块/方法/实现指纹/重复 patch），失效即 stderr 醒目警告并 **fail-open**。

```
scripts/piignore.py（解析，零依赖）
      ↓ JSON + 预编译正则
extensions/pi-ignore/arbiter.mjs（匹配 + mtime 指纹缓存 + 健康检查）
      ↓
extensions/pi-ignore/patch.mjs（--import 预加载补丁）
      ↓
~/.pi/bin/pi（可选 wrapper：node --import patch.mjs <real cli.js>，双保险）
extensions/pi-ignore/index.ts（/piignore 命令，状态展示）
```

## 测试

```bash
python3 -m pytest tests/            # parser 24 项
node --test tests/arbiter.test.mjs  # JS 仲裁 10 项
node --test tests/integration/      # 真实 preload 集成 8 项
node --test tests/e2e-real.mjs      # 真实 pi runner E2E 4 项（需先 install.py）
```

## 故障排查

- pi 升级后 stderr 出现「pi-ignore patch 未生效」→ `python3 install.py --fix`
- 规则不生效 → 先 `/piignore` 看规则加载与 patch 状态
- 想彻底移除 → `--uninstall` + 从 shell rc 删 PATH 行

## 文档

- 中文说明：本文件
- English: [README.en.md](./README.en.md)
