Skip to content

feat(sidebar): hide gears whose agent reports them unavailable - #119

Merged
sarg3nt merged 2 commits into
mainfrom
fix/issue-112-sidebar-capability-filter
May 17, 2026
Merged

feat(sidebar): hide gears whose agent reports them unavailable#119
sarg3nt merged 2 commits into
mainfrom
fix/issue-112-sidebar-capability-filter

Conversation

@sarg3nt

@sarg3nt sarg3nt commented May 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • filterGearsByAgentCapabilities already exists and is used by the Gears settings page. Today the sidebar doesn't consult it — so a box whose agent has no haproxy / logs / services / certificates gear still renders all those entries in the left nav. Clicking them lands the operator on an empty page or (post-PR fix(errors): emit JSON envelope from WriteHTTPError + harden fetch callers #114) a JSON-envelope error toast.
  • Run the same filter inside InjectIntegrationStatus so the sidebar shows only what the agent can actually serve for the active box.
  • Fail-open posture is preserved: an unreachable agent does not strip the sidebar, matching how the Gears settings page handles the same case.

Phase 2 slice of #112.

Test plan

  • go build ./... and go test -count=1 ./internal/framework/handler/... clean
  • Switch the header pill to a box whose agent reports only host/metrics/access-log — confirm the sidebar drops HAProxy / Logs / Services / Certificates entries while keeping Bx / Home / Metrics.
  • Switch back to a fully-capable box — confirm the full sidebar returns without a refresh issue.
  • Stop the agent on the selected box; reload — confirm the sidebar stays unchanged (fail-open).

🤖 Generated with Claude Code

filterGearsByAgentCapabilities is the framework's existing
capability-aware gear filter. Today it's only used by the Gears
settings page (`/settings/gears`) — so the **sidebar** still renders
HAProxy, Logs, Services, Certificates, etc. for an active box whose
agent doesn't run any of those gears. Clicking them lands the
operator on an empty page or a JSON-envelope error.

Run the same filter on the per-box integration list inside
InjectIntegrationStatus, so the sidebar reflects what the agent can
actually serve. Failures stay fail-open (an unreachable agent does
not strip the sidebar) by reusing the existing helper's contract.

Phase 2 slice of #112.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

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

This PR applies existing agent-capability filtering to sidebar integration rendering so the active box’s navigation better reflects what its agent can serve.

Changes:

  • Calls filterGearsByAgentCapabilities while building per-box sidebar integrations.
  • Preserves fail-open behavior when capabilities are unavailable.

Comment thread gearbox/internal/framework/handler/handler.go
Comment thread gearbox/internal/framework/handler/handler.go
Two findings:

1. Services dashboard gear had no entry in dashboardGearToAgentGear,
   so the sidebar filter passed it through unconditionally — the
   exact symptom this PR was supposed to fix. Map it to "metrics"
   (the agent gear that registers /api/v1/services per
   gearbox-agent/internal/gears/metrics/plugin.go), and document that
   this is imprecise: the agent's metrics gear can be Available on a
   host where systemd isn't introspectable from the container, so a
   tighter gate (an explicit `services` capability that advertises
   systemd reachability) is part of the Phase 2 extension in #112.

2. No regression test covered the middleware path or the filter's
   fail-open contract. Add three focused tests on
   filterGearsByAgentCapabilities driven by a real httptest.Server
   returning a CapabilitiesResponse:
   - Mjolnir-shaped probe table → only available gears + dashboard-
     only gears (alerts) survive.
   - Agent unreachable → fail open, full list passes through.
   - Older agent that doesn't surface a gear name at all → that gear
     is kept (forward-compat, mirrors the #116 fix).

The tests share a slim Handler fixture (logger, capabilities cache,
static servers slice) so they exercise the production fetch path
through CapabilitiesCache without needing a DB or auth manager.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sarg3nt
sarg3nt merged commit 852cb98 into main May 17, 2026
22 checks passed
@sarg3nt
sarg3nt deleted the fix/issue-112-sidebar-capability-filter branch May 28, 2026 16:59
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.

2 participants