Skip to content

Feat/markus remote access via hub & better chrome automation#136

Merged
jsyqrt merged 19 commits into
mainfrom
feat/markus-remote-access-via-hub
May 20, 2026
Merged

Feat/markus remote access via hub & better chrome automation#136
jsyqrt merged 19 commits into
mainfrom
feat/markus-remote-access-via-hub

Conversation

@jsyqrt
Copy link
Copy Markdown
Contributor

@jsyqrt jsyqrt commented May 20, 2026

No description provided.

jsyqrt and others added 18 commits May 17, 2026 20:12
Enable accessing a local Markus instance from mobile/remote networks
through markus-hub as intermediary. Uses WebRTC DataChannels for P2P
data transfer with signal server relay as fallback.

- Add @markus/remote package (node-datachannel WebRTC agent)
- Add web-ui transport abstraction (Direct / P2P / Relay)
- Add Remote Access section in Settings (toggle, URL, QR code)
- Add API endpoints for remote status/enable/disable
- Add remote config options in MarkusConfig
- Wire RemoteAccessAgent into CLI start command

Co-authored-by: Cursor <cursoragent@cursor.com>
- Discover local owner user ID at startup for accurate JWT generation
  (fixes missing avatar/chat history in remote UI)
- Add TURN server support with IceServer object format for node-datachannel
- Prefer relay transport in sendToPeer for reliability
- Add connection state tracking (idle/registering/connecting/connected)
- Generate markus_token with real userId instead of synthetic 'remote_owner'
- Support HTTPS Hub URLs with redirect following
- Real-time status updates via WebSocket, i18n support for remote UI
- Non-blocking enable endpoint (fire-and-forget start)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…settings

Co-authored-by: Cursor <cursoragent@cursor.com>
Large HTTP responses (e.g. HTML pages) could exceed DataChannel max
message size. Split into 48KB chunks with reassembly on client side.

Co-authored-by: Cursor <cursoragent@cursor.com>
…annel

RelayType enum doesn't exist in node-datachannel runtime exports,
causing undefined relayType in ICE server config. Use string literals
instead. Also fix URL parsing for ?transport=tcp parameter.

Co-authored-by: Cursor <cursoragent@cursor.com>
…rawer menu

- Desktop: hide main app sidebar on Settings page, show back button in settings sidebar
- Mobile: remove Settings from bottom nav, add hamburger drawer menu with avatar/settings
- Mobile settings: show grouped list navigation, each item opens sub-page with back button
- Replace MobileSettingsTabs with unified Settings component (mobile-aware)
- Add slide-in drawer animations (fadeIn, slideInLeft)
- Add QR code generation with real qrcode library
- Add settings sidebar with hash-based sub-path routing

Co-authored-by: Cursor <cursoragent@cursor.com>
- Integrate hamburger menu button into each page's own header instead of a separate top bar for better space utilization
- Fix avatar click in mobile drawer to open user's own profile settings instead of user management
- Fix report button navigation by removing MOBILE_REDIRECTS for reports and adding reports page to mobile
- Create reusable MobileMenuButton component

Co-authored-by: Cursor <cursoragent@cursor.com>
- Fix team page deep navigation: when navigating with agentId/dm/channel
  params on mobile, automatically enter the detail view instead of staying
  on the list
- Redesign home page header on mobile: replace deploy button with search
  icon and "+" create menu (agent, team, skill, discover more)
- Create global search page with search across agents, tasks, projects,
  and deliverables
- Reorder bottom nav to: Home, Team, Notifications, Work, Deliverables
- Remove Builder tab from bottom nav (accessible via "+" menu on Home)
- Add storeTab param support to MobileBuilderTabs for direct tab switching

Co-authored-by: Cursor <cursoragent@cursor.com>
…search

