Skip to content

docs: system tray daemon design document#218

Open
zzhan111 wants to merge 20 commits into
epiral:mainfrom
zzhan111:main
Open

docs: system tray daemon design document#218
zzhan111 wants to merge 20 commits into
epiral:mainfrom
zzhan111:main

Conversation

@zzhan111
Copy link
Copy Markdown

Summary

  • Design doc for evolving bb-browser daemon into a Windows system tray application
  • Covers availability (zero-config, visual status, self-healing)
  • Covers multi-scenario (personal dev, team sharing, CI/CD, remote, multi-browser)
  • Covers security (4-layer defense: network, auth, permissions, audit)
  • Covers stability (process isolation, watchdog, graceful degradation, memory protection)

Motivation

Current daemon is a CLI black box. This document outlines the architecture and 4-phase roadmap to make it a visible, controllable, self-healing system service — especially relevant after #217 (port conflict with Windows iphlpsvc).

🤖 Generated with Claude Code

zzhan111 and others added 20 commits May 15, 2026 17:59
Daemon refactoring (commit 2d834e5) removed the Extension-based trace
implementation but did not migrate the DOM event listener injection.
trace start/stop commands ran without error but always returned 0 events.

This fix reimplements trace recording via CDP Runtime.evaluate and
Runtime.consoleAPICalled, replacing the old chrome.runtime.sendMessage
channel:

- trace-inject.ts: Ported DOM event listeners (click, input, change,
  keydown, scroll) from the original Extension content script. Events
  are reported via console.log('__BB_TRACE__:' + JSON) back to the
  daemon's existing console monitoring channel.
- cdp-connection.ts: Intercept __BB_TRACE__: prefix in
  Runtime.consoleAPICalled handler, parse TraceEvent, store per-tab.
  Auto-re-inject listeners on Page.frameNavigated.
- tab-state.ts: Add SeqTraceEvent type, traceEvents RingBuffer,
  traceRecording flag, addTraceEvent/getTraceEvents/clearTrace methods.
- command-dispatch.ts: Remove global trace state, wire trace start/stop
  to per-tab CDP injection and event collection.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…idation)

Address PR review follow-ups:
- Use longer collision-resistant prefix __BB_BROWSER_TRACE_8fd3__ instead of __BB_TRACE__
- Verify __bbBrowserTraceInjected flag after injection so callers learn when
  console.log is overridden or script execution is blocked
