revert the chat tabs and panes work, back to one conversation
Andre asked for zero, not another fix on top. Reverts ec4f06a..7726c9f — the ten commits from "tabs and panes" onward: the tab bar and pane splitting, tab renaming and its page title, the per-server directory picker, the render-loop fix, pane transcript resolution, the send queue, the two socket fixes from the other session, the pane-socket notes, and my own socket-set change from tonight. He is rebuilding from here. Deliberately KEPT:dc6b623, "talk to two officers at once from one browser". That was a separate ask that predates the tabs one, and the multi-server client, the server chips and the connections store stand on their own without panes. Reverting it too is one more command if that was the intent. Collateral, worth naming:cb7ab55carried an unrelated MusicPlayerHost change alongside its socket instrumentation, so that came out with it. Reverts, not a reset — every one of these is pushed and a second session is live in this repo. Typecheck clean. 600 pass, 2 fail — cliamp path-escape and the pty transport test, both failing identically before this and unrelated to chat. What is NOT explained by this revert: the browser symptoms tonight. The server was verified good throughout — two real turns streamed back through the public URL on both models, and the full 2,281-message history came through nginx intact. Whatever the client fault is, it is still unfound, and the pre-tabs code is where it now has to be looked for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,74 +0,0 @@
|
||||
# Multi-pane chat: where it stands, and the one open bug
|
||||
|
||||
Written 2026-08-10 at the end of a long session, so the next one starts from evidence instead of
|
||||
re-deriving it.
|
||||
|
||||
## The open bug
|
||||
|
||||
**A pane pointed at a REMOTE server shows `Disconnected` and never gets a reply.** The pane opens, lists
|
||||
and reads that server's conversations fine (HTTP with the API key works). Sending produces nothing.
|
||||
|
||||
Console, repeatedly:
|
||||
|
||||
```
|
||||
WebSocket connection to 'wss://officer.pastilhas.dev/api/chat/ws?token=ofk_…' failed:
|
||||
WebSocket is closed before the connection is established.
|
||||
```
|
||||
|
||||
The same message also appears for the LOCAL pane's `ws://localhost:9010/...`, yet the local pane works
|
||||
and shows connected. So the message alone is not the bug — something closes the remote one and it never
|
||||
comes back.
|
||||
|
||||
## Ruled out, each by direct test — do not re-test these
|
||||
|
||||
- **The server.** `wss://officer.pastilhas.dev/api/chat/ws?token=<the same ofk_ key>` opens on the first
|
||||
try from outside the browser. Tested twice: with no `Origin` header, and with
|
||||
`Origin: http://localhost:9010` (what the browser sends). Both `OPEN`.
|
||||
- **The key.** Same key, works over HTTP for `/chat/sessions`, and opens the socket above.
|
||||
- **Websocket auth not understanding API keys.** `upgradeWs` in `server.tsx` uses `resolveAuthToken`, the
|
||||
same resolver as the HTTP doors, and comments say so explicitly. `chat` is an `execution` capability
|
||||
and the owner passes `isWsProviderAllowed`.
|
||||
- **Officer being stale on alpha.** Pulled and restarted; the failure persists.
|
||||
- **Send being dropped.** Fixed in `243bd04` — `useChatWebSocket.send` used to `return` silently when the
|
||||
socket was not `OPEN`. It now queues and flushes on open. That fix is real and worth keeping, but it
|
||||
did not resolve this: a socket that never opens never flushes.
|
||||
|
||||
## Where to look next
|
||||
|
||||
`src/workspaces/hooks/src/useChatWebSocket.ts`, and specifically what happens with SEVERAL instances
|
||||
mounted at once — one per pane.
|
||||
|
||||
The handlers look individually correct: `close` returns early when `socketRef.current !== socket`, the
|
||||
effect depends on `[url]` alone, and `isCleaningUpRef` is reset on mount. What has NOT been established
|
||||
is how those interact across three simultaneous instances plus React's dev StrictMode double-invoke,
|
||||
which creates, closes and recreates every socket on mount.
|
||||
|
||||
Concrete things to try, cheapest first:
|
||||
|
||||
1. **Instrument before theorising.** Log `url`, `readyState` and instance identity on every create,
|
||||
open, close and retry. The console message says a close arrived during CONNECTING; it does not say
|
||||
who called it. That is the whole question and it is one log line away.
|
||||
2. **Check whether the effect re-runs.** `url` is a string, so it should be stable — but
|
||||
`chatSocketUrl(serverId, localStorage.getItem('BEARER_TOKEN'))` is recomputed every render, and if
|
||||
anything makes `serverId` flip (say, a pane re-resolving its target) the URL changes and the socket
|
||||
is torn down mid-handshake, forever.
|
||||
3. **Suspect the transcript resolver in `ChatPane`.** It calls `onTargetChange` on success, which
|
||||
rewrites the tab state, which produces a new `target` object for every pane in that tab. If that ever
|
||||
loops, every pane's socket is rebuilt on every pass and none survives the handshake.
|
||||
4. **Try one pane pointed at the remote server, alone.** If it connects, the bug is about multiplicity
|
||||
rather than about the remote server, which would be the single most useful fact to have.
|
||||
|
||||
## What works, so it is not re-litigated
|
||||
|
||||
- Adding a second server by URL + `ofk_` key, verified against `/api/auth/me` before storing.
|
||||
- Per-pane server chips; the list, the directory picker and the transcript all follow the pane's server.
|
||||
- Tabs, splitting to three panes, closing, renaming a tab, and the tab name winning the page title.
|
||||
- Reading a remote conversation end to end.
|
||||
|
||||
## Setup facts worth not rediscovering
|
||||
|
||||
- Andre's Mac key lives in agent memory. Alpha needs its own; the one in the console above is alpha's.
|
||||
- `bun dev` on the Mac serves a STALE bundle whenever a new file is added to a workspace package — the
|
||||
symptom is `X is not a function` for an export that plainly exists. Restart it; do not debug it.
|
||||
- The Mac is `https://macbook.pastilhas.dev` through NPM on alpha (`100.64.0.1` → Mac `100.64.0.9:9010`),
|
||||
and the cert is valid under strict TLS.
|
||||
Reference in New Issue
Block a user