diff --git a/src/features/tmux-subagent/manager.test.ts b/src/features/tmux-subagent/manager.test.ts index 976871982..f252b3efe 100644 --- a/src/features/tmux-subagent/manager.test.ts +++ b/src/features/tmux-subagent/manager.test.ts @@ -226,6 +226,29 @@ describe('TmuxSessionManager', () => { // then expect(manager).toBeDefined() }) + + test('falls back to default port when serverUrl has port 0', async () => { + // given + mockIsInsideTmux.mockReturnValue(true) + const { TmuxSessionManager } = await import('./manager') + const ctx = { + ...createMockContext(), + serverUrl: new URL('http://127.0.0.1:0/'), + } + const config: TmuxConfig = { + enabled: true, + layout: 'main-vertical', + main_pane_size: 60, + main_pane_min_width: 80, + agent_pane_min_width: 40, + } + + // when + const manager = new TmuxSessionManager(ctx, config, mockTmuxDeps) + + // then + expect((manager as any).serverUrl).toBe('http://localhost:4096') + }) }) describe('onSessionCreated', () => { diff --git a/src/features/tmux-subagent/manager.ts b/src/features/tmux-subagent/manager.ts index 27909db71..ca329ac3c 100644 --- a/src/features/tmux-subagent/manager.ts +++ b/src/features/tmux-subagent/manager.ts @@ -73,10 +73,18 @@ export class TmuxSessionManager { this.tmuxConfig = tmuxConfig this.deps = deps const defaultPort = process.env.OPENCODE_PORT ?? "4096" + const fallbackUrl = `http://localhost:${defaultPort}` try { - this.serverUrl = ctx.serverUrl?.toString() ?? `http://localhost:${defaultPort}` + const raw = ctx.serverUrl?.toString() + if (raw) { + const parsed = new URL(raw) + const port = parsed.port || (parsed.protocol === 'https:' ? '443' : '80') + this.serverUrl = port === '0' ? fallbackUrl : raw + } else { + this.serverUrl = fallbackUrl + } } catch { - this.serverUrl = `http://localhost:${defaultPort}` + this.serverUrl = fallbackUrl } this.sourcePaneId = deps.getCurrentPaneId() this.pollingManager = new TmuxPollingManager(