Skip to content

feat(bx): replace server dropdown with Bx fleet gear - #61

Merged
sarg3nt merged 4 commits into
mainfrom
feature/multi-box-revamp
May 12, 2026
Merged

feat(bx): replace server dropdown with Bx fleet gear#61
sarg3nt merged 4 commits into
mainfrom
feature/multi-box-revamp

Conversation

@sarg3nt

@sarg3nt sarg3nt commented May 12, 2026

Copy link
Copy Markdown
Owner

Closes #48.

Summary

  • New built-in bx gear: a fleet view that replaces the server-name dropdown in the top bar. Tabular grid of all configured boxes with sort/filter, click-through to hydrate the per-box sidebar.
  • Live status: status.go polls each box and pushes updates over SSE so the fleet view never shows stale state.
  • Box switcher (box-switcher.js) handles the click-into-box → menu-hydrate → land-on-default-gear flow described in the issue.
  • Layout (base.templ) updated so non-box gears (e.g. the fleet view itself) remain available when no box is selected.

Test plan

  • Manually exercised: fleet view loads, sort/filter works, click into a box hydrates the left menu, SSE status updates arrive without refresh.
  • CI: build + lint + tests green.
  • Visual: confirm the top-bar real estate previously held by the server dropdown is now clean.

🤖 Generated with Claude Code

- Implemented Bx sidebar icon in icons.go for consistent UI.
- Created pages.templ for the Bx fleet view, including index page, headers, and empty state.
- Developed status.go to manage box status monitoring, including polling and SSE for live updates.
- Added bx-page.js for client-side behaviors, including row navigation and relative time formatting.
- Enhanced box-selector.js and introduced box-switcher.js for improved box selection and navigation.
Copilot AI review requested due to automatic review settings May 12, 2026 04:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new built-in Bx (Boxes) fleet gear and replaces the old server dropdown UX with a persistent header chip + command-palette box switcher, backed by a server-side status monitor that streams updates over SSE.

Changes:

  • Introduces the bx gear (fleet page at /bx, JSON status snapshot, SSE events stream, status poller).
  • Adds the header box-switcher chip + palette UI and client-side behaviors (including g b shortcut).
  • Updates request middleware + sidebar rendering to support “no active box” (box-agnostic) navigation.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
gearbox/static/js/common/box-switcher.js New command-palette switcher UI with SSE-driven status dots
gearbox/static/js/common/box-selector.js Extends legacy switchBox helper to support optional path + clearing context
gearbox/static/js/bx/bx-page.js Fleet page client behaviors (row click, SSE updates, relative timestamps)
gearbox/internal/gears/bx/status.go Background status monitor (polling + subscriptions) producing BoxStatus snapshots
gearbox/internal/gears/bx/README.md Gear documentation (scope, routes, semantics)
gearbox/internal/gears/bx/pages.templ Fleet page server-rendered UI (table + empty state)
gearbox/internal/gears/bx/icons.go Bx SVG icon component
gearbox/internal/gears/bx/handlers.go HTTP handlers for /bx, /bx/api/status, /bx/api/events
gearbox/internal/gears/bx/gear.go Gear registration, lifecycle wiring, permissions, sidebar placement
gearbox/internal/framework/templates/layouts/base.templ Header chip/palette + scope-aware sidebar rendering + bx link
gearbox/internal/framework/services/server_adapter.go Exposes underlying *database.DB for monitor usage
gearbox/internal/framework/handler/handler.go Injects enabled-box roster + resolves active box via ?box_id=
gearbox/internal/framework/gear/interface.go Adds ScopeBoxAgnostic and Scope.IsBoxScoped() helper
gearbox/internal/framework/auth/middleware.go Adds request-context storage for selected box + enabled box roster
gearbox/cmd/server/main.go Registers the new bx gear
DESIGN.md Documents new scope semantics and multi-box UX flow

Comment thread gearbox/internal/gears/bx/status.go Outdated
Comment thread gearbox/internal/gears/bx/status.go
Comment thread gearbox/internal/gears/bx/gear.go Outdated
Comment thread gearbox/internal/framework/templates/layouts/base.templ Outdated
Comment thread gearbox/internal/gears/bx/pages.templ Outdated
sarg3nt and others added 2 commits May 12, 2026 09:17
- statusMonitor.Start now guards against multi-start with sync.Once
  (matches its docstring; previously spawned a new goroutine per call).
- bx.Gear.Start passes its lifecycle ctx through to the monitor instead
  of context.Background(), so framework shutdown actually cancels it.
- The per-probe 5s budget is now enforced: probe uses
  agent.NewClientWithTimeout(..., m.timeout) instead of the default 30s
  agent client. Removed the unused pctx that the old comment promised.
- canViewIntegration("bx") now checks bx:view via
  auth.HasPermissionFromContext, matching the handler-side gate and the
  SidebarItem.RequiresPermission — so the sidebar no longer renders a
  Bx link for users who'd just get a 403 clicking it.
- Fix stale comment on boxTable: the page reconciles via the SSE
  snapshot pushed on (re)connect, not a /bx/api/status fetch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-existing dead field from the original commit; golangci-lint v2.8.0
(running on PR CI) flagged it as unused. Removed rather than wired up —
m.deps.Logger is already available when logging is needed later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 12, 2026 16:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Comment thread gearbox/static/js/common/box-switcher.js
Comment thread gearbox/internal/gears/bx/status.go Outdated
Comment thread gearbox/internal/framework/handler/handler.go Outdated
Comment thread gearbox/internal/framework/templates/layouts/base.templ
- box-switcher.js: register the visibilitychange listener once at module
  load instead of inside subscribeSSE(). Previously each tab-show added a
  new listener, eventually opening multiple EventSource connections.
  subscribeSSE() now also short-circuits if evt is already set.

- status.go probe(): `/health` is unauthenticated, so a missing API key
  no longer skips the reachability check. Boxes with an Agent URL but no
  key now probe normally; if Health() succeeds, the rollup degrades to
  Yellow with "API key missing — authenticated endpoints unavailable" as
  a contributor instead of being permanently Gray.

- handler.go InjectIntegrationStatus: publish the *full* configured-box
  roster (not just enabled-and-UsesAgentAPI) so the Bx fleet view and
  switcher palette can show disabled / partially-configured boxes — the
  StatusGray semantic only works if those rows are actually rendered.
  Active-box resolution (?box_id=) still uses the enabled+configured
  subset; landing on a disabled box has no gears to render anyway.

- base.templ box-switcher palette: add `role="dialog"`,
  `aria-modal="true"`, `aria-labelledby="box-switcher-title"`, a visually-
  hidden h2 title, `aria-label` on the search input, and `aria-hidden`
  on the decorative magnifier SVG. Matches the existing confirm/prompt/
  alert dialog patterns in this template.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sarg3nt
sarg3nt merged commit bc07b89 into main May 12, 2026
22 checks passed
@sarg3nt
sarg3nt deleted the feature/multi-box-revamp branch May 12, 2026 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revamp multiple box strategy

2 participants