Skip to content

feat(ui): add A2A Case Inspector and Dashboard views#17

Merged
jinon86 merged 26 commits intomainfrom
dungae/a2a-inspector-phase1
Apr 19, 2026
Merged

feat(ui): add A2A Case Inspector and Dashboard views#17
jinon86 merged 26 commits intomainfrom
dungae/a2a-inspector-phase1

Conversation

@seoseo-ai
Copy link
Copy Markdown
Collaborator

Summary

Closes #13 (Phase 1)

Implements the read-only A2A Case Inspector and Dashboard list view in Control UI.

New files (3)

  • controllers/a2a.ts — RPC controller for a2a.task.list, a2a.task.detail, a2a.dashboard
  • views/a2a.ts — Dashboard list view (summary counts, alerts, filter chips, task table, click-to-inspect)
  • views/a2a-inspector.ts — Case inspector (header strip, transcript, timeline, decision card, proposal panel, artifacts, diagnostics, raw drilldowns, Phase 2 trading placeholder)

Modified files (6)

  • types.ts — A2ATaskStatusCategory (6), A2ATaskWorkerView (10), detail/list/dashboard types
  • navigation.ts — a2a tab in Control group
  • app-view-state.ts — 9 A2A state fields
  • app.ts@State() A2A properties
  • app-render.ts — A2A view rendering (inspector when taskId selected, dashboard otherwise)
  • app-settings.ts — A2A data loading in refreshActiveTab

Notes

  • UI-only changes. No backend modifications.
  • Graceful loading/error states for all panels.
  • Ready for gateway RPC integration when backend is available.
  • Phase 2 (trading inspector) gated on broker read model — placeholder included.

Acceptance criteria from #13

  • Operator can inspect one case without switching between raw endpoints
  • Transcript and timeline are readable and stable
  • Decision and evidence chain visible in same screen
  • Trading thesis→outcome rendered as separate stages when data available (placeholder)

steipete and others added 5 commits April 19, 2026 08:43
@jinon86 jinon86 force-pushed the dungae/a2a-inspector-phase1 branch 2 times, most recently from 2ce0ae3 to 8400b1e Compare April 19, 2026 08:44
mbelinky and others added 3 commits April 19, 2026 10:56
* tasks: extract detached task lifecycle runtime

* tests: relax gateway seam expectation

---------

Co-authored-by: Mariano Belinky <mariano@mb-server-643.local>
…chen-zhang-cs-code)

* fix(cron): parse PowerShell tools allow list

* fix(cron): clarify tools allow-list help

