[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,116 @@
import assert from "node:assert/strict";
import test from "node:test";
import { readFileSync } from "node:fs";
import {
isTerminalCloseGenerationCurrent,
resolveConnectionLogCapturePayload,
resolveHibernateSnapshotCapturePayload,
scheduleTerminalCloseTeardown,
} from "./terminalCloseCapture.ts";
test("resolveConnectionLogCapturePayload returns null when finalize produces empty data", () => {
assert.equal(
resolveConnectionLogCapturePayload(() => ""),
null,
);
});
test("resolveConnectionLogCapturePayload returns buffered connection log data", () => {
assert.deepEqual(
resolveConnectionLogCapturePayload(() => "line one\r\nline two"),
{ data: "line one\r\nline two", source: "connection-log" },
);
});
test("resolveHibernateSnapshotCapturePayload prefers combined snapshot fields", () => {
assert.deepEqual(
resolveHibernateSnapshotCapturePayload({
snapshot: "full snapshot",
viewportSnapshot: "viewport",
scrollbackSnapshot: "scrollback",
alternateScreen: false,
}),
{ data: "full snapshot", source: "hibernate-serialize" },
);
assert.deepEqual(
resolveHibernateSnapshotCapturePayload({
snapshot: "",
viewportSnapshot: "viewport",
scrollbackSnapshot: "scrollback",
alternateScreen: false,
}),
{ data: "scrollbackviewport", source: "hibernate-serialize" },
);
});
test("scheduleTerminalCloseTeardown runs teardown asynchronously", async () => {
let ran = false;
scheduleTerminalCloseTeardown(() => {
ran = true;
});
assert.equal(ran, false);
await new Promise<void>((resolve) => {
setTimeout(resolve, 0);
});
assert.equal(ran, true);
});
test("isTerminalCloseGenerationCurrent rejects stale close generations", () => {
assert.equal(isTerminalCloseGenerationCurrent(1, 1), true);
assert.equal(isTerminalCloseGenerationCurrent(1, 2), false);
});
test("terminal close fully drains pending output before finalizing capture", () => {
const source = readFileSync(
new URL("../useTerminalEffects.ts", import.meta.url),
"utf8",
);
const cleanupStart = source.indexOf("return () => {", source.indexOf("void boot();"));
const flushIndex = source.indexOf("await flushPendingTerminalWritesBeforeHibernate(term)", cleanupStart);
const incompleteIndex = source.indexOf("if (!flushed)", flushIndex);
const finalizeIndex = source.indexOf("resolveConnectionLogCapturePayload(finalizeTerminalLogData)", cleanupStart);
assert.ok(cleanupStart >= 0);
assert.ok(flushIndex > cleanupStart);
assert.ok(incompleteIndex > flushIndex);
assert.ok(finalizeIndex > flushIndex);
});
test("never-connected StrictMode cleanup sync-disposes its owned xterm runtime", () => {
const source = readFileSync(
new URL("../useTerminalEffects.ts", import.meta.url),
"utf8",
);
const cleanupStart = source.indexOf("return () => {", source.indexOf("void boot();"));
assert.ok(cleanupStart >= 0);
const neverConnectedClose = source.indexOf(
"if (!hasConnectedRef.current)",
cleanupStart,
);
assert.ok(neverConnectedClose > cleanupStart);
const branch = source.slice(
neverConnectedClose,
source.indexOf("const persistCloseCapture", neverConnectedClose),
);
assert.match(branch, /if \(!attachExistingSession\)/);
assert.match(branch, /disposeOwnedRuntime\(\);/);
assert.match(branch, /return;/);
assert.ok(
branch.indexOf("disposeOwnedRuntime();") < branch.indexOf("return;"),
"orphaned StrictMode xterm must be disposed before leaving cleanup",
);
});
test("createXTermRuntime clears orphaned .xterm children before open", () => {
const source = readFileSync(
new URL("./createXTermRuntime.ts", import.meta.url),
"utf8",
);
const openAt = source.indexOf("term.open(ctx.container);");
assert.ok(openAt > 0);
const beforeOpen = source.slice(Math.max(0, openAt - 350), openAt);
assert.match(beforeOpen, /querySelectorAll\(":scope > \.xterm"\)/);
assert.match(beforeOpen, /orphan\.remove\(\)/);
});