fix(agent): stabilize large tool results
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { mkdtemp, mkdir, rm, symlink } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
|
||||
import {
|
||||
canAutoApprovePermission,
|
||||
@@ -9,10 +12,100 @@ describe("permission approval policy", () => {
|
||||
it.each([
|
||||
"show_chart",
|
||||
"web_search",
|
||||
"skill",
|
||||
])("allows low-risk permission %s", (permission) => {
|
||||
expect(canAutoApprovePermission(permission)).toBe(true);
|
||||
});
|
||||
|
||||
it("allows structured searches within the workspace", () => {
|
||||
const workspaceRoot = process.cwd();
|
||||
const context = {
|
||||
workspaceRoot,
|
||||
metadata: { path: join(workspaceRoot, "src"), include: "*.ts" },
|
||||
patterns: ["*.ts"],
|
||||
};
|
||||
expect(canAutoApprovePermission("glob", context)).toBe(true);
|
||||
expect(canAutoApprovePermission("grep", context)).toBe(true);
|
||||
});
|
||||
|
||||
it("allows a glob with an explicit safe prefix from the workspace root", () => {
|
||||
expect(
|
||||
canAutoApprovePermission("glob", {
|
||||
workspaceRoot: process.cwd(),
|
||||
metadata: { path: process.cwd(), pattern: "src/**/*.ts" },
|
||||
patterns: ["src/**/*.ts"],
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ metadata: { path: dirname(process.cwd()) }, patterns: ["*"] },
|
||||
{ metadata: { path: join(process.cwd(), ".local.env") }, patterns: ["*"] },
|
||||
{ metadata: { path: join(process.cwd(), "data") }, patterns: ["*"] },
|
||||
{ metadata: { path: join(process.cwd(), "src") }, patterns: ["../logs/**"] },
|
||||
{ metadata: { path: process.cwd() }, patterns: ["**/*.env"] },
|
||||
{ metadata: { path: process.cwd() }, patterns: ["**/*"] },
|
||||
{ metadata: { path: join(process.cwd(), "src") }, patterns: [".[e]nv"] },
|
||||
])("keeps protected or external searches interactive", (request) => {
|
||||
expect(
|
||||
canAutoApprovePermission("glob", {
|
||||
workspaceRoot: process.cwd(),
|
||||
...request,
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps grep from the workspace root interactive", () => {
|
||||
expect(
|
||||
canAutoApprovePermission("grep", {
|
||||
workspaceRoot: process.cwd(),
|
||||
metadata: { path: process.cwd(), include: "*.ts" },
|
||||
patterns: ["secret"],
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects a workspace symlink that resolves outside the workspace", async () => {
|
||||
const workspaceRoot = await mkdtemp(join(tmpdir(), "permission-workspace-"));
|
||||
const externalRoot = await mkdtemp(join(tmpdir(), "permission-external-"));
|
||||
try {
|
||||
await mkdir(join(externalRoot, "src"));
|
||||
const linkedPath = join(workspaceRoot, "linked");
|
||||
await symlink(join(externalRoot, "src"), linkedPath, "dir");
|
||||
|
||||
expect(
|
||||
canAutoApprovePermission("grep", {
|
||||
workspaceRoot,
|
||||
metadata: { path: linkedPath, include: "*.ts" },
|
||||
patterns: ["secret"],
|
||||
}),
|
||||
).toBe(false);
|
||||
} finally {
|
||||
await Promise.all([
|
||||
rm(workspaceRoot, { force: true, recursive: true }),
|
||||
rm(externalRoot, { force: true, recursive: true }),
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects protected descendants below an otherwise safe search root", async () => {
|
||||
const workspaceRoot = await mkdtemp(join(tmpdir(), "permission-descendant-"));
|
||||
try {
|
||||
const sourceRoot = join(workspaceRoot, "src");
|
||||
await mkdir(join(sourceRoot, "data"), { recursive: true });
|
||||
|
||||
expect(
|
||||
canAutoApprovePermission("grep", {
|
||||
workspaceRoot,
|
||||
metadata: { path: sourceRoot, include: "*.ts" },
|
||||
patterns: ["secret"],
|
||||
}),
|
||||
).toBe(false);
|
||||
} finally {
|
||||
await rm(workspaceRoot, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
it.each([
|
||||
"bash",
|
||||
"edit",
|
||||
|
||||
Reference in New Issue
Block a user