* fix: parse PowerShell cron tools allow-list (openclaw#68858) (thanks @chen-zhang-cs-code)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
@jinon86 jinon86 marked this pull request as draft April 19, 2026 09:42
@jinon86 jinon86 marked this pull request as ready for review April 19, 2026 09:42
openclaw#68715)

* fix(browser): discover CDP websocket from bare ws:// URL before attach

When browser.cdpUrl is set to a bare ws://host:port (no /devtools/ path), ensureBrowserAvailable would call isChromeReachable -> canOpenWebSocket against the URL verbatim. Chrome only accepts WebSocket upgrades at the specific path returned by /json/version, so the handshake failed immediately with HTTP 400. With attachOnly: true, that surfaced as:

  Browser attachOnly is enabled and profile "openclaw" is not running.

even though the CDP endpoint was reachable and the profile was healthy. Reproduced by the new tests in chrome.test.ts and cdp.test.ts (openclaw#68027).

Fix: introduce isDirectCdpWebSocketEndpoint(url) — true only when a ws/wss URL has a /devtools/<kind>/<id> handshake path. Route any other ws/wss cdpUrl (including the bare ws://host:port shape) through HTTP /json/version discovery by normalising the scheme via the existing normalizeCdpHttpBaseForJsonEndpoints helper. Apply this in isChromeReachable, getChromeWebSocketUrl, and createTargetViaCdp. Direct WS endpoints with a /devtools/ path are still opened without an extra discovery round-trip.

Fixes openclaw#68027

* test(browser): add seeded fuzz coverage for CDP URL helpers

Adds property-based / seeded-fuzz tests for the URL helpers the
attachOnly CDP fix depends on (openclaw#68027):

  - isWebSocketUrl
  - isDirectCdpWebSocketEndpoint
  - normalizeCdpHttpBaseForJsonEndpoints
  - parseBrowserHttpUrl
  - redactCdpUrl
  - appendCdpPath
  - getHeadersWithAuth

Follows the existing repo convention (see
src/gateway/http-common.fuzz.test.ts): no fast-check dep, small
mulberry32 PRNG + hand-rolled generators, deterministic per-describe
seeds so failures are reproducible.

Lifts cdp.helpers.ts coverage from 77.77% -> 89.54% statements,
67.9% -> 80.24% branches, 78% -> 90% lines. Remaining uncovered
lines are inside the WS sender internals (createCdpSender,
withCdpSocket, fetchCdpChecked rate-limit branch), which require
integration-style mocks and are unrelated to the attachOnly fix.

* test(browser): drive cdp.helpers/cdp/chrome to 100% coverage

Lifts the three files touched by the openclaw#68027 attachOnly fix to 100% statements/branches/functions/lines across the extensions test suite. Adds cdp.helpers.internal.test.ts, cdp.internal.test.ts, and chrome.internal.test.ts covering error paths, branch matrices, CDP session helpers, Chrome spawn/launch/stop flows, and canRunCdpHealthCommand. Defensively unreachable guards are annotated with c8 ignore + inline justifications.

* fix(browser): restore WS fallback for non-/devtools ws:// CDP URLs

When /json/version discovery is unavailable (or returns no
webSocketDebuggerUrl), fall back to treating the original bare ws/wss
URL as a direct WebSocket endpoint. This preserves the openclaw#68027 fix for
Chrome's debug port while restoring compatibility with Browserless/
Browserbase-style providers that expose a direct WebSocket root without
a /json/version endpoint.

Priority order for bare ws/wss cdpUrl inputs:
  1. /devtools/<kind>/<id> URL \u2192 direct handshake, no discovery (unchanged)
  2. bare ws/wss root \u2192 try HTTP discovery first; if discovery returns a
     webSocketDebuggerUrl use it; otherwise fall back to the original URL
     as a direct WS endpoint
  3. HTTP/HTTPS URL \u2192 HTTP discovery only, no fallback (unchanged)

Affected call sites: isChromeReachable, getChromeWebSocketUrl,
createTargetViaCdp.

Also renames a misleading test ('still enforces SSRF policy for direct
WebSocket URLs') to accurately describe what it tests: SSRF enforcement
on the navigation target URL, not on the CDP endpoint.

New tests added for all three fallback paths. Coverage remains 100% on
all three touched files (238 tests).

* fix: browser attachOnly bare ws CDP follow-ups (openclaw#68715) (thanks @visionik)
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8400b1e9d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

</div>
</div>
${artifact.uri
? html`<a href=${artifact.uri} target="_blank" rel="noopener noreferrer">Open</a>`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Sanitize artifact URIs before rendering external links

artifact.uri comes from task payload data and is inserted directly into an anchor href, so a malicious case payload can supply unsafe schemes (for example javascript:) and execute code when an operator clicks Open. This UI already has safe URL helpers (open-external-url.ts) that enforce protocol allowlists; this path should use the same validation before exposing clickable links.

Useful? React with 👍 / 👎.

mbelinky and others added 5 commits April 19, 2026 12:21
…penclaw#68891)

* browser: route user profile through browser nodes

* browser: align existing-session node docs

* browser: preserve host fallback on node discovery errors

* browser: preserve configured node pin errors

* browser: widen config mock in node pin test
Co-authored-by: termtek <termtek@ubuntu.tail2b72cd.ts.net>
)

* tasks: register detached runtime plugins

* tasks: harden detached runtime ownership

* tasks: extract detached runtime contract types

* changelog: note detached runtime contract

* changelog: attribute detached runtime contract
@jinon86 jinon86 merged commit e08bd32 into main Apr 19, 2026
49 checks passed
@jinon86
Copy link
Copy Markdown
Owner

jinon86 commented Apr 19, 2026

Landed clean after green CI.

Thanks @seoseo-ai!

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.

[dungae] Build the A2A Case Inspector and trading inspector UI