Skip to content

feat(ui): launch at login and harden menu popover - #55

Merged
DevVig merged 6 commits into
mainfrom
feat/launch-at-login
Jul 19, 2026
Merged

feat(ui): launch at login and harden menu popover#55
DevVig merged 6 commits into
mainfrom
feat/launch-at-login

Conversation

@DevVig

@DevVig DevVig commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • move launch-at-login ownership into the Tauri app for Homebrew, DMG, and source installs
  • add a General settings toggle and one-time first-launch prompt with dev-build safeguards
  • throttle opt-in automatic update checks to once per 24 hours while keeping manual checks immediate
  • keep production daemon failures honest instead of showing browser demo sessions
  • fit the popover to the active screen, show 10 scrollable thread rows, and cap DOM rendering at 50 sessions
  • make the popover focusable so click-outside dismissal works, with a blur/click race guard for tray toggling
  • preserve current right-click menu, bundled daemon, Cursor adapter, and live Agent Key behavior from main

Verification

  • make ci
  • cargo check --manifest-path apps/microbridge-ui/src-tauri/Cargo.toml
  • 9 UI tests, including daily updater timing and runaway thread-list coverage
  • native bundled-app focus-loss dismissal smoke test
  • browser audit at 25 threads across short and full-height viewports

Notes

The physical Micro is not required for this UI and launch-at-login change. Hardware HID validation remains a separate device-arrival gate.

Copilot AI review requested due to automatic review settings July 19, 2026 23:16
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3107dfed-7d6f-4a63-ae08-7fd6a9cfc5fa

📥 Commits

Reviewing files that changed from the base of the PR and between e8f0959 and 6d9540f.

⛔ Files ignored due to path filters (1)
  • apps/microbridge-ui/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (20)
  • Formula/microbridge.rb
  • INSTALL.md
  • apps/microbridge-ui/src-tauri/Cargo.toml
  • apps/microbridge-ui/src-tauri/src/lib.rs
  • apps/microbridge-ui/src-tauri/tauri.conf.json
  • apps/microbridge-ui/src/App.tsx
  • apps/microbridge-ui/src/components/DeviceEcho.tsx
  • apps/microbridge-ui/src/lib/autostart.ts
  • apps/microbridge-ui/src/lib/bus.ts
  • apps/microbridge-ui/src/lib/popoverFit.ts
  • apps/microbridge-ui/src/lib/tauri.ts
  • apps/microbridge-ui/src/lib/threads.ts
  • apps/microbridge-ui/src/lib/updater.test.ts
  • apps/microbridge-ui/src/lib/updater.ts
  • apps/microbridge-ui/src/surfaces/Disconnected.tsx
  • apps/microbridge-ui/src/surfaces/Popover.tsx
  • apps/microbridge-ui/src/surfaces/Settings.tsx
  • apps/microbridge-ui/src/surfaces/surfaces.test.tsx
  • scripts/install-from-release.sh
  • scripts/install.sh
📝 Walkthrough

Walkthrough

The PR adds app-owned launch-at-login management, adaptive popover sizing, improved daemon-disconnected states, guarded Tauri/browser runtime handling, and compact popover/thread presentation updates. Installers now open the app instead of managing its UI LaunchAgent directly.

Changes

Microbridge UI behavior

