diff --git a/AGENTS.md b/AGENTS.md index a2a7b33..6184e3d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -99,7 +99,7 @@ - Codex native compaction 必须直接消费当前 projection 生成的 ResponseItems,不得从 raw branch 重建输入;native checkpoint 同时保存有界 portable summary 供模型或 Provider 切换。配置只从 `settings.json.piCompaction` 读取且不写回,默认 soft/hard/target 比例为 72%/90%/55%。 - Kitty 完成通知只在 TUI 模式的 `agent_settled` 后发送;自动重试、自动 compaction 和 follow-up 期间不得提前通知或重置总耗时。权限通知只订阅 `permissions:ui_prompt`,在人类确认界面即将出现时立即发送,不得为策略或 AutoReview 已直接决定的请求通知,也不受完成通知时长门槛影响。默认 `o=always`、`a=focus`,每个 Pi Session 使用独立稳定 ID,标题和正文必须 Base64 编码。 - `/notify on|off` 只覆盖当前 Session;持久默认来自 `PI_NOTIFY_*` 环境变量。`PI_NOTIFY_MESSAGE_SOURCE=none` 必须继续提供不泄露回复正文、权限值或请求者细节的隐私模式,非 TUI 模式不得写入 OSC 序列。 -- 权限策略默认允许常规工具,允许 FFF 工具;拒绝 Bash 直搜,硬防御默认只保留确定性的破坏性 Shell 命令;Git 非只读操作、包管理、文件/系统/网络高风险操作与普通 MCP 调用按唯一全局 policy 判定。项目外路径不再产生独立 `external_directory` 判断,只走配置中的工具、`path` 与 Bash pattern。 +- 权限策略默认允许常规工具,允许 FFF 工具;拒绝 Bash 直搜,硬防御默认只保留确定性的破坏性 Shell 命令;Git 非只读操作、包管理、文件/系统/网络高风险操作与内置 MCP 的 `mcp____` 调用按唯一全局 policy 判定。项目外路径不再产生独立 `external_directory` 判断,只走配置中的工具、`path` 与 Bash pattern。 - SSH 权限沿用同一条 `pi-permission-system` gate 与 `auto-review` authorizer chain:`ssh_connect`、`ssh_cd`、`ssh_read`、`ssh_write`、`ssh_edit`、`ssh_find`、`ssh_grep` 默认 `ask`;连接前的证据解析已导入 host ID 为非秘密 target、port 与请求/default cwd,AutoReview 只可依据用户直接消息中的明确目标授权连接。`ssh_bash` 通过 `shellTools` 映射到完整 Bash 策略并设置 `decisionFloor: "ask"`,把普通 Bash `allow` 提升为复核请求,同时保留原有 `ask` 与硬 `deny`。全部远端路径不得送入基于本机 cwd 的默认 `input.path` 归一化。 - `auto-review` 是 `pi-permission-system` 内置 authorizer,不是独立扩展或第二个 `tool_call` gate;只复核普通策略产生的 `ask`,不会重复处理普通策略已 `allow` / `deny` 或硬防御已 `deny` 的请求。 - reviewer 是对话式 Codex Guardian 风格审查:以独立请求(不写入主会话)把有界 active-branch 对话记录与权限请求交给模型,模型只能通过 `approve` / `reject` 两个工具给出带 `reason` 的结论,不强制 `toolChoice`。`approve` 自动批准(包括 `path`);`reject` 以及配置、模型、超时、Provider 错误、截断、未调用工具、多次调用或参数无效等一切异常都必须 `defer` 到人工提示,并在弹窗中显示原因(模型理由标注为模型生成)。正文文本即使是合法 JSON 也不得作为结论;只有用户按 Esc 中止当前操作时才直接拒绝。不得在 authorizer chain 外增加第二层内置授权范围限制,也不得恢复 annotator 机制。 @@ -275,7 +275,7 @@ ## 验证 -组合包依赖或加载入口变化时,至少验证根 `npm install` 幂等、锁文件有效、MCP adapter 唯一所有者不变量测试,以及全部扩展可在隔离的临时 Pi agent 目录加载。权限配置变化时使用仓库内固定快照的 `pi-permission-system` schema 校验,并验证包装入口部署后的文件与仓库源配置一致。 +组合包依赖或加载入口变化时,至少验证根 `npm install` 幂等、锁文件有效,以及全部扩展可在隔离的临时 Pi agent 目录加载。权限配置变化时使用仓库内固定快照的 `pi-permission-system` schema 校验,并验证包装入口部署后的文件与仓库源配置一致。 安装、升级、卸载、搜索或 SSH 配置脚本变化时,至少运行 `sh -n install.sh`、`sh -n update.sh`、`sh -n uninstall.sh`、`sh -n search_config.sh`、`sh -n ssh_config.sh` 和 ShellCheck,并核对脚本仍具有可执行权限、仍包含在根 `package.json` 的 `files` 中、README 描述与实际流程一致。组合包配置重建必须用隔离 agent dir 覆盖:`my-pi/` 全量替换且内容字节一致、权限 `600`/`700`、目录外文件不受影响、空或相对 agentDir 拒绝且不删除、manifest 目标越界拒绝且不删除、`my-pi/` 为符号链接时只替换链接且不触碰目标目录;`update.sh` 中 helper 无法定位时必须记录失败且不回退脚本目录。搜索配置测试只能使用虚拟 key 和隔离 HOME;SSH 配置测试必须使用隔离 HOME、虚拟凭据与 mock transport,不得连接真实服务器或把真实密码写入测试输出。涉及真实 `pi install`、`pi update`、`pi remove`、Homebrew、远程安装器、Git 克隆、真实 SSH 连接或真实用户终端配置的端到端验证属于外部写操作,未经明确要求不得执行;可以使用隔离的临时 HOME 和 mock 命令验证分支行为。 diff --git a/README.md b/README.md index de1320f..c4502bc 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ CodeGraph 的更新或遥测设置。 本地源码直接使用 `@earendil-works/pi-coding-agent`、当前 `typebox`、`ModelRegistry.complete()` 与 `setActiveTools()`,不安装、别名映射或加载旧 `@mariozechner` runtime,也不使用 provider payload 改写、代理执行或隐藏 `sendMessage` 循环。 -新 session 默认常驻 Pi 核心 `read`、`write`、`edit`、`bash`、`grep`、`find`,以及 `codegraph_explore`、`lsp_diagnostics`、`ctx_execute`、`ctx_execute_file`、`ctx_batch_execute` 和 `tool_search`;Windows 上额外把内置 `powershell` 与 `bash` 作为同类本地 Shell 核心工具固定启用,非 Windows 平台则从目录中过滤它。组合包在 `pi-tool-search/extensions/bundle-groups.ts` 中为自身暴露的工具预置权威分组,包括本地文件导航、SSH 远端文件/命令、Chrome 导航/交互/调试、用户交互、CodeGraph/LSP、Tavily、Exa、Keenable、Context Mode 执行/知识库/观测/管理、Memory 查询/维护、Skill 和 MCP 管理。不可用、已固定或尚未授权而未注册的可选工具会自动从动态组中滤除。 +新 session 默认常驻 Pi 核心 `read`、`write`、`edit`、`bash`、`grep`、`find`,以及 `codegraph_explore`、`lsp_diagnostics`、`ctx_execute`、`ctx_execute_file`、`ctx_batch_execute` 和 `tool_search`;Windows 上额外把内置 `powershell` 与 `bash` 作为同类本地 Shell 核心工具固定启用,非 Windows 平台则从目录中过滤它。组合包在 `pi-tool-search/extensions/bundle-groups.ts` 中为自身暴露的工具预置权威分组,包括本地文件导航、SSH 远端文件/命令、Chrome 导航/交互/调试、用户交互、CodeGraph/LSP、Tavily、Exa、Keenable、Context Mode 执行/知识库/观测/管理、Memory 查询/维护与 Skill 管理。不可用、已固定或尚未授权而未注册的可选工具会自动从动态组中滤除。 标准组合包的全部隐藏工具都能命中预置目录,因此首次使用不调用模型、不生成用户缓存,也不把完整隐藏 schema 发送给 provider。只有用户另外安装了未识别工具,并且当前调用不是精确加载已有分组时,才可使用当前已认证模型补充目录;精确已有分组始终立即按当前确定性目录激活,不等待无关未知工具的模型增强。模型结果必须保留组合包预置分组,否则直接拒绝。有效增强缓存以 `0600` 写到 agent 目录的 `my-pi/tool-search/catalog-v1.json`,调用用量计入工具结果。用户 `groupOverrides` 的优先级高于预置目录;`/tool-search-rebuild` 会恢复预置目录,`/tool-search-status` 显示目录来源、容量、LRU 顺序和最近淘汰原因。 diff --git a/pi-permission-system/README.md b/pi-permission-system/README.md index 7364e63..7d60c8a 100644 --- a/pi-permission-system/README.md +++ b/pi-permission-system/README.md @@ -69,7 +69,7 @@ pi install npm:@gotgenes/pi-permission-system 3. Restart Pi or run `/reload`. Ordinary `ask` requests now reach AutoReview first; only `defer` opens the human dialog. The `path` surface is a cross-cutting gate that applies to **all** file access — Pi tools, bash commands, MCP calls, and extension tools alike. -Extension and MCP tools that operate on paths (via `input.path`, MCP's `input.arguments.path`, or a registered access extractor) are gated by default, so a `path` deny cannot be overridden by a per-tool allow — making it the right place to protect sensitive files like `.env` or `~/.ssh/*` from every tool at once. +Extension and MCP tools that operate on paths (via `input.path`, a unified `mcp` proxy tool's `input.arguments.path`, or a registered access extractor) are gated by default, so a `path` deny cannot be overridden by a per-tool allow — making it the right place to protect sensitive files like `.env` or `~/.ssh/*` from every tool at once. A `path` pattern matches both the path as the agent references it and its canonical (symlink-resolved) form, so a deny still fires when a symlink aliases a sensitive target. For per-tool path patterns (`read`, `write`, `edit`, `find`, `grep`, `ls`), patterns are matched against the file path from `input.path`. diff --git a/pi-permission-system/docs/configuration.md b/pi-permission-system/docs/configuration.md index 49bc470..150fcda 100644 --- a/pi-permission-system/docs/configuration.md +++ b/pi-permission-system/docs/configuration.md @@ -432,6 +432,8 @@ To deliberately opt into permissive bash, set `"bash": { "*": "allow" }` explici ### `mcp` Surface +The `mcp` surface applies to a unified proxy tool named `mcp` (e.g. `pi-mcp-adapter`) whose input carries `tool`/`server`/`connect`/`describe`/`search` fields. Pi's built-in MCP (0.99+) instead exposes each server tool as a first-class `mcp____` tool — gate those with ordinary tool-name rules such as `"mcp__myServer__*": "ask"`, not this surface. + MCP permissions match against derived targets from tool input: | Target type | Examples | @@ -486,7 +488,7 @@ Skill name patterns use `*` and `?` wildcards (note: surface is `skill`, not `sk ### `path` Surface -Cross-cutting gate that applies to **all** file access — built-in Pi tools (`read`, `write`, `edit`, `find`, `grep`, `ls`), bash commands, MCP calls (via `input.arguments.path`), and extension tools (via `input.path` or a registered access extractor). +Cross-cutting gate that applies to **all** file access — built-in Pi tools (`read`, `write`, `edit`, `find`, `grep`, `ls`), bash commands, `mcp` proxy calls (via `input.arguments.path`), and extension tools (via `input.path` or a registered access extractor). A `path` deny cannot be overridden by a per-tool allow. Extension and MCP path tools are gated by default — no registration needed — so a `path` deny protects sensitive files from every path-aware tool, not just the built-in six. diff --git a/pi-permission-system/docs/troubleshooting.md b/pi-permission-system/docs/troubleshooting.md index 1d4db22..84f0a42 100644 --- a/pi-permission-system/docs/troubleshooting.md +++ b/pi-permission-system/docs/troubleshooting.md @@ -6,7 +6,7 @@ | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | Config not applied (everything asks) | File not found or parse error | Verify the global policy at `~/.pi/agent/my-pi/permission-system/policy.jsonc` (respects `PI_CODING_AGENT_DIR`); check JSONC syntax | | Per-agent override not applied | Frontmatter parsing issue | Ensure `---` delimiters at file top; keep YAML simple; restart session | -| Tool blocked as unregistered | Unknown tool name | Use a registered `mcp` tool for server tools: `{ "tool": "server:tool" }` | +| Tool blocked as unregistered | Unknown tool name | Server tools arrive as `mcp____` under Pi's built-in MCP (check `/mcp`); a unified `mcp` proxy tool uses `{ "tool": "server:tool" }` | | `/skill:` blocked | Deny policy or confirmation unavailable | Check merged `skill` policy (global/project/agent layers). `ask` still requires UI or forwarded confirmation. | | External file path blocked | `external_directory` is `ask` without UI or `deny` | Allow/ask the permission or keep file tools inside the active working directory. | | Spurious external-path prompt for `cd && grep … ../path` | Relative path was resolved against cwd instead of the `cd` target | Fixed in current version — paths after a leading `cd &&` are resolved against the cd target, matching actual shell behavior. | diff --git a/pi-tool-search/README.md b/pi-tool-search/README.md index d6b0866..5b462c5 100644 --- a/pi-tool-search/README.md +++ b/pi-tool-search/README.md @@ -44,7 +44,6 @@ Run `/tool-search-status` to inspect the current catalog source, pinned count, d | `chrome-navigation` | Chrome bridge setup, tabs, navigation, snapshots/find/inspect, waits, and screenshots | | `chrome-interaction` | Chrome click/type/fill/key/hover/drag/tap/scroll input | | `chrome-debugging` | Chrome page evaluation, console/network diagnostics, response retrieval, and file upload | -| `mcp-management` | Shared MCP adapter management | Pinned tools are removed from these dynamic groups at runtime. The defaults pin `codegraph_explore`, `lsp_diagnostics`, the three high-frequency Context Mode execution tools, and all six Hermes memory tools, so none of them consume dynamic group or tool capacity. diff --git a/pi-tool-search/extensions/bundle-groups.ts b/pi-tool-search/extensions/bundle-groups.ts index 6a65591..f1f12a2 100644 --- a/pi-tool-search/extensions/bundle-groups.ts +++ b/pi-tool-search/extensions/bundle-groups.ts @@ -184,15 +184,6 @@ export const BUNDLE_GROUP_DEFINITIONS: BundleGroupDefinition[] = [ keywords: ["chrome", "browser", "console", "network", "javascript", "upload", "调试", "网络请求", "文件上传"], tools: ["chrome_evaluate", "chrome_list_console_messages", "chrome_list_network_requests", "chrome_get_network_request", "chrome_upload_file"], }, - { - id: "mcp-management", - title: "MCP management", - summary: "Inspect and manage MCP server connections exposed by Pi's shared adapter.", - useWhen: ["The user explicitly asks about MCP server status or operations"], - avoidWhen: ["A mapped first-class MCP tool already handles the task"], - keywords: ["mcp", "server", "connection", "MCP 服务", "连接"], - tools: ["mcp"], - }, ]; export interface BundleCatalogResult {