Context
During local pilot testing on plotlink-ows@1.0.34, a newly-created Untitled cartoon story opens the terminal reconnect overlay. Both Resume Session and Start Fresh fail because the OWS server crashes as soon as PTY output is relayed.
Server log:
/Users/cho/Projects/plotlink-ows/app/routes/terminal.ts:353
if (ws.readyState === WebSocket.OPEN) {
^
ReferenceError: WebSocket is not defined
at <anonymous> (.../app/routes/terminal.ts:353:27)
Root Cause
app/routes/terminal.ts runs in Node/Hono, not the browser. It receives a raw WebSocket object from the server upgrade path, but WebSocket.OPEN is a browser global and is not available in this runtime. The code should not reference the browser WebSocket constructor in server code.
Current problematic code:
if (ws.readyState === WebSocket.OPEN) {
ws.send(data);
}
Required Fix
- Replace server-side
WebSocket.OPEN usage with a runtime-safe check.
- Prefer a local constant such as
const WS_OPEN = 1 or a helper like isSocketOpen(ws).
- Audit
app/routes/terminal.ts for any other browser-only WebSocket globals.
- Add/adjust a regression test for
attachTerminalWs or the terminal command helper if practical.
- Verify both buttons work:
Resume Session reconnects using stored session id when valid.
Start Fresh kills the old PTY/session state and spawns a fresh Claude session without crashing.
Notes
The reconnect overlay itself can be legitimate for _new_* sessions because ~/.plotlink-ows/data/terminal-sessions.json currently contains stored untitled session ids. The immediate blocker is that reconnect/fresh actions crash the server before Claude can start.
Verification
npm run typecheck
npm test -- --run app/routes/terminal.test.ts
- Manual local check with
npm run app:dev, then create a new story and click Start Fresh from the reconnect overlay.
Context
During local pilot testing on
plotlink-ows@1.0.34, a newly-createdUntitledcartoon story opens the terminal reconnect overlay. BothResume SessionandStart Freshfail because the OWS server crashes as soon as PTY output is relayed.Server log:
Root Cause
app/routes/terminal.tsruns in Node/Hono, not the browser. It receives a raw WebSocket object from the server upgrade path, butWebSocket.OPENis a browser global and is not available in this runtime. The code should not reference the browserWebSocketconstructor in server code.Current problematic code:
Required Fix
WebSocket.OPENusage with a runtime-safe check.const WS_OPEN = 1or a helper likeisSocketOpen(ws).app/routes/terminal.tsfor any other browser-only WebSocket globals.attachTerminalWsor the terminal command helper if practical.Resume Sessionreconnects using stored session id when valid.Start Freshkills the old PTY/session state and spawns a fresh Claude session without crashing.Notes
The reconnect overlay itself can be legitimate for
_new_*sessions because~/.plotlink-ows/data/terminal-sessions.jsoncurrently contains stored untitled session ids. The immediate blocker is that reconnect/fresh actions crash the server before Claude can start.Verification
npm run typechecknpm test -- --run app/routes/terminal.test.tsnpm run app:dev, then create a new story and clickStart Freshfrom the reconnect overlay.