[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,142 @@
import test from "node:test";
import assert from "node:assert/strict";
import {
DEFAULT_THEME,
getContrastRatio,
buildAppThemeCssVars,
getHslTokenRelativeLuminance,
resolveReadableForegroundForHsl,
resolveThemeAccentForeground,
migrateIncomingTerminalFontId,
} from "./settingsStateDefaults.ts";
import { TERMINAL_FONT_AUTO } from "../../infrastructure/config/fonts.ts";
import { STORAGE_KEY_TERM_FONT_FAMILY } from "../../infrastructure/config/storageKeys.ts";
import type { UiThemeTokens } from "../../infrastructure/config/uiThemes.ts";
function installMemoryLocalStorage(): Map<string, string> {
const store = new Map<string, string>();
(globalThis as { localStorage?: unknown }).localStorage = {
getItem: (k: string) => (store.has(k) ? store.get(k)! : null),
setItem: (k: string, v: string) => void store.set(k, v),
removeItem: (k: string) => void store.delete(k),
clear: () => store.clear(),
};
return store;
}
test("fresh installs follow the operating system color scheme by default", () => {
assert.equal(DEFAULT_THEME, "system");
});
test("migrateIncomingTerminalFontId rewrites deprecated ids to the auto sentinel, not menlo", () => {
// menlo would put Windows/Linux upgrade users back into the #1647 path,
// and a concrete id would leak across OSes via sync; auto resolves per device.
const store = installMemoryLocalStorage();
try {
assert.equal(migrateIncomingTerminalFontId("pingfang-sc"), TERMINAL_FONT_AUTO);
// The rewrite is persisted as the platform-neutral sentinel, never a concrete id.
assert.equal(store.get(STORAGE_KEY_TERM_FONT_FAMILY), TERMINAL_FONT_AUTO);
assert.equal(migrateIncomingTerminalFontId("microsoft-yahei"), TERMINAL_FONT_AUTO);
} finally {
delete (globalThis as { localStorage?: unknown }).localStorage;
}
});
test("migrateIncomingTerminalFontId leaves valid ids and empty values untouched", () => {
assert.equal(migrateIncomingTerminalFontId("jetbrains-mono"), "jetbrains-mono");
assert.equal(migrateIncomingTerminalFontId(TERMINAL_FONT_AUTO), TERMINAL_FONT_AUTO);
assert.equal(migrateIncomingTerminalFontId(""), null);
assert.equal(migrateIncomingTerminalFontId(null), null);
});
test("readable foreground picks white text for dark accent colors", () => {
assert.equal(resolveReadableForegroundForHsl("270 70% 45%"), "0 0% 100%");
});
test("readable foreground picks black text for light accent colors", () => {
assert.equal(resolveReadableForegroundForHsl("48 95% 72%"), "0 0% 0%");
});
test("computed contrast chooses the stronger black or white foreground", () => {
const purpleLuminance = getHslTokenRelativeLuminance("270 70% 45%");
assert.equal(typeof purpleLuminance, "number");
assert.ok(getContrastRatio(1, purpleLuminance as number) > getContrastRatio(0, purpleLuminance as number));
const yellowLuminance = getHslTokenRelativeLuminance("48 95% 72%");
assert.equal(typeof yellowLuminance, "number");
assert.ok(getContrastRatio(0, yellowLuminance as number) > getContrastRatio(1, yellowLuminance as number));
});
test("theme accent foreground uses the computed color for preset accent buttons", () => {
const tokens: UiThemeTokens = {
background: "0 0% 100%",
foreground: "222 47% 12%",
card: "0 0% 100%",
cardForeground: "222 47% 12%",
popover: "0 0% 100%",
popoverForeground: "222 47% 12%",
primary: "270 70% 45%",
primaryForeground: "0 0% 0%",
secondary: "220 12% 95%",
secondaryForeground: "222 47% 12%",
muted: "220 12% 95%",
mutedForeground: "220 10% 45%",
accent: "270 70% 45%",
accentForeground: "0 0% 0%",
destructive: "0 70% 50%",
destructiveForeground: "0 0% 100%",
border: "220 12% 88%",
input: "220 12% 88%",
ring: "270 70% 45%",
};
assert.equal(resolveThemeAccentForeground(tokens, "theme", "48 95% 72%"), "0 0% 100%");
assert.equal(resolveThemeAccentForeground(tokens, "custom", "48 95% 72%"), "0 0% 0%");
});
test("app surface theme vars isolate non-terminal pages from active terminal chrome", () => {
const tokens: UiThemeTokens = {
background: "0 0% 100%",
foreground: "222 47% 12%",
card: "0 0% 100%",
cardForeground: "222 47% 12%",
popover: "0 0% 100%",
popoverForeground: "222 47% 12%",
primary: "270 70% 45%",
primaryForeground: "0 0% 0%",
secondary: "220 12% 95%",
secondaryForeground: "222 47% 12%",
muted: "220 12% 95%",
mutedForeground: "220 10% 45%",
accent: "270 70% 45%",
accentForeground: "0 0% 0%",
destructive: "0 70% 50%",
destructiveForeground: "0 0% 100%",
border: "220 12% 88%",
input: "220 12% 88%",
ring: "270 70% 45%",
};
assert.deepEqual(buildAppThemeCssVars(tokens, "theme", "48 95% 72%"), {
"--background": "0 0% 100%",
"--foreground": "222 47% 12%",
"--card": "0 0% 100%",
"--card-foreground": "222 47% 12%",
"--popover": "0 0% 100%",
"--popover-foreground": "222 47% 12%",
"--primary": "270 70% 45%",
"--primary-foreground": "0 0% 100%",
"--secondary": "220 12% 95%",
"--secondary-foreground": "222 47% 12%",
"--muted": "220 12% 95%",
"--muted-foreground": "220 10% 45%",
"--accent": "270 70% 45%",
"--accent-foreground": "0 0% 100%",
"--destructive": "0 70% 50%",
"--destructive-foreground": "0 0% 100%",
"--border": "220 12% 88%",
"--input": "220 12% 88%",
"--ring": "270 70% 45%",
});
});