Only the zap VM remains in the fleet. Remove orb/sun from the README
architecture/config docs, the getVMClassName allowlist, and their
.timeline-vm-tag color styles.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Targeted UI/UX polish on the Agents page, keeping the existing dark
aesthetic and both Overview/Live view modes:
- Add a readable --text-mute token (dark + light) and apply it to the
summary chips, lane meta, and idle/offline status, which previously
used the near-invisible --text-dim.
- Event feed: demote the generic "Span Started/Completed" label to a
quiet mono category tag and promote the tool name, with a left-edge
accent by event kind (run/span/error/session). Scoped to
#agents-content so other pages' feeds are unaffected.
- Active-op pills: add a per-kind left accent bar (tool/subagent/run).
- Lane sparkline: raise opacity and add a gradient so it actually reads.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The stats layer reads usage/duration only from run.end, but neither
framework populated them, so tokens/cost/avg-duration were always 0.
- hermes: accumulate token usage across each run's api-result calls in
session state and attach the summed usage plus a computed duration_ms
(from a stored runStartedAt) onto run.end. metric.snapshot emission is
unchanged, so there is no double counting.
- claude-code: store runStartedAt and use it as a duration_ms fallback at
all run.end sites. Usage is unavailable from CC hook inputs.
Live verification: a real hermes run now reports duration_ms and
total_tokens on run.end; dashboard tokens_today/avg_duration_ms, both
previously 0, now populate. cost_today stays 0 (no provider emits cost
through the hooks).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tool spans already carry duration_ms and status, but the metrics layer
only counted them. Expose that data:
- GetTopTools now returns avg/p95 duration and error count per tool.
- Timeseries buckets gain tool_avg_ms / tool_p95_ms (filtered
percentile_cont over tool spans).
- Dashboard Top Tools shows avg latency per tool; the Latency panel,
previously always empty (it read run-level duration that is never
emitted), now plots real tool-span latency (min/avg/p95).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce components.js with barTrack, barRow, barRankList, metricPill,
metricStrip, and chartHeader helpers. Migrate dashboard.js and usage.js
to use these primitives, replacing 13 families of duplicated CSS
(stat-list, fw-bar, token-bar, metric-pill, chart-insight, chart-header,
usage-chart-total, etc.) with a unified .am-* namespace. Net: -256 lines.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Usage page: add 7-day trend chart (activity/tokens/cost tabs),
framework breakdown panel with per-framework run/tool/error counts
and proportional bars, and 7d aggregate pills above the chart.
Dashboard: add avg cost/run metric pill to the metrics strip.
Run detail: extract and display prompt preview from the first agent
span's payload above the spans table.
Bug fixes: stat-list bars now render correctly (flex-direction:column),
right-panel-tab active background uses correct accent color, missing
framework colors added for hermes/codex/gemini/copilot. Dead code
renderSessionRow removed from sessions.js. Hardcoded font-family
replaced with CSS variable in metric-pill-value and token-stat-value.
Usage page cleanup() wired into router teardown.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers three improvements to /runs/🆔 prompt/error header callouts,
client-side span filter/search, and an interactive waterfall with hover
tooltips and inline detail drawers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ship the in-progress ES-module refactor of the web-ui (new static/modules/
layout, Usage/Settings pages, uplot-based dashboard) alongside a round of
security and UX fixes:
- main.go: add CSP + X-Frame-Options: DENY + X-Content-Type-Options:
nosniff + Referrer-Policy middleware on every response; WS CheckOrigin
now requires Origin host to match Host (blocks cross-site WebSocket
hijacking); upgrade client before dialing upstream so origin check
runs first; fatal on unparseable AGENTMON_QUERY_BASE.
- app.js: delegated click handler intercepts same-origin <a> clicks for
SPA navigation (prev. every nav link caused a full page reload,
dropping WS + in-memory state); delegated .copy-btn[data-copy]
handler replaces inline onclick=; removed window.navigate /
window.copyToClipboard globals and the duplicated handleGlobalSearch.
- modules/nav-signal.js: per-route AbortController so in-flight fetches
are cancelled when the user navigates away, preventing stale toasts
and wasted renders.
- modules/api.js: honours the nav signal by default; AbortError is
silent.
- modules/router.js: resets the nav controller on every route; dropped
the fixed 80ms transition delay; breadcrumbs no longer emit inline
onclick= (delegated handler picks them up).
- modules/utils.js: renderCopyButton emits data-copy=\"...\" instead of
nesting a JS string inside an HTML attribute — fixes an XSS where
values containing ' broke out via ' decoding.
Verified: go build clean; `node --check` clean on all modified modules;
manual curl probes confirm security headers present on every response
and WS upgrade returns 403 for cross-origin/missing Origin while 101
for same-origin.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
handleNotification("Done") was incorrectly emitting session.end and
calling clearState at the end of each Claude turn. Since "Done" means
a turn finished (not the session), clearing state caused subsequent
tool calls to find no runId, storing spans without run_id and making
them invisible in run-level queries.
- handleNotification: remove session.end emission and clearState call;
only emit run.end for the completed turn
- handleSessionEnd: load state file to get runId (in-memory activeRuns
is always empty in a subprocess)
- handlePromptSubmit: load state file to get runId for ending previous
run before starting a new one
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Label all agentmon docker-compose services with agentmon.monitor=true
and agentmon.group=agentmon so the swarm-monitor picks them up.
Adds Group field to ServiceSnapshot, probes /healthz for api/web roles,
and renders a separate "Agentmon" section below Swarm Services on the
Infrastructure page with new api and worker card renderers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace exec.CommandContext calls (docker ps, docker inspect, nc -z) with
direct HTTP calls over the Unix socket using Go's net/http + custom transport.
Also removes netcat-openbsd from Dockerfile since nc is no longer used.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add agent:bootstrap handler to capture run.start events for cron and
automation runs that bypass the message:received path
- Remove dead event subscriptions (tool_result_persist, session:compact:*)
which are plugin hook events and never fire through triggerInternalHook
- Remove AGENTMON_INGEST_URL from requires.env since handler has a
hardcoded fallback URL
- Drop activeCompactions map (no longer needed after removing compaction handlers)
Deployed to zap VM with hooks.internal.enabled=true in openclaw.json.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>