diff --git a/src/main/ports/advertised-url-watcher.test.ts b/src/main/ports/advertised-url-watcher.test.ts index 3d9078b1613..443b2d4dd74 100644 --- a/src/main/ports/advertised-url-watcher.test.ts +++ b/src/main/ports/advertised-url-watcher.test.ts @@ -123,6 +123,18 @@ describe('AdvertisedUrlWatcher.ingest', () => { expect(watcher.lookup(WORKTREE, 3001)?.origin).toBe('https://local.getmontecarlo.com:3001') }) + it('does not scan buffered PTY text until a line break arrives', () => { + const watcher = bindFresh() + const charCodeAtSpy = vi.spyOn(String.prototype, 'charCodeAt') + watcher.ingest(PTY, ' Network: https://local.getmontecarlo') + const charCodeAtCalls = charCodeAtSpy.mock.calls.length + charCodeAtSpy.mockRestore() + + expect(charCodeAtCalls).toBe(0) + watcher.ingest(PTY, '.com:3001/\n') + expect(watcher.lookup(WORKTREE, 3001)?.origin).toBe('https://local.getmontecarlo.com:3001') + }) + it('reassembles an ANSI escape split across two chunks', () => { const watcher = bindFresh() watcher.ingest(PTY, '\x1b[32mhttps://example.com:3001/\x1b') diff --git a/src/main/ports/advertised-url-watcher.ts b/src/main/ports/advertised-url-watcher.ts index 3eb4d6f05b2..6e3b5a5f1a3 100644 --- a/src/main/ports/advertised-url-watcher.ts +++ b/src/main/ports/advertised-url-watcher.ts @@ -82,10 +82,14 @@ class PtyBuffer { * and including the last newline). Whatever follows the last newline stays * buffered so that a URL or ANSI sequence split across chunks survives. */ ingest(chunk: string): string { + const chunkHasLineBreak = chunk.includes('\n') || chunk.includes('\r') this.raw += chunk if (this.raw.length > PER_PTY_BUFFER_LIMIT) { this.raw = this.raw.slice(-PER_PTY_BUFFER_LIMIT) } + if (!chunkHasLineBreak) { + return '' + } const lastNewline = lastLineBreak(this.raw) if (lastNewline === -1) { return ''