Files
pi-agent-integrated/pi-web/lib/app-runtime.test.mjs

107 lines
4.1 KiB
JavaScript

import assert from "node:assert/strict";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import test from "node:test";
import { createJiti } from "jiti";
const jiti = createJiti(import.meta.url);
const {
createAppSettingsManager,
getAppResourceLoaderOptions,
getManagedRuntimePaths,
getSkillsCliEnvironment,
isManagedPath,
} = await jiti.import("./app-runtime.ts");
async function managedFixture(t) {
const root = await mkdtemp(join(tmpdir(), "pi-web-managed-runtime-"));
const appRoot = join(root, "app");
const dataDir = join(appRoot, "data");
const agentDir = join(dataDir, "agent");
const resourcesDir = join(appRoot, "resources");
const skillsHomeDir = join(dataDir, "skills-home");
const stateDir = join(dataDir, "state");
const cwd = join(root, "workspace");
await Promise.all([
mkdir(agentDir, { recursive: true }),
mkdir(resourcesDir, { recursive: true }),
mkdir(skillsHomeDir, { recursive: true }),
mkdir(stateDir, { recursive: true }),
mkdir(join(cwd, ".pi"), { recursive: true }),
]);
const previous = new Map();
const env = {
PI_AGENT_MANAGED_RUNTIME: "1",
PI_AGENT_APP_ROOT: appRoot,
PI_AGENT_DATA_DIR: dataDir,
PI_AGENT_RESOURCES_DIR: resourcesDir,
PI_AGENT_SKILLS_HOME: skillsHomeDir,
PI_CODING_AGENT_DIR: agentDir,
XDG_STATE_HOME: stateDir,
};
for (const [key, value] of Object.entries(env)) {
previous.set(key, process.env[key]);
process.env[key] = value;
}
t.after(async () => {
for (const [key, value] of previous) {
if (value === undefined) delete process.env[key];
else process.env[key] = value;
}
await rm(root, { recursive: true, force: true });
});
return { root, appRoot, dataDir, agentDir, resourcesDir, skillsHomeDir, stateDir, cwd };
}
test("managed runtime resolves every mutable path inside its application profile", async (t) => {
const fixture = await managedFixture(t);
const paths = getManagedRuntimePaths();
assert.equal(paths.appRoot, fixture.appRoot);
assert.equal(paths.agentDir, fixture.agentDir);
assert.ok(paths.managedSkillRoots.every((path) => isManagedPath(path)));
const cliEnv = getSkillsCliEnvironment();
assert.equal(cliEnv.HOME, fixture.skillsHomeDir);
assert.equal(cliEnv.USERPROFILE, fixture.skillsHomeDir);
assert.equal(cliEnv.XDG_STATE_HOME, fixture.stateDir);
assert.equal(cliEnv.npm_config_cache, join(fixture.dataDir, "cache", "npm"));
});
test("managed resource policy removes skills outside the application", async (t) => {
const fixture = await managedFixture(t);
const appSkill = join(fixture.resourcesDir, "skills", "inside", "SKILL.md");
const externalSkill = join(fixture.root, "outside", "SKILL.md");
await mkdir(join(appSkill, ".."), { recursive: true });
await mkdir(join(externalSkill, ".."), { recursive: true });
await writeFile(appSkill, "---\nname: inside\n---\n");
await writeFile(externalSkill, "---\nname: outside\n---\n");
const options = getAppResourceLoaderOptions();
assert.ok(options.skillsOverride);
const filtered = options.skillsOverride({
skills: [
{ filePath: appSkill },
{ filePath: externalSkill },
],
diagnostics: [
{ type: "warning", message: "inside", path: appSkill },
{ type: "warning", message: "outside", path: externalSkill },
],
});
assert.deepEqual(filtered.skills.map((skill) => skill.filePath), [appSkill]);
assert.deepEqual(filtered.diagnostics.map((diagnostic) => diagnostic.path), [appSkill]);
});
test("managed settings ignore the opened workspace's .pi settings", async (t) => {
const fixture = await managedFixture(t);
await writeFile(join(fixture.agentDir, "settings.json"), JSON.stringify({ defaultModel: "app-model" }));
await writeFile(join(fixture.cwd, ".pi", "settings.json"), JSON.stringify({ defaultModel: "workspace-model" }));
const settings = createAppSettingsManager(fixture.cwd, fixture.agentDir);
assert.equal(settings.isProjectTrusted(), false);
assert.deepEqual(settings.getProjectSettings(), {});
assert.equal(settings.getDefaultModel(), "app-model");
});