- Validate event type and field types before pushing into the trace buffer
fix(daemon): restore trace recording via CDP console.log injection
fix(daemon): harden trace injection (longer prefix, health check, val…
- Add packages/web: React-based Trace Studio for recording and viewing browser interactions
- Fix CLI build: define __BB_BROWSER_VERSION__ via tsup to resolve ReferenceError
- Fix daemon build: mark ws as external to resolve ESM dynamic require error
- Add /ping endpoint to daemon (no auth) for frontend health check and token discovery
- Switch frontend from WebSocket to HTTP with Bearer token auth
- Add trace events subcommand for real-time incremental event polling during recording
- Filter non-interactive click targets (div/span) in trace injection to reduce noise
- Add deduplication for clicks (300ms) and keypresses (50ms)
- Propagate trace recording state to iframes on stop

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… reliability

- web/vite: port 3000 → 3004 + strictPort to prevent silent port drift
- web/TraceStudio: add tabId to poll request, reset cursor on new recording
- web/TabPanel: filter out chrome://errorpage and other non-http(s) tabs
- web/store: sync traceEventCount on SET_TRACE_EVENTS to match array length
- daemon/click: append element.click() call for React synthetic event compat
- daemon/trace-inject: raise scroll threshold 50→200px to reduce noise

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add 360ChromeX path to browser discovery candidates
- Use existing local Chrome profile instead of creating blank one
- Move Chrome paths to forward slash for consistency

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- daemon/cdp-connection: set __bbBrowserTraceRecording=true before injecting,
  then force-sync into every same-origin frame. The previous order let
  trace-inject propagate `false` into frames (because it ran before the
  top-level flag was set), so frameset mainFrames stayed silent forever.
- daemon/trace-inject: re-entrant on re-injection. walkFrames() always runs
  (covers Page.frameNavigated), each frame gets a load listener for late or
  re-navigated subframes, and recording state is re-synced on every walk.
- web/TraceStudio: read cursor from response.data.cursor (not response.cursor),
  so polling actually advances instead of refetching the full event list and
  duplicating into the store.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Use Web Worker timer for recording poll (Chrome throttles setInterval
  to >=60s in hidden tabs, causing events to freeze when user switches away)
- Reset polling cursor only on false→true recording transition (not every
  effect re-mount), preventing full-history re-fetch and duplication
- Add seq-based dedup in ADD_TRACE_EVENT reducer to guard against
  double-adds from StrictMode or cursor resets
- Sync realTimeStats in SET_TRACE_EVENTS so monitor count matches
  actual events after stop
- Use event.seq as React key in TraceTimeline for stable DOM diffing

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ExportDialog previously required event.ref to generate click/fill code.
Frameset page events only have cssSelector/xpath, producing empty scripts.

- Add bestSelector() helper: ref > cssSelector > xpath fallback
- Add page.goto() navigation step from activeTab.url
- Support select, check, scroll event types in all three formats
- Escape single quotes in generated string values

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…able buffer

ExportDialog gains Auto/CSS/XPath selector modes and a smart-wait toggle so
generated scripts can run outside bb-browser and survive async rendering.
Strings are now quoted via JSON.stringify, fixing newline/tab/unicode escaping.

trace-inject listens for popstate/hashchange to capture SPA navigation; the
daemon emits a 'navigation' trace event on main-frame Page.frameNavigated,
deduped by URL. The first navigation matching activeTab.url is dropped at
codegen time to avoid double goto.

TabState trace buffer capacity is now overridable via BB_TRACE_CAPACITY
(min 100, default 1000) and warns once when first full instead of silently
dropping the oldest events.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CLAUDE.md roadmap items P1-P3 are now implemented; rewrite the file as a
"done" record and reset the open-items section to empty. CHANGELOG adds
Features and Bug Fixes entries describing the export improvements.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…o, and TraceStudio fusion plan

- Clarify MCP commands vs Trace events as two independent data pipes
- Add WSL2 cross-system scenario (mDNS auto-discovery, wsl-probe tool, security)
- Add TraceStudio + Dashboard fusion plan preserving all existing functionality

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…order

Two root causes for the "no tabs" issue:

1. daemon: tab_list was placed inside the switch after ensurePageTarget(),
   so if Chrome had no attached page targets it would throw before reaching
   the handler. Moved tab_list before ensurePageTarget() alongside tab_new.

2. web: TraceStudio.loadTabs and TabPanel filtered tabs to http/https only
   before storing in state, so users with only chrome:// tabs (e.g. New Tab)
   saw an empty list. Store now holds all page-type tabs; TabPanel renders
   all of them but marks non-http ones with a lock icon and disabled style,
   while auto-selection still prefers the first recordable http/https tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Complete system-tray-design.md with five-layer UI architecture, Acrylic material design, multi-port control, and three-phase MVP roadmap
- Create system-tray-future.md with 60% of deferred features organized into five categories with explicit trigger conditions
- Formalize four critical infrastructure decisions in design.md §14.0
- Document eight secondary implementation-time decisions in design.md §14.1

These design specifications are ready for Phase 1 tray daemon and UI implementation.
Merge branch 'zzhan111/review-system-tray-design' into main

Brings in:
- Complete system-tray-design.md with five-layer UI architecture, Acrylic material design, multi-port control, and three-phase MVP roadmap
- Complete system-tray-future.md with deferred features (5 categories, 60% of scope)
- Formalized critical infrastructure decisions (§14.0) and implementation-time decisions (§14.1)

Ready for Phase 1 implementation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants