Skip to content

fix(webui): surface tool-level quarantine on the Servers list#5

Merged
electrolobzik merged 1 commit into
halo-mainfrom
fix/server-card-tool-quarantine-banner-halo-main
May 23, 2026
Merged

fix(webui): surface tool-level quarantine on the Servers list#5
electrolobzik merged 1 commit into
halo-mainfrom
fix/server-card-tool-quarantine-banner-halo-main

Conversation

@electrolobzik
Copy link
Copy Markdown
Collaborator

@electrolobzik electrolobzik commented May 23, 2026

Cherry-pick of the upstream PR onto halo-main so the Halo build picks up the fix without waiting on upstream review.

Upstream PR: smart-mcp-proxy#519

Problem

Servers added by setup.sh are registered with --no-quarantine and then have their tools auto-approved in a post-add poll. For OAuth-gated servers (atlassian), lazy-spawn servers, or anything that exceeds the ~90s approval-poll timeout, the server lands with quarantined=false but quarantine.pending_count > 0. The Servers list view treats that as a minor footnote: a tiny stat-desc under the tool count, hidden entirely behind X disabled whenever any tool is also disabled.

Meanwhile the detail page does show a yellow alert + Approve-All for the same state, so users hitting the daemon's quarantine pending approval error find clear remediation on Details but nothing on the list. They report the list as broken / inconsistent.

Change

  • New alert-warning banner on ServerCard.vue for tool-level quarantine, with a Review router-link to /servers/<name>?tab=tools. Mutually exclusive with the existing server-level banner.
  • Splits the stat-desc v-if / v-else-if chain so X disabled and N pending approval can render side-by-side.
  • Context-aware summary: "All N tools pending" / "N of M tools pending" / "N tools changed since approval" / mixed.
  • Extends ServerCard.test.ts with five new cases covering each path.

No backend change; quarantine.{pending_count,changed_count,blocked_count} is already on the REST + SSE response (see enrichServersWithQuarantineStats).

Test plan

  • Local tests pass (could not exercise in the sandbox, registry-side block on @guolao/vue-monaco-editor prevented npm install).
  • After bump in halo-tools: open mcpproxy Web UI, confirm yellow banner + Review link appears on Servers added with --no-quarantine whose tools weren't all auto-approved.
  • Manually quarantine a server → only the existing Server is quarantined banner shows (no double warning).

Summary by CodeRabbit

  • Bug Fixes

    • Improved quarantine status messaging with clearer distinction between server-level and tool-level warnings
    • Server quarantine alerts now display separately from tool warnings
    • Tool quarantine warnings now include review links and summaries of pending approvals
  • Tests

    • Added comprehensive test coverage for quarantine and tool-status UI scenarios

Review Change Stack

The Servers grid only renders the big orange "Server is quarantined"
banner + Approve button when `server.quarantined === true`. Servers
that are trusted at the server level but ship tools blocked by Spec 032
tool-level quarantine (pending / changed) had only a tiny `stat-desc`
under the tool count — easy to miss, and shadowed entirely by the
`X disabled` line when any tool was also disabled, because both lines
shared a `v-if / v-else-if` chain.

The asymmetry is confusing: the detail page DOES escalate tool-level
quarantine to a yellow alert panel with an Approve-All button, so users
who hit the "tool requires approval" error from the daemon find
clear remediation on Details but nothing on the list view. They report
the list as broken or inconsistent.

This commit:

* Adds a second `alert-warning` banner (`v-else-if="quarantineToolCount > 0"`)
  with a Review link that routes to `/servers/<name>?tab=tools`. Server
  and tool quarantine remain mutually exclusive on the card — the
  server-level banner already implies the tools won't run, so we don't
  stack two warnings.
* Splits the stat-desc `v-if / v-else-if` chain so `X disabled` and
  `N pending approval` can render side-by-side. Token-size hint stays
  the "nothing wrong" fallback.
* Computes a context-aware summary string:
  - "All N tools pending security approval" when every tool is pending
  - "N of M tools pending security approval" when partial
  - "N tools changed since approval — re-review needed" for rug-pull
  - mixed pending+changed when both apply

No backend change: the `quarantine.pending_count` / `changed_count` /
`blocked_count` block is already populated by
`enrichServersWithQuarantineStats` (REST + SSE).

Extends the existing ServerCard test with five new cases covering the
partial / full / changed / mixed-with-server-level / mixed-with-disabled
scenarios.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

