# pi-config-manager **Repository Path**: fanchen53/pi-config-manager ## Basic Information - **Project Name**: pi-config-manager - **Description**: Manage Pi tools, skills, context files, and extensions from one searchable TUI overlay. - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-10 - **Last Updated**: 2026-08-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Pi Config Manager 在一个可搜索的 TUI 浮层中管理 Pi 的工具、技能、上下文文件与扩展。 [English](README.md) | 简体中文 Pi Config Manager 是 [Pi Coding Agent](https://github.com/earendil-works/pi) 的资源策略扩展。资源的发现、加载、去重与来源标注仍由 Pi 负责;Config Manager 只决定 Pi 已发现的资源是否启用。 ## 主要特性 - 在一个可搜索的界面中管理 **Tools、Skills、Context Files 和 Extensions** - **Effective 状态显示**:始终展示模型实际接收的内容,即所有策略层组合后的结果 - 三种编辑目标:**Global**(持久化)、**Project**(版本控制)和 **Session**(Preset 作用域),按 `P` 切换 - 四象限冲突模型,以最小覆盖写入语义解析 Global × Project 设置 - **Context Monitor**:显示每个资源对系统提示词的行级贡献与高亮 - 编辑器上方显示紧凑的资源状态 HUD,展示激活/总数 - 内置命名 Preset,可统一配置模型、思考等级、工具、技能和指令 - 运行时约束策略层,供只读模式和沙箱集成使用 - 可搜索、全键盘操作的浮层,并保留当前对话作为背景 - 根据资源来源,通过 Pi 公开设置 API 保存扩展开关 - 无遥测,不发起网络请求 - 可编译为 JavaScript 发布到 npm,附带 TypeScript 类型声明 ## 环境要求 - Pi Coding Agent **0.83.x** - 可视化管理器需要交互式 TUI 模式 当前版本已在 Pi 0.83.0 上完成测试。更高版本的 Pi 可能也能运行,但 Pi 的扩展与 TUI API 可能发生变化;升级前请先查看本项目的发布说明。 ## 安装 全局安装,供所有项目使用: ```bash pi install npm:pi-config-manager ``` 仅为当前项目安装: ```bash pi install -l npm:pi-config-manager ``` 不修改设置,临时试用一次: ```bash pi -e npm:pi-config-manager ``` 启动 Pi 后运行: ```text /config-manager ``` ## 快速上手 1. 运行 `/config-manager`。 2. 按 `Tab` 在资源页签之间切换。 3. 直接输入文字过滤当前列表。 4. 按 `Space` 或 `Enter` 在当前目标中切换所选资源。 5. 按 `P` 在 Global 和 Project 编辑目标之间切换。 6. 在 Extensions 页按 `S` 保存暂存变更并重新加载 Pi。 ### 键盘操作 | 按键 | 操作 | | --- | --- | | `Tab` | 切换到下一个资源页签(Overview → Tools → Skills → Contexts → Extensions → Overview) | | `Shift+Tab` | 切换到上一个资源页签(反向循环) | | 输入文字 | 按名称、状态或详情过滤当前列表。切换页签时清空。 | | `↑` / `↓` | 在资源列表中移动选择,或滚动已聚焦的 Context Monitor 面板(每次 3 行) | | `←` / `→` | 在资源列表和 Context Monitor 面板之间切换焦点 | | `Space` / `Enter` | 在当前编辑目标(Global、Project 或 Session)中切换所选资源 | | `P` | 在 Global 和 Project 编辑目标之间切换(只在未激活 Preset 时可用) | | `S` | 保存暂存的扩展变更并重新加载 Pi(只在 Extensions 页可用) | | `Alt+S` | 全局保存所有暂存变更并重新加载 Pi | | `Esc` | 关闭管理器(丢弃未保存的扩展变更) | 过滤、导航和切换操作支持 Pi 键位配置,会遵循当前 TUI keybindings。底部提示行会显示当前页签最常用的操作。 ## 命令 | 命令 | 说明 | | --- | --- | | `/config-manager` | 打开统一概览 | | `/tools` | 打开 Tools 页 | | `/skills` | 打开 Skills 页 | | `/contexts` | 打开 Context Files 页 | | `/extensions` | 打开 Extensions 页 | | `/preset` | 选择或清除命名 Preset | | `/preset <名称>` | 直接激活命名 Preset | 也可以直接修改全局默认值: ```text /tools global enable|disable /skills global enable|disable /contexts global enable|disable ``` ## Effective 视图与编辑目标 可视化管理器始终展示 **Effective** 资源状态:Pi 默认值、Global/项目设置、活动 Preset、Session 覆盖、外部激活和运行时约束组合后的最终结果。该状态是模型在下一次 Provider 请求中实际接收的内容。 ### 页头布局 管理器页头显示三行内容,共同描述你正在查看和编辑的内容: ```text Pi Config Manager · Context Monitor [Overview] Tools Skills Contexts Extensions View: Effective · Edit: Global Constraints: none ``` - **页签行**:显示五个资源页签,当前页签以方括号高亮。 - **目标行**:显示视图模式(`Effective`)和当前编辑目标(`Global`、`Project` 或 `Session · `)。按 `P` 在 Global 和 Project 之间切换。 - **约束行**:列出活动的运行时约束策略层 ID(例如 `plan-mode`),或在项目级禁用生效时显示 `project settings`。被约束的工具会显示锁图标且无法切换。 ### 编辑目标 编辑目标决定资源修改写入的位置。按 `P` 可在 Global 和 Project 之间切换: - **Global**(页头显示 **View: Effective · Edit: Global**):Tools、Skills 和 Context Files 的修改会写入 `~/.pi/agent/resource-settings.json`,并由新会话继承。这是默认的编辑目标。 - **Project**(页头显示 **View: Effective · Edit: Project**):修改写入受信任项目的 `.pi/resource-settings.json`,这些设置会留在仓库中并适用于所有协作者。只对受信任项目可用。 - **Session**(页头显示 **View: Effective · Edit: Session · preset名称**):激活命名 Preset 时,所有资源切换都会创建该 Preset 专属的 Session 作用域覆盖。这些覆盖存入当前 Session 分支,在 `/tree` 导航后仍然保留,但不会修改 Global 设置或 `presets.json`。Preset 名称会显示在页头中。 ### 四象限冲突模型 每个资源根据其 Global 和 Project 设置,处于四个状态之一: | | Project enabled | Project disabled / 未设置 | | --- | --- | --- | | **Global enabled** | enabled | disabled(Project 覆盖) | | **Global disabled / 未设置** | enabled(Project 覆盖) | disabled | 当你切换一个资源时: - 在 **Global** 模式下:只有 Global 记录发生变化。如果资源同时被项目设置锁定,该行会显示 `blocked by project settings` 并拒绝切换。 - 在 **Project** 模式下:写入项目记录。如果新的 Project 状态与 Global 状态一致,则完全移除项目记录(回到继承 Global 的状态)。这种最小覆盖写入方式保持项目文件干净且易于审查。 被项目设置禁用的资源在 Global 模式下会被锁定(`blocked by project settings`)。要重新启用它们,需要直接编辑项目文件或在 Project 模式下切换。 ### 运行时约束 运行时约束具有最高工具优先级。它们由外部集成(例如只读模式)通过 `config-manager:layer-set` 事件设置,无法从管理器中覆盖。 受约束的工具会显示锁图标,其状态中会包含所属的策略层: - `🔒 edit · blocked by plan-mode` — 被运行时策略层禁用 - `🔒 grep · required by plan-mode` — 被运行时策略层强制激活 要修改受约束工具的状态,必须首先通过 `config-manager:layer-clear` 清除所属的运行时约束。 ### Preset 的 Session 覆盖 激活 Preset 后,切换任何资源都会创建该 Preset 专属的 **Session 覆盖**。这些覆盖存储在 Session Tree 的 `pi-config-manager-state` 条目中,并在以下场景中持续保留: - 恢复会话 - `/tree` 分支导航 - 同一 Session 内的新对话轮次 Session 覆盖不会修改 `resource-settings.json` 或 `presets.json`。清除 Preset 会移除其所有 Session 覆盖并恢复捕获的原始状态。 ### 扩展变更 扩展开关独立于 Effective 资源视图,因此 Extensions 页显示 **View/Edit: Pi settings**。切换操作会在界面中暂存,按 `S` 并确认重新加载提示后,再根据扩展来源写入对应的全局或项目 Pi 设置。Config Manager 不允许在自己的活动界面中禁用自身,也会报告 Pi 无法按扩展单独过滤的直接文件包。 ## 各类资源的行为 ### Tools 未受约束的工具变更通过 `pi.setActiveTools()` 立即生效。Config Manager 使用 Pi 已发现的工具清单,并在能够观察到时保留其他扩展动态加入的工具(归类为"external tools")。Global defaults 同时保存显式启用和禁用,因此 Pi 注册但初始未激活的工具也可以被持久启用。 ### Skills 已禁用的技能会在 `before_agent_start` 阶段从 Pi 标准系统提示词的技能目录中移除。调用已禁用的 `/skill:` 命令时,会显示通知并阻止展开。带有 `disableModelInvocation` 元数据的技能保持启用供手动使用,但会从技能目录中省略;其可用性还取决于 `read` 工具是否处于激活状态。 ### Context Files 已禁用的上下文文件会在 `before_agent_start` 阶段从 Pi 标准的 `project_context` 提示词区段中移除。该设置只控制模型可见的提示词内容,**不会**阻止工具直接读取一个已知文件路径。上下文过滤依赖 Pi 的标准提示词区段;如果自定义系统提示词重写了这些区段,Config Manager 会保留原提示词并每个 Session 警告一次。 ### Extensions 扩展开关在保存前只处于暂存状态。Config Manager 通过公开的 `SettingsManager` 写入 Pi 原生扩展/包过滤设置,然后请求 Pi 重新加载。变更根据扩展来源作用到对应的全局或项目范围。 如果本地包来源直接指向单个扩展文件,Pi 无法为它应用单扩展过滤规则。Config Manager 会报告这个限制,而不是保存一个无效开关。管理器也不会允许在自己的活动界面中禁用自身。 ## 资源状态对照表 每个资源行都会显示一个状态标签。含义取决于资源类型和活动的策略层: | 状态 | 含义 | | --- | --- | | `active` | 工具在激活集中,会出现在下一次 Provider 请求中 | | `inactive` | 工具已被发现但被当前策略排除 | | `enabled` | 技能或上下文已启用,会出现在系统提示词中 | | `disabled` | 技能或上下文被当前策略排除 | | `blocked by ` | 工具被运行时约束锁定(例如 `plan-mode`) | | `blocked by project settings` | 资源被项目的 `.pi/resource-settings.json` 禁用 | | `staged` | 扩展开关已排队但尚未保存 | | `required by ` | 工具被运行时约束强制激活 | 受约束或项目锁定的行会显示锁图标(🔒)。这些行无法从管理器中切换。 ## Context Monitor 终端宽度足够时(68 列以上),浮层左侧显示资源列表,右侧显示 Context Monitor。选择资源后可查看它对模型可见提示词的贡献: - **Tools:**描述、参数 schema、prompt snippet 与 prompt guidelines。未激活的工具会显示占位符而不是其 snippet。 - **Skills:**该技能在系统提示词目录中的条目(Pi 为每个启用的技能注入系统提示词的块)。 - **Context Files:**包裹文件内容的完整 `` 区块。 - **Extensions:**来源、作用域、包来源类型与绝对路径信息。 ### 提示词捕获 Monitor 反映的系统提示词来自两个来源: 1. **第一次代理运行前**:使用 Pi 当前的提示词预览(`command` 来源)。这是实时预览,会随着你切换资源而更新。 2. **代理运行开始后**:切换到最新一次 `agent_start` 事件捕获的有效系统提示词(`agent-start` 来源)。这是最近一次运行开始时策略状态的快照。 在管理器打开期间做出的策略变更,会在下一次代理运行更新快照后反映到捕获的提示词中。 ### 高亮 当在捕获的系统提示词中找到所选资源时,Monitor 会高亮其对应行: - **Tools**:prompt snippet 行和所有 prompt guideline 行会被高亮。 - **Skills**:技能目录块中的名称和描述字段会被高亮。 - **Context Files**:`` 开始标签行会被高亮。 如果未找到资源(例如自定义系统提示词中未重写的已禁用技能),Monitor 会显示警告:`selected resource was not found in this captured system prompt`。 选择资源时,Monitor 会自动滚动到第一个高亮行。 ### 窄终端 终端较窄时(不足 68 列),Config Manager 会退化为不带 Monitor 的资源列表。请拉宽终端以查看 Monitor。 ## 配置文件 全局默认值: ```text ~/.pi/agent/resource-settings.json ``` 受信任项目的默认值: ```text .pi/resource-settings.json ``` 配置格式: ```json { "version": 1, "enabledTools": ["ast_grep_search"], "disabledTools": ["write"], "disabledSkills": ["deploy"], "disabledContexts": ["/absolute/path/to/AGENTS.md"] } ``` 上面的 `version: 1` 表示 **resource-settings 配置格式版本**。它不是 npm 包版本,也与内部 Session 状态版本无关。当前加载器会把缺失的值标准化为格式 1,但手动编写配置文件时建议保留该字段,以便将来明确识别格式升级。 ### 内部 Session 状态 Config Manager 会另外在 Pi 的 Session Tree 中自动写入 `pi-config-manager-state` 条目。这些内部条目用于保存当前 Preset、恢复状态及 Preset 专属的 Session 覆盖,使 `/tree`、恢复会话和分支导航能够还原正确策略。用户不需要、也不应该把这些条目写入 `resource-settings.json` 或 `presets.json`。 内部 `pi-config-manager-state` 当前使用格式版本 2。这个数字只属于 Session 条目,**不会取代** `resource-settings.json` 的格式版本 1。破坏性状态重置后,旧的 Session 格式版本 1,以及独立的 `preset-state`、`tools-config` 和 `skills-manager-state` 条目不会被导入。 ## Preset Config Manager 从以下位置加载命名 Preset: ```text ~/.pi/agent/presets.json .pi/presets.json ``` 项目 Preset 只会在项目受信任时加载,并覆盖同名的全局 Preset。每个 Preset 可以配置: ```json { "review": { "provider": "openai-codex", "model": "gpt-5.6-sol", "thinkingLevel": "high", "tools": ["read", "bash"], "skills": ["preset-settings"], "instructions": "修改前先认真审查。" } } ``` 可以使用 `/preset`、`/preset <名称>`、`pi --preset <名称>` 或 `Ctrl+Shift+U` 打开 Preset 选择器。选择器会列出所有已定义的 Preset 及其配置摘要,以及一个 `(none)` 选项用于清除当前 Preset。 激活 Preset 时: 1. 当前模型、思考等级和工具集会被捕获为**原始状态**,供后续恢复。 2. 应用 Preset 的 provider/model、思考等级、工具和技能。 3. Preset 的 `instructions` 会被追加到系统提示词。 4. 页头变为 **View: Effective · Edit: Session · preset名称**。 选择 `(none)` 会恢复捕获的原始状态:模型、思考等级和所有 Session 覆盖。资源回到当前 Global/项目策略。 显式空的 `tools` 或 `skills` 数组表示全部禁用;省略字段表示保留对应的正常策略。Preset 激活期间,其 `instructions` 会追加到系统提示词。 该包同时提供 `preset-settings` Skill,用于安全编辑这些配置文件。 ## 策略优先级 ```text 运行时约束 > Preset Session 覆盖 > Preset > 项目/Global 设置 > Pi 默认值 ``` 所有策略层都提交到单一的 `PolicyManager` 核心,由核心计算最终的 Effective 状态。优先级顺序确保安全关键的约束(只读模式、沙箱)始终生效。 目前运行时约束只作用于工具,主要供只读模式、沙箱模式等扩展集成使用。 ### 策略架构 Config Manager 只有一个扩展入口和一个 `PolicyManager`。Pi 默认值、Global/项目设置、第一方 Session Preset Feature 及其 Session 覆盖和外部运行时策略层都向该核心提交策略,只有核心负责计算并应用最终资源状态。因此 Preset 使用包内类型化 Profile Policy 接口,而不是兼容事件桥;外部插件无法共享包内 controller,所以继续使用下方具备生命周期防护的运行时策略层事件 API。 ### 外部工具观察 当 Config Manager 应用工具变更时,它会查询 Pi 的激活工具集,并将其他扩展动态加入的工具归类为"external tools"。这些工具会在 Config Manager 自身的更新中保留,避免意外移除动态注册的工具。 ## 扩展集成事件 Config Manager 可以独立运行。其他扩展也可以选择通过 `pi.events` 协调策略。 ### 运行时工具层 ```typescript pi.events.emit("config-manager:layer-set", { id: "read-only-mode", disableTools: ["edit", "write"], requireTools: ["read"], }); pi.events.emit("config-manager:layer-clear", { id: "read-only-mode", }); ``` 每个策略层以 ID 区分并参与组合。每层中的必需工具会在禁用工具之后加入,而且只能激活 Pi 已发现的工具。调用方可以在任意时刻设置或清除策略层,包括 Config Manager 的 `session_start` 之前;提前到达的事件会先保存,等默认工具清单初始化后才应用。 如需监听资源数量,可以订阅 `config-manager:state-changed`。发送 `config-manager:request-snapshot` 可以请求管理器立即发布一次快照。 原来的 `preset:tools-changed`、`preset:skills-changed` 和 `config-manager:preset-state` 集成事件已删除;Preset 现在由 Config Manager 直接拥有。 ## 限制与安全说明 - Pi 扩展拥有当前用户的完整系统权限,安装第三方包前请先审查源码。 - Config Manager 是提示词/资源策略工具,不是文件系统或进程沙箱。 - 技能和上下文过滤依赖 Pi 的标准提示词区段。如果自定义系统提示词删除或重写了这些区段,Config Manager 会保留原提示词并警告用户。 - 可视化管理器只支持 TUI 模式;RPC、JSON 和 print 模式不能打开浮层。 - 扩展变更需要重新加载 Pi。 ## 开发 需要 Node.js 22.19+、[Bun](https://bun.sh/) 与 Pi 0.83.0+。 ```bash git clone https://github.com/Hor1zonZzz/pi-config-manager.git cd pi-config-manager npm install npm run check ``` 构建包(将 TypeScript 编译到 `dist/` 目录): ```bash npm run build ``` 直接加载本地扩展(使用源码 TypeScript,无需构建): ```bash pi --no-extensions -e ./src/index.ts ``` ### 包结构 ```text dist/ # 编译后的 JavaScript + TypeScript 类型声明 + source maps skills/ # 随包发布的 Pi 技能(如 preset-settings) package.json # main → ./dist/index.js, types → ./dist/index.d.ts ``` `package.json` 中的 `files` 字段确保发布到 npm 的包只包含 `dist/`、`skills/`、文档和许可证。测试文件、构建脚本和开发文件不会被包含。 ### 自动发布 `npm publish` 会自动触发 `prepublishOnly`,先清理 `dist/` 目录并重新构建,再上传到 npm。发布稳定版 GitHub Release 时,`.github/workflows/publish.yml` 会自动把对应版本发布到 npm。工作流会检出 Release tag,验证该 tag 与 `v` 完全一致,运行完整检查,然后通过 npm Trusted Publishing 发布。Prerelease 会被跳过。 首次自动发布前,需要在 npmjs.com 的包设置中打开 **Settings → Trusted Publisher → GitHub Actions**,并填写: - Organization or user:`Hor1zonZzz` - Repository:`pi-config-manager` - Workflow filename:`publish.yml` - Allowed action:`npm publish` 之后更新 `package.json` 和 `package-lock.json`、整理 `CHANGELOG.md`、提交并推送,再创建匹配的 tag(例如 `v0.1.1`)和对应 GitHub Release。该工作流使用 OIDC,不需要保存长期 `NPM_TOKEN` Secret。npm 配置和工作流文件名区分大小写。 ## 许可证 [MIT](LICENSE)