Skip to content

v1.5.0 — Observability, Dashboard Customization & Hardening#196

Merged
s-b-e-n-s-o-n merged 359 commits intomainfrom
feature/v1.5-observability
Mar 30, 2026
Merged

v1.5.0 — Observability, Dashboard Customization & Hardening#196
s-b-e-n-s-o-n merged 359 commits intomainfrom
feature/v1.5-observability

Conversation

@s-b-e-n-s-o-n
Copy link
Copy Markdown
Contributor

@s-b-e-n-s-o-n s-b-e-n-s-o-n commented Mar 22, 2026

Summary

v1.5.0 brings real-time observability, a fully customizable dashboard, and significant hardening across the stack.

Highlights

  • Real-time container logs — WebSocket streaming with ANSI color rendering, JSON pretty-print, search/filter, pause/resume
  • System log streaming — Live WebSocket delivery with level and component filtering
  • Customizable dashboard — Drag-and-drop widget layout, resize, show/hide, progressive collapse at small sizes
  • Container resource monitoring — CPU/memory stats with ring-buffer history and Prometheus metrics
  • Debug dump endpoint — One-click diagnostics download with sensitive value redaction
  • Digest notification mode — Accumulate updates and send a single batch email on a cron schedule
  • Success toasts — Visual confirmation for every container action (update, start, stop, restart, scan, delete, rollback, trigger run)
  • View Containers navigation — Jump from Watchers/Agents detail panels directly to filtered container list
  • Trigger aliasesDD_ACTION_* and DD_NOTIFICATION_* prefixes alongside legacy DD_TRIGGER_*

Bug Fixes

Security

  • WebSocket origin validation and closed-socket error handling
  • Auth lockout with configurable threshold and expiry
  • Debug dump redacts sensitive environment variables

Infrastructure

  • CI workflow renames (drop numeric prefixes)
  • Stryker mutation testing dashboard reporting
  • .stryker-tmp gitignored + excluded from vitest
  • Security policy updated to latest-only

Test plan

  • 219 commits, all gitmoji conventional commit format
  • Full QA checklist (184/200+ items verified via Playwright + code review)
  • Lefthook pre-push: all 7 gates green (ts-nocheck, biome, qlty, build-and-test, e2e, e2e-playwright, clean-tree)
  • UI: 2054 tests passing, 100% coverage thresholds
  • App: 11700+ tests passing, 100% coverage thresholds
  • E2E + Playwright E2E passing
  • Docker build succeeds
  • All 11 open issues addressed (8 fixed, 2 config/awaiting user, 1 responded)

Closes #156, #180, #183, #184, #186, #187, #189, #192, #195, #200

🤖 Generated with Claude Code

Defer trimming until the array exceeds 2x the configured max instead of
splicing on every insertion past the limit. Read methods already use
slice(-limit) so they return correct results regardless of array size.
…thods

Cover network errors (ECONNREFUSED, ETIMEDOUT), timeout, rate limit
(429), and HTTP error propagation in Hub, Dhi, Gitlab, Gcr, Gar, Mau,
and Lscr authenticate() methods. Also cover Hub getImagePublishedAt
error propagation for network, 404, and 429 scenarios.
status and kind query params are already pushed down to the store as
updateAvailable and updateKind.* filters. Remove them from the
full-collection-load gate so the store handles pagination directly,
avoiding loading all matching containers into memory just to slice a page.

Only sort (non-default) and maturity still require the full collection
since they need JS-level computation across all items before pagination.
Modularize container list query logic into focused single-concern files:
list-query-validation, maturity, pagination, query-filters, query-values,
sorting, and update-age.
- Add centralized WebSocket log stream config (rate limits, close codes)
- Add shared mock factories to reduce test setup boilerplate
Extract focused test suites for configuration/container-ops, lifecycle
rollback, self-update compose sync, and trigger prune progress with
shared test helpers.
Replace expect.objectContaining() with exact object assertions across
API test suites to strictly enforce response contracts.
Add `**/*.test.helpers.ts` to tsconfig exclude — test helpers using
vitest globals leaked into tsc compilation and broke Docker builds.
…avigation

- Add Escape keydown listener to close customize panel when in edit mode
- Change stat cards from <div> to <button> so interactjs dragIgnoreFrom
  excludes them, fixing Registries card click-to-navigate
