import test from "node:test"; import assert from "node:assert/strict"; import { buildSessionRestorePayload, isRestoredDisconnectedSession, quoteRestoreCwdForShell, resolveRestoredActiveTabId, resolveInheritedCwdIntent, resolveInteractiveTerminalCdIntent, resolveRestoreCwdIntent, sanitizeSessionRestorePayload, shouldAttemptRestoreCwd, } from "./sessionRestore.ts"; import type { TerminalSession, Workspace } from "./models.ts"; const session = (id: string, workspaceId?: string): TerminalSession => ({ id, hostId: `host-${id}`, hostLabel: `Host ${id}`, hostname: `${id}.example.test`, username: "root", status: "connected", protocol: "ssh", workspaceId, }); test("buildSessionRestorePayload stores restored sessions as disconnected and drops reuse pointers", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), reuseConnectionFromSessionId: "source" }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.equal(payload.version, 1); assert.equal(payload.savedAt, 123); assert.equal(payload.sessions[0].status, "disconnected"); assert.equal(payload.sessions[0].reuseConnectionFromSessionId, undefined); assert.equal(payload.sessions[0].restoreState, "restored-disconnected"); }); test("restore keeps the duplicate-session fresh-connection marker and sanitizes it on load", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), requireFreshConnection: true }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.equal(payload.sessions[0].requireFreshConnection, true); const restored = sanitizeSessionRestorePayload({ version: 1, savedAt: 123, activeTabId: "s1", tabOrder: ["s1"], sessions: [payload.sessions[0] as unknown as Record], }); assert.equal(restored.sessions[0].requireFreshConnection, true); const corrupted = sanitizeSessionRestorePayload({ version: 1, savedAt: 123, activeTabId: "s1", tabOrder: ["s1"], sessions: [{ ...payload.sessions[0], requireFreshConnection: "yes" } as unknown as Record], }); assert.equal(corrupted.sessions[0].requireFreshConnection, undefined); }); test("buildSessionRestorePayload excludes ephemeral-host sessions and their tabs", () => { const payload = buildSessionRestorePayload({ sessions: [ session("s1"), { ...session("s2"), ephemeralHost: true }, ], workspaces: [], tabOrder: ["s1", "s2"], activeTabId: "s2", now: 123, }); assert.deepEqual(payload.sessions.map((entry) => entry.id), ["s1"]); assert.deepEqual(payload.tabOrder, ["s1"]); assert.notEqual(payload.activeTabId, "s2"); }); test("buildSessionRestorePayload excludes silent MCP sessions and their tabs", () => { const payload = buildSessionRestorePayload({ sessions: [ session("s1"), { ...session("s2"), hiddenFromTabs: true }, ], workspaces: [], tabOrder: ["s1", "s2"], activeTabId: "s2", now: 123, }); assert.deepEqual(payload.sessions.map((entry) => entry.id), ["s1"]); assert.deepEqual(payload.tabOrder, ["s1"]); assert.notEqual(payload.activeTabId, "s2"); }); test("buildSessionRestorePayload only stores allowlisted session fields", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), terminalData: "do-not-store", reuseConnectionFromSessionId: "source", } as TerminalSession & { terminalData: string }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.deepEqual(Object.keys(payload.sessions[0]).sort(), [ "hostId", "hostLabel", "hostname", "id", "protocol", "restoreState", "status", "username", ].sort()); }); test("buildSessionRestorePayload preserves local terminal start directory", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), protocol: "local", localStartDir: "/Users/alice/project", }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.equal(payload.sessions[0].localStartDir, "/Users/alice/project"); }); test("buildSessionRestorePayload preserves a bounded plugin connection snapshot", () => { const providerId = "com.example.transport.connection"; const payload = buildSessionRestorePayload({ sessions: [{ ...session("plugin"), protocol: `plugin:${providerId}`, pluginConnection: { providerId, configuration: { endpoint: "saved.example", nested: { mode: "safe" } }, authenticationProviderId: "com.example.transport.authentication", credentialId: "credential-reference-1234", }, }], workspaces: [], tabOrder: ["plugin"], activeTabId: "plugin", now: 123, }); assert.equal(payload.sessions[0].protocol, `plugin:${providerId}`); assert.deepEqual(payload.sessions[0].pluginConnection, { providerId, configuration: { endpoint: "saved.example", nested: { mode: "safe" } }, authenticationProviderId: "com.example.transport.authentication", credentialId: "credential-reference-1234", }); }); test("buildSessionRestorePayload deeply allowlists serial config fields", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), protocol: "serial", serialConfig: { path: "/dev/tty.usbserial", baudRate: 115200, dataBits: 8, stopBits: 1, parity: "none", flowControl: "none", localEcho: true, lineMode: true, backspaceBehavior: "ctrl-h", password: "do-not-store", }, } as TerminalSession & { serialConfig: TerminalSession["serialConfig"] & { password: string } }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.deepEqual(payload.sessions[0].serialConfig, { path: "/dev/tty.usbserial", baudRate: 115200, dataBits: 8, stopBits: 1, parity: "none", flowControl: "none", localEcho: true, lineMode: true, backspaceBehavior: "ctrl-h", }); }); test("buildSessionRestorePayload preserves serial sessions with empty usernames", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), username: "", protocol: "serial", serialConfig: { path: "/dev/tty.usbserial", baudRate: 115200, }, }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.equal(payload.sessions.length, 1); assert.equal(payload.sessions[0].username, ""); assert.equal(payload.sessions[0].protocol, "serial"); }); test("buildSessionRestorePayload preserves missing Backspace behavior on legacy serial sessions", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), username: "", protocol: "serial", serialConfig: { path: "/dev/tty.usbserial", baudRate: 115200, }, }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.equal(payload.sessions[0].serialConfig?.backspaceBehavior, undefined); }); test("buildSessionRestorePayload preserves serial-only workspaces", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1", "ws-1"), username: "", protocol: "serial", serialConfig: { path: "/dev/tty.usbserial", baudRate: 115200, }, }], workspaces: [{ id: "ws-1", title: "Serial workspace", root: { id: "pane-1", type: "pane", sessionId: "s1" }, }], tabOrder: ["ws-1"], activeTabId: "ws-1", now: 123, }); assert.equal(payload.sessions.length, 1); assert.equal(payload.workspaces.length, 1); assert.equal(payload.activeTabId, "ws-1"); }); test("buildSessionRestorePayload drops startup commands from restored sessions", () => { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), startupCommand: "rm -rf /tmp/example", noAutoRun: false, }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", now: 123, }); assert.equal(payload.sessions[0].startupCommand, undefined); assert.equal(payload.sessions[0].noAutoRun, undefined); }); test("sanitizeSessionRestorePayload prunes invalid workspace panes and drops empty workspaces", () => { const workspace: Workspace = { id: "ws-1", title: "Workspace", root: { id: "split-1", type: "split", direction: "vertical", children: [ { id: "pane-1", type: "pane", sessionId: "s1" }, { id: "pane-2", type: "pane", sessionId: "missing" }, ], sizes: [0.25, 0.75], }, focusedSessionId: "missing", focusSessionOrder: ["missing", "s1"], }; const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "missing", tabOrder: ["missing", "ws-1", "s1"], sessions: [session("s1", "ws-1")], workspaces: [workspace], }); assert.equal(sanitized.sessions.length, 1); assert.equal(sanitized.workspaces.length, 1); assert.equal(sanitized.workspaces[0].root.type, "pane"); assert.equal(sanitized.workspaces[0].focusedSessionId, "s1"); assert.deepEqual(sanitized.workspaces[0].focusSessionOrder, ["s1"]); assert.deepEqual(sanitized.tabOrder, ["ws-1"]); assert.equal(sanitized.activeTabId, "ws-1"); }); test("sanitizeSessionRestorePayload preserves explicit workspace autoTitle across restore", () => { const workspace: Workspace = { id: "ws-1", title: "Workspace", // User explicitly named this workspace "Workspace"; must not be relabeled. autoTitle: false, root: { id: "pane-1", type: "pane", sessionId: "s1" }, focusedSessionId: "s1", focusSessionOrder: ["s1"], }; const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1"], sessions: [session("s1", "ws-1")], workspaces: [workspace], }); assert.equal(sanitized.workspaces.length, 1); assert.equal(sanitized.workspaces[0].autoTitle, false); }); test("generated workspace titles survive JSON restore only with a valid boolean flag", () => { const workspace: Workspace = { id: "ws-1", title: "01/02", autoTitle: false, generatedTitle: true, root: { id: "split-1", type: "split", direction: "vertical", children: [ { id: "pane-1", type: "pane", sessionId: "s1" }, { id: "pane-2", type: "pane", sessionId: "s2" }, ], }, focusedSessionId: "s1", focusSessionOrder: ["s1", "s2"], }; const payload = buildSessionRestorePayload({ sessions: [session("s1", "ws-1"), session("s2", "ws-1")], workspaces: [workspace], tabOrder: ["ws-1"], activeTabId: "ws-1", now: 123, }); const restored = sanitizeSessionRestorePayload(JSON.parse(JSON.stringify(payload))); assert.equal(restored.workspaces[0].title, "01/02"); assert.equal(restored.workspaces[0].autoTitle, false); assert.equal(restored.workspaces[0].generatedTitle, true); const malformed = sanitizeSessionRestorePayload({ ...payload, workspaces: [{ ...payload.workspaces[0], generatedTitle: "true" }], }); assert.equal(malformed.workspaces[0].generatedTitle, undefined); }); test("sanitizeSessionRestorePayload leaves legacy workspaces without an autoTitle flag", () => { const workspace: Workspace = { id: "ws-1", title: "Workspace", root: { id: "pane-1", type: "pane", sessionId: "s1" }, focusedSessionId: "s1", focusSessionOrder: ["s1"], }; const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1"], sessions: [session("s1", "ws-1")], workspaces: [workspace], }); assert.equal(sanitized.workspaces[0].autoTitle, undefined); }); test("sanitizeSessionRestorePayload drops malformed session and workspace records", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1", "s1"], sessions: [null, session("s1")], workspaces: [{ id: "ws-1" }], } as unknown); assert.deepEqual(sanitized.sessions.map((item) => item.id), ["s1"]); assert.deepEqual(sanitized.workspaces, []); assert.deepEqual(sanitized.tabOrder, ["s1"]); assert.equal(sanitized.activeTabId, "s1"); }); test("sanitizeSessionRestorePayload preserves local terminal start directory", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "s1", tabOrder: ["s1"], sessions: [{ ...session("s1"), protocol: "local", localStartDir: "/Users/alice/project", }], workspaces: [], }); assert.equal(sanitized.sessions[0].localStartDir, "/Users/alice/project"); }); test("sanitizeSessionRestorePayload enforces workspace session ownership", () => { const workspace: Workspace = { id: "ws-1", title: "Workspace", root: { id: "split-1", type: "split", direction: "horizontal", children: [ { id: "pane-1", type: "pane", sessionId: "owned" }, { id: "pane-2", type: "pane", sessionId: "standalone" }, { id: "pane-3", type: "pane", sessionId: "other-workspace" }, ], sizes: [0.2, 0.3, 0.5], }, focusedSessionId: "standalone", focusSessionOrder: ["standalone", "owned", "other-workspace"], }; const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1", "standalone", "ws-2"], sessions: [ session("owned", "ws-1"), session("standalone"), session("other-workspace", "ws-2"), ], workspaces: [ workspace, { id: "ws-2", title: "Other", root: { id: "pane-4", type: "pane", sessionId: "other-workspace" }, }, ], }); assert.equal(sanitized.workspaces[0].root.type, "pane"); assert.equal(sanitized.workspaces[0].root.sessionId, "owned"); assert.equal(sanitized.workspaces[0].focusedSessionId, "owned"); assert.deepEqual(sanitized.workspaces[0].focusSessionOrder, ["owned"]); assert.deepEqual(sanitized.tabOrder, ["ws-1", "standalone", "ws-2"]); }); test("sanitizeSessionRestorePayload drops workspace sessions missing from the restored root", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1"], sessions: [ session("s1", "ws-1"), session("s2", "ws-1"), ], workspaces: [{ id: "ws-1", title: "Workspace", root: { id: "pane-1", type: "pane", sessionId: "s1" }, focusedSessionId: "s2", focusSessionOrder: ["s2", "s1"], }], }); assert.deepEqual(sanitized.sessions.map((entry) => entry.id), ["s1"]); assert.equal(sanitized.workspaces[0].focusedSessionId, "s1"); assert.deepEqual(sanitized.workspaces[0].focusSessionOrder, ["s1"]); assert.deepEqual(sanitized.tabOrder, ["ws-1"]); }); test("sanitizeSessionRestorePayload allowlists workspace node fields", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1"], sessions: [session("s1", "ws-1"), session("s2", "ws-1")], workspaces: [{ id: "ws-1", title: "Workspace", root: { id: "split-1", type: "split", direction: "horizontal", terminalData: "do-not-store", children: [ { id: "pane-1", type: "pane", sessionId: "s1", terminalData: "do-not-store" }, { id: "pane-2", type: "pane", sessionId: "s2", secret: "do-not-store" }, ], sizes: [0.4, 0.6], }, }], }); const root = sanitized.workspaces[0].root; assert.equal("terminalData" in root, false); assert.equal(root.type, "split"); assert.equal("terminalData" in root.children[0], false); assert.equal("secret" in root.children[1], false); }); test("sanitizeSessionRestorePayload deeply allowlists unknown serial config fields", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "s1", tabOrder: ["s1"], sessions: [{ ...session("s1"), protocol: "serial", serialConfig: { path: "/dev/tty.usbserial", baudRate: 115200, dataBits: 8, stopBits: 1, parity: "none", flowControl: "none", localEcho: true, lineMode: true, backspaceBehavior: "default", secret: "do-not-store", }, }], workspaces: [], }); assert.deepEqual(sanitized.sessions[0].serialConfig, { path: "/dev/tty.usbserial", baudRate: 115200, dataBits: 8, stopBits: 1, parity: "none", flowControl: "none", localEcho: true, lineMode: true, backspaceBehavior: "default", }); }); test("sanitizeSessionRestorePayload drops invalid protocol and shell type enum values", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "s1", tabOrder: ["s1"], sessions: [{ ...session("s1"), protocol: "ftp", shellType: "bash", }], workspaces: [], }); assert.equal(sanitized.sessions[0].protocol, undefined); assert.equal(sanitized.sessions[0].shellType, undefined); }); test("sanitizeSessionRestorePayload falls back to equal split sizes when saved sizes are non-positive", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1"], sessions: [session("s1", "ws-1"), session("s2", "ws-1")], workspaces: [{ id: "ws-1", title: "Workspace", root: { id: "split-1", type: "split", direction: "horizontal", children: [ { id: "pane-1", type: "pane", sessionId: "s1" }, { id: "pane-2", type: "pane", sessionId: "s2" }, ], sizes: [-1, 2], }, }], }); assert.equal(sanitized.workspaces[0].root.type, "split"); if (sanitized.workspaces[0].root.type === "split") { assert.deepEqual(sanitized.workspaces[0].root.sizes, [0.5, 0.5]); } }); test("sanitizeSessionRestorePayload preserves split sizes when nested splits collapse", () => { const sanitized = sanitizeSessionRestorePayload({ version: 1, savedAt: 1, activeTabId: "ws-1", tabOrder: ["ws-1"], sessions: [session("s1", "ws-1"), session("s3", "ws-1")], workspaces: [{ id: "ws-1", title: "Workspace", root: { id: "root-split", type: "split", direction: "horizontal", sizes: [0.7, 0.3], children: [ { id: "left-split", type: "split", direction: "vertical", sizes: [0.4, 0.6], children: [ { id: "pane-1", type: "pane", sessionId: "s1" }, { id: "pane-missing", type: "pane", sessionId: "missing" }, ], }, { id: "pane-3", type: "pane", sessionId: "s3" }, ], }, }], }); const root = sanitized.workspaces[0].root; assert.equal(root.type, "split"); if (root.type === "split") { assert.deepEqual(root.children.map((child) => child.type === "pane" ? child.sessionId : "split"), ["s1", "s3"]); assert.deepEqual(root.sizes, [0.7, 0.3]); assert.ok(root.sizes?.every((size) => size > 0)); } }); test("resolveRestoredActiveTabId falls back to vault when no restored tab is valid", () => { assert.equal(resolveRestoredActiveTabId("missing", [], [], []), "vault"); }); test("resolveRestoredActiveTabId does not restore sftp as an active startup tab", () => { assert.equal(resolveRestoredActiveTabId("sftp", ["sftp"], [], []), "vault"); }); test("isRestoredDisconnectedSession detects only explicit restored sessions", () => { assert.equal( isRestoredDisconnectedSession({ ...session("s1"), status: "disconnected", restoreState: "restored-disconnected", }), true, ); assert.equal(isRestoredDisconnectedSession({ ...session("s1"), status: "disconnected" }), false); }); test("shouldAttemptRestoreCwd allows restored local and unix ssh sessions only when enabled", () => { assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...session("s1"), status: "disconnected", restoreState: "restored-disconnected", lastCwd: "/srv/app" }, isNetworkDevice: false, }), true); assert.equal(shouldAttemptRestoreCwd({ enabled: false, session: { ...session("s1"), status: "disconnected", restoreState: "restored-disconnected", lastCwd: "/srv/app" }, isNetworkDevice: false, }), false); }); test("restored fresh SSH duplicates retain metadata without injecting the previous target directory", () => { for (const protocol of ["ssh", undefined, "local"] as const) { const payload = buildSessionRestorePayload({ sessions: [{ ...session("s1"), protocol, requireFreshConnection: true, lastCwd: "/srv/old-target" }], workspaces: [], tabOrder: ["s1"], activeTabId: "s1", }); const restored = sanitizeSessionRestorePayload(JSON.parse(JSON.stringify(payload))).sessions[0]; assert.equal(restored.requireFreshConnection, true); assert.equal(restored.lastCwd, "/srv/old-target"); const intent = resolveRestoreCwdIntent({ enabled: true, session: restored, isNetworkDevice: false }); if (protocol === "local") assert.equal(intent?.command, "cd -- '/srv/old-target'"); else assert.equal(intent, null, "a fresh bastion login must await target selection"); } }); test("shouldAttemptRestoreCwd skips ineligible protocols and network devices", () => { const base = { ...session("s1"), status: "disconnected" as const, restoreState: "restored-disconnected" as const, lastCwd: "/srv/app" }; assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, protocol: "telnet" }, isNetworkDevice: false }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, protocol: "serial" }, isNetworkDevice: false }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, protocol: "ssh" }, isNetworkDevice: true }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, protocol: "ssh", moshEnabled: true }, isNetworkDevice: false }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, protocol: "ssh", etEnabled: true }, isNetworkDevice: false }), false); }); test("shouldAttemptRestoreCwd skips local Windows-like shell types", () => { const base = { ...session("s1"), status: "disconnected" as const, restoreState: "restored-disconnected" as const, protocol: "local" as const, lastCwd: "/srv/app", }; assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, shellType: "posix" }, isNetworkDevice: false }), true); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, shellType: "fish" }, isNetworkDevice: false }), true); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, shellType: "powershell" }, isNetworkDevice: false }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, shellType: "cmd" }, isNetworkDevice: false }), false); }); test("shouldAttemptRestoreCwd skips missing and windows-like cwd values", () => { const base = { ...session("s1"), status: "disconnected" as const, restoreState: "restored-disconnected" as const }; assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base }, isNetworkDevice: false }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, lastCwd: "C:\\Users\\alice" }, isNetworkDevice: false }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, lastCwd: "relative/path" }, isNetworkDevice: false }), false); assert.equal(shouldAttemptRestoreCwd({ enabled: true, session: { ...base, lastCwd: "~alice/project" }, isNetworkDevice: false }), false); }); test("quoteRestoreCwdForShell treats cwd as shell data", () => { assert.equal(quoteRestoreCwdForShell("/srv/app"), "'/srv/app'"); assert.equal(quoteRestoreCwdForShell("/srv/app dir"), "'/srv/app dir'"); assert.equal(quoteRestoreCwdForShell("/tmp/it's ok; $(rm -rf ~)"), "'/tmp/it'\\''s ok; $(rm -rf ~)'"); }); test("resolveInteractiveTerminalCdIntent quotes path-only cd without session transport checks", () => { assert.deepEqual(resolveInteractiveTerminalCdIntent("/srv/app dir"), { cwd: "/srv/app dir", command: "cd -- '/srv/app dir'", }); assert.deepEqual(resolveInteractiveTerminalCdIntent("/srv/project "), { cwd: "/srv/project ", command: "cd -- '/srv/project '", }); assert.equal(resolveInteractiveTerminalCdIntent("C:\\Users\\alice"), null); }); test("resolveInteractiveTerminalCdIntent rejects control bytes that readline would interpret", () => { // Tab / ESC / Ctrl-U / newline / DEL must not be typed into an interactive PTY. assert.equal(resolveInteractiveTerminalCdIntent("/srv/app\tdir"), null); assert.equal(resolveInteractiveTerminalCdIntent("/srv/app\u001bdir"), null); assert.equal(resolveInteractiveTerminalCdIntent("/srv/app\u0015dir"), null); assert.equal(resolveInteractiveTerminalCdIntent("/srv/app\ndir"), null); assert.equal(resolveInteractiveTerminalCdIntent("/srv/app\u007fdir"), null); // Trailing spaces remain valid POSIX names and must still quote exactly. assert.deepEqual(resolveInteractiveTerminalCdIntent("/srv/project "), { cwd: "/srv/project ", command: "cd -- '/srv/project '", }); }); test("resolveRestoreCwdIntent captures a one-shot restore command", () => { assert.deepEqual(resolveRestoreCwdIntent({ enabled: true, session: { ...session("s1"), status: "disconnected", restoreState: "restored-disconnected", lastCwd: "/srv/app dir" }, isNetworkDevice: false, }), { cwd: "/srv/app dir", command: "cd -- '/srv/app dir'", }); }); test("resolveRestoreCwdIntent does not emit POSIX cd for local Windows-like shells", () => { assert.equal(resolveRestoreCwdIntent({ enabled: true, session: { ...session("s1"), status: "disconnected", restoreState: "restored-disconnected", protocol: "local", shellType: "powershell", lastCwd: "/srv/app", }, isNetworkDevice: false, }), null); }); test("resolveRestoreCwdIntent keeps home-relative cwd expandable", () => { assert.deepEqual(resolveRestoreCwdIntent({ enabled: true, session: { ...session("s1"), status: "disconnected", restoreState: "restored-disconnected", lastCwd: "~/project dir" }, isNetworkDevice: false, }), { cwd: "~/project dir", command: "cd -- ~/'project dir'", }); assert.deepEqual(resolveRestoreCwdIntent({ enabled: true, session: { ...session("s1"), status: "disconnected", restoreState: "restored-disconnected", lastCwd: "~" }, isNetworkDevice: false, }), { cwd: "~", command: "cd -- ~", }); }); test("resolveInheritedCwdIntent: ssh clone gets a cd command", () => { const intent = resolveInheritedCwdIntent({ session: { protocol: "ssh", shellType: "posix", cwd: "/var/log" }, isNetworkDevice: false, }); assert.deepEqual(intent, { cwd: "/var/log", command: "cd -- '/var/log'" }); }); test("resolveInheritedCwdIntent: fires without restoreState or enabled flag", () => { const intent = resolveInheritedCwdIntent({ session: { protocol: "ssh", cwd: "/home/me/proj" }, isNetworkDevice: false, }); assert.equal(intent?.command, "cd -- '/home/me/proj'"); }); test("resolveInheritedCwdIntent: skips mosh/et and network devices and bad paths", () => { assert.equal(resolveInheritedCwdIntent({ session: { protocol: "ssh", etEnabled: true, cwd: "/x" }, isNetworkDevice: false }), null); assert.equal(resolveInheritedCwdIntent({ session: { protocol: "ssh", cwd: "/x" }, isNetworkDevice: true }), null); assert.equal(resolveInheritedCwdIntent({ session: { protocol: "ssh", cwd: "C:\\Users" }, isNetworkDevice: false }), null); assert.equal(resolveInheritedCwdIntent({ session: { protocol: "ssh", cwd: " " }, isNetworkDevice: false }), null); }); test("resolveInheritedCwdIntent: skips windows local shells", () => { assert.equal(resolveInheritedCwdIntent({ session: { protocol: "local", shellType: "powershell", cwd: "/x" }, isNetworkDevice: false }), null); });