Repository navigation
Closed
Description
Problem
Two editor-integration port parsers in packages/tui use bare Number.parseInt, which stops at the first non-digit and silently accepts malformed values as a different (valid-looking) port:
- Env port —
packages/tui/src/context/editor.ts:117-120const value = process.env.CLAUDE_CODE_SSE_PORT || process.env.OPENCODE_EDITOR_SSE_PORT const parsedPort = value ? Number.parseInt(value, 10) : undefined const port = parsedPort && Number.isInteger(parsedPort) && parsedPort > 0 && parsedPort <= 65535 ? parsedPort : undefined
- IDE lock-file port —
packages/tui/src/editor.ts:56-57(discoverEditorConnection, reading~/.claude/ide/*.lock)const port = Number.parseInt(path.basename(file, ".lock"), 10) if (!Number.isInteger(port) || port <= 0 || port > 65535) return []
Verified repro (Node, same expressions as the code)
| input | parseInt | accepted port |
|---|---|---|
8080 |
8080 | 8080 |
8080abc |
8080 | 8080 (should be rejected) |
8080.9 |
8080 | 8080 (should be rejected) |
8080abc.lock (basename) |
8080 | 8080 (should be rejected) |
8080.9.lock (basename) |
8080 | 8080 (should be rejected) |
65536 / -1 |
— | correctly rejected by the existing range check |
Why it matters
- A typo'd / copy-pasted
CLAUDE_CODE_SSE_PORTorOPENCODE_EDITOR_SSE_PORT(trailing junk, a fractional paste) does not disable the editor integration or surface an error — the TUI silently opens a WebSocket tows://127.0.0.1:8080and sends itsinitializehandshake to whatever happens to listen there. - A stray or malformed file in
~/.claude/ide/whose name merely starts with digits (e.g.8080backup.lock) is treated as a live IDE lock for port 8080 and can win discovery (score/mtime ordering), shadowing the real lock. - This is the same bare-
parseIntport bug class already fixed forOC_PORTin the restart driver (fix(cli): restart-driver passes OC_PORT to the server unvalidated — NaN, fractional, out-of-range and empty values bind the wrong port #241) — these two sites were missed.packages/tui/test/editor.test.tshas no tests at all fordiscoverEditorConnectionor the env-port parsing, so it can regress silently.
Acceptance criteria
- Both sites accept only a canonical decimal port: digits only (
/^\d+$/on the raw value / lock basename), integer in 1–65535. Anything else (8080abc,8080.9,+8080, whitespace-padded, empty) is treated as no port / no lock — same as the existing out-of-range behaviour. - Prefer one shared strict-parse helper used by both sites (they are both in
packages/tui, andcontext/editor.tsalready imports from../editor) over two divergent copies. - New unit tests in
packages/tui/test/editor.test.ts(or equivalent) covering at least: valid8080,8080abcrejected,8080.9rejected,0/65536rejected, lock basename with trailing junk rejected. - Existing tui editor tests still pass;
bun typecheckclean inpackages/tui.
Scope note
Single-repo: CLAUDE_CODE_SSE_PORT / OPENCODE_EDITOR_SSE_PORT / discoverEditorConnection occur only in developing-today/opencode (checked developing-today/code, developing-today/openchamber, dezren39/nix — no copies).
Metadata
Metadata
Assignees
Labels
No labels
Activity
docs: record the #241, #243, #246 and #235 completions in ROADMAP Done (