Skip to content

v2.19.4 — unified certificate-creation flow, MCP lifecycle tools, refinements - #360

Merged
fabriziosalmi merged 43 commits into
mainfrom
ui-shots-bugfixes
Jun 28, 2026
Merged

v2.19.4 — unified certificate-creation flow, MCP lifecycle tools, refinements#360
fabriziosalmi merged 43 commits into
mainfrom
ui-shots-bugfixes

Conversation

@fabriziosalmi

@fabriziosalmi fabriziosalmi commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Unifies the certificate-creation and list surfaces into one flow, adds three MCP lifecycle tools toward REST parity, plus the refinements and broader UI sweep that landed alongside. No change to the issuance protocol.

Highlights

  • One creation flow for server and client certificates: a single right-side overlay drawer opened from a [ Server | Client | + New ] page-header cluster — no layout jump, available from either view.
  • Async issuance feedback in the list: an optimistic "Issuing" row, polled to Valid or to a Failed-with-Retry row.
  • The Cmd-K palette is the single search surface (cross-type + jump-and-flash); the per-page search boxes were removed, the topbar search is a lens icon, the stale Certificates link is gone, and logout is icon-only.
  • Status/usage filter chips, a compact stat strip, the regrouped detail modal (auto-renew in the banner; Deployment/Actions as aligned quick-action rows; danger-red delete), and the client table aligned to the server one.
  • MCP lifecycle tools (#358): certmate_delete_certificate, certmate_update_certificate (reissue in place), and certmate_get_certificate_file (raw PEM). A versions/rollback tool was deferred — it needs a backend revision-history endpoint that does not exist yet.
  • Plus a broad UI fix/polish sweep across the dashboard, settings, activity, notifications, and help.

Fix

  • POST /api/web/certificates/download/batch returned 500 — it called certificate_manager.get_certificate_path(), which does not exist. It now bundles each domain's fullchain.pem as <domain>.crt (cert-only), which the new Export ZIP action drives.

Testing

  • Full real-cert E2E suite green against the built Docker image: 13/13 in ~4m (Let's Encrypt staging via Cloudflare DNS-01, random subdomains) — create / renew / download / async-issuance, with the staging-issuer safety assertion.
  • MCP npm test: static + stdio-handshake smoke (16 tools) plus an offline behavioural test pinning each new tool's HTTP method/path/body.
  • theme-token and frontend-css gates pass locally; the test_pages toggle assertion was updated to the redesigned markup.

Full notes in RELEASE_NOTES.md (v2.19.4 section).

fabriziosalmi and others added 30 commits June 27, 2026 14:42
The top-bar icon-only buttons (search, shortcuts, logout) are bare
<button>s, not .btn, so the focus floor in input.css — which only
targeted a/summary — left them with no visible keyboard focus
indicator (WCAG 2.4.7) on the app-wide top nav. Extend the
focus-visible floor to button:not(.btn) and [role=button]:not(.btn);
.btn keeps its own ring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
help.html's container had py-6 sm:px-6 lg:px-8 with no base px-4, so
every content card sat flush to the viewport edge < 640px (rounded
corners clipped, looks broken) while the search/nav above were inset.
Same defect fixed for index/settings/activity in #337 but missed on
help. Add px-4 to match index.html.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Snoozing or unsnoozing an expiry warning fired CertMate.toast(..., 'info')
— a neutral blue toast — for a completed positive action. Same
success-shown-as-info class as the dashboard cert-created bug, separate
call site. Use the 'success' (green) variant.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The empty, all-snoozed and load-error states put the icon and text in a
text-center div relying on `block` on the <i>, but the FontAwesome
webfont keeps the icon inline, so icon and label rendered glued on one
line. Switch the container to flex flex-col items-center gap-3 and wrap
the label in <p>, which stacks reliably regardless of the icon display.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Auto/Light/Dark segmented control marked the active option with
aria-pressed:bg-surface on a bg-surface-2 track; in dark mode those two
grays are nearly identical, so the selected segment was indistinguishable
— the control's whole job. Add an aria-pressed primary ring so the active
state reads clearly in both themes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 11-tab Settings strip lives in an overflow-x-auto container, but on
overlay-scrollbar platforms (macOS) the scrollbar is hidden until you
scroll, so at tablet width five tabs (Probe/Users/API Keys/SSO/Backup)
clipped off-screen with no hint they exist. Add a .scroll-x-affordance
utility (thin always-present scrollbar once content overflows) and apply
it to the tab container.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Snooze control is a <details>/<summary> that opens a duration menu,
but with list-none and no marker it looked identical to the plain View
link beside it — nothing signalled it expands. Add a chevron-down so the
disclosure affordance is visible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 'Common endpoints' list was a bare font-mono <ul>, unlike the curl
blocks beside it which use <pre overflow-x-auto>. The longest path
reached the card edge and would wrap mid-token / clip on narrow screens.
Add overflow-x-auto + whitespace-nowrap so long endpoints scroll cleanly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…p form

The setup wizard auto-launched on pathname '/', but '/' also serves
setup.html (the admin-creation form) when no users exist yet, so on first
run the 'Welcome to CertMate' wizard rendered on top of the
username/password setup form — two competing first-run flows on the most
trust-sensitive screen. Gate the auto-launch on the absence of the setup
form (#setupForm): setup.html owns first-run, the wizard owns dashboard
onboarding once an admin account exists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Related Activity-log display defects from the screenshot review:
- Filter matched only the exact operation, so 'Created' hid create_account
  and batch_create, and update/deploy were not filterable at all. Match the
  operation family (op, op_*, batch_op); add Updated/Deployed options.
- 'All user activity' relabelled 'All operations' (it filters operations,
  not users).
- opLabel humanizes any unmapped operation instead of leaking raw
  snake_case (update, create_account, oidc_config_changed, ...).
- Filtered-empty state no longer claims 'No activity recorded yet' when a
  filter matched nothing: shows 'No activity matches the current filters'
  plus a Clear-filters action; filter changes reset pagination.
- Resource line humanizes resource_type and drops the tautological id
  ('settings: settings').
- Copy-JSON confirmation uses a success (not info) toast.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The mobile/tablet table reused the desktop column layout with hard
truncation:
- Domain truncated to a few characters on phones (max-w-0 + truncate).
  Let it wrap below md (break-words md:truncate, md:max-w-0) so the full
  name is visible.
- Mobile 'days left' was clipped to a bare number ('8 …'). Drop the
  truncate on the mobile expiry line so the unit and date survive.
- Tablet (768-1023px) showed neither the Provider/Deployment columns
  (lg-only) nor the mobile meta block (md:hidden), so both vanished. Show
  the meta block through lg (lg:hidden) and keep the expiry line
  mobile-only (md:hidden, the Expires column covers tablet), filling the
  gap without double-rendering.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 'Deployed' stat card showed a pulsing '...' placeholder with a static
  'reachable' subtitle even with zero certs. Render 0 / 'none deployed'
  when there are no certs, and use a calmer em-dash loading glyph otherwise.
- 'Expired' card sub-label read 'N expiring soon' under the expired count
  — two unrelated metrics. Lead with the action ('renew now') and append
  the expiring count as clearly-secondary context.
- Row action icons were text-gray-400, barely visible on dark rows until
  hover. Use text-gray-500 dark:text-gray-300 for a visible resting state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On the long form tabs (General/DNS/CA/Storage) the Save button sat at the
very bottom, reachable only after scrolling the whole form — never visible
beside the fields being edited. Pin the submit row to the viewport bottom
(sticky bottom-0) while scrolling; it already lives in #formControls which
x-shows only on the four form tabs, so the auto-save tabs are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Regenerate static/css/tailwind.min.css so the new utility classes used by
the fixes (scroll-x-affordance, aria-pressed ring, break-words/md:max-w-0,
flex-col empty states, sticky save footer) are present in the committed
bundle (frontend-css stale-bundle gate).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
UI_SHOTS_ANALYSIS.md is an internal DO-NOT-COMMIT working doc, like
UI_AUDIT.md and UI_DRACONIAN_ANALYSIS.md which are already ignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… CTA

The Generate button (mints a secure API token) was a low-emphasis gray
control that read as disabled next to the icon-only eye toggle. Make it an
outline-primary secondary CTA so it reads as the recommended action.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ty color

The summary line, the group headers and every row's meta all repeated the
same red/amber, so the card read as a wall of color. Make the summary text
neutral (text-foreground) with a small coloured count badge, letting the
grouped rows carry the severity colour and giving the card tonal hierarchy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Help prose used the full max-w-7xl card width (~150+ chars/line) on wide
viewports. Cap paragraphs inside help sections ([data-help-section] p) to a
65ch reading measure; tables, code blocks and the API grid are not <p>, so
they keep full width.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "What's new" section and nav pill only linked to RELEASE_NOTES.md on
GitHub, duplicating the "Full changelog" link two pills over. Remove both;
the changelog link stays.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…glyph

The top-bar nav marked the active item with colour only (text-primary),
invisible to colour-blind users, and the Certificates glyph (fa-certificate)
read as a starburst. Add a border-b-2 underline accent on the active item
(border-transparent otherwise so heights match) and switch to
fa-shield-halved. Stays icon-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Each row showed only a relative time ('2h ago') with the absolute behind a
title tooltip, unreachable on touch. Add a compact absolute line (month/day
+ HH:MM) under the relative so the exact moment is always visible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The icon column fell back to an identical grey fa-circle for the dominant
operations (update, create_account, ...), so it carried no information. Map
all ~25 operations to a family-based glyph+colour system (green=create,
blue=update, cyan=renew, red=delete/revoke, purple=deploy, indigo=download,
teal=restore, amber=auto-renew/test, slate=maintenance) so the column triages
at a glance. Unknown ops still fall back to a grey circle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The three sections (Appearance / Certificate Management / API Security) were
identical flat tinted boxes of equal weight, so security-sensitive settings
read the same as the cosmetic theme picker. Drop the tinted boxes for plain
sections separated by border-t dividers with stronger semibold headings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The action column showed 5-6 identical icons (renew, force-renew, download,
API, auto-renew, delete) with the destructive delete inline at the same
weight. Keep the daily-use Renew + Download inline and move force-renew,
API, auto-renew and delete into a '...' overflow menu (delete separated and
red). The menu is appended to <body> as position:fixed so the table's
overflow wrappers don't clip it, with click-away + Escape to close.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…C1/S1)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…cluster (redesign phase 1)

First phase of the unified creation-flow redesign (variant C). Replace the
in-body Server/Client tab buttons + the inline 'Create New Certificate'
expand-in-place form (which pushed the page down on open) with:
- a page-header cluster [ Server | Client | New ]: segments are ghost state
  toggles, New is a filled imperative action that opens the drawer;
- a right-side creation DRAWER (overlay, scrim + Esc + scroll-lock) holding the
  existing create form, relocated out of the inline layout. No field IDs
  changed, so the submit handler is untouched; it now also closes the drawer
  on success.

Stats, the certificate table and the client view are unchanged this phase.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e 2)

Phase 2 of the creation-flow redesign. The drawer now holds BOTH types,
switched by a [ Server | Client ] type segment (preset from the active view,
locally overridable). Client creation (single + bulk CSV) was extracted from
the inline card in _client_certs.html into partials/_client_create.html and
included in the drawer; all field IDs are unchanged, so client-certs.js binds
them as before (lazily re-init'd when the client form is first shown). The
drawer moved out of the server x-show so it is available from either view, and
'+ New' now opens it preset to the current view. This kills the original
asymmetry (server-behind-toggle vs client-always-inline) — both types use the
same overlay now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
UI_REDESIGN_PLAN.md and UI_UX_Opinioni_CertMate.pdf are internal
DO-NOT-COMMIT working docs, like the other UI_* docs already ignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ign phase 3)

Phase 3 of the creation-flow redesign. Fresh server-cert creates now opt into
async issuance (async:true on the body). On a 202 the drawer closes immediately
and an optimistic "Issuing" row is prepended to the table; a poller on
/api/certificates/jobs/<id> resolves it to the real certificate on success (via
loadCertificates) or to a "Failed" row carrying the failure reason plus Retry /
Dismiss actions. Reissue stays synchronous — it edits a row that already exists,
so an optimistic new row would be wrong. When the server has no async executor
it ignores the flag and replies synchronously (200), which the same handler
falls through to, so the change degrades gracefully.

SSE is unchanged: certificate_created already owns the success toast + reload,
and there is no certificate_failed handler for creates, so the poller is the
sole owner of the failure UX (no duplicate toast).

- displayCertificates re-attaches pending rows after any full rebuild, so an
  SSE/reload triggered by another event never drops an in-flight optimistic
  row; a job whose real certificate has already landed is skipped to avoid a
  duplicate Issuing/Valid pair.
- Retry re-POSTs the captured payload; Dismiss clears a failed row. Both are
  exposed on window for the inline row handlers.
- The sync-success field reset was factored into clearCreateFormAfterSubmit()
  and shared by both paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fabriziosalmi and others added 8 commits June 28, 2026 03:10
…redesign phase 4)

Phase 4 of the creation-flow redesign. The global command palette becomes the
one search surface (closes the D1 "triple search" opinion), and the redundant
per-page search boxes are retired.

cmd-palette.js:
- Cross-type search: prefetches client certificates (/api/client-certs) alongside
  server certs and groups results under "Server Certificates" / "Client
  Certificates". Results refresh when either fetch resolves while the palette is
  open (previously certs only appeared after the first keystroke).
- Open-drawer actions: "New Server Certificate" / "New Client Certificate" open
  the creation drawer preset to that type (the old "Create Certificate" focused
  the retired inline #domain). Cross-page, they stash cm_open_drawer and navigate
  to the dashboard, which opens the drawer on load.
- Jump-and-flash: selecting a server cert ensures the server view and pulses the
  matching row in place (cmd-flash, a brief primary-tinted double-pulse); from
  another page it navigates with ?flash=<domain> and pulses once the list loads.
  Client-cert results switch to the client view (row-level flash lands with the
  client table in phase 5).

Retired per-page searches → palette:
- Dashboard #certificateSearch and client #searchInput removed; filterCertificates
  / ccFilterCertificates now filter by status/usage only; clearFilters and the
  empty-state "isFiltered" check updated. The status (and client usage/status)
  filters stay — they become chips in phase 5.
- The "/" shortcut now always opens the palette (was: focus the dashboard search).
- Kept the help page's in-page section filter: it filters documentation blocks,
  not cert data, so the palette doesn't replace it — removing it would be a
  regression. (Plan listed it for removal; deliberately deviated.)

Supporting: rows carry data-row-domain for flash targeting; window.flashCertRow +
maybeFlashCertFromQuery added; the two view-cluster buttons got ids
(certViewServerBtn / certViewClientBtn) so the palette can switch views.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… (redesign phase 5)

Phase 5 of the creation-flow redesign.

Status chips replace the #statusFilter <select>: a row of [All|Valid|Expiring|
Expired] chips, each showing a live count and lighting up in its status colour
when active (aria-pressed drives the styling, so it stays accessible). They are
the single source of truth via a currentStatusFilter module var — filterCertificates,
clearFilters and the empty-state "isFiltered" check all read it; updateStats keeps
the counts in sync. The chips are filtering only (jump-to-cert lives in the ⌘K
palette — separate gestures, per the variant-C decisions).

Compact stat strip: the four KPI tiles (server and client) drop from chunky cards
to a tighter single row — icon+label inline, a smaller hero number, the subtitle
hidden below sm so four tiles fit in one row even on phones. Server (statCard +
skeleton in dashboard.js) and client (_client_certs.html) share one vocabulary.

Client list: the sortable table already existed; its bare "No client certificates
found" row becomes a styled empty-state — an id-card glyph, a short pitch, and a
"New Client Certificate" CTA that opens the client drawer. A filtered-but-empty
result shows a distinct "no matches" hint instead. The By Usage tile truncates to
one line with the full breakdown on hover.

Verified (browser, light + dark): chips filter + colour correctly across all four
states; the strip renders as a single row both views; the empty-state CTA opens
the client drawer. No console errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…11y polish (redesign phase 6)

Final phase of the creation-flow redesign — polish across what phases 1-5 built.

Mono machine-values: a .cm-mono class (JetBrains Mono stack + tabular-nums, one
semantic hook) renders identifiers in the mono face so hostnames are easy to scan
and compare. Applied to server domain names and client common names; the cert
detail panel already used font-mono for its title/SANs.

A11y — drawer focus trap: the creation drawer is aria-modal, but Tab could escape
to the page behind it. openCertDrawer now traps Tab/Shift+Tab within the drawer's
visible controls (the hidden server/client form is excluded via offsetParent) and
remembers the opener; closeCertDrawer restores focus to it (the +New button, a
palette action, or the empty-state CTA). prefers-reduced-motion is already handled
globally, and the slide uses motion-reduce:transition-none.

Responsive: verified the redesigned surface at 375 / 560 / 1280 — no horizontal
overflow, the compact stat strip stays a single row of four, the status chips fit
on one row by 560 (wrap to two on the narrowest phones), the nav cluster fits, and
the table falls back to its stacked mobile-card layout. Confirmed in light and dark.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
POST /api/web/certificates/download/batch called
certificate_manager.get_certificate_path(), which does not exist on the
manager — every batch export raised AttributeError and returned 500. The
loop already has the per-domain directory from _sanitize_domain(), so bundle
<domain>/fullchain.pem directly as <domain>.crt. Cert-only by design: a bulk
export must never leak private keys.

This unblocks the new "Export ZIP" list action.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…icon-only

- The labelled "Search ⌘K" box becomes a plain magnifying-glass icon (a click
  just opens the command palette, so the box was redundant). It now sits where
  the Certificates link was — visible at all widths so mobile keeps search.
- Removed the stale Certificates topbar link: the logo still links home and the
  Server/Client toggle handles cert navigation.
- Logout is icon-only now (the red danger border/hover stays).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…up, list-action icon group

Several requested refinements to the server dashboard:

- Counters moved up into the Server/Client/+New toggle's row at the same
  height, freeing the separate stat row. Dropped the Deployed counter; number
  and label sit on one line ("7 TOTAL"). State shows in the number colour.
- Cert-detail modal regrouped: Auto-Renew moved into the status banner; the
  Deployment and Actions sections are now two columns of quick-action buttons
  on one row each; the two deploy indicators became squares matching the
  buttons; the delete action is danger-red (matching Logout) and still confirms.
- The "Check All" button became a quick-action icon group: Check all / Export
  ZIP / Refresh (Debug folded in, still hidden by default). Added
  exportAllCertificates() driving the batch-download endpoint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…er, filter chips + actions

Brings the client view to parity with the server one:

- Counters mirror the server strip in the toggle row (Total / Active / Revoked;
  By Usage dropped to match the three-counter shape).
- The list header matches the server table: same thead (sticky + blur), card
  chrome (no more blue gradient), rows carry the status-coloured left border
  (active/expiring/revoked) and the mono CN.
- The usage/status selects became filter chips (status with live counts) plus a
  Refresh action — same vocabulary as the server list header.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds .cm-icon-btn (quick-action icon button) and .cm-chip (filter chip base)
in @layer components so single-utility overrides like `hidden` still win over
the component's own display, and rebuilds the minified bundle for the new
classes used by the dashboard and client list headers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@fabriziosalmi fabriziosalmi self-assigned this Jun 28, 2026
Comment thread static/js/dashboard.js Fixed
fabriziosalmi and others added 3 commits June 28, 2026 06:01
The dashboard header's toggle was relabelled from "Server Certificates" /
"Client Certificates" to "Server" / "Client" in the creation-flow redesign.
Pin the stable button ids (certViewServerBtn / certViewClientBtn) instead of
the prose so the test tracks the toggle's presence, not its wording.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…#358)

Three tools toward REST/UI parity for agentic certificate management:

- certmate_delete_certificate(domain) -> DELETE /api/certificates/<domain>.
- certmate_update_certificate(domain, sans?, domain_alias?) -> POST
  /api/certificates/<domain>/reissue. Omitting sans keeps the current SAN set
  ([] drops all); the primary domain cannot change. May return a job_id (202).
- certmate_get_certificate_file(domain, file) -> GET .../download?file=<file>,
  returned as raw PEM text (not JSON-wrapped) for direct use by HAProxy/nginx.

The versions/rollback tool from the issue is deferred — it needs a backend
certificate-revision-history endpoint that does not exist yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spawns the server against a local mock CertMate (no running instance needed),
calls each new tool over stdio, and asserts the HTTP method, path and body it
emits — including that update omits san_domains when sans is absent and that
get-file returns raw PEM rather than a JSON wrapper. Wired into `npm test`
alongside the existing static + handshake smoke test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@fabriziosalmi fabriziosalmi changed the title v2.19.3 — unified certificate-creation flow, dashboard and topbar refinements v2.19.4 — unified certificate-creation flow, MCP lifecycle tools, refinements Jun 28, 2026
@codecov

codecov Bot commented Jun 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 25.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.99%. Comparing base (39e2803) to head (48d6f26).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #360   +/-   ##
=======================================
  Coverage   70.99%   70.99%           
=======================================
  Files          50       50           
  Lines       11953    11953           
=======================================
  Hits         8486     8486           
  Misses       3467     3467           
Flag Coverage Δ
unittests 70.99% <25.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

fabriziosalmi and others added 2 commits June 28, 2026 06:30
The jump-and-flash row lookup interpolated the (user-derived) domain into a CSS
attribute selector with an incomplete fallback escape (only quotes, not
backslashes — CodeQL js/incomplete-string-escaping). Match the row by reading
data-row-domain directly instead, removing the selector and the escaping
subtlety entirely.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump version and add release notes for the three MCP certificate-lifecycle
tools (delete / update / get-file, #358) on top of the unified creation-flow
redesign and the broader UI sweep.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@fabriziosalmi
fabriziosalmi merged commit 7c3a403 into main Jun 28, 2026
9 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.

2 participants