# muse.ai Chat Panel & Sidechat DOM Reference
> Originally captured live via CDP on `opm` browser (warp-opm netns, CDP 9440).
> **Re-verified 2026-10-04** via CDP `Runtime.evaluate` on three nodes:
> `opm` (warp-opm, CDP 9440), `muse` (warp-muse, CDP 9410), `pip` (warp-pip, CDP 9420).
> Page: `https://muse.ai/`. Sections marked โ verified 2026-10-04,
> ๐ง corrected, ๐ new since original capture.
> This is a development reference for reliable automation of the chat navigation panel
> and sidechat creation. Prefer these selectors over text matching.
---
## 1. Chat Panel Switcher โ (with corrections)
**Selector:** `[data-testid="hatch-chat-switcher-trigger"]`
The button that toggles the chat navigation panel open/closed.
```html
```
**Key facts (โ verified 2026-10-04 on opm/muse/pip):**
| Property | Value |
|---|---|
| Tag | `BUTTON` |
| In DOM on `https://muse.ai/` or `/thread/` | โ Yes (both panel states) |
| In DOM on `/thread/new` stripped state | ๐ง **NO โ completely absent** (see ยง8) |
| Visible | Yes (`offsetParent !== null`) |
| Position | Top-left: `x:84, y:12, w:82, h:36` (exact on opm) |
| `aria-expanded` | **Not set** (`null`) โ do NOT use for state detection |
| `data-pel-click` | `chat_threads_open_click` |
| `data-slot` | `popover-anchor` |
| Visible text | ๐ง **Active chat title, NOT static "Chats".** Shows e.g. `Heartbeat check for job scheduler`, `646 pip cross-operator coordination chat`; reads `Chats` only when main chat is active |
| Screen-reader text | `Open chat and side chats` (+ `Unread chats` when unread exist) |
| Icon | Hamburger menu (3 horizontal `` lines), not a chat bubble |
**Parent chain (bottom-up, 4 levels):** โ unchanged
```
1. DIV [data-testid="hatch-chat-leading-controls"]
class="pointer-events-auto absolute start-3 top-0 flex h-[60px] items-center gap-2"
2. DIV (no testid) class="pointer-events-none absolute inset-x-0 top-0 z-10 h-44"
3. DIV (no testid) class="absolute inset-0 overflow-hidden"
4. DIV (no testid) class="relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden"
```
**Behavior (โ verified atomically 2026-10-04):** The switcher **toggles in place โ
no navigation**. Click when closed โ panel opens (shell `innerHTML` 0 โ 60667,
rows 0 โ 26 on opm). Click when open โ panel closes. Always check panel state
before clicking โ never blind-click. (An earlier non-atomic probe appeared to
navigate; that was a race with the live heartbeat job driving the same browser โ
see ยง9.)
**Child testids** (for reference):
- `[data-testid="hatch-chat-switcher-icon-knockout"]` โ icon wrapper span
- `[data-testid="hatch-chat-switcher-navigation-icon"]` โ the hamburger SVG span
- ๐ `[data-testid="hatch-chat-switcher-unread-indicator"]` โ unread blue dot (see ยง1b)
---
## 1b. Unread Indicator ๐ (verified 2026-10-04 on muse)
When unread chats exist, the switcher gains:
```html
Unread chats
```
| Property | Value |
|---|---|
| Selector | `[data-testid="hatch-chat-switcher-unread-indicator"]` |
| Visual | Blue dot (`bg-fill-blue`, 8px circle) overlaid on the switcher icon |
| `aria-hidden` | `true` โ screen readers get the sr-only `Unread chats` text instead |
| Programmatic signal | **Presence = unread chats exist.** Most reliable unread check |
| Companion signal | `document.title` gains an `(N)` prefix, e.g. `(1) Chat โ operator-pip` |
---
## 2. Sidechat Create Button ("New side chat") โ
**Selector:** `[data-testid="hatch-chat-compose"]`
The `+` button that creates a new sidechat. **Only exists in the DOM when the panel
is OPEN.** This makes it the most reliable "panel is open and ready" signal.
```html
```
**Key facts (โ verified):**
| Property | Value |
|---|---|
| Tag | `BUTTON` |
| In DOM when panel closed | **No** โ completely absent |
| In DOM when panel open | โ Yes (`visible: offsetParent !== null`) |
| Text content | None (icon-only) |
| `aria-label` / `title` | `New side chat` |
| Icon | Plus sign (`+`), single SVG path |
**Parent chain (bottom-up, 8 levels):** โ unchanged โ `SPAN.contents > DIV.group/nav-section`
(header row: `H3 "Side chats"` + compose) inside the `SECTION` "Side chats".
**What clicking does (โ verified 2026-10-04):** Creates a new sidechat draft.
Browser navigates `https://muse.ai/` โ `https://muse.ai/thread/new`
(placeholder URL; the real thread UUID appears after the first message is sent
or navigation settles). **No sidechat exists server-side until a message is sent**
โ navigating to `/thread/new` and back is harmless.
---
## 3. Chat Navigation Panel Structure โ
### 3a. Panel shell (always in DOM โ except ยง8)
**Selector:** `[data-testid="hatch-side-chats-panel-shell"]`
```html
```
| State | `innerHTML` | `style.width` / computed |
|---|---|---|
| Closed | โ `""` (empty string) | โ `0px` |
| Open | โ Full `