Files
my-pi/extensions/AGENTS.md
T
云服务部-叶林立andDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> dae1a01f23 feat(prompt): 搜索引导改为意图→工具的正向指引,multi_grep 按上游保持关闭
真实会话中模型仍用 bash grep -o | sort -u 做抽取,被拒后直接放弃核对;
原提示词只说"不要",没告诉它抽取/计数、给程序传文件清单、过滤命令输出时该用什么。

- routing:按已知信息选 grep/find(多变体用 grep 正则 alternation),
  codemode + tools.grep 做聚合,bash 文件清单用 git ls-files,
  overflow_query 过滤输出,被拒后改用替代方案继续
- 权限策略:rg/grep/git grep/find/fd 的 deny 附带指向替代工具的 reason
- tools.jsonc:grep/find 新 snippet,补上 codegraph_explore snippet
- FFF 上游标注 multi_grep 有害:wrapper 删除 PI_FFF_MULTIGREP,清理全部引用
- JSONC 测试改用字符串感知的注释剥离(reason 中含 'src/**/*.ts')

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-22 00:14:49 -07:00

11 KiB
Raw Blame History

my-pi 维护约定(extensions/)

本目录是组合包的薄 wrapper 与纯 helper 层:第三方扩展一律经这里的包装文件(多数再套 prompt-guard.ts 代理)加载,自维护实现位于各自顶层目录。

系统提示词单一所有权

  • extensions/system-prompt.ts 是组合包唯一的系统提示词出口,必须排在 pi.extensions 最后,也是唯一允许在 before_agent_start 返回 systemPrompt 的扩展。提示词内容统一由 config/prompt/ 管理:preamble.md(开场白)、tools.jsonc(每个工具的简介、规则及第三方工具说明覆盖)、routing.jsonc(跨工具工作流规则,渲染为 <tool_routing>)、sections.jsonc(分区顺序)。
  • 其他组合包扩展不得返回 systemPrompt,也不得在 context 钩子中注入提示性消息;需要动态提示时只能写入 event.systemPromptOptions.sections.<name> 并在 sections.jsonc 登记顺序,静态规则写入 promptGuidelines 或该工具在 tools.jsonc 中的条目。
  • 第三方扩展必须经 extensions/ 下的组合包包装文件加载,由 extensions/prompt-guard.ts 的代理 API 拦截其对系统提示词的直接改写,并在注册工具时应用 tools.jsonc 的 description 覆盖;上游硬编码且无配置开关的注入只能在对应包装文件内处理,并以测试锁定所依赖的上游原文(依赖保持精确版本)。
  • 新增工具必须在 tools.jsonc 登记(覆盖说明,或以 "inherit": true 表示已按本组合包审阅上游原文),否则 tests/system-prompt.test.ts 失败;config/prompt/ 中的文字不得引用被策略禁止或被替换的用法。运行时若检测到其他扩展已定死提示词或存在未登记工具,system-prompt.ts 会各提示一次。

