feat: enable permission-aware subagents

This commit is contained in:
叶林立
2026-08-26 10:49:26 +08:00
parent d3bf562189
commit 7571ba6dd9
185 changed files with 48365 additions and 26 deletions
@@ -0,0 +1,55 @@
import { mkdirSync, mkdtempSync, realpathSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import {
assertMandatoryExtensionsLoaded,
extensionPathMatches,
normalizeMandatoryExtensionPaths,
} from "../src/mandatory-extensions.js";
function fixturePath(name = "permission-system.ts"): string {
const dir = mkdtempSync(join(tmpdir(), "pi-subagents-mandatory-"));
const path = join(dir, name);
writeFileSync(path, "export default () => {};\n");
return path;
}
describe("mandatory extension paths", () => {
it("requires absolute existing extension entries and canonicalizes duplicates", () => {
const path = fixturePath();
expect(normalizeMandatoryExtensionPaths([path, path])).toEqual([
realpathSync.native(path),
]);
expect(() => normalizeMandatoryExtensionPaths(["relative.ts"]))
.toThrow("must be absolute");
expect(() => normalizeMandatoryExtensionPaths([join(tmpdir(), "missing-extension.ts")]))
.toThrow("is unavailable");
});
it("accepts extension directories", () => {
const dir = mkdtempSync(join(tmpdir(), "pi-subagents-mandatory-dir-"));
const extensionDir = join(dir, "permission-system");
mkdirSync(extensionDir);
expect(normalizeMandatoryExtensionPaths([extensionDir])).toEqual([
realpathSync.native(extensionDir),
]);
});
it("matches the exact canonical entry rather than a same-named impostor", () => {
const trusted = fixturePath();
const impostor = fixturePath();
const [canonical] = normalizeMandatoryExtensionPaths([trusted]);
expect(extensionPathMatches(trusted, canonical)).toBe(true);
expect(extensionPathMatches(impostor, canonical)).toBe(false);
});
it("fails closed when the exact mandatory entry did not survive reload", () => {
const trusted = fixturePath();
const impostor = fixturePath();
const mandatory = normalizeMandatoryExtensionPaths([trusted]);
expect(() => assertMandatoryExtensionsLoaded([impostor], mandatory))
.toThrow(`Mandatory extension failed to load: ${mandatory[0]}`);
expect(() => assertMandatoryExtensionsLoaded([trusted], mandatory)).not.toThrow();
});
});