Menu
popagent
publicLatest change 43f7c6e69d8ea772bc9fb7f0a8aa53d43aa16c8e - Account for language server warmup by Ólafur Búi Ólafsson
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { resolve } from "node:path";
import { createWorkspaceTools, WORKSPACE_TOOLS } from "@mastra/core/workspace";
import { agentWorkspace } from "./workspace";
const testFile = `workspace-test-${crypto.randomUUID()}.txt`;
const workspaceRoot = resolve(
process.env.POPAGENT_WORKSPACE_ROOT ?? "workspace",
process.env.POPAGENT_DEFAULT_REPOSITORY ?? ".",
);
const filesystem = agentWorkspace.filesystem!;
const sandbox = agentWorkspace.sandbox!;
beforeAll(() => agentWorkspace.init());
afterAll(async () => {
await filesystem.deleteFile(testFile, { force: true });
await agentWorkspace.destroy();
});
describe("agentWorkspace", () => {
test("reads and writes files inside the contained workspace", async () => {
await filesystem.writeFile(testFile, "workspace file access");
expect(await filesystem.readFile(testFile, { encoding: "utf8" })).toBe("workspace file access");
expect(filesystem.basePath).toBe(workspaceRoot);
});
test("requires a fresh read before an agent overwrites a file", async () => {
await filesystem.writeFile(testFile, "original");
const tools = await createWorkspaceTools(agentWorkspace);
const readFile = tools[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]!;
const writeFile = tools[WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]!;
await expect(writeFile.execute!({
path: testFile,
content: "unreviewed overwrite",
overwrite: true,
}, {} as never)).rejects.toThrow("must read a file before writing");
await readFile.execute!({ path: testFile }, {} as never);
await writeFile.execute!({
path: testFile,
content: "reviewed overwrite",
overwrite: true,
}, {} as never);
expect(await filesystem.readFile(testFile, { encoding: "utf8" }))
.toBe("reviewed overwrite");
await expect(writeFile.execute!({
path: testFile,
content: "stale second overwrite",
overwrite: true,
}, {} as never)).rejects.toThrow("must read a file before writing");
});
test("performs semantic LSP inspection with repository-relative paths", async () => {
const tools = await createWorkspaceTools(agentWorkspace);
const inspect = tools[WORKSPACE_TOOLS.LSP.LSP_INSPECT]!;
await inspect.execute!({
path: "src/workspace.test.ts",
line: 4,
match: 'import { <<<agentWorkspace } from "./workspace";',
}, {} as never);
const result = await inspect.execute!({
path: "src/workspace.test.ts",
line: 4,
match: 'import { <<<agentWorkspace } from "./workspace";',
}, {} as never);
expect(result).toMatchObject({
hover: { value: expect.stringContaining("agentWorkspace: Workspace") },
definition: expect.arrayContaining([
expect.objectContaining({ location: expect.stringContaining("src/workspace.ts") }),
]),
});
}, 30_000);
test("instructs agents to use contained repository-relative tool paths", () => {
expect(filesystem.getInstructions?.()).toContain(
"Use repository-relative paths for every workspace tool, including LSP inspection",
);
});
test("rejects filesystem paths outside the workspace", async () => {
await expect(filesystem.readFile("../package.json")).rejects.toThrow();
});
test("executes shell commands from the workspace", async () => {
const result = await sandbox.executeCommand?.("pwd");
expect(result?.success).toBe(true);
expect(result?.stdout.trim()).toBe(workspaceRoot);
const escaped = await sandbox.executeCommand?.("sh", ["-c", "test -e ../package.json"]);
expect(escaped?.exitCode).not.toBe(0);
});
});