Layer / File(s) Summary
App-owned launch-at-login flow
apps/microbridge-ui/src-tauri/Cargo.toml, apps/microbridge-ui/src-tauri/src/lib.rs, apps/microbridge-ui/src/lib/autostart.ts, apps/microbridge-ui/src/surfaces/Settings.tsx, scripts/*.sh, INSTALL.md, Formula/microbridge.rb
The app registers and controls ai.microbridge.ui, prompts once on first launch, exposes a General setting, and owns login-launch behavior across installation methods.
Adaptive popover geometry
apps/microbridge-ui/src-tauri/src/lib.rs, apps/microbridge-ui/src-tauri/tauri.conf.json, apps/microbridge-ui/src/lib/popoverFit.ts, apps/microbridge-ui/src/surfaces/Popover.tsx, apps/microbridge-ui/src/components/DeviceEcho.tsx, apps/microbridge-ui/src/lib/threads.ts
Popover placement and resizing now use monitor-aware bounds, blur suppression, compact mode, fixed thread-row sizing, and denser device preview styling.
Runtime detection and disconnected surfaces
apps/microbridge-ui/src/lib/tauri.ts, apps/microbridge-ui/src/lib/bus.ts, apps/microbridge-ui/src/App.tsx, apps/microbridge-ui/src/surfaces/Disconnected.tsx
Browser previews use one demo snapshot, Tauri failures produce offline state, control calls distinguish unavailable runtimes, and missing snapshots render a disconnected surface.
Backend integration cleanup
apps/microbridge-ui/src-tauri/src/lib.rs
Existing cursor integration, lookup, cleanup, error handling, and event-loop code received formatting and control-flow-only adjustments.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Popover
  participant AutostartModule
  participant TauriBackend
  participant LaunchAgent
  User->>Popover: Open menu bar app
  Popover->>AutostartModule: promptLaunchAtLoginOnce()
  AutostartModule->>TauriBackend: Query capability and enabled state
  TauriBackend-->>AutostartModule: Return launch-at-login state
  AutostartModule-->>User: Show first-launch prompt
  User->>AutostartModule: Confirm or decline
  AutostartModule->>TauriBackend: Set launch-at-login
  TauriBackend->>LaunchAgent: Enable or disable login item
Loading

Possibly related PRs

Suggested reviewers: copilot

Poem

I’m a rabbit, hopping through the tray,
Launch-at-login now knows the way.
Popovers fit, threads line up neat,
Offline screens wait with paws and feet.
Settings bloom where startup grows—
Carrots for code, and off it goes!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main themes of the change: launch-at-login support and popover hardening.

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR moves “launch at login” ownership from installer scripts into the Tauri app (consistent across Homebrew/DMG/source installs), while also improving the tray popover’s sizing/scroll behavior and making daemon-offline states display honestly (instead of browser demo data).

Changes:

  • Shift login-item management into the app via tauri-plugin-autostart, with a first-launch prompt and a Settings → General toggle.
  • Rework popover geometry: fit to active screen/work area, keep footer visible, and make the thread list scroll with a fixed 10-row viewport.
  • Replace “connecting…” placeholder with a dedicated Disconnected surface and tighten the browser-preview vs. real-app snapshot behavior.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/install.sh Stop writing/bootstrapping the UI LaunchAgent; just open the app bundle.
scripts/install-from-release.sh Same: remove installer-managed UI LaunchAgent and rely on in-app behavior.
INSTALL.md Document the ai.microbridge.ui LaunchAgent and the new launch-at-login workflow.
Formula/microbridge.rb Update caveats to mention in-app launch-at-login offer and Settings path.
apps/microbridge-ui/src/surfaces/Settings.tsx Add “General” tab with launch-at-login toggle wired to new autostart APIs.
apps/microbridge-ui/src/surfaces/Popover.tsx Use usePopoverFit, add scrollable thread list with fixed row height/count, and compact-mode behavior.
apps/microbridge-ui/src/surfaces/Disconnected.tsx New honest offline surface shown when no snapshot yet (in-app).
apps/microbridge-ui/src/lib/threads.ts Add thread row constants and a render safety limit API surface.
apps/microbridge-ui/src/lib/tauri.ts Centralize “has Tauri vs. command failure” distinction and guarded invocations.
apps/microbridge-ui/src/lib/popoverFit.ts New hook to cap card height per-monitor and resize the popover window to content.
apps/microbridge-ui/src/lib/bus.ts Ensure demo snapshot is browser-only; return null in-app until daemon snapshot exists.
apps/microbridge-ui/src/lib/autostart.ts New launch-at-login prompt-once + toggle helpers.
apps/microbridge-ui/src/components/DeviceEcho.tsx Reduce echo footprint to fit better alongside a 10-row thread list.
apps/microbridge-ui/src/App.tsx Show Disconnected when no snapshot (except HUD), and prompt for launch-at-login once.
apps/microbridge-ui/src-tauri/tauri.conf.json Make popover focusable; adjust HUD window height.
apps/microbridge-ui/src-tauri/src/lib.rs Implement popover sizing/fit commands and autostart (label pinning + blur/click guard).
apps/microbridge-ui/src-tauri/Cargo.toml Add tauri-plugin-autostart dependency.
apps/microbridge-ui/src-tauri/Cargo.lock Lockfile updates for autostart and transitive dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/microbridge-ui/src/lib/threads.ts
Comment thread apps/microbridge-ui/src/surfaces/Disconnected.tsx Outdated
Comment thread apps/microbridge-ui/src/surfaces/Disconnected.tsx Outdated
@DevVig
DevVig force-pushed the feat/launch-at-login branch from 9508b2e to 8f1d13f Compare July 19, 2026 23:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/microbridge-ui/src/lib/threads.ts (1)

44-62: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

limit parameter is accepted but never applied — the render-count safety valve is a no-op.

threads = ranked uses the full sorted array; it's never sliced to limit/RENDER_LIMIT. As a result:

  • truncated is always false (threads.length always equals snapshot.sessions.length), so the "x/y" truncation label in Popover.tsx can never appear.
  • The safety valve this function's own docstring describes ("a runaway session count can't put thousands of rows in the DOM") does not actually apply — Popover.tsx renders every session as a DOM row regardless of count.
🐛 Proposed fix
   const ranked = [...snapshot.sessions].sort((a, b) => {
     const diff = rank(b, snapshot, onKeys) - rank(a, snapshot, onKeys);
     if (diff !== 0) return diff;
     return b.updated_at_ms - a.updated_at_ms;
   });
-  const threads = ranked;
+  const threads = ranked.slice(0, limit);
   return {
     threads,
     total: snapshot.sessions.length,
     truncated: snapshot.sessions.length > threads.length,
   };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/microbridge-ui/src/lib/threads.ts` around lines 44 - 62, Apply the limit
parameter in visibleThreads by slicing the ranked sessions to at most limit
before assigning threads. Preserve the full snapshot.sessions.length as total,
and compute truncated from whether the limited result is shorter than the full
session list so Popover.tsx can display the truncation state.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/microbridge-ui/src/lib/bus.ts`:
- Around line 247-252: Update the listener setup around the bus-snapshot
callback and initial fetchSnapshot seed to track whether a live event has been
received; apply the fetched DAEMON_OFFLINE/initial snapshot only when no live
event arrived, preserving the live event payload when it races with
fetchSnapshot.

---

Outside diff comments:
In `@apps/microbridge-ui/src/lib/threads.ts`:
- Around line 44-62: Apply the limit parameter in visibleThreads by slicing the
ranked sessions to at most limit before assigning threads. Preserve the full
snapshot.sessions.length as total, and compute truncated from whether the
limited result is shorter than the full session list so Popover.tsx can display
the truncation state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4f021aac-65dc-422e-bfdc-22b72aa37c16

📥 Commits

Reviewing files that changed from the base of the PR and between a8aab01 and e8f0959.

⛔ Files ignored due to path filters (1)
  • apps/microbridge-ui/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • Formula/microbridge.rb
  • INSTALL.md
  • apps/microbridge-ui/src-tauri/Cargo.toml
  • apps/microbridge-ui/src-tauri/src/lib.rs
  • apps/microbridge-ui/src-tauri/tauri.conf.json
  • apps/microbridge-ui/src/App.tsx
  • apps/microbridge-ui/src/components/DeviceEcho.tsx
  • apps/microbridge-ui/src/lib/autostart.ts
  • apps/microbridge-ui/src/lib/bus.ts
  • apps/microbridge-ui/src/lib/popoverFit.ts
  • apps/microbridge-ui/src/lib/tauri.ts
  • apps/microbridge-ui/src/lib/threads.ts
  • apps/microbridge-ui/src/surfaces/Disconnected.tsx
  • apps/microbridge-ui/src/surfaces/Popover.tsx
  • apps/microbridge-ui/src/surfaces/Settings.tsx
  • scripts/install-from-release.sh
  • scripts/install.sh

Comment thread apps/microbridge-ui/src/lib/bus.ts Outdated
@DevVig
DevVig merged commit fb62038 into main Jul 19, 2026
7 checks passed
@DevVig
DevVig deleted the feat/launch-at-login branch July 19, 2026 23:28
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