95 lines
3.7 KiB
Markdown
95 lines
3.7 KiB
Markdown
|
|
# hatch_menu — Modular Settings-Menu Navigation + Toggles
|
||
|
|
|
||
|
|
`bin/hatch_menu/` drives the muse.ai Settings menu in the agent
|
||
|
|
browsers. One module per part: a site change means patching one file.
|
||
|
|
Exposed as `box chromebox permissions ...`; `bin/invite.py` usage
|
||
|
|
reads ride the same tree.
|
||
|
|
|
||
|
|
## Layout
|
||
|
|
|
||
|
|
```text
|
||
|
|
bin/hatch_menu/
|
||
|
|
__init__.py package surface (dialog + mouse + toggles fns)
|
||
|
|
mouse.py trusted input: real_click, escape, close, MouseError
|
||
|
|
dialog.py open_settings (retried), goto_tab, click_row,
|
||
|
|
describe_rows, go_back, dialog_text, TAB_NAMES
|
||
|
|
controls.py radio/switch list + set (verify, else trusted
|
||
|
|
click, verify again)
|
||
|
|
toggles.py toggle registry + sessions: resolve/get/set/list,
|
||
|
|
describe_tab, MenuError
|
||
|
|
tabs/
|
||
|
|
__init__.py TAB_MODULES (10 tabs, uniform describe(ws))
|
||
|
|
permissions.py defaults radios, website modes, protocols,
|
||
|
|
advanced switches, counts, tasks
|
||
|
|
general.py usage parse, theme, redeem entrypoint
|
||
|
|
data_controls.py model-improvement switch (rest read-only)
|
||
|
|
connectors|wallet|secure_store|messaging|devices|
|
||
|
|
help_support|legal.py read-only inventories
|
||
|
|
```
|
||
|
|
|
||
|
|
Dependency order (no cycles): `mouse` <- `dialog` <- `controls`
|
||
|
|
<- `tabs/*` <- `toggles`. Tab modules own their contracts
|
||
|
|
(headings, labels, slugs, modes); `toggles.py` only addresses them.
|
||
|
|
|
||
|
|
## Toggle addresses
|
||
|
|
|
||
|
|
Static: `permissions.connector_defaults`,
|
||
|
|
`permissions.web_access` (`auto_allow`/`always_ask`);
|
||
|
|
`permissions.advanced.transparent_proxy|tls_interception|
|
||
|
|
sni_mismatch_rejection`, `data_controls.ai_improvement` (`on`/`off`);
|
||
|
|
`general.theme` (match/default/blue/purple/pink/orange/green/
|
||
|
|
beige/monochrome).
|
||
|
|
|
||
|
|
Families: `permissions.websites:<host>` (`Allow`/`Ask`/`Deny`),
|
||
|
|
`permissions.protocols:<slug>` (`on`/`off`; slugs discovered live,
|
||
|
|
e.g. `mcp-sse`, `mcp-streamable`, `agent-skills`, `mcp-apps`,
|
||
|
|
`mcp-oauth`).
|
||
|
|
|
||
|
|
Every `set` verifies in place and reads back through a fresh
|
||
|
|
session; readback mismatch reports failure, never partial success.
|
||
|
|
Caller errors (unknown node/toggle/tab/value) raise `MenuError`
|
||
|
|
before any CDP traffic. Transport failures return `{"ok": False}`.
|
||
|
|
|
||
|
|
## CLI
|
||
|
|
|
||
|
|
```bash
|
||
|
|
box chromebox permissions <node> list [--tab TAB] [--json]
|
||
|
|
box chromebox permissions <node> get <toggle> [--json]
|
||
|
|
box chromebox permissions <node> set <toggle> <value> [--json]
|
||
|
|
box chromebox permissions <node> describe <tab> # JSON inventory
|
||
|
|
```
|
||
|
|
|
||
|
|
Exit 2 on caller errors, 1 on transport/unreadable toggles.
|
||
|
|
|
||
|
|
## Patch guide
|
||
|
|
|
||
|
|
| Site change | Patch |
|
||
|
|
|---|---|
|
||
|
|
| Dock button / dialog open flow | `dialog.py` (`open_settings`) |
|
||
|
|
| Radio/switch mechanics | `controls.py` |
|
||
|
|
| Permissions headings, modes, slugs, adv labels | `tabs/permissions.py` |
|
||
|
|
| Usage text, theme values | `tabs/general.py` |
|
||
|
|
| Data-controls switch label | `tabs/data_controls.py` |
|
||
|
|
| New settable toggle | tab module contract + `toggles.py` registry row |
|
||
|
|
| Trusted-click transport | `mouse.py` |
|
||
|
|
|
||
|
|
`describe <tab>` dumps a tab's live inventory for debugging.
|
||
|
|
|
||
|
|
## Provenance
|
||
|
|
|
||
|
|
Contracts come from live read-only DOM recon (2026-10-06):
|
||
|
|
Permissions radios `auto_allow`/`always_ask`, Websites Allow/Ask/
|
||
|
|
Deny chooser (real click to open), 8 protocol switches, Advanced
|
||
|
|
section (Transparent proxy off, TLS interception off, SNI mismatch
|
||
|
|
rejection on), Data-controls single switch, General theme radios.
|
||
|
|
Radix menus need real `Input.dispatchMouseEvent` press+release with
|
||
|
|
monotonic CDP ids; synthetic clicks fail. Recon never touches Reset.
|
||
|
|
|
||
|
|
## Tests
|
||
|
|
|
||
|
|
`tests/test_hatch_menu.py` (mocked CDP, per-module):
|
||
|
|
mouse/trusted-clicks, dialog open-retry/tab/row flows, control
|
||
|
|
verify-then-fallback, registry resolution + readback mismatch,
|
||
|
|
tab contracts on live-captured fixtures. `tests/test_invite.py`
|
||
|
|
covers the invite shims + flat usage parse.
|