Files
box/docs/DOM-SETTINGS.md
T

8.3 KiB

DOM Reference: Settings, Profile & Dock Rail

Inspected live via CDP on the opm browser (warp-opm netns, CDP 9440), 2026-10-04. Structure only — no credential, token, or personal values are recorded here.

Related: DOM-CHAT-PANEL.md (chat panel), DOM-MESSAGES.md (messages), DOM-PAGE-STRUCTURE.md (page states).


1. Dock rail

The left vertical nav rail. Container:

<div data-testid="hatch-dock-rail" class="relative flex h-full">

Rail items (top to bottom)

# Selector Tag aria-label Notes
1 [data-testid="hatch-nav-chat"] <a href="/"> Chat The chat/message button from the user's screenshot. Navigates /thread/new → https://muse.ai/. See "chat activation" below.
2 [data-testid="hatch-nav-search"] <button> Search Opens quick-search dialog [data-testid="hatch-quick-search-frame"] (heading "Search Muse").
3 (none) <button> Get the Muse app App download upsell. No data-testid.
4 [data-testid="hatch-dock-more"] <button> Settings Opens the settings menu (radix menu). Bottom of rail (div.mt-auto).

Parent chain of the settings button (4 levels):

div[data-testid="hatch-dock-rail"].relative.flex.h-full
  > div.relative.z-10.flex
    > div.mt-auto.flex.flex-col
      > button#radix-_[data-testid="hatch-dock-more"].hatch-dock-reveal-item.group.relative

Key attributes on the button:

<button type="button"
        aria-label="Settings"
        data-testid="hatch-dock-more"
        aria-haspopup="menu"
        aria-expanded="false"      <!-- unreliable: stays "false" even when menu is open -->
        data-state="closed"       <!-- unreliable: stays "closed" even when menu is open -->
        data-pel-click="settings_menu_open_click">

Automation note: data-state / aria-expanded do NOT reflect the real open state. Detect the open menu by counting [role="menuitem"] elements (> 0 means open). Synthetic .click() does not open the radix menu; use real mouse events via CDP Input.dispatchMouseEvent (mousePressed + mouseReleased at the button center). The button toggles, so click only when [role="menuitem"] count is 0.

Chat activation via hatch-nav-chat

Clicking [data-testid="hatch-nav-chat"] from the stripped /thread/new state navigates to https://muse.ai/ and the chat switcher appears (~1s). This is the reliable "activate chat" primitive — see the _ensure_chat_active() logic in muse-chat-api.py (priority: compose → switcher → nav-chat). aria-label on this link is unstable ("Chat" vs "Chat, N notification"); always match on the data-testid.


2. Settings menu (dock "more" menu)

Radix menu rendered in a popper. Items (role="menuitem", no data-testid):

Text data-pel-click Action (observed)
Keyboard shortcuts keyboard_shortcuts_nav_click No dialog rendered under automation (see §5)
Download apps mobile_app_upsell_menu_click — (not opened)
Report an issue bug_report_nav_click — (not opened)
Settings settings_nav_click Opens the Settings dialog (§3)

Menu container selectors (either may match):

document.querySelector('[role="menu"]')
document.querySelector('[data-radix-popper-content-wrapper]')

Find a menuitem reliably:

[...document.querySelectorAll('[role="menuitem"]')]
  .find(m => m.getAttribute('data-pel-click') === 'settings_nav_click')

3. Settings dialog