- Add Registries card to navigation test coverage
Extend the status query parameter to accept running, stopped, exited,
paused, restarting, dead, and created in addition to update-available
and up-to-date. Runtime statuses filter by container state; update
statuses filter by update availability.
Change getDebugDumpFilename from full ISO timestamp to YYYY-MM-DD
format for cleaner filenames. The .json extension was already present
but the timestamp noise made it hard to see.
Add backface-visibility, will-change, and overflow:hidden to
view-transition pseudo-elements to prevent black bar artifacts
at overflow boundaries during circular clip-path reveal.
Start clip-path at 0.5% instead of 0% to avoid zero-area rendering.
Enable grid-layout-plus responsive mode with breakpoints:
- lg (≥1024px): 12 columns (desktop)
- md (≥768px): 6 columns (tablet)
- sm (≥640px): 2 columns (large phone)
- xs/xxs (<640px): 1 column (phone, full-width stacking)
…er list

- sort: name, status, updated, created with order: asc/desc
- kind: watched (dd.watch=true), unwatched (no label), all
- Applied after filtering, before pagination
- Legacy wud.watch label supported as fallback
…lently dropping them

Containers whose image reference is a raw sha256 digest with no
RepoTags were silently filtered out of results, making them invisible
in the UI. Now falls back to RepoDigests to extract the image name,
or uses 'unknown' tag as last resort. The container appears in the UI
with update checking gracefully skipped.

Fixes: #192
Move dropdown outside DataFilterBar slot to avoid overflow clipping
and switch from right to left-based positioning to avoid scrollbar
width mismatch. Matches ContainersView pattern.

Fixes: #187
- resolveImageName now logs container name alongside sha256 digest
- Container processing error logs include container display name
  instead of just hex ID
- Helps users identify which container is causing warnings

Ref: #191
…info

First reconnect attempt is expected behavior (proxy timeout, network
blip) and resolves automatically. Log as info to reduce noise.
Subsequent failures still log as warn.
- Format v1.4 docs (markdownlint blank lines around lists/fences)
- Add language spec to fenced code block in container.mdx
- Fix shellcheck warnings in cpu-bench.sh
- Search test: use "nginx" instead of "postgres" (more reliably discovered)
- Detail panel: clear search filter before opening, use force clicks to
  bypass banner occlusion, accept stopped-container log view state
- Dashboard scroll: relax maxScroll assertion for 6-row cap
- Banner dismiss: wait for dismiss button visibility before iterating
ALARGECOMPANY
ALARGECOMPANY previously approved these changes Mar 30, 2026
The trigger and triggerBatch methods were only escaping body text in
some code paths, causing Telegram API 400 errors when container names
or version numbers contained reserved MarkdownV2 characters (dots,
dashes, parentheses, etc.). Now all paths escape via a format-aware
helper that uses escapeMarkdown for MarkdownV2 and escapeHtml for HTML.

Fixes: discussion #211
- index.ts: remove version interpolation from startup log to prevent
  log injection via crafted package.json
- migrate.ts: replace version-interpolated log with static message
- podman-redirect-guard: 404 handler no longer reflects request URL
  in response body (XSS); added integration test for verification
- apply-sri.mjs: use readdirSync withFileTypes to eliminate TOCTOU
  race between stat() and read()
- Docker.containers.test.ts: remove 8 unused factory functions (OIDC,
  device flow, token response, registry state adapters)
- Docker.test.ts: remove unused factory functions, move mockImage to
  proper describe scope
- ButtonStandard.spec.ts: use JSDOM for HTML text extraction instead of
  regex strip to fix CodeQL incomplete-sanitization finding
Telegram escaping, dashboard edit-mode borders, DataTable icon clipping,
version column alignment, competitor page corrections, Kind column
badges, and CodeQL security fixes.
@s-b-e-n-s-o-n s-b-e-n-s-o-n merged commit a45d533 into main Mar 30, 2026
35 of 36 checks passed
@s-b-e-n-s-o-n s-b-e-n-s-o-n deleted the feature/v1.5-observability branch March 30, 2026 01:42
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.

The container is output multiple times in Trigger

3 participants