feat: 组合包配置集中到 my-pi/ 目录并改为整体重建

- 组合包拥有、可随时重建的配置、日志与缓存统一放在
  <agentDir>/my-pi/:permission-system/(policy.jsonc、hard-guards.jsonc、
  logs/)、rtk-optimizer/config.json、tool-search/(config.json、
  catalog-v1.json)与 system-prompt-cover.md。hashline.json、lsp.json
  由外部扩展读取固定路径,是唯一例外。
- 新增 config/bundle-manifest.json 与 scripts/rebuild-bundle-config.mjs:
  先校验全部来源与目标,在临时目录构建完整树,再整体删除旧 my-pi/
  (符号链接只删链接)并原子替换,不备份。install.sh / update.sh 每次
  运行都调用它;扩展自身不再播种或迁移配置。
- update.sh 删除 pi update 失败后的 git clean 恢复逻辑:Pi 1.3.0 会在
  下一次 pi update 时依据中断标记自行恢复。同时删除 Tool Search
  settings.json 快照迁移与封面部署脚本。
- Tool Search 改为读取 my-pi/tool-search/config.json(源为
  config/tool-search.json,须与 BUNDLE_TOOL_SEARCH_DEFAULTS 一致),
  不再读写 settings.json 的 toolSearch 段,移除 bundleDefaultsVersion。
- 默认权限策略开启 debugLog。
- 旧位置的残留文件不迁移、不清理;AGENTS.md / README 同步新约束。

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
云服务部-叶林立
2026-10-19 02:26:57 -07:00
co-authored by Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent 7e6a8faae1
commit 2682bd7fa7
40 changed files with 711 additions and 1339 deletions
+8 -44
View File
@@ -1,49 +1,13 @@
import permissionSystemExtension from "../pi-permission-system/src/index.ts";
import { getAgentDir, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
const BUNDLE_CONFIGS = [
{
source: fileURLToPath(new URL("../config/pi-permission-policy.jsonc", import.meta.url)),
target: "policy.jsonc",
},
{
source: fileURLToPath(new URL("../config/pi-permission-hard-guards.jsonc", import.meta.url)),
target: "hard-guards.jsonc",
},
] as const;
function seedBundlePermissionConfigs(): void {
const targetDir = join(getAgentDir(), "extensions", "pi-permission-system");
mkdirSync(targetDir, { recursive: true, mode: 0o700 });
for (const entry of BUNDLE_CONFIGS) {
const targetPath = join(targetDir, entry.target);
if (existsSync(targetPath)) continue;
const legacyPath = entry.target === "policy.jsonc"
? join(targetDir, "config.json")
: undefined;
const sourcePath = legacyPath && existsSync(legacyPath) ? legacyPath : entry.source;
const temporaryPath = `${targetPath}.${process.pid}.${Date.now()}.tmp`;
writeFileSync(temporaryPath, readFileSync(sourcePath, "utf8"), {
encoding: "utf8",
mode: 0o600,
flag: "wx",
});
try {
renameSync(temporaryPath, targetPath);
} catch (error) {
try { unlinkSync(temporaryPath); } catch { /* best effort */ }
if (!existsSync(targetPath)) throw error;
}
}
}
/** Seed user-editable policy files before registering permission hooks. */
/**
* Load the bundled permission system directly.
*
* Its bundle-owned config (policy.jsonc, hard-guards.jsonc) is deployed by
* install.sh / update.sh into `<agentDir>/my-pi/permission-system/`; the
* extension itself never seeds or migrates configuration.
*/
export default function bundledPermissionSystemExtension(pi: ExtensionAPI): void {
seedBundlePermissionConfigs();
permissionSystemExtension(pi);
}
+4 -4
View File
@@ -1,8 +1,8 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
/** File name of the bundle-managed system prompt cover inside the agent directory. */
export const COVER_FILE_NAME = "SYSTEM_COVER.md";
/** File name of the bundle-managed system prompt cover inside `<agentDir>/my-pi/`. */
export const COVER_FILE_NAME = "system-prompt-cover.md";
/**
* Matches the newline-delimited boundary before the first top-level prompt section.
@@ -14,9 +14,9 @@ export const COVER_FILE_NAME = "SYSTEM_COVER.md";
*/
const FIRST_SECTION_BOUNDARY = /\n<[a-z][a-z0-9_-]*>\n/;
/** Resolve the cover path inside a given agent directory. */
/** Resolve the cover path inside a given agent directory's bundle-owned `my-pi/` tree. */
export function resolveCoverPath(agentDir: string): string {
return join(agentDir, COVER_FILE_NAME);
return join(agentDir, "my-pi", COVER_FILE_NAME);
}
/**
+1 -1
View File
@@ -8,7 +8,7 @@ export { COVER_FILE_NAME, readCoverFile, resolveCoverPath, spliceCover } from ".
* Replaces Pi's default system prompt preamble with the bundle-managed cover while
* preserving every other prompt section in its original position.
*
* The cover is read on each `before_agent_start`, so edits to `SYSTEM_COVER.md` take
* The cover is read on each `before_agent_start`, so edits to `system-prompt-cover.md` take
* effect on the next turn of an already-running session rather than requiring a restart.
*
* Returning `systemPrompt` sets Pi's `forceSystemPrompt`, which is projected onto the