first commit

This commit is contained in:
douboer
2026-03-21 18:57:10 +08:00
commit c49aa1a5e9
570 changed files with 107167 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
import { describe, expect, it } from "vitest";
const {
DEFAULT_TERMINAL_RESUME_MINUTES,
MAX_TERMINAL_RESUME_MINUTES,
buildTerminalSessionSnapshot,
isTerminalSessionAiHighlighted,
isTerminalSessionConnecting,
isTerminalSessionHighlighted,
normalizeCodexSandboxMode,
normalizeTerminalResumeMinutes,
normalizeTerminalSessionSnapshot,
resolveTerminalResumeGraceMs
} = require("./terminalSessionState");
describe("terminalSessionState", () => {
it("收敛后台保活分钟数到合法区间", () => {
expect(normalizeTerminalResumeMinutes(undefined)).toBe(DEFAULT_TERMINAL_RESUME_MINUTES);
expect(normalizeTerminalResumeMinutes(0)).toBe(1);
expect(normalizeTerminalResumeMinutes(MAX_TERMINAL_RESUME_MINUTES + 10)).toBe(
MAX_TERMINAL_RESUME_MINUTES
);
});
it("根据设置生成毫秒级续接窗口", () => {
expect(resolveTerminalResumeGraceMs({ backgroundSessionKeepAliveMinutes: 15 })).toBe(15 * 60 * 1000);
});
it("保留未过期的可续接快照", () => {
const now = 1_700_000_000_000;
const snapshot = buildTerminalSessionSnapshot(
{
serverId: "srv-1",
serverLabel: "server-1",
sessionId: "mini-1",
sessionKey: "mini-key-1",
status: "resumable",
activeAiProvider: "codex",
codexSandboxMode: "danger-full-access",
resumeGraceMs: 15 * 60 * 1000
},
now
);
expect(snapshot).toBeTruthy();
expect(snapshot && snapshot.codexSandboxMode).toBe("danger-full-access");
expect(normalizeTerminalSessionSnapshot(snapshot, now + 1000)).toEqual(snapshot);
expect(normalizeTerminalSessionSnapshot(snapshot, now + 15 * 60 * 1000 + 1)).toBeNull();
});
it("仅在 Codex 前台态下保留 sandbox并收敛脏值", () => {
const now = 1_700_000_000_000;
expect(normalizeCodexSandboxMode("danger-full-access")).toBe("danger-full-access");
expect(normalizeCodexSandboxMode("invalid")).toBe("workspace-write");
expect(normalizeCodexSandboxMode("")).toBe("");
const codexSnapshot = buildTerminalSessionSnapshot(
{
serverId: "srv-codex",
sessionId: "mini-codex",
sessionKey: "mini-key-codex",
status: "connected",
activeAiProvider: "codex",
codexSandboxMode: "invalid",
resumeGraceMs: 15 * 60 * 1000
},
now
);
const copilotSnapshot = buildTerminalSessionSnapshot(
{
serverId: "srv-copilot",
sessionId: "mini-copilot",
sessionKey: "mini-key-copilot",
status: "connected",
activeAiProvider: "copilot",
codexSandboxMode: "danger-full-access",
resumeGraceMs: 15 * 60 * 1000
},
now
);
expect(codexSnapshot && codexSnapshot.codexSandboxMode).toBe("workspace-write");
expect(copilotSnapshot && copilotSnapshot.codexSandboxMode).toBe("");
});
it("区分高亮态与连接中态", () => {
const now = 1_700_000_000_000;
const resumable = buildTerminalSessionSnapshot(
{
serverId: "srv-2",
sessionId: "mini-2",
sessionKey: "mini-key-2",
status: "resumable",
activeAiProvider: "copilot",
resumeGraceMs: 15 * 60 * 1000
},
now
);
const connecting = buildTerminalSessionSnapshot(
{
serverId: "srv-3",
sessionId: "mini-3",
sessionKey: "mini-key-3",
status: "connecting",
activeAiProvider: "invalid",
resumeGraceMs: 15 * 60 * 1000
},
now
);
expect(isTerminalSessionHighlighted(resumable, "srv-2", now)).toBe(true);
expect(isTerminalSessionConnecting(resumable, "srv-2", now)).toBe(false);
expect(isTerminalSessionConnecting(connecting, "srv-3", now)).toBe(true);
expect(isTerminalSessionHighlighted(connecting, "srv-3", now)).toBe(false);
expect(connecting && connecting.activeAiProvider).toBe("");
});
it("仅在目标服务器存在 AI 前台态时点亮 AI 按钮", () => {
const now = 1_700_000_000_000;
const aiResumable = buildTerminalSessionSnapshot(
{
serverId: "srv-ai",
sessionId: "mini-ai",
sessionKey: "mini-key-ai",
status: "resumable",
activeAiProvider: "copilot",
resumeGraceMs: 15 * 60 * 1000
},
now
);
const plainConnected = buildTerminalSessionSnapshot(
{
serverId: "srv-shell",
sessionId: "mini-shell",
sessionKey: "mini-key-shell",
status: "connected",
activeAiProvider: "",
resumeGraceMs: 15 * 60 * 1000
},
now
);
expect(isTerminalSessionAiHighlighted(aiResumable, "srv-ai", now)).toBe(true);
expect(isTerminalSessionAiHighlighted(aiResumable, "srv-other", now)).toBe(false);
expect(isTerminalSessionAiHighlighted(plainConnected, "srv-shell", now)).toBe(false);
expect(isTerminalSessionAiHighlighted(null, "srv-ai", now)).toBe(false);
});
});