A radix dialog (div[role="dialog]", id like radix-_r_10g_; the id suffix is random per render — do not hardcode it).

div#radix-_<role=dialog>
  • Heading is an H2 with text Settings (not h1).
  • Layout: left nav column + right content column.

3a. Left nav (section buttons)

Plain <button> elements, no data-testids. In order:

General
Connectors
Wallet
Secure store
Permissions
Messaging channels
Devices
Data controls
Help & support
Legal info
Log out        ← the sign-out control; no confirmation dialog observed at open
Close

3b. General section

Headings (all h2): General, Usage, Appearance.

Usage — one button:

Control Label Notes
<button> Upgrade Plan upgrade upsell

Appearance — theme + accent color:

Control Label
<button> Light
<button> Dark
<button> System
<input type="radio"> Match my avatar
<input type="radio"> Default
<input type="radio"> Blue
<input type="radio"> Purple
<input type="radio"> Pink
<input type="radio"> Orange
<input type="radio"> Green
<input type="radio"> Beige
<input type="radio"> Monochrome

3c. Profile / avatar

  • Avatar image: <img> with empty alt, src present (value not recorded). No data-testid on the img.
  • Edit avatar and name button (aria-label="Edit avatar and name", <button>, no data-testid) appears in the profile area of the settings dialog. Chain (3 levels):
div.pointer-events-auto.absolute.z-20
  > div.group-has-[[data-hatch-avatar-media-loading]]/status-avatar:hidden
    > span.contents
      > button[aria-label="Edit avatar and name"].inline-flex.shrink-0.cursor-pointer

3d. Other sections (not opened)

Connectors, Wallet, Secure store, Permissions, Messaging channels, Devices, Data controls, Help & support, Legal info were not opened during mapping (each is a left-nav <button>; clicking one swaps the right content column). Secure store / Wallet likely contain credential-adjacent UI — map with care, structure only, never values.


4. Account switching

No multi-account switcher was observed in the settings dialog or dock rail. The only account control found is the Log out button in the settings left nav. Each Muse account runs in its own isolated browser profile (muse, pip, 646, opm nodes), so in this fleet account switching happens at the profile level, not inside the app UI.


5. Keyboard shortcuts modal

Menu item exists:

[...document.querySelectorAll('[role="menuitem"]')]
  .find(m => m.getAttribute('data-pel-click') === 'keyboard_shortcuts_nav_click')

Clicking it via automation (menuitem .click() after opening the dock menu with real mouse events) produced no [role="dialog"] within 3s and no URL change. The modal likely requires a trusted user gesture deeper in the radix event chain, or renders on a longer delay. Status: selector documented, modal content not captured — needs a headed/manual pass or longer wait.


6. Quick reference: reliable selectors

// Dock rail
'[data-testid="hatch-dock-rail"]'
'[data-testid="hatch-nav-chat"]'        // chat button (stable; aria-label unstable)
'[data-testid="hatch-nav-search"]'      // search
'[data-testid="hatch-dock-more"]'       // settings menu trigger

// Settings menu (after real mouse click on hatch-dock-more)
'[role="menuitem"]'                     // count > 0 => menu open
'[data-pel-click="settings_nav_click"]'
'[data-pel-click="keyboard_shortcuts_nav_click"]'
'[data-pel-click="bug_report_nav_click"]'
'[data-pel-click="mobile_app_upsell_menu_click"]'

// Settings dialog
'div[role="dialog"]'                    // id is random per render
'button[aria-label="Edit avatar and name"]'

// Search dialog
'[data-testid="hatch-quick-search-frame"]'

7. Automation recipes

Open the settings menu:

// 1. real mouse click at button center (synthetic .click() does NOT work)
const b = document.querySelector('[data-testid="hatch-dock-more"]');
const r = b.getBoundingClientRect();
// CDP: Input.dispatchMouseEvent mousePressed + mouseReleased at (r.x + r.width/2, r.y + r.height/2)
// 2. verify: document.querySelectorAll('[role="menuitem"]').length > 0
//    (the button toggles — only click when count is 0)

Open the Settings dialog:

[...document.querySelectorAll('[role="menuitem"]')]
  .find(m => m.getAttribute('data-pel-click') === 'settings_nav_click')
  .click();
// dialog appears in ~2s: document.querySelector('div[role="dialog"]')
// heading: [...document.querySelectorAll('h2')].find(h => h.innerText.trim() === 'Settings')

Close any dialog: Escape keydown (works for the settings dialog).