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
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
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
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
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
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
alex
836f733a2e
feat: Add API key authentication for backup tool
...
- Add get_api_key() and require_api_key() to auth.py
- Add generic key-value settings storage to SettingsStore
- Add test_api_key_auth to verify the implementation
- Uses secrets.compare_digest for timing-safe comparison
- Auto-generates API key on first use and stores in settings DB
2026-05-11 21:25:46 +02:00