- Implement read/unread tracking with new user_read_cursors table, API endpoints, and WebSocket events
- Add mobile team page 3-layer navigation (roster -> team detail -> agent chat) with proper back navigation
- Add global search modal with keyboard navigation (↑↓, Tab, Enter), persisted state, and dynamic section ordering
- Support deep navigation from search results to tasks, requirements, deliverables, and agents
- Increase search results per category from 5 to 8 with "show all" expansion
- Fix mobile deliverable deep navigation to open detail view

Co-authored-by: Cursor <cursoragent@cursor.com>
…utomation

Adds a native macOS/Windows helper that automatically clicks Chrome's
"Allow remote debugging?" dialog when agents use the chrome-devtools MCP,
removing the need for manual user intervention. Includes a settings toggle,
accessibility permission guidance, and SKILL.md documentation updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
…rt mutex, fix lazy startup

- Remove Strategy 3 (estimated/blind click) from Swift auto-clicker binary
- Restore smart mutex so only one clicker process runs at a time
- Only trigger auto-click on initial MCP connection, not every reconnect
- Make first agent truly lazy: disconnect after caching tool list
- Route global mcpServers chrome-devtools through registerChromeDevtoolsLazy
- Skip chrome-devtools in scheduleMcpRelease idle disconnect
- Change setReconnector to Map<serverKey, callback> per agent
- Add withAgentLock to wrapListPages
- Prune ownedPages against actual list_pages after reconnect

Co-authored-by: Cursor <cursoragent@cursor.com>
…ols startup

The 30s timeout was too short when npx needs to download chrome-devtools-mcp
on first run, causing the connection to fail before the auto-clicker can
dismiss Chrome's "Allow debugging" dialog.

Co-authored-by: Cursor <cursoragent@cursor.com>
- On WebRTC failed/closed: close PC/DC resources but keep PeerSession
  alive for relay fallback (don't destroy markusToken)
- Rename startDcPing to startPeerPing: sends ping via sendRaw which
  falls back to relay, starts on auth not DC open
- Add 5-minute relay inactivity timeout for abandoned sessions
- Handle relay frames from unknown peers (create relay-only session)
- Preserve session state on ICE restart (new offer for existing peer)
- Clean up proxied WebSocket connections on peer cleanup

Co-authored-by: Cursor <cursoragent@cursor.com>
Send first ping immediately on startPeerPing so the client can respond
before the first interval check. Change timeout threshold from 10s to
25s (interval + timeout) to allow a full ping cycle before declaring
the peer unresponsive.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Use a module-level cache to remember loaded images so re-mounts
start in the loaded state instead of flashing the placeholder.

Co-authored-by: Cursor <cursoragent@cursor.com>
… routing

Replace static bridge-vs-npx decision at agent creation time with dynamic
per-call routing, so agents always use the extension when connected.

- New chrome-extension package with Manifest V3 service worker, CDP tools,
  WebSocket bridge client, popup UI, and Markus logo icons
- WebSocket bridge server (markus-browser-bridge) and in-process MCP proxy
  (markus-browser-mcp) in core package
- Dynamic dispatch in registerChromeDevtoolsLazy: check bridge.connected
  at call time, fall back to npx chrome-devtools-mcp transparently
- Settings UI: step-by-step extension install guide with download zip,
  open chrome://extensions, and 5s auto-polling for connection status
- Onboarding: detect Chrome browser and show extension setup card
- pack.mjs script to produce markus-browser-extension.zip (14KB, zero deps)
- API endpoints for zip download and opening chrome://extensions
- Integrated into Dockerfile and build-binary.sh for distribution

Co-authored-by: Cursor <cursoragent@cursor.com>
@jsyqrt jsyqrt changed the title Feat/markus remote access via hub Feat/markus remote access via hub & better chrome automation May 20, 2026
…onst)

Co-authored-by: Cursor <cursoragent@cursor.com>
@jsyqrt jsyqrt merged commit 7fd9408 into main May 20, 2026
1 check passed
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.

1 participant