[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,204 @@
"use strict";
const assert = require("node:assert/strict");
const { EventEmitter } = require("node:events");
const test = require("node:test");
const {
BrowserPluginRuntime,
normalizeConsoleLevel,
sanitizePluginSource,
} = require("./browserPluginRuntime.cjs");
class FakePort extends EventEmitter {
constructor() {
super();
this.sent = [];
this.transferLists = [];
}
postMessage(message, transfer = []) {
this.sent.push(message);
this.transferLists.push(transfer);
if (message.method === "plugin.initialize") {
queueMicrotask(() => this.emit("message", { data: {
jsonrpc: "2.0",
id: message.id,
result: {
pluginId: "com.example.browser-runtime",
pluginVersion: "1.0.0",
apiVersion: "0.1.0-internal",
enabledFeatures: [],
},
} }));
} else if (message.method === "plugin.activate" || message.method === "plugin.deactivate") {
queueMicrotask(() => this.emit("message", { data: {
jsonrpc: "2.0",
id: message.id,
result: null,
} }));
}
}
start() {}
close() { this.emit("close"); }
}
test("browser host waits for preload and the installed plugin RPC listener", async () => {
const contents = new EventEmitter();
let resolveLoading;
let postedPort = false;
contents.loadURL = () => new Promise((resolve) => { resolveLoading = resolve; });
contents.postMessage = (_channel, _message, ports) => { postedPort = ports.length === 1; };
contents.setWindowOpenHandler = () => {};
let webRtcPolicy;
contents.setWebRTCIPHandlingPolicy = (policy) => { webRtcPolicy = policy; };
const pluginSession = new EventEmitter();
pluginSession.protocol = { handle() {}, unhandle() {} };
pluginSession.webRequest = {
onBeforeRequest() {},
onCompleted() {},
onErrorOccurred() {},
};
pluginSession.setPermissionCheckHandler = () => {};
pluginSession.setPermissionRequestHandler = () => {};
pluginSession.setDevicePermissionHandler = () => {};
let proxyOptions;
let networkEmulation;
pluginSession.setProxy = async (options) => { proxyOptions = options; };
pluginSession.enableNetworkEmulation = (options) => { networkEmulation = options; };
let windowOptions;
class FakeWindow extends EventEmitter {
constructor(options) {
super();
windowOptions = options;
this.webContents = contents;
}
isDestroyed() { return false; }
destroy() {}
}
const port1 = new FakePort();
const port2 = new FakePort();
const onBeforeMessage = () => {};
let processReadyCalls = 0;
let sessionDisposed = false;
const runtime = new BrowserPluginRuntime({
electron: {
BrowserWindow: FakeWindow,
MessageChannelMain: class { constructor() { this.port1 = port1; this.port2 = port2; } },
session: { fromPartition: () => pluginSession },
},
protocol: {
registerSession: () => ({ dispose() { sessionDisposed = true; } }),
registerRuntime: () => ({
token: "runtime-token",
url: "netcatty-plugin://runtime-token/index.html",
dispose() {},
}),
},
plugin: {
id: "com.example.browser-runtime",
manifest: { main: { browser: "dist/index.js" } },
},
packageRoot: "/plugins/com.example.browser-runtime/1.0.0/package",
preloadPath: "/runtime/browserPreload.cjs",
handlers: {},
onBeforeMessage,
onProcessReady: () => { processReadyCalls += 1; },
});
const started = runtime.start({
pluginId: "com.example.browser-runtime",
pluginVersion: "1.0.0",
netcattyVersion: "0.0.0",
apiVersion: "0.1.0-internal",
supportedFeatures: [],
enabledFeatures: [],
environment: { locale: "en" },
}, {
getActivationEnvironment: () => ({ locale: "zh-CN", theme: "dark" }),
});
await new Promise((resolve) => setImmediate(resolve));
assert.equal(processReadyCalls, 1);
contents.emit("ipc-message", {}, "netcatty-plugin:preload-ready");
resolveLoading();
await new Promise((resolve) => setImmediate(resolve));
assert.equal(postedPort, true);
assert.equal(port1.sent.length, 0, "initialize must wait until the peer installs its RPC listener");
contents.emit("ipc-message", {}, "netcatty-plugin:runtime-connected");
const initialized = await started;
assert.equal(initialized.pluginId, "com.example.browser-runtime");
assert.equal(runtime.router.onBeforeMessage, onBeforeMessage);
assert.deepEqual(port1.sent.map((message) => message.method), ["plugin.initialize", "plugin.activate"]);
assert.deepEqual(port1.sent.find((message) => message.method === "plugin.activate").params, {
environment: { locale: "zh-CN", theme: "dark" },
});
const transferable = new ArrayBuffer(8);
runtime.router.send({ type: "transfer-test", transferable }, [transferable]);
assert.deepEqual(port1.transferLists.at(-1), [transferable]);
assert.equal(windowOptions.webPreferences.sandbox, true);
assert.equal(windowOptions.webPreferences.nodeIntegration, false);
assert.equal(windowOptions.webPreferences.contextIsolation, true);
assert.equal(proxyOptions.mode, "fixed_servers");
assert.equal(proxyOptions.proxyBypassRules, "<-loopback>");
assert.equal(webRtcPolicy, "disable_non_proxied_udp");
assert.deepEqual(networkEmulation, { offline: true });
let downloadPrevented = false;
pluginSession.emit("will-download", { preventDefault() { downloadPrevented = true; } });
assert.equal(downloadPrevented, true);
await runtime.stop();
assert.equal(sessionDisposed, true);
assert.doesNotThrow(() => port1.emit("message", { data: {
jsonrpc: "2.0",
method: "late.notification",
} }));
});
test("browser console levels and source paths are normalized without runtime tokens", () => {
assert.equal(normalizeConsoleLevel("error"), "error");
assert.equal(normalizeConsoleLevel("warning"), "warn");
assert.equal(normalizeConsoleLevel("debug"), "debug");
assert.equal(normalizeConsoleLevel(3), "error");
assert.equal(normalizeConsoleLevel(2), "warn");
assert.equal(normalizeConsoleLevel(1), "info");
assert.equal(
sanitizePluginSource("netcatty-plugin://secret-runtime-token/package/dist/index.js"),
"/package/dist/index.js",
);
});
test("aborted browser startup cannot create a window after proxy setup resumes", async () => {
let releaseProxy;
const proxyBlocked = new Promise((resolve) => { releaseProxy = resolve; });
const pluginSession = new EventEmitter();
pluginSession.protocol = { handle() {}, unhandle() {} };
pluginSession.setProxy = () => proxyBlocked;
let windows = 0;
const runtime = new BrowserPluginRuntime({
electron: {
BrowserWindow: class { constructor() { windows += 1; } },
MessageChannelMain: class {},
session: { fromPartition: () => pluginSession },
},
protocol: {
registerSession: () => ({ dispose() {} }),
registerRuntime: () => ({ token: "token", dispose() {} }),
},
plugin: {
id: "com.example.cancelled-browser",
manifest: { main: { browser: "dist/index.js" } },
},
packageRoot: "/plugins/cancelled/package",
preloadPath: "/runtime/browserPreload.cjs",
handlers: {},
});
const controller = new AbortController();
const starting = runtime.start({}, { signal: controller.signal });
await new Promise((resolve) => setImmediate(resolve));
controller.abort(new Error("cancelled"));
await runtime.stop();
releaseProxy();
await assert.rejects(starting, /cancelled/);
assert.equal(windows, 0);
});