system-prompt.ts 开发约定

  • 扩展入口是 extensions/system-prompt.ts,必须排在 pi.extensions 最后;纯 helper(JSONC 加载与校验、applyToolCatalog / renderRouting / orderSections / spliceCover / readPreamble 等)位于 extensions/system-prompt-config.ts 以便 node --test 单测;组合包权威源是 config/prompt/(preamble.md / tools.jsonc / routing.jsonc / sections.jsonc),扩展运行时直接读取已安装组合包内文件,不经任何脚本部署。
  • 现代 Pi 下必须通过修改规范化 systemPromptOptions(toolSnippets / toolGuidelines / sections)保留分区结构,再读取重渲染的 event.systemPrompt 拼入封面并返回 systemPrompt;宿主不提供结构化 options 或 options 不参与重渲染时自动降级为文本拼接。不得改用 customPrompt 选项——它会抑制 tools / rules / docs 分区。
  • 宿主传入 customPrompt(pi-subagents 子 Agent prompt、SYSTEM.md)时,该开场白自含身份标记(如 <active_agent/>),不得用 preamble.md 覆盖;其余分区处理(tool catalog、<tool_routing>、分区排序、降级追加)照常。子会话判定只用 systemPromptOptions.customPrompt 上的 <active_agent name="..."/> 契约(isSubagentCustomPrompt),绝不检测渲染后提示词——主会话的项目文档也可能含该字面量。
  • 子 Agent 提示词画像在 config/prompt/subagent/(preamble.md + agents/*.md):由 extensions/subagents.ts 注入 pi-subagents 的 basePrompt/bundledAgentsDir 选项,替代上游的父提示词嵌入与内置默认 Agent;子会话经 excludedExtensionPaths 排除 pi-ask-user(子会话无人可问)。
  • routing.jsonc 规则可选 "scope": "main" | "subagent"(缺省两者皆适用,其他值校验失败),renderRouting 按 audience 过滤;sections.jsonc 可选 "subagentExclude" 分区名列表,子会话在排序前删除这些分区(当前排除 memory_policy 与 chrome_profile_bridge)。
  • 封面拼接边界必须是独占一行的裸标签,不能匹配带属性的标签:<project_instructions path="..."> 嵌套在 <project_context> 内,只有裸标签才是分区边界。
  • preamble.md 缺失、不可读或空白时保持 Pi 默认封面,不得写入空 preamble;config/prompt/ 解析或校验失败时 before_agent_start 警告一次并整体 no-op,绝不抛出。
  • 检测到其他扩展已设置 forceSystemPrompt、或激活工具未在 tools.jsonc 登记时各提示一次(warning);本扩展返回的 systemPrompt 把提示词冻结为最终文本是刻意设计——这也是它必须最后加载的原因。
  • config/prompt/ 随组合包发布,pi install / pi update 后即就位,无需任何部署 helper;对已安装副本的临时修改由 pi update 覆盖。路由规则本体见 config/prompt/routing.jsonc 与 README,system-prompt.ts 只负责渲染,不得替换 Pi 默认系统提示词。
  • 修改 loader、spliceCover 语义、注册顺序或 config/prompt/ 路径后,必须运行 node --test tests/system-prompt.test.ts、node --test tests/bundle-config.test.ts、node --test tests/extension-load.test.ts,并确认 npm pack --dry-run 包含 config/prompt/。

各 wrapper 约定

  • fff-override.ts:强制 FFF 官方 override 模式,统一接管 find、grep 和 @ 补全;multi_grep 按上游保持关闭(加载前删除 PI_FFF_MULTIGREP 环境变量)。FFF 独占本地字面搜索,远端服务器搜索由 ssh_find / ssh_grep 负责,RTK 不得接管搜索工具(见 pi-rtk-optimizer/AGENTS.md)。显式 CLI flag 仍遵循 FFF 官方优先级。
  • codegraph.ts + codegraph-client.ts:注册原生 codegraph_explore 工具,按索引根惰性常驻 codegraph serve --mcp -p <root> 子进程,经组合包自有 stdio 逐行 JSON-RPC 客户端直连(不经 shell、不带 pi-mcp-adapter 或 MCP SDK);serve 进程内置文件监听自动同步索引,无结果缓存。子进程 10 分钟无调用自动关闭、会话结束统一关闭;调用中死亡换新客户端透明重试一次;其启动的上游 daemon(.codegraph/daemon.sock)退出后可多驻留 ≤5 分钟,属上游行为,组合包不管理。
  • CodeGraph 是机器级依赖,install.sh/update.sh 经官方安装器管理 codegraph CLI,组合包不内置其运行时。安装、升级和普通启动流程不得执行 codegraph init;只有 codegraph_explore 在未初始化项目上被调用、且用户在 ctx.ui.confirm 中明确确认后才可 codegraph init 当前目录,拒绝记入会话级 declined 不再重复询问;init 失败必须如实报告并让模型回退内置工具;不得改动 CodeGraph 更新或遥测设置。CLI 缺失、init 被拒或服务调用失败都不得抛出,必须以文本结果打回并引导模型改用 find/grep/read/LSP。已移除的 plugin-init.ts(原 /plugin_init)职责已并入本文件的惰性确认,不得恢复。
  • hashline.ts + hashline-config.ts:部署组合包权威 config/pi-hashline-edit.json 后加载 pi-hashline-edit;默认以 2 字符行哈希覆盖内置 read / edit,grep 与 replaceText 均关闭。它保证锚定编辑而不负责压缩,大文件上下文节省必须来自先定位/隔离分析、再做最小范围 offset/limit 读取。
  • permission-system.ts:直接加载仓库内 pi-permission-system/src/index.ts,自身不部署、不播种、不迁移任何配置;运行时直接读取已安装组合包内 config/pi-permission-policy.jsonc / config/pi-permission-hard-guards.jsonc;日志保留在 <agentDir>/my-pi/permission-system/logs/。旧 extensions/pi-permission-system/ 位置的残留文件被忽略,不迁移也不清理;项目级 policy 不读取。
  • lsp.ts + lsp-config.ts:TypeScript/JavaScript 后端由根包固定依赖提供,用当前 Node 可执行文件直接启动包内 typescript-language-server CLI,不得依赖或调用 VS Code GUI;Kotlin/JDT LS 使用组合包部署的 kotlin-lsp --stdio 与 jdtls 配置,根包不安装这两个系统可执行文件。
  • subagents.ts:pi-subagents 的组合包 wrapper,注入权威 permission-system.ts 的 canonical absolute path 为子会话 mandatory extension,并提供 config/prompt/subagent/ 提示词画像(basePrompt + bundledAgentsDir)与 excludedExtensionPaths(排除 pi-ask-user);完整规则见 pi-subagents/AGENTS.md。
  • context-view.ts:只读的本地 effective-context observer(/context),只读取 pi-compaction/src/service.ts 发布的 projection metrics,不注册生产 context writer;pi-minimal-footer 优先显示同一 effective usage。
  • .pi-debug/ 是 /dump-system-prompt 生成的本地诊断目录,不提交到仓库,也不作为组合包运行时配置源。

根目录 TypeScript 与 LSP 验证约定

  • 根目录当前有意不安装 Pi runtime,也没有根级 tsconfig.json、devDependencies 或 @types/node;@earendil-works/pi-* 只作为 optional host peer dependencies。TypeScript LSP 因而会把根目录 .ts 文件放入 inferred project,不能把宿主 Pi 的运行时解析能力等同于仓库内静态类型环境。
  • 每个任务首次对相关根目录 TypeScript 文件调用 lsp_diagnostics 时先建立并记录基线;后续只关注相对基线新增、消失或位置变化的诊断。文件和类型环境都未变化时不得重复调用 LSP 并重复报告同一组结果。
  • 当前可预期的基线包括:宿主 peer 缺失导致的 TS2307(例如找不到 @earendil-works/pi-coding-agent),Node 类型缺失导致的 node:* / node:test / node:assert TS2591,以及由这些上游类型缺失级联产生的 TS7006、TS18048、TS2722 等。遇到级联错误时先确认其是否随缺失类型而产生,不要把它们直接归因于本次实现。
  • 已知基线不等于忽略所有诊断:凡是无法由上述缺失依赖解释的新语法错误、结构类型错误、错误属性访问或本次修改所在代码的新诊断,必须修复并重新验证。交付时应把“已知类型环境基线”和“本次新增诊断”分开说明。
  • 不得为了消除 LSP 基线而在根包安装第二套 Pi runtime、加入机器相关的宿主绝对路径或提交只在单机有效的 paths 映射。若确需新增根级 tsconfig.json、@types/node 或其他开发类型环境,必须作为明确的仓库设计变更评估,并同步更新依赖、锁文件和本文档。
  • 不要从泛型或重载的 ExtensionAPI 方法直接用 Parameters<...> 猜取具体工具定义;解析失败时它可能退化为 unknown。包装第三方工具时优先使用上游导出的具体类型;没有稳定导出时定义覆盖实际访问字段的最小结构类型,并用运行时集成测试验证。
  • node --test 可直接测试仓库内的纯 TypeScript helper,但测试入口不得静态导入 node_modules 中的 .ts;Node 原生 type stripping 会对这种路径报 ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING。第三方 TypeScript 扩展 wrapper 应拆出本地纯 helper 做单元测试,并通过隔离的临时 Pi agent/jiti 加载验证真实扩展入口。
  • 对根目录扩展的最终验证优先组合使用:纯 helper 的 node --test、git diff --check、所需 npm 锁文件检查,以及隔离 Pi 环境的扩展加载。LSP 启动成功、单元测试通过和真实 Pi 加载通过是不同证据,不得互相替代或把类型环境基线误报为 LSP 后端启动失败。