Commit Graph

124 Commits

Author SHA1 Message Date
Developer f6a86310cc style(widgets): apply formatter to widget rebind files 2026-06-22 18:22:18 +00:00
Developer 10fd4ead4a feat(widgets): rebind widgets to the service registry
PR 2 of 4 for the runtime service registry change.

- dashboard_widgets gains service_id + widget_kind columns (legacy
  addon_id/widget_type kept but unused).
- Source adapters take (service: ServiceRecord | None, widget_kind, config).
  SERVICE_ADAPTERS keyed by service_type; BUILTIN_ADAPTERS for backups/static.
- Backups and static stay as service-less built-ins (service_id nullable),
  exposed via GET /api/widgets/builtin.
- SSH task adapter resolves the task + instance, runs over SSH, and appends a
  service_task_runs history row on success/failure/timeout/error.
- Retire widgets/registry.py; widget metadata now comes from the integrations
  registry + widgets/builtin. Remove /api/widgets/types and /api/widgets/sources.
- Stop default widget seeding (fresh install = empty dashboard).
- Rewrite widget tests around the service-bound + built-in model (26 tests).

Backend-only breaking change; frontend is reconciled in Slice 3. Build/lint
stay green; pytest 222 passed.
2026-06-22 16:42:56 +00:00
Developer 2452e2e1e4 Merge pull request 'feat(services): backend service registry foundation' (#7) from feat/service-registry-backend-foundation into main 2026-06-22 14:00:07 +00:00
Developer fd534a816b style(services): apply formatter to service registry files 2026-06-22 14:00:07 +00:00
Developer 8cdeadd6dd feat(services): backend service registry foundation (encryption, definitions, CRUD)
PR 1 of 4 for the runtime service registry change.

- Add Fernet encryption helper (services/secrets.py) with a required
  MANAGE_ENCRYPTION_KEY; validate it on startup.
- Add closed integrations/ registry with Pydantic config + widget-config
  definitions for grafana, prometheus, jellyfin, nextcloud, and ssh_tasks.
- Add services + service_task_runs tables and SettingsStore CRUD with
  cascade-delete (defensive until widgets carry service_id).
- Add /api/services/types and /api/services/instances CRUD (encrypted secrets,
  secrets_set flags only; never plaintext).
- Declare cryptography as a direct dependency.
- Require MANAGE_ENCRYPTION_KEY in compose + .env.example + README.
- Add 25 backend tests (registry, encryption, CRUD, cascade, task-run history).

Verification: ruff clean; pytest 225 passed; frontend lint/build green.
2026-06-22 12:56:03 +00:00
Developer d1819c0186 Merge pull request 'docs(service-registry): SDD artifacts' from docs/service-registry-sdd into main 2026-06-22 11:14:01 +00:00
Developer 9459de5c07 docs(service-registry): lock decisions (cascade delete, required key, SSH runner model)
- §11 decisions: cascade-delete services with widgets; MANAGE_ENCRYPTION_KEY
  always required; SSH task runner is multi-instance with reusable tasks.
- §12 SSH task runner model: instances absorb SSH task transport, tasks stay
  global/reusable with default_service_id, service_task_runs logs history,
  widget config { task_id, service_id? }.
- tasks.md: add service_task_runs table + cascade-delete tests to Slice 1,
  SSH run-logging to Slice 2, follow-ups (Actions rebuild, machine unification).
2026-06-22 11:14:01 +00:00
Developer 9782280a03 docs(service-registry): SDD proposal, design, and tasks
Design-only artifacts for the runtime service registry change. No
implementation yet.

- proposal: motivation, goals, non-goals, grilling decisions, risks
- design: data model, Pydantic service definitions, encryption, API,
  frontend structure, migration/breaking changes, 4-PR slice plan
- tasks: backend foundation, backend widget rebind, frontend services
  runtime, dashboard + settings rework + docs
2026-06-22 10:07:25 +00:00
Developer 0ad6a04053 Merge pull request 'docs(deploy): update README and .env.example for Docker deployment' (#6) from docs/update-readme-env-deployment into main 2026-06-22 09:28:06 +00:00
Developer 75636c00d4 docs(deploy): update README and .env.example for Docker deployment
- Refresh README feature list and remove references to the legacy
  in-app monitoring charts / backend poller.
- Document configurable dashboard widgets, addon pages, and widget env vars.
- Add VITE_PROMETHEUS_URL support to frontend Dockerfile and both compose files.
- Add header comment to .env.example explaining shell-export workflow.
- Update remote server requirements to match current capabilities.
2026-06-22 09:28:06 +00:00
Developer f4b16b5844 Merge pull request 'feat(widgets): dashboard loop, widget config UI, and addon pages' (#5) from feat/dashboard-widgets-ui-pages into main 2026-06-22 08:05:45 +00:00
Developer 09eb76bf0f style(widgets): apply formatter to dashboard and addon files 2026-06-22 08:05:44 +00:00
Developer ed7a7a5ce0 feat(widgets): dashboard loop, widget config UI, and addon pages
PR 4 of 4 for configurable dashboard widgets.

- Replace hard-coded Jellyfin/Backups dashboard sections with a loop that
  renders enabled widget instances by sort_order.
- Add WidgetInstance renderer and WidgetConfigDialog for adding, editing,
  enabling/disabling, deleting, and reordering widgets.
- Add addon pages for grafana, prometheus, and ssh-tasks at /addons/:addonId.
- Register /addons/:addonId route in App.tsx.
- Update docs/REQUIREMENTS.md with the widget system design and API.

Verification:
- backend ruff clean; pytest 200 passed
- frontend npm run lint: 0 errors
- frontend npm run build: success
- frontend npm run test -- src/widgets/registry.test.ts: 3 passed
2026-06-21 20:45:42 +00:00
Developer e4e879d1c8 Merge pull request 'feat(widgets): add frontend widget runtime (types, API, hooks, registry, components)' (#4) from feat/dashboard-widgets-frontend-runtime into main 2026-06-21 16:55:13 +00:00
Developer 2557185fb7 style(widgets): apply formatter to widget runtime files 2026-06-21 16:55:12 +00:00
Developer e1356b20f1 feat(widgets): add frontend widget runtime (types, API, hooks, registry, components)
PR 3 of 4 for configurable dashboard widgets.

- Add TypeScript widget interfaces (WidgetInstance, WidgetInstanceInput,
  WidgetTypeInfo, WidgetDataResponse).
- Create widget API client for CRUD, registry metadata, and per-widget data.
- Create TanStack Query hooks for instances, data, sources, types, and mutations.
- Create closed frontend widget registry with metadata, source type, refresh
  intervals, and config fields.
- Add six shadcn/ui-based widget components: Jellyfin, Backups, Grafana link,
  Prometheus metric, SSH task output, and static text.
- Add Vitest unit tests for registry metadata.

Verification:
- backend ruff clean; pytest 200 passed
- frontend npm run lint: 0 errors
- frontend npm run build: success
- frontend npm run test -- src/widgets/registry.test.ts: 3 passed
2026-06-21 16:24:44 +00:00
Developer e6d333ef7b Merge pull request 'feat(widgets): add backend source adapters and per-widget data endpoint' (#3) from feat/dashboard-widgets-backend-adapters into main 2026-06-21 16:01:44 +00:00
Developer 1cd8e926de feat(widgets): add backend source adapters and per-widget data endpoint
PR 2 of 4 for configurable dashboard widgets.

- Add grafana_url and prometheus_url settings (config.py + compose/env).
- Create WidgetSource protocol and adapters for jellyfin, backups, grafana,
  prometheus, ssh_task, and static sources.
- Add GET /api/widgets/instances/{id}/data endpoint.
- Extract shared dashboard helpers into domain/dashboard.py so widgets and
  the dashboard router reuse the same logic.
- Add adapter and data-endpoint tests.
- Update apply-progress.md.

Verification: ruff clean; backend pytest 200 passed; frontend lint/build green.
2026-06-21 10:09:45 +00:00
alex 1a52dfb087 Merge pull request 'feat(widgets): add backend CRUD, registry, and default seeding' (#2) from feat/dashboard-widgets-backend-crud into main
Reviewed-on: #2
2026-06-19 22:15:58 +02:00
alex 9dfe62eb6f Merge pull request 'chore(config): remove dead GRAFANA_URL and wire VITE_GRAFANA_URL' (#1) from chore/wire-grafana-url-envs into main
Reviewed-on: #1
2026-06-19 22:15:46 +02:00
Developer 200d319fb0 feat(widgets): add backend CRUD, registry, and default seeding
Introduce a closed, compile-time widget registry and backend CRUD for
dashboard widget instances.

- Add dashboard_widgets SQLite table in SettingsStore with CRUD helpers and
  default seeding (Jellyfin + Backups) on first install.
- Add Pydantic models with credential-key and secret-value rejection.
- Add widgets router: /api/widgets/sources, /types, /instances CRUD.
- Call ensure_defaults() in app lifespan so fresh installs seed defaults.
- Add backend tests covering registry, CRUD, validation, and seeding.
- Include SDD artifacts: exploration, proposal, spec, design, tasks.
2026-06-19 20:07:47 +00:00
Developer 24427b4869 chore(config): remove dead GRAFANA_URL and wire VITE_GRAFANA_URL
- Remove GRAFANA_URL from backend environment (backend never consumed it).
- Add VITE_GRAFANA_URL to frontend build-args (prod), dev environment, and
  frontend/Dockerfile ARG/ENV so Grafana deep-links resolve correctly.
- Add ALERTMANAGER_WEBHOOK_URL to backend environment so the documented
  alert-forwarding feature is reachable from compose.
- Document VITE_GRAFANA_URL in .env.example.
2026-06-19 20:07:47 +00:00
Developer bb8b040657 docs(monitoring): record legacy poller decommission (slice 3)
Update docs to reflect that Manage no longer scrapes its own system
metrics (slices 1-2). AGENTS.md, REQUIREMENTS.md (decision log +
observability section), monitoring-logging-design.md, MIGRATION_PLAN.md.

Gate: docs only; backend pytest (173) + frontend build/lint/test (22/63)
remain green from slices 1-2.
2026-06-17 20:55:24 +00:00
Developer a8eb751322 refactor(monitoring): remove orphaned frontend DiskSpaceCard (slice 2)
After slice 1 removed /api/monitoring/disk, the frontend DiskSpaceCard
component (and its DiskSpace type) had zero importers — it fed nothing.
Delete them.

Removed (frontend):
- components/DiskSpaceCard.tsx
- components/__tests__/DiskSpaceCard.test.tsx
- types/index.ts: DiskSpace interface

Gate: build + lint + vitest (22 files / 63 tests) green.
2026-06-17 20:51:54 +00:00
Developer 08a3b616f6 refactor(monitoring): decommission legacy SSH-scraping poller (slice 1)
The 2026-06-16/17 observability update externalised metrics to
Prometheus + node_exporter + Grafana, but the legacy Manage-side
SSH-scraping monitor was never removed. It duplicated the new stack,
ran SSH df on every machine every 300s, and fed nothing (its UI was
deleted in e2ad731). This slice decommissions the duplication.

Removed (backend):
- services/monitoring_poller.py (MonitoringPoller) — entire file
- services/monitoring_actions.py (disk_space, run_machine_operation,
  poll_machine_snapshot, build_machine_client) — entire file;
  run_machine_operation had only 2 callers (the poller + /disk), both gone
- tests/test_monitoring_actions.py
- endpoints: POST /api/monitoring/poller, GET /machines/{id}/actions,
  GET /disk (and the now-dead _resolve_machine helper)
- lifespan wiring (main.py), dependency wrapper (dependencies.py),
  poller.start()/kick() from machine save (routers/settings.py)
- SettingsStore: monitoring_machine_actions table CREATE + 2 indexes +
  record/list/prune_machine_actions methods; DROP TABLE IF EXISTS on
  startup cleans existing DBs (user-approved)
- config knobs: monitoring_poll_interval_seconds,
  monitoring_poll_initial_delay_seconds, monitoring_action_retention_days
- test_api.py: TestMonitoring._ensure_machine + test_disk

Kept (fits the new model): /machines, /prometheus-targets, /alerts,
/alertmanager-status, /alertmanager-webhook; the disk_usage JOB template
(manual on-demand, not monitoring); node_exporter_* machine fields
(they point Prometheus at the right host).

Gate: backend pytest 173 passed; ruff clean.
2026-06-17 20:48:56 +00:00
Developer 1c29299e8c chore(openspec): archive web-ui-rework change
Move the completed, verified, synced change folder to the dated archive:
openspec/changes/web-ui-rework/ -> openspec/changes/archive/2026-06-17-web-ui-rework/

Canonical spec stays in place at openspec/specs/web-ui/spec.md (not moved).
This is the physical archive step deferred (documented-pending-manual) in
archive-report.md ec46e26; user-approved.
2026-06-17 19:44:57 +00:00
Developer 0ec2a8806b style(frontend): wrap long ResizeObserver assignment in test setup
Background linter/runner keeps re-applying this single-line wrap; commit it
so the working tree stays stable. No behavior change.
2026-06-17 19:44:57 +00:00
Developer 9cae5fc98c chore(openspec): archive report — web-ui-rework lifecycle complete
Disposition: documented-pending-manual (archive-move deferred to avoid guessing
the OpenSpec archive convention destructively). Remaining manual step recorded:
move openspec/changes/web-ui-rework/ -> openspec/changes/archive/2026-06-17-web-ui-rework/
(canonical openspec/specs/web-ui/spec.md stays in place).

All 8 lifecycle phases done: proposal/spec/design/tasks/apply/verify/sync/archive.
71/71 tasks complete; gates green (build + lint + vitest 23/64 + node 5/5).

Carry-over follow-ups recorded for future cleanup:
- slice-5 shipped without the prescribed 5a/5b sub-split (correct + tested)
- tasks.md 'node --test tests' cross-check is a pre-existing broken command
  (correct: 'node --test'); recommend docs/npm-script follow-up
- no visual/browser smoke performed (component tests are structural)
2026-06-17 19:36:23 +00:00
Developer 7646f3236f chore(openspec): verify + sync reports, canonical web-ui spec (rework PASS)
Web UI rework lifecycle: verify + sync phases.
- verify-report.md: PASS verdict (23/64 vitest, 5/5 node, zero @mui in src,
  71/71 tasks, all spec scenarios green). Non-blocking findings recorded:
  slice-5 review-budget overage (5a/5b not split); node --test tests cmd typo.
- sync-report.md + openspec/specs/web-ui/spec.md: canonical domain spec
  distilled from the verified change (design system, thin-dashboard model,
  TanStack visibility-only tables, reconciled IA, removed deps, Vitest harness).
- Change-side delta spec under openspec/changes/web-ui-rework/specs/.
2026-06-17 19:15:15 +00:00
Developer 9de2d5b8d2 feat(frontend): slice 8 — remove MUI/@emotion deps + update REQUIREMENTS
Web UI rework. Final slice.
- Remove from package.json: @mui/material, @mui/icons-material,
  @mui/x-data-grid, @emotion/react, @emotion/styled (zero consumers
  remain in src after slices 1-7b; grep-verified).
- Update docs/REQUIREMENTS.md (+63 lines): single design system
  (shadcn/ui + Tailwind v4 + lucide-react), thin-dashboard observability
  model (no in-app charts; Grafana deep-links), TanStack tables
  (visibility-only parity), reconciled IA (Backups top-level nav;
  Media at /media with /applications redirect), repurposed chart-*
  status cues, removed deps list.
- Note: AGENTS.md 'node --test tests' invocation is a pre-existing
  broken command (treats tests/ as a module); correct form is
  'node --test' (auto-discover, 5/5 pass) — verified identical at
  pre-rework baseline ef5311b.

Gate: build + lint + vitest (23/64) + node --test (5/5) green.
Web UI rework complete.
2026-06-17 18:52:27 +00:00
Developer 3dc1b31fc3 feat(frontend): slice 7b — Media on TanStack Table (server pagination)
Web UI rework. Completes the DataGrid migration (7a + 7b):
- pages/Media.tsx off @mui/x-data-grid + @mui/material onto DataTable:
  15 locked columns (title/series/season/episode/type/year/runtime_min/
  size/bitrate/hdr/video/resolution/date_added/library/path);
  enablePagination + manualPagination + rowCount from queryResult.total;
  page state (pageIndex/pageSize) -> offset/limit into useMediaQuery;
  onRowClick -> navigate('/files?path=...') preserved; stable path-derived
  getRowId so selection survives server paging; column-visibility toggle.
  Hard rule honored: NO sorting, NO resizing (visibility-only).
- Migrate Media shell (Select/Input/Progress/Card/grid/Typography/Tabs).
- Media component tests (column set + row-click nav).
- Harness fix: polyfill ResizeObserver in test/setup.ts — jsdom lacks it
  and Radix primitives (Select/ScrollArea/etc.) reference it; was causing
  cross-test failures once Media pulled shadcn Select into the pool.

Gate: build + lint + test green (23 files / 64 tests).
2026-06-17 18:33:59 +00:00
Developer e8b0f1144b feat(frontend): slice 7a — DataTable wrapper + FileBrowser (TanStack Table)
Web UI rework. Highest-risk slice, part 1 of 2:
- New components/ui/data-table.tsx: generic TanStack Table wrapper on the
  shadcn Table primitive. Controlled rowSelection/columnVisibility/
  pagination, optional selection column (stopPropagation on cell click),
  row-click, column-visibility dropdown, manual-pagination support.
  Hard rule honored: NO getSortedRowModel, NO column resizing/sizing.
- Migrate pages/FileBrowser.impl.tsx off @mui/x-data-grid + @mui/material
  onto DataTable: 5 columns (type/name/ext/size/modified), row-click ->
  ffprobe preview preserved, column-visibility toggle, no pagination.
- DataTable + FileBrowser component tests (RED->GREEN).

Gate: build + lint + test green (22 files / 58 tests).
2026-06-17 18:02:47 +00:00
Developer 04f2e59c92 feat(frontend): slice 6b — Users compose dialog + 9 icons (finish Users)
Web UI rework. Completes the Users migration (6a directory + 6b compose):
- Compose dialog off @mui: shadcn Dialog family + Input (subject) +
  Textarea (html body) + Separator + Label; IconButton -> Button ghost
- 9 @mui/icons-material -> lucide-react: Close->X, AttachFile->Paperclip,
  FormatBold->Bold, FormatItalic->Italic, Link->Link,
  FormatListBulleted->List, MailOutlined->Mail, Send->Send,
  DeleteOutlined->Trash2
- Rich-text compose parity: markup insertion, attachments (FormData),
  queue-status polling, send via useSendUserMessage
- UsersPage.impl.tsx now has ZERO @mui imports

Gate: build + lint + test green (20 files / 46 tests).
2026-06-17 16:18:49 +00:00
Developer 1e23c07a20 feat(frontend): slice 6a — Users directory surface + drawer (shadcn)
Web UI rework. Slice 6a (force-split; 6b = compose dialog next):
- UsersPage.impl.tsx directory surface off @mui: shadcn Table family +
  Checkbox + Badge (status: success=chart-2/destructive/secondary) +
  Avatar + Tooltip + Progress + Alert/Button/Stack/Typography
- MUI Drawer -> shadcn Sheet side="right" for user detail drawer
  (buildUserDrawerModel rendering preserved)
- Selection-across-pagination + search/filter parity preserved
- Compose-dialog MUI subset (Dialog/TextField/Divider/IconButton +
  9 icons) intentionally LEFT for slice 6b

Gate: build + lint + test green.
2026-06-17 14:36:07 +00:00
Developer b6da7df7f9 feat(frontend): slice 5 — migrate Settings + Actions to shadcn/Tailwind
Web UI rework. Form-heavy pair (controlled useState parity, no form lib):
- pages/Settings.tsx off @mui: monitoring-machine CRUD, SSH-key mgmt,
  SSH test/validation feedback, danger-zone reset (ConfirmDialog), tabs
- pages/Actions.tsx off @mui: saved-task editor, machine selection,
  run history, tabs
- Both reuse migrated shared components (SectionCard/SelectionRailCard/
  TabbedCard/HoverEditButton/ConfirmDialog/DialogFooter) as before
- Behavioral tests added (mocked hooks; no live SSH)

Gate: build + lint + test green (19 files / 39 tests).
2026-06-17 13:47:57 +00:00
Developer c721f0dece feat(frontend): slice 4 — migrate Dashboard + Applications to shadcn/Tailwind
Web UI rework.
- Migrate pages/Dashboard.tsx off @mui (shortcut CRUD dialogs, machine
  switcher, BackupDashboardWidget mount; shortcuts reuse ConfirmDialog/
  DialogFooter from slice 2)
- Migrate pages/Applications.tsx shell off @mui (tabs + library counts);
  keeps <Media/> child intact (Media.tsx still MUI, deferred to slice 7
  with its DataGrid)
- Behavioral tests for both pages

Gate: build + lint + test green.
2026-06-17 13:15:51 +00:00
Developer 77c6b62ee2 feat(frontend): slice 3 — Backups cluster migration + nav/IA
Web UI rework.
- Migrate BackupAlertsTable, BackupJobsTable, BackupRunsTable,
  BackupsPage, BackupDashboardWidget off @mui (shadcn Table + Badge
  severity variants: success=chart-2, warning=chart-3, destructive)
- App.tsx IA: Backups now top-level nav (DatabaseBackup icon);
  Media surface primary at /media; /applications -> /media redirect
  in both route trees (mirrors /monitoring -> /observability)

Gate: build + lint + test green.
2026-06-17 12:53:36 +00:00
Developer 109e74db41 feat(frontend): slice 2 — migrate 11 shared components to shadcn/Tailwind
Web UI rework. Shared-components slice (drift prevention):
- Migrate SectionCard, SelectionRailCard, TabbedCard, MetricCard,
  DiskSpaceCard, HoverEditButton, DialogFooter, ConfirmDialog,
  LibraryOverview, NowPlaying, SessionActivityPanel off @mui
- HoverEditButton: MUI IconButton + EditOutlined -> Button + lucide Pencil
- Status mapping uses the success Badge variant (chart-2) for healthy
- Exported APIs preserved so consuming pages still compile (no page edits)
- 11 behavioral Vitest component tests added

Gate: build + lint + test green.
2026-06-17 12:33:47 +00:00
Developer dd778d8850 feat(frontend): slice 1 — foundation for MUI->shadcn migration
Web UI rework (openspec/changes/web-ui-rework). Foundation slice:
- Add @tanstack/react-table; remove orphaned recharts, d3
- Vendor shadcn primitives: tabs table dialog input label checkbox
  switch progress separator avatar textarea dropdown-menu scroll-area
- Add Vitest + @testing-library/react + jsdom harness; npm test script
- Delete no-op theme.ts shim; remove getAppTheme references
- Smoke test proves the harness

Gate: build + lint + test green.
2026-06-17 12:11:05 +00:00
Developer ef5311bdbb feat(observability): per-service root directories for config and data
- Replace OBSERVABILITY_DATA_ROOT with per-service *_ROOT variables in
  docker-compose.observability.yml.
- Each service root must contain config/ (mounted read-only) and data/
  (mounted read-write), grouping config and state together for Portainer.
- Update docs/observability-runbooks.md with the new variables, a setup
  script that copies repo configs into each service root, and updated
  backup/restore examples.
2026-06-17 10:11:17 +00:00
Developer 2d1674cb08 feat(observability): add Traefik routing and required absolute data root
- Make OBSERVABILITY_DATA_ROOT required in docker-compose.observability.yml
  so Portainer deployments must set an absolute host path.
- Add Traefik labels and the web external network to Grafana, Prometheus,
  and Alertmanager with env-driven hostnames, router/service names,
  internal ports, entrypoint, and cert resolver.
- Keep direct host ports as a fallback for local debugging.
- Update docs/observability-runbooks.md with required variables,
  Traefik hostname column, and a .env.observability example.
2026-06-16 16:23:54 +00:00
Developer 53dcd16735 feat(observability): persist standalone stack data and expose ports via env
- Switch docker-compose.observability.yml from named volumes to host
  bind mounts under OBSERVABILITY_DATA_ROOT, defaulting to
  ./observability-data.
- Make all service ports configurable via environment variables
  (PROMETHEUS_PORT, LOKI_PORT, ALLOY_PORT, GRAFANA_PORT,
  ALERTMANAGER_PORT, NODE_EXPORTER_PORT).
- Add VITE_GRAFANA_URL handling to ObservabilityPage so Grafana links
  point to the configured standalone instance.
- Update docs/observability-runbooks.md with the env variable table,
  reachable-web-UI table, and backup/restore instructions for the new
  host-directory layout.
2026-06-16 15:37:41 +00:00
Developer e783d2c07b refactor(observability): decouple Grafana from Manage
- Replace embedded Grafana iframes in ObservabilityPage with external
  Grafana link cards. Grafana URL is configurable via VITE_GRAFANA_URL
  (frontend) or GRAFANA_URL (backend env exposed to frontend build).
- Remove the grafana scrape job from monitoring/prometheus/prometheus.yml
  so the main Prometheus stack no longer depends on Grafana.
- Pass GRAFANA_URL through docker-compose.yml and docker-compose.dev.yml.
2026-06-16 15:20:26 +00:00
Developer 7f9b40cd4f feat(observability): add standalone observability compose stack
Add docker-compose.observability.yml to run Grafana, Prometheus, Loki,
Alertmanager, Alloy and Node Exporter independently of Manage.
Includes a standalone Prometheus config, empty file-SD placeholder,
and runbook documentation.
2026-06-16 14:55:25 +00:00
Developer e2ad731b5f feat(observability): add Prometheus/Grafana/Loki/Alertmanager/Alloy stack and remove legacy Monitoring UI 2026-06-16 13:44:35 +00:00
alex 615e02e970 fix(frontend): make dark mode toggle actually work
The dark mode button was toggling React state but never applying it to the
DOM. Add a useDarkMode hook that:

- Persists the preference in localStorage
- Defaults to the OS prefers-color-scheme on first visit
- Adds/removes the 'dark' class on <html> to trigger CSS variable overrides

Also add dark-mode color overrides for all Tailwind v4 theme variables in
index.css.

Co-authored-by: openhands <openhands@all-hands.dev>
2026-06-11 21:50:13 +02:00
alex dd12631f07 cleaned up 2026-05-12 15:19:25 +02:00
alex 43e132971b Build new shell layout with left sidebar (el-3po) 2026-05-12 11:08:33 +02:00
alex a748512d22 test: verify backup monitoring implementation 2026-05-11 21:57:31 +02:00
alex 322b3d1a3b feat(backups): wire up routes, nav, dashboard widget, and docs
- Add /backups route and navigation tab in App.tsx
- Add BackupDashboardWidget to Dashboard page
- Document backup monitoring feature in REQUIREMENTS.md
2026-05-11 21:54:50 +02:00