feat(v0.3): M6 — new tab opens in the active tab's directory

- title-util.cwdFromOsc7: parse cwd from OSC 7 (file:// URL); 4 unit tests
- terminal-session: register OSC 7 handler → cwd getter; opts.cwd → sent in the
  attach frame on a fresh session
- protocol/types: ClientMessage attach.cwd (absolute path); validated
- session/manager/server: thread cwd → createSession spawn cwd (defaults homeDir)
- tabs: '+' (newTab) opens in the active tab's reported cwd, falls back to home
- Verified: server attach.cwd spawns there; cd /private/tmp → + → new tab pwd is
  /private/tmp. 212 tests green.
This commit is contained in:
Yaojia Wang
2026-06-18 07:14:52 +02:00
parent f79f14b89d
commit 87e11734d8
9 changed files with 97 additions and 13 deletions

View File

@@ -82,11 +82,13 @@ export function createSessionManager(cfg: Config): SessionManager {
sessionId: string | null,
dims: Dims,
now: number,
cwd?: string,
): Session {
// ── Case 1: null → always create a new session ──────────────────────────
if (sessionId === null) {
// M4: createSession may throw (spawn failure). Do NOT catch here.
const session = createSession(cfg, dims, now, onSessionExit);
// M6: cwd (if given) is the spawn directory for "new tab here".
const session = createSession(cfg, dims, now, onSessionExit, undefined, cwd);
const kicked = attachWs(session, ws);
if (kicked !== null) kicked.close();
sessions = new Map(sessions).set(session.meta.id, session);

View File

@@ -61,6 +61,8 @@ export function createSession(
// H1: pass an existing id to RE-ATTACH to a surviving tmux session (e.g. after
// a server restart). Default = a fresh id for a brand-new session.
id: string = randomUUID(),
// M6: spawn directory for a new session ("new tab here"); defaults to homeDir.
cwd?: string,
): Session {
// The id is injected into the shell env so Claude Code hooks know which tab an
// event belongs to ($WEBTERM_SESSION) and where to POST ($WEBTERM_HOOK_URL, H2).
@@ -76,7 +78,7 @@ export function createSession(
name: 'xterm-256color',
cols: dims.cols,
rows: dims.rows,
cwd: cfg.homeDir,
cwd: cwd ?? cfg.homeDir,
env: {
...process.env,
WEBTERM_SESSION: id,