[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled

This commit is contained in:
2026-09-13 18:24:01 +08:00
commit 3c72efcb7f
3255 changed files with 907009 additions and 0 deletions

View File

@@ -0,0 +1,392 @@
"use strict";
const assert = require("node:assert/strict");
const fs = require("node:fs");
const fsp = require("node:fs/promises");
const os = require("node:os");
const path = require("node:path");
const test = require("node:test");
const { PluginFilesystemBroker, MAX_FILESYSTEM_BYTES } = require("./filesystemBroker.cjs");
const { RPC_ERRORS } = require("./rpcRouter.cjs");
function createRoot(context) {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "netcatty-plugin-filesystem-"));
context.after(() => fs.rmSync(root, { recursive: true, force: true }));
return fs.realpathSync(root);
}
function runtimeContext(authorization) {
return {
runtimeId: "runtime-1",
authorization,
assertActive: async () => {},
};
}
async function openTestDirectoryHandle(directoryPath) {
const stats = await fsp.stat(directoryPath);
const directory = await fsp.opendir(directoryPath);
return {
stat: async () => stats,
read: () => directory.read(),
close: async () => {
try { await directory.close(); }
catch (error) { if (error?.code !== "ERR_DIR_CLOSED") throw error; }
},
};
}
test("filesystem broker uses canonical authorization for bounded read, write, stat, and list", async (context) => {
const root = createRoot(context);
const source = path.join(root, "source.txt");
const target = path.join(root, "target.txt");
await Promise.all([
fsp.writeFile(source, "hello"),
fsp.writeFile(target, "prior"),
]);
const charges = [];
const broker = new PluginFilesystemBroker({
quotaManager: { chargeBytes: (...args) => charges.push(args) },
openDirectoryHandle: openTestDirectoryHandle,
});
const readAuthorization = await broker.describeReadAuthorization({ path: source });
assert.deepEqual(readAuthorization.resourceKinds, ["exact"]);
assert.deepEqual(
await broker.readFile({ path: source }, runtimeContext(readAuthorization)),
{ data: "hello" },
);
assert.equal((await broker.stat({ path: source }, runtimeContext(readAuthorization))).kind, "file");
const writeAuthorization = await broker.describeWriteAuthorization({
path: target,
data: "world",
overwrite: true,
});
assert.deepEqual(writeAuthorization.resourceKinds, ["exact"]);
await broker.writeFile({
path: target,
data: "world",
overwrite: true,
}, runtimeContext(writeAuthorization));
assert.equal(await fsp.readFile(target, "utf8"), "world");
const overwriteAuthorization = await broker.describeWriteAuthorization({
path: target,
data: "short",
overwrite: true,
});
await broker.writeFile(
{ path: target, data: "short", overwrite: true },
runtimeContext(overwriteAuthorization),
);
assert.equal(await fsp.readFile(target, "utf8"), "short");
const listAuthorization = await broker.describeReadAuthorization({ path: root }, "directory");
assert.deepEqual(listAuthorization.resourceKinds, ["directory"]);
const list = await broker.readDirectory({ path: root }, runtimeContext(listAuthorization));
assert.deepEqual(list.entries.map(({ name }) => name), ["source.txt", "target.txt"]);
assert.deepEqual(charges, [
["runtime-1", "filesystem", 5],
["runtime-1", "filesystem", 5],
["runtime-1", "filesystem", 5],
]);
});
test("filesystem authorization removes trailing directory separators before permission", async (context) => {
const root = createRoot(context);
const requestedPath = `${root}${path.sep}`;
await fsp.writeFile(path.join(root, "entry.txt"), "entry");
const broker = new PluginFilesystemBroker({ openDirectoryHandle: openTestDirectoryHandle });
const statAuthorization = broker.describeReadAuthorization({ path: requestedPath }, "exact");
const listAuthorization = broker.describeReadAuthorization({ path: requestedPath }, "directory");
assert.deepEqual(statAuthorization.resources, [root]);
assert.deepEqual(listAuthorization.resources, [root]);
assert.equal(
(await broker.stat({ path: requestedPath }, runtimeContext(statAuthorization))).kind,
"directory",
);
assert.deepEqual(
(await broker.readDirectory({ path: requestedPath }, runtimeContext(listAuthorization))).entries,
[{ name: "entry.txt", kind: "file" }],
);
});
test("filesystem write quota is enforced before mutating the target", async (context) => {
const root = createRoot(context);
const target = path.join(root, "target.txt");
await fsp.writeFile(target, "original");
const broker = new PluginFilesystemBroker({
quotaManager: { chargeBytes: () => { throw new Error("quota denied"); } },
});
const authorization = await broker.describeWriteAuthorization({
path: target,
data: "blocked",
overwrite: true,
});
await assert.rejects(
broker.writeFile({
path: target,
data: "blocked",
overwrite: true,
}, runtimeContext(authorization)),
/quota denied/,
);
assert.equal(await fsp.readFile(target, "utf8"), "original");
});
test("filesystem authorization descriptors never probe path existence before permission", async (context) => {
const root = createRoot(context);
const missing = path.join(root, "missing.txt");
let filesystemCalls = 0;
const broker = new PluginFilesystemBroker({
fileSystem: new Proxy({}, {
get() {
return async () => {
filesystemCalls += 1;
throw new Error("filesystem must not be queried while describing authorization");
};
},
}),
});
assert.deepEqual(broker.describeReadAuthorization({ path: missing }), {
permission: "filesystem.read",
resources: [missing],
resourceKinds: ["exact"],
reason: `Read ${missing}`,
operationId: `filesystem.read:${missing}`,
});
assert.deepEqual(broker.describeReadAuthorization({ path: root }, "directory").resourceKinds, ["directory"]);
assert.deepEqual(broker.describeWriteAuthorization({
path: missing,
data: "blocked",
overwrite: true,
}).resources, [missing]);
await assert.rejects(
broker.readFile({ path: missing }, runtimeContext(null)),
(error) => error.code === RPC_ERRORS.permissionDenied,
);
await assert.rejects(
broker.writeFile(
{ path: missing, data: "blocked", overwrite: true },
runtimeContext(null),
),
(error) => error.code === RPC_ERRORS.permissionDenied,
);
assert.equal(filesystemCalls, 0);
});
test("filesystem writes reject missing targets without opening or creating them", async (context) => {
const root = createRoot(context);
const target = path.join(root, "missing.txt");
let openCalls = 0;
const broker = new PluginFilesystemBroker({
fileSystem: {
...fsp,
async open(...args) {
openCalls += 1;
return fsp.open(...args);
},
},
});
const authorization = broker.describeWriteAuthorization({
path: target,
data: "blocked",
overwrite: true,
});
await assert.rejects(
broker.writeFile(
{ path: target, data: "blocked", overwrite: true },
runtimeContext(authorization),
),
(error) => error.code === RPC_ERRORS.failedPrecondition,
);
assert.equal(openCalls, 0);
await assert.rejects(fsp.stat(target), (error) => error.code === "ENOENT");
});
test("filesystem path swaps after authorization fail closed", async (context) => {
const root = createRoot(context);
const first = path.join(root, "first.txt");
const second = path.join(root, "second.txt");
const link = path.join(root, "selected.txt");
await Promise.all([fsp.writeFile(first, "first"), fsp.writeFile(second, "second")]);
await fsp.symlink(first, link);
const broker = new PluginFilesystemBroker();
const authorization = await broker.describeReadAuthorization({ path: link });
await fsp.unlink(link);
await fsp.symlink(second, link);
await assert.rejects(
broker.readFile({ path: link }, runtimeContext(authorization)),
(error) => error.code === RPC_ERRORS.permissionDenied,
);
});
test("filesystem directory replacement between authorization and open fails closed", async (context) => {
const root = createRoot(context);
const selected = path.join(root, "selected");
const replacement = path.join(root, "replacement");
const original = path.join(root, "original");
await Promise.all([
fsp.mkdir(selected),
fsp.mkdir(replacement),
]);
await Promise.all([
fsp.writeFile(path.join(selected, "allowed.txt"), "allowed"),
fsp.writeFile(path.join(replacement, "secret.txt"), "secret"),
]);
let swapped = false;
const broker = new PluginFilesystemBroker({
openDirectoryHandle: async (directoryPath) => {
if (!swapped) {
swapped = true;
await fsp.rename(selected, original);
await fsp.rename(replacement, selected);
}
return openTestDirectoryHandle(directoryPath);
},
});
const authorization = await broker.describeReadAuthorization({ path: selected }, "directory");
await assert.rejects(
broker.readDirectory({ path: selected }, runtimeContext(authorization)),
(error) => error.code === RPC_ERRORS.permissionDenied,
);
});
test("filesystem directory listing fails closed without a handle-bound adapter", async (context) => {
const root = createRoot(context);
await fsp.writeFile(path.join(root, "entry.txt"), "entry");
const broker = new PluginFilesystemBroker();
const authorization = broker.describeReadAuthorization({ path: root }, "directory");
await assert.rejects(
broker.readDirectory({ path: root }, runtimeContext(authorization)),
(error) => error.code === RPC_ERRORS.unsupported,
);
});
test("filesystem writes recheck runtime activity immediately before mutation", async (context) => {
const root = createRoot(context);
const target = path.join(root, "target.txt");
await fsp.writeFile(target, "original");
let active = true;
let armed = false;
const broker = new PluginFilesystemBroker({
fileSystem: {
...fsp,
async stat(filePath, options) {
const stats = await fsp.stat(filePath, options);
if (armed) active = false;
return stats;
},
},
});
const authorization = await broker.describeWriteAuthorization({
path: target,
data: "replacement",
overwrite: true,
});
armed = true;
await assert.rejects(broker.writeFile({
path: target,
data: "replacement",
overwrite: true,
}, {
...runtimeContext(authorization),
assertActive: async () => { if (!active) throw new Error("runtime stopped"); },
}), /runtime stopped/);
assert.equal(await fsp.readFile(target, "utf8"), "original");
});
test("filesystem reads reject a replacement inode opened after authorization", async (context) => {
const root = createRoot(context);
const target = path.join(root, "selected.txt");
const original = path.join(root, "original.txt");
const replacement = path.join(root, "replacement.txt");
await Promise.all([
fsp.writeFile(target, "allowed"),
fsp.writeFile(replacement, "secret"),
]);
let swapped = false;
const broker = new PluginFilesystemBroker({
fileSystem: {
...fsp,
async open(filePath, flags, mode) {
if (!swapped) {
swapped = true;
await fsp.rename(target, original);
await fsp.rename(replacement, target);
}
return fsp.open(filePath, flags, mode);
},
},
});
const authorization = broker.describeReadAuthorization({ path: target });
await assert.rejects(
broker.readFile({ path: target }, runtimeContext(authorization)),
(error) => error.code === RPC_ERRORS.permissionDenied,
);
});
test("filesystem writes reject a replacement inode opened after authorization", async (context) => {
const root = createRoot(context);
const target = path.join(root, "selected.txt");
const original = path.join(root, "original.txt");
const replacement = path.join(root, "replacement.txt");
await Promise.all([
fsp.writeFile(target, "allowed"),
fsp.writeFile(replacement, "secret"),
]);
let swapped = false;
const broker = new PluginFilesystemBroker({
fileSystem: {
...fsp,
async open(filePath, flags, mode) {
if (!swapped) {
swapped = true;
await fsp.rename(target, original);
await fsp.rename(replacement, target);
}
return fsp.open(filePath, flags, mode);
},
},
});
const authorization = broker.describeWriteAuthorization({
path: target,
data: "overwritten",
overwrite: true,
});
await assert.rejects(
broker.writeFile({
path: target,
data: "overwritten",
overwrite: true,
}, runtimeContext(authorization)),
(error) => error.code === RPC_ERRORS.permissionDenied,
);
assert.equal(await fsp.readFile(original, "utf8"), "allowed");
assert.equal(await fsp.readFile(target, "utf8"), "secret");
});
test("filesystem broker rejects oversized and non-canonical payloads", async (context) => {
const root = createRoot(context);
const target = path.join(root, "target.bin");
const broker = new PluginFilesystemBroker();
assert.throws(() => broker.validateWrite({
path: target,
data: "YQ",
encoding: "base64",
}), /not canonical/);
assert.throws(() => broker.validateWrite({
path: target,
data: "a".repeat(MAX_FILESYSTEM_BYTES + 1),
}), (error) => error.code === RPC_ERRORS.resourceExhausted);
assert.throws(() => broker.validateRead({ path: `${target}\0suffix` }), /absolute/);
await fsp.writeFile(target, "12345");
const authorization = await broker.describeReadAuthorization({ path: target, maxBytes: 4 });
await assert.rejects(
broker.readFile({ path: target, maxBytes: 4 }, runtimeContext(authorization)),
(error) => error.code === RPC_ERRORS.resourceExhausted,
);
});