📝 Walkthrough

Walkthrough

ServerCard component updates its quarantine UI from a single server-level alert to a two-tier system: server quarantine takes precedence with its own alert, otherwise tools show a quarantine banner with computed summary text and a Review link to the Tools tab.

Changes

Two-Tier Quarantine UI System

Layer / File(s) Summary
Tool Quarantine Summary Computation
frontend/src/components/ServerCard.vue
Adds toolQuarantineSummary computed that formats the tool-quarantine banner text by combining pending and changed tool counts, with logic to detect all-tools-pending vs rug-pull scenarios.
Quarantine Alert UI Logic
frontend/src/components/ServerCard.vue
Template reworked to split server-level and tool-level quarantine alerts: shows "Server is quarantined" when server.quarantined, otherwise renders tool-quarantine banner with summary and router link to Tools tab; adjusts Tools stats to use dedicated conditional for pending-approval indicator.
Quarantine Banner Tests
frontend/src/components/__tests__/ServerCard.test.ts
Adds comprehensive test cases for tool-quarantine banner (Review link, all-pending messaging, changed-tools messaging), server-level precedence blocking tool messages, and combined disabled/pending tool rendering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A server and tools, both needing care,
Now quarantine badges show who needs repair,
When tools await scanning, a banner appears,
Server takes precedence, calming all fears! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: surfacing tool-level quarantine warnings on the Servers list view.
Description check ✅ Passed The description covers the problem, solution, and testing approach comprehensively, though the testing checklist items are unchecked and note limitations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/server-card-tool-quarantine-banner-halo-main

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@frontend/src/components/ServerCard.vue`:
- Around line 125-136: The quarantine banner and its Review link are missing
Playwright data-test attributes; add them to the root banner div (the v-else-if
block rendering quarantineToolCount > 0), the summary span that displays
toolQuarantineSummary, and the router-link that navigates to
`/servers/${server.name}?tab=tools` (use clear identifiers like
data-test="tool-quarantine-banner", data-test="tool-quarantine-summary" and
data-test="tool-quarantine-review-link") so E2E tests can reliably target these
elements in ServerCard.vue.
🪄 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: 5d355b96-cf2d-4cc9-97c0-d7ab3b965f06

📥 Commits

Reviewing files that changed from the base of the PR and between eefa2d1 and 6225c42.

📒 Files selected for processing (2)
  • frontend/src/components/ServerCard.vue
  • frontend/src/components/__tests__/ServerCard.test.ts

Comment on lines +125 to +136
<div v-else-if="quarantineToolCount > 0" class="alert alert-warning alert-sm mb-4">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
</svg>
<span class="text-xs flex-1">{{ toolQuarantineSummary }}</span>
<router-link
:to="`/servers/${server.name}?tab=tools`"
class="btn btn-xs btn-warning"
>
Review
</router-link>
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add data-test attributes for Playwright E2E testing.

The new tool-level quarantine banner and Review link are missing data-test attributes. As per coding guidelines, Vue components in frontend/src/**/*.vue should use data-test attributes for E2E testing with Playwright.

Suggested additions
-      <div v-else-if="quarantineToolCount > 0" class="alert alert-warning alert-sm mb-4">
+      <div v-else-if="quarantineToolCount > 0" class="alert alert-warning alert-sm mb-4" data-test="tool-quarantine-banner">
         <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
           <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
         </svg>
         <span class="text-xs flex-1">{{ toolQuarantineSummary }}</span>
         <router-link
           :to="`/servers/${server.name}?tab=tools`"
-          class="btn btn-xs btn-warning"
+          class="btn btn-xs btn-warning"
+          data-test="tool-quarantine-review-link"
         >
           Review
         </router-link>
       </div>
🤖 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 `@frontend/src/components/ServerCard.vue` around lines 125 - 136, The
quarantine banner and its Review link are missing Playwright data-test
attributes; add them to the root banner div (the v-else-if block rendering
quarantineToolCount > 0), the summary span that displays toolQuarantineSummary,
and the router-link that navigates to `/servers/${server.name}?tab=tools` (use
clear identifiers like data-test="tool-quarantine-banner",
data-test="tool-quarantine-summary" and data-test="tool-quarantine-review-link")
so E2E tests can reliably target these elements in ServerCard.vue.

@electrolobzik electrolobzik merged commit f978fb9 into halo-main May 23, 2026
14 of 15 checks 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