Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269import assert from "node:assert/strict";import { test } from "node:test";import * as Effect from "effect/Effect";import { build } from "esbuild";
const bundle = await build({ entryPoints: ["worker/skill-script-workspace.ts"], bundle: true, write: false, format: "esm", platform: "node",});const { SkillScriptWorkspace } = await import( `data:text/javascript;base64,${Buffer.from(bundle.outputFiles[0].text).toString("base64")}`);
// Trusted grant fixture: actual permission revisions/declared requirements are// covered by skill-permissions.test.mjs. Here every host boundary is observable.function authority( permissions = ["execute", "workspaceRead", "workspaceWrite"],) { const state = { active: true, permissions: new Set(permissions), calls: [], before: null, after: null, onCheck: null, }; const check = (kind) => { state.calls.push(kind); state.onCheck?.(kind); if (!state.active || !state.permissions.has(kind)) throw new Error("Permission denied"); }; const grant = { check, use: (kind, operation) => Effect.gen(function* () { yield* Effect.try({ try: () => check(kind), catch: (error) => error }); if (state.before) yield* Effect.promise(state.before); const value = yield* operation(); state.after?.(); yield* Effect.try({ try: () => check(kind), catch: (error) => error }); return value; }), }; return { state, grant };}
test("workspace exposes only selected files, local directories and bounded glob syntax", async () => { const { grant } = authority(); const input = [ { path: "notes/a.txt", content: "é" }, { path: "root.md", content: "selected" }, ]; const workspace = new SkillScriptWorkspace(grant, input); input[0].content = "caller mutation"; assert.equal(await workspace.readFile("notes/a.txt"), "é"); assert.equal(await workspace.readFile("other.txt"), null); assert.deepEqual(await workspace.stat("notes/a.txt"), { type: "file", size: 2, }); assert.deepEqual(await workspace.stat("notes"), { type: "directory" }); assert.deepEqual(await workspace.stat(""), { type: "directory" }); assert.deepEqual(await workspace.stat("."), { type: "directory" }); assert.equal(await workspace.stat("missing"), null); assert.deepEqual(await workspace.readDir(""), [ { name: "notes", type: "directory" }, { name: "root.md", type: "file" }, ]); assert.deepEqual(await workspace.readDir("notes"), [ { name: "a.txt", type: "file" }, ]); assert.deepEqual(await workspace.readDir("."), await workspace.readDir("")); assert.deepEqual(await workspace.readDir("missing"), []); assert.deepEqual(await workspace.glob("*"), ["root.md"]); assert.deepEqual(await workspace.glob("notes/*.txt"), ["notes/a.txt"]); assert.deepEqual(await workspace.glob("notes/a.txt"), ["notes/a.txt"]); assert.deepEqual(await workspace.glob("other.txt"), []); assert.deepEqual(workspace.snapshot(), []); await workspace.writeFile("notes/a.txt", "edited"); await workspace.writeFile("result.txt", "new"); const output = workspace.snapshot(); assert.deepEqual(output, [ { path: "notes/a.txt", content: "edited" }, { path: "result.txt", content: "new" }, ]); output[0].content = "output mutation"; assert.equal(await workspace.readFile("notes/a.txt"), "edited");});
test("workspace checks read admission and each read, listing, stat and write permission", async () => { const { grant, state } = authority(["execute"]); assert.throws( () => new SkillScriptWorkspace(grant, [{ path: "input", content: "secret" }]), /Permission denied/, ); const workspace = new SkillScriptWorkspace(grant); for (const operation of [ () => workspace.readFile("input"), () => workspace.stat(""), () => workspace.readDir(""), () => workspace.glob("*"), ]) { await assert.rejects(operation(), /Permission denied/); assert.equal(state.calls.at(-1), "workspaceRead"); } await assert.rejects( workspace.writeFile("out", "denied"), /Permission denied/, ); assert.equal(state.calls.at(-1), "workspaceWrite"); state.permissions.add("workspaceWrite"); await workspace.writeFile("out", "write-only"); assert.deepEqual(workspace.snapshot(), [ { path: "out", content: "write-only" }, ]); await assert.rejects(workspace.readFile("out"), /Permission denied/);});
test("workspace rejects traversal, absolute, hidden and unsupported glob paths at every boundary", async () => { const { grant } = authority(); const workspace = new SkillScriptWorkspace(grant); for (const path of [ "", "/etc/passwd", "../secret", "a/../b", "a/./b", ".env", "a/.hidden", "a//b", "a/", "a\\b", "C:/file", "a\0b", "a b", "a%2fb", "é", "a".repeat(241), ]) { assert.throws( () => new SkillScriptWorkspace(grant, [{ path, content: "x" }]), /Workspace paths/, ); await assert.rejects(workspace.readFile(path), /Workspace paths/); await assert.rejects(workspace.writeFile(path, "x"), /Workspace paths/); if (path) { await assert.rejects(workspace.stat(path), /Workspace paths/); await assert.rejects(workspace.readDir(path), /Workspace paths/); } } for (const pattern of [ "**", "a/**/b", "*.{js,ts}", "file?", "[ab]", "../*", ".*", ]) { await assert.rejects(workspace.glob(pattern)); } await workspace.writeFile("a", "file"); await assert.rejects(workspace.writeFile("a/b", "nested"), /overlap/); await workspace.writeFile("nested/b", "file"); await assert.rejects(workspace.writeFile("nested", "parent"), /overlap/);});
test("workspace enforces UTF-8 file, aggregate and count limits, including concurrent writes", async () => { const { grant } = authority(); assert.throws( () => new SkillScriptWorkspace( grant, Array.from({ length: 9 }, (_, i) => ({ path: `f${i}`, content: "" })), ), /8 input files/, ); assert.throws( () => new SkillScriptWorkspace(grant, [ { path: "big", content: "é".repeat(8193) }, ]), /16 KiB/, ); assert.throws( () => new SkillScriptWorkspace( grant, Array.from({ length: 5 }, (_, i) => ({ path: `f${i}`, content: "a".repeat(16384), })), ), /64 KiB/, ); const workspace = new SkillScriptWorkspace(grant); const countResults = await Promise.allSettled( Array.from({ length: 9 }, (_, i) => workspace.writeFile(`f${i}`, "")), ); assert.equal( countResults.filter((entry) => entry.status === "fulfilled").length, 8, ); assert.equal(workspace.snapshot().length, 8); await workspace.writeFile("f0", "overwrite at capacity"); assert.equal(workspace.snapshot().length, 8); const bytes = new SkillScriptWorkspace(grant); const byteResults = await Promise.allSettled( Array.from({ length: 5 }, (_, i) => bytes.writeFile(`f${i}`, "é".repeat(8192)), ), ); assert.equal( byteResults.filter((entry) => entry.status === "fulfilled").length, 4, ); assert.equal( bytes .snapshot() .reduce((sum, file) => sum + Buffer.byteLength(file.content), 0), 65536, ); await assert.rejects(bytes.writeFile("extra", "x"), /64 KiB/); await bytes.writeFile("f0", ""); await bytes.writeFile("extra", "x"); await assert.rejects(bytes.writeFile("too-big", "a".repeat(16385)), /16 KiB/);});
test("workspace rejects cancellation/revocation before commit and before returning host data", async () => { const { grant, state } = authority(); const workspace = new SkillScriptWorkspace(grant, [ { path: "input", content: "private" }, ]); state.before = async () => { state.active = false; }; await assert.rejects( workspace.writeFile("late", "must not commit"), /Permission denied/, ); state.active = true; state.before = null; assert.equal(await workspace.readFile("late"), null); state.after = () => { state.active = false; }; await assert.rejects(workspace.readFile("input"), /Permission denied/); assert.throws(() => workspace.snapshot(), /Permission denied/); state.active = true; state.after = null; let checks = 0; state.onCheck = (kind) => { if (kind === "workspaceWrite" && ++checks === 3) state.active = false; }; await assert.rejects( workspace.writeFile("input", "revoked at commit"), /Permission denied/, ); state.active = true; state.onCheck = null; assert.equal(await workspace.readFile("input"), "private"); assert.deepEqual(workspace.snapshot(), []);});