feat(webui): the Assistant page holds up to three threads from any organization side by side, Side by side removed (#1873) #1970

Merged
jason.woltje merged 4 commits from sp6-threads into refactor 2026-11-15 11:26:14 +00:00
Owner

What changes

  • #/assistant is a system address. The page holds up to three chat threads side by side, from any organization. Each pane reads, sends and updates on its own.
  • The open set lives in the address: #/assistant?open=<org>:<uuid>,<org>:<uuid>&show=<org>:<uuid>. A reload or a pasted address restores it. A bare #/assistant reopens the last set from localStorage.
  • Each pane header shows the thread title, the organization chip, the project chip when the thread has one, and close.
  • A send in a pane goes to that pane's organization, never the one opened last.
  • A stopped organization is named at the top as not read. Its pane says so, stops reading and keeps an unsent draft. The other panes keep working.
  • At 390 one pane shows at a time, with a tab strip.
  • "Open thread" lists threads by organization and can start a new thread in an organization whose config lets this Console send there.
  • Side by side is removed: panes.js, panes.css and its test are deleted, the sidebar item is gone, and #/side-by-side lands on #/assistant.

How

  • New assistant.js (MosaicAssistant.mount/unmount/refresh/hasDraft) and assistant.css.
  • chat.js becomes a MosaicChat.pane(org) factory. The full chat view is one instance of it, so there is one renderer.
  • display.js system(hash) adds /assistant. Unsent pane drafts count for the organization-switch and Console-restart guards.
  • No new server route. serve.mjs serves assistant.* in place of panes.*.

Tests

  • New tests/assistant-threads-browser.test.mjs, 10 tests, written red first.
  • Lane gate on 789e2bcdd: 188 webui test files, 1472 pass, 0 fail, 4 skipped (org-quick-live, needs a live scratch instance).
  • Lead check on 789e2bcdd: 95 pass, 0 fail over the changed test files plus the system Tasks, Agents, Inbox, single-pane and org-switch files.
  • Not tested: the held-draft fixes in 02df2a3a2 (notes 1 and 2) and 789e2bcdd. The fixture cannot turn a composer off while its bus stays healthy. They were checked by reading the code.

Review

Four rounds, each a fresh claude-opus-5-5 reviewer. Round 1 asked for changes, fixed in b98240496. Rounds 2, 3 and 4 approved; their P3 notes were fixed in 02df2a3a2 and 789e2bcdd or are listed below.

Left for later

  • Project thread links and "open in chat" still open the per-organization chat view, not a pane.
  • Unused pane and idPrefix parameters remain in projects.js and workspace.js.
  • No unread badge on the Assistant sidebar item.
  • Pane drafts are dropped on same-organization navigation and on pane close.
  • A held draft can be lost if the bus drops while other text is typed.
  • The held preview cuts on code points, and a comment at assistant.js:254 is stale.
## What changes - `#/assistant` is a system address. The page holds up to three chat threads side by side, from any organization. Each pane reads, sends and updates on its own. - The open set lives in the address: `#/assistant?open=<org>:<uuid>,<org>:<uuid>&show=<org>:<uuid>`. A reload or a pasted address restores it. A bare `#/assistant` reopens the last set from `localStorage`. - Each pane header shows the thread title, the organization chip, the project chip when the thread has one, and close. - A send in a pane goes to that pane's organization, never the one opened last. - A stopped organization is named at the top as not read. Its pane says so, stops reading and keeps an unsent draft. The other panes keep working. - At 390 one pane shows at a time, with a tab strip. - "Open thread" lists threads by organization and can start a new thread in an organization whose config lets this Console send there. - Side by side is removed: `panes.js`, `panes.css` and its test are deleted, the sidebar item is gone, and `#/side-by-side` lands on `#/assistant`. ## How - New `assistant.js` (`MosaicAssistant.mount/unmount/refresh/hasDraft`) and `assistant.css`. - `chat.js` becomes a `MosaicChat.pane(org)` factory. The full chat view is one instance of it, so there is one renderer. - `display.js` `system(hash)` adds `/assistant`. Unsent pane drafts count for the organization-switch and Console-restart guards. - No new server route. `serve.mjs` serves `assistant.*` in place of `panes.*`. ## Tests - New `tests/assistant-threads-browser.test.mjs`, 10 tests, written red first. - Lane gate on 789e2bcdd: 188 webui test files, 1472 pass, 0 fail, 4 skipped (`org-quick-live`, needs a live scratch instance). - Lead check on 789e2bcdd: 95 pass, 0 fail over the changed test files plus the system Tasks, Agents, Inbox, single-pane and org-switch files. - Not tested: the held-draft fixes in 02df2a3a2 (notes 1 and 2) and 789e2bcdd. The fixture cannot turn a composer off while its bus stays healthy. They were checked by reading the code. ## Review Four rounds, each a fresh claude-opus-5-5 reviewer. Round 1 asked for changes, fixed in b98240496. Rounds 2, 3 and 4 approved; their P3 notes were fixed in 02df2a3a2 and 789e2bcdd or are listed below. ## Left for later - Project thread links and "open in chat" still open the per-organization chat view, not a pane. - Unused `pane` and `idPrefix` parameters remain in `projects.js` and `workspace.js`. - No unread badge on the Assistant sidebar item. - Pane drafts are dropped on same-organization navigation and on pane close. - A held draft can be lost if the bus drops while other text is typed. - The held preview cuts on code points, and a comment at `assistant.js:254` is stale.
jason.woltje added 4 commits 2026-11-15 11:26:01 +00:00
The sidebar Assistant opens one system page, #/assistant. Each pane is the
chat thread view of its own organization: it reads, sends and updates
through that organization's routes, with a header carrying the title, the
organization chip, the project chip and a close control. "Open thread"
lists the threads of every answering organization, grouped by organization,
and starts a new thread in a chosen one. The open set and its order live in
the hash (open=org:id,...&show=org:id), validated on read. A stopped
organization is named at the top and in its own pane; the other panes keep
working. At 390 one pane shows with a tab strip.

Side by side is removed (panes.js, panes.css and its test); its old address
lands on the Assistant page.
A pane whose organization's bus is stopped or unavailable no longer polls or offers Refresh; it says
nothing is read until the bus starts again, holds any typed draft, and restores it untouched when the
bus returns. Unsent pane drafts now count for the organization-switch and Console-restart guards.
The Assistant sidebar item drops the Messages unread badge. "Start thread" is the primary action.
Tests cover the stopped pane's draft, a reply arriving with no refresh, and an uppercase show id.
The held draft goes back only into an empty composer and is cleared only once it is in it. A thread
that reads without a composer shows the held message in the pane's line. Only a stopped or
unavailable bus says the message comes back when the pane reads again.
jason.woltje merged commit 789e2bcdd4 into refactor 2026-11-15 11:26:14 +00:00
Sign in to join this conversation.