From d303e15e63019f6f59ab663edd60ba924803a53f Mon Sep 17 00:00:00 2001 From: Minseo Lee Date: Tue, 11 Aug 2026 16:39:04 +0900 Subject: [PATCH] test(browse): update stale terminal-agent static guards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The lazy-spawn guard grepped for spawnClaude( in the message handler, but v1.44 routes both spawn triggers through maybeSpawnPty( — the guard was failing on main. - The protocol-echo guard pinned acceptedProtocol, which the duplicate- header fix removed; it now pins the no-manual-echo invariant instead. Co-Authored-By: Claude --- browse/test/terminal-agent.test.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/browse/test/terminal-agent.test.ts b/browse/test/terminal-agent.test.ts index d908052d2..450acc4e1 100644 --- a/browse/test/terminal-agent.test.ts +++ b/browse/test/terminal-agent.test.ts @@ -131,15 +131,18 @@ describe('Source-level guard: terminal-agent', () => { expect(wsHandler).toContain('validTokens.has'); }); - test('Sec-WebSocket-Protocol auth: strips gstack-pty. prefix and echoes back', () => { + test('Sec-WebSocket-Protocol auth: strips gstack-pty. prefix, no manual echo', () => { const wsHandler = AGENT_SRC.slice(AGENT_SRC.indexOf("if (url.pathname === '/ws')")); // Browsers send `Sec-WebSocket-Protocol: gstack-pty.`. The agent - // must strip the prefix before checking validTokens, AND echo the - // protocol back in the upgrade response — without the echo, the - // browser closes the connection immediately. + // must strip the prefix before checking validTokens. The protocol echo + // is Bun's job: Bun >= 1.3 auto-echoes the first offered protocol in the + // 101 response. A manual echo on top produced a DUPLICATE + // Sec-WebSocket-Protocol header, which strict clients (Chromium, python + // websockets) reject per RFC 6455 — the sidebar terminal could never + // connect. Pin the invariant: no manual echo in the upgrade call. expect(wsHandler).toContain("'gstack-pty.'"); - expect(wsHandler).toContain('Sec-WebSocket-Protocol'); - expect(wsHandler).toContain('acceptedProtocol'); + expect(wsHandler).toContain('sec-websocket-protocol'); + expect(wsHandler).not.toContain("headers: { 'Sec-WebSocket-Protocol'"); }); test('lazy spawn: claude PTY is spawned in message handler, not on upgrade', () => { @@ -152,8 +155,10 @@ describe('Source-level guard: terminal-agent', () => { ); expect(upgradeBlock).not.toContain('spawnClaude('); // Spawn must be invoked from the message handler (lazy on first byte). + // v1.44 routes both spawn triggers (explicit {type:"start"} text frame + // and the lazy binary-frame path) through the maybeSpawnPty helper. const messageHandler = AGENT_SRC.slice(AGENT_SRC.indexOf('message(ws, raw)')); - expect(messageHandler).toContain('spawnClaude('); + expect(messageHandler).toContain('maybeSpawnPty('); expect(messageHandler).toContain('!session.spawned'); });