feat(permission): integrate auto-review and hard guards

This commit is contained in:
云服务部-叶林立
2026-09-02 15:34:29 +08:00
parent a4807dde67
commit 180da95ab7
79 changed files with 4263 additions and 9203 deletions
+38 -20
View File
@@ -1,31 +1,49 @@
import permissionSystemExtension from "../pi-permission-system/src/index.ts";
import { getAgentDir, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
const BUNDLE_CONFIG_PATH = fileURLToPath(new URL("../config/pi-permission-system.json", import.meta.url));
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 deployBundlePermissionConfig(): void {
const targetPath = join(getAgentDir(), "extensions", "pi-permission-system", "config.json");
const bundledConfig = readFileSync(BUNDLE_CONFIG_PATH, "utf8");
function seedBundlePermissionConfigs(): void {
const targetDir = join(getAgentDir(), "extensions", "pi-permission-system");
mkdirSync(targetDir, { recursive: true, mode: 0o700 });
try {
if (readFileSync(targetPath, "utf8") === bundledConfig) {
return;
}
} catch {
// Missing or unreadable target: replace it with the bundle-owned baseline.
}
for (const entry of BUNDLE_CONFIGS) {
const targetPath = join(targetDir, entry.target);
if (existsSync(targetPath)) continue;
mkdirSync(dirname(targetPath), { recursive: true });
const temporaryPath = `${targetPath}.my-pi.tmp`;
writeFileSync(temporaryPath, bundledConfig, "utf8");
renameSync(temporaryPath, targetPath);
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;
}
}
}
/** Deploy the bundle-owned policy before registering permission hooks. */
/** Seed user-editable policy files before registering permission hooks. */
export default function bundledPermissionSystemExtension(pi: ExtensionAPI): void {
deployBundlePermissionConfig();
permissionSystemExtension(pi);
seedBundlePermissionConfigs();
permissionSystemExtension(pi);
}