What's Changed
- chore(release): bump version to 2.3.0-alpha.2 (9452b0c)
- feat(prune): compare every policy when the preview page opens (#1112) (7c54a74)
- fix(prune): make the whole compared-policy row clickable (c4e65a4)
- feat(prune): exact lost-file bounds, plus an archives and prune UI pass (#1110) (76cc06c)
- fix(activity): add the cancel route the job lists call (agent 0.1.7) (#1108) (e8b993f)
- perf(dashboard): aggregate the overview in SQL and send per-day counts (#1085) (ff64417)
- fix(agents): complete a maintenance log file from lines that arrive after the outcome (#1094) (4ac2cd6)
- feat(archives): build file history for managed-agent repositories (#1074) (8ce1f0e)
- docs: Hetzner Storage Box wording checked against Hetzner's docs (#1107) (bc6cb9b)
- perf(repositories): load the list's per-repository lookups once per page (#1096) (21649ee)
- test: enforce foreign keys on the shared test database (#1104) (4b62844)
- perf(settings): stop running borg --version on GET /api/settings/system (#1106) (8c4f8e0)
- fix(borg): ask borg for the modern exit codes on every path (#1100) (84e4eb3)
- feat(repositories): read repository info from the stored columns, live borg info on refresh only (#1105) (f2bdbad)
- docs(specs): space family phase 4 done, PR #1097 merged (04a5158)
- feat(prune): retention comparison (space family phase 4) (#1097) (ca19cb8)
- perf(settings): stop stating every log file on GET /api/settings/system (#1086) (9153c53)
- docs(specs): space family phase 4, comparison re-measures nothing (G5) (484e5a4)
- fix(history): accept Borg's modern warning exit codes in the history index (#1093) (632d700)
- test(unit): skip the land_watch tests when .codex/ is not in the tree (#1089) (ad25daf)
- docs(specs): space family phase 4 PR threads addressed (aa113ee)
- docs(specs): space family phase 4 reviewed, fixes in PR #1097 (082b923)
- docs(specs): space family phase 4 implemented, at review gate (0e16acf)
- docs(specs): space family phase 4 designed and planned (retention comparison) (ecb4c4a)
- docs(specs): space family phase 3 done (PR #1087) (e8147be)
- feat(archives): prune preview (space family phase 3) (#1087) (6fb972b)
- feat(repositories): one stats component reads the stored storage payload (#1070) (ae4794c)
- docs(specs): space family phase 2 done (PR #1084) (7a56b80)
- feat(archives): repository growth graph (space family phase 2) (#1084) (2edeaf3)
- docs(specs): space family phase 1 done (PR #1080) (07de110)
- feat(archives): stats measurement date and archive stats header (space family phase 1) (#1080) (58bac64)
- fix(ci): give gh run download an explicit repo in the visual report (#1081) (3394aa0)
- chore(deps): bump the backend-minor-patch group with 2 updates (#1053) (3e41c46)
- docs(specs): pro roadmap for search, space family, empty-source guard (03c1a02)
- feat(agent): repository.diff job for the archive history (agent 0.1.6) (#1072) (1a804b7)
- fix(agents): keep only the small part of a consumed machine-parsed result (#1069) (16dd376)
- docs(installation): name Easypanel in the platform pointer (7418c1c)
- docs: mention Easypanel deployment option (#1067) (fed4662)
- Publish visual reports for fork pull requests (#1071) (83e27c2)
- feat(archives): download archive folders as tar files (#1066) (ba2fe90)
- fix: preserve occupied archive mount targets (#1064) (aa47731)
- fix(services): escalate to SIGKILL when a cancelled task's process wedges (#1061) (6f60a04)
- chore(deps): bump the frontend-minor-patch group (#1054) (7e916a2)
- fix(agents): refuse Borg 2 on an endpoint that cannot run it, and say why a job failed (#1059) (c20f273)
- fix(agents): stop version pin labels overlapping their values (6961b6e)
- fix(archives): heatmap tells the truth, search dialog becomes usable (#943) (#1051) (cfedd83)
- fix(activity): open a backup's archive by borg id and surface listing errors (#1048) (448b880)
- fix(agents): clean up after deleted agents, surface borg errors in the info dialog (#1050) (da349c9)
- fix(borg2): cancel runner-dispatched check and delete_archive (#1049) (6e38185)
- fix(archives): show restore progress and outcome on the archive page (#1047) (22f24e4)
- docs(agent-recovery): both phases merged, live gates still open (#1046) (1091833)
- feat(agent): uninstall an endpoint from its card (#1043) (85d7635)
- fix(operations): name the running index work in the queue payload (#1045) (c016d80)
- fix(operations): combine index serialization and accurate repository lane waits (#1042) (799f909)
- chore(storage): one byte formatter, not six (#1041) (8995348)
- feat(activity): pin running work in the timeline, say how a plan run started (#1040) (e6afc38)
- feat(agent): change an endpoint's server URL from the fleet card (#1039) (bda3fa0)
- feat(repositories): one stored storage payload for every size reader (#1030) (816d888)
- refactor(operations): restore a handed-over start where the runner ends the run (#1038) (cbb510c)
- fix(operations): hand a runner-claimed maintenance row to the Borg 2 service in the shape it claims (#1025) (cda923e)
- fix(agents): queue a plan's agent script job again after phase 9 (#1029) (03601a5)
- feat(activity): cursor pagination, and a timeline that reads as the run (#1035) (130ccf7)
- refactor(frontend): drop three duplicated components (#1034) (6ed20c6)
- ci(pages): publish Storybook at docs.borgui.com/storybook (#1033) (a19503f)
- feat(operations): link from the background work hub to the repository (#1032) (3cfaf4a)
- chore(dev): add a yarn dev entry point (172d757)
- fix(dev): reach the backend through the dev server over a tunnel (8413fcc)
- fix(dev): move the dev sqlite db off the macOS bind mount (363820d)
- feat(activity): repository journey timeline (#1027) (0395ef7)
- fix(archives): give agent repositories a history capability instead of a stage that always skips (#1016) (631edd5)
- docs(operations): mark phase 10 done in the spec progress table (#1022) (7df2346)
- feat(operations): per-repository index mode (phase 10) (#1021) (430f48a)
- chore(deps): bump sharp and wrangler in /updates-worker (#1020) (4745417)
- chore(lint): enable ruff F811 and F821 and clear their hits (#1018) (a6a5535)
- test(agents): build the maintenance payload from the production builder (#1019) (ed00561)
- docs(operations): draft the phase 10 per-repository index mode plan (3e3b607)
- fix(plans): wait out transient read work before refusing a plan's prune or compact (#1011) (51ad2d4)
- fix(ui): drop the 2.0 badge and settle on the Borg UI name (#1017) (f4eb63c)
- docs(operations): mark phase 9 done in the spec progress table (4057a49)
- feat(operations): collapse legacy job tables into operations (phase 9) (#1010) (44c2cc4)
- fix(auth): treat a blank INITIAL_ADMIN_PASSWORD as unset (#1014) (178b128)
- fix(agents): align the upgrade and Borg pin chips with their neighbours (#1015) (5cd1480)
- fix(dashboard): read maintenance operations in the activity timeline (#1004) (3bbc7dd)
- fix(operations): defer the stats operation when the repository is busy (#1012) (1d2665b)
- docs(agents): mark phase 5 done in the spec progress table (#1013) (eddaa37)
- feat(ssh): persist and show a Borg-only badge for restricted connections (#1009) (65b274d)
- fix(operations): close the inline maintenance operation when its agent job cannot be queued (#1008) (1ebc008)
- feat(agents): centralized agent upgrades, phase 5 (per-endpoint Borg version) (#1007) (30ca96a)
- fix(ssh): restricted (forced-command) keys report as connected, not failed (#1006) (0586f6d)
- feat(backup-plans): skip a repository inside a plan without removing it (#1000) (39ee2e3)
- feat(agents): centralized agent upgrades, phase 4 (fleet upgrade) (#997) (a640a11)
- test: collect every test file in CI and move the live-server scripts out of tests/integration (#990) (0b436b9)
- fix(ci): unhang the integration suite and fix the shard 4 unit failure (#995) (77c75f9)
- feat(analytics): segment Umami visitors by plan (#993) (f797cc0)
- fix(sshfs): mount the SSHFS cache under /tmp so AppArmor allows it (#994) (28364fd)
- docs(operations): mark phase 8 done in the spec progress table (#992) (3cccc57)
- feat(operations): migrate backup onto the operations runner (phase 8) (#988) (6587efb)
- docs(agents): mark phase 3 done (#991) (b1a8612)
- feat(agents): centralized agent upgrades, phase 3 (#989) (3ab2790)
- feat(borg2): run compact with --stats and persist the repository statistics (#974) (f6194af)
- docs(agents): mark phase 2 done (#987) (63e142d)
- feat(ssh-connections): add rsync.net setup preset (#986) (841be80)
- feat(agents): centralized agent upgrades, phase 2 (#984) (ae2b89a)
- docs(provider-guides): per-provider troubleshooting tables (#985) (5c7fad5)
- fix(repositories): allow permanent deletion of Borg 2 repos (#980) (b62e46d)
- docs(operations): mark phase 7 done in the spec progress table (#979) (ff4639f)
- chore(restore): drop the dead dry_run field from RestoreRequest (#978) (f94b048)
- feat(operations): migrate restore onto the operations runner (phase 7) (#976) (ecea9d6)
- fix(distribution): drop REDIS_URL from the Portainer container template (1fe885c)
- fix(distribution): use the rounded green logo for catalogue icons (ae34657)
- feat(distribution): official Unraid and Portainer templates (#972) (7e8282d)
- refactor(repositories): retire the status strip, keep last prune and last index in the card's metadata row (#975) (6824a3d)
- fix(operations): enqueue the backup follow-up chain when a backup completes (#949) (dbce181)
- fix(db): add the agent upgrade tracking columns as an Alembic revision (#973) (125493d)
- feat(operations): migrate wipe, cloud mirror sync, and package install onto the operations runner (#971) (c679cd8)
- feat(agent): repository.storage_usage job and compact --stats (agent 0.1.4) (#968) (48a4adc)
- fix(operations): index chain gives agent repositories stats and per-archive info (#948) (33fab72)
- fix(retention): keep the backup job of a pruned archive, mark it instead of deleting it (#966) (48c515e)
- feat(operations): repository status from repository evidence (#967) (ac06542)
- feat(install): native install for Debian and Ubuntu hosts (bare metal, VM, LXC) (#946) (323fc78)
- feat(operations): migrate check, prune, compact, delete archive, and restore check onto the operations runner (#947) (0ea52cd)
- chore(deps): bump the frontend-minor-patch group in /frontend with 13 updates, pin happy-dom to 20.11.12 (#969) (a4da4a7)
- feat(operations): read-only repository size by source order, persist Borg's last_modified (#950) (90e8361)
- feat(agents): centralized agent upgrades, phase 1 (version visibility) (#951) (bec4a5e)
- test(ssh): check the -i identity flag as an argv token, not a substring (#952) (c28aa6b)
- chore(deps): bump the backend-minor-patch group with 6 updates (#956) (82ab1d3)
- chore(deps-dev): upgrade vitest, @vitest/ui and @vitest/coverage-v8 to 5.0.0 together (#962) (644d2fb)
- fix(archives): say "< 1%" instead of "0%" for a non-zero unique share (#955) (ec3c2c7)
- test(main): reset the licensing refresh task global after each startup test (#945) (37cee43)
- fix(storybook): give every story a router so components render (#942) (3b55717)
- docs: add a trust page for what Borg UI stores and sends (#938) (da30b8c)
- docs(operations): mark phase 4 done in the spec progress table (#939) (7c7681f)
- chore(deps-dev): bump typescript from 6.0.3 to 7.0.2 in /frontend (#826) (96adc69)
- Feat/operations phase 4 (#913) (91c1f78)
- fix(mounts): address Borg 2 series archives by aid: selector (#906) (5289918)
- test: restore shadowed prune test and drop duplicate archive-failure test (#920) (e11818a)
- fix(security): verify SSH host keys instead of trusting any answer (#919) (a7dcb23)
- chore(runtime-base): adopt Borg 2.0.0b24 (#928) (74aa45a)
- fix(import): roll the session back when post-import enqueue fails (#910) (26c08ed)
- fix: restore delete-job cancel endpoint and fail smoke test on 500 (#926) (c8fd162)
- test(config): derive SSH dirs without reloading app.config (#916) (071855b)
- fix: log repository.id in inline script error handler (#927) (f253261)
- fix(security): encrypt repository passphrase at rest (#918) (c7f32d1)
- ci(security): update npm before audit - quick endpoint retired (#901) (56ecef2)
- fix(db): pin the PostgreSQL session timezone to UTC (#892) (d5b1c36)
- refactor: route all borg timestamp parsing through the shared parser (#891) (5ab8168)
- fix(archive-index): drop B-tree indexes on the unbounded path column (#911) (a9354e6)
- fix(archives): render archive-contents mtime in UTC (#909) (47df6d1)
- feat(plan): contextual upgrade links and trial countdown (#905) (3926e88)
- fix(ssh): derive SSH key deploy and secret paths from settings for native installs (#907) (af255e5)
- fix(frontend): drop tsconfig baseUrl removed in TypeScript 7 (#908) (feef1c6)
- fix: run machine-parsed borg invocations under TZ=UTC (#889) (6bb6b94)
- chore(deps): bump undici and wrangler in /updates-worker (#904) (ce93ace)
- fix(retention): take job log files along when purging rows (#900) (4843353)
- fix(restore-check): address Borg 2 series archives by aid: selector (#898) (b68d6c1)
- chore(frontend): migrate lint gate from ESLint to oxlint (#894) (f4c2bcc)
- docs(operations): mark phase 3 done in the spec progress table (#903) (062933e)
- feat(operations): phase 3 background work tab and repository status strip (#902) (56d7b28)
- docs(operations): mark phase 2 done in the spec progress table (#899) (75e556d)
- feat(operations): phase 2 history index, merge, and archive routes (#897) (7de5e51)
- feat(archives): support {utcnow} in archive name templates (#893) (7e71f61)
- fix: keep a malformed job_id from unwinding the session (#896) (bdb936e)
- docs(operations): mark phase 1 done in the spec progress table (5b388cb)
- feat(operations): phase 1 foundation for the repository operations runner (#888) (bd4ba89)
- fix: let a reconnecting agent reclaim its job before the reaper fails it (#877) (7f183e0)
- chore(deps-dev): bump @humanfs/node from 0.16.7 to 0.16.8 in /frontend (#883) (abe275f)
- fix(notifications): notify when no valid source paths remain (#890) (7bdc905)
- fix: allow cloud mirrors on managed-agent repositories (#876) (d508de9)
- fix: report repository size for Borg 2 agent repositories (#875) (d468ed4)
- fix(repositories): stop treating borg's local archive times as UTC (#871) (533e452)
- feat(borg2): adopt Borg 2.0.0b23 (#881) (f298c4c)
- fix: send an agent real rclone credentials, not the redacted ones (#878) (0bdb1ee)
- ci(deps): bump peter-evans/create-pull-request from 7 to 8 (#866) (36facf7)
- ci(deps): bump actions/setup-python from 6 to 7 (#865) (297ba1f)
- fix(agents): send notifications for agent-executed jobs (#870) (36f8a94)
- fix(activity): apply status filter before the row limit (#873) (faa7641)
- chore(runtime-base): adopt Borg 2.0.0b22, with the command changes it forces (#841) (13048b8)
- chore: add skill for continue spec (7cb0910)
- chore: add implementation plan for new archive browsing (3d141ad)
- fix(remote): use sudo for all remote repository operations (#859) (40e94e1)
- fix(remote): remove hidden backup-source gate (#857) (85e3217)
- fix(security): enforce v2 repository access checks (#864) (f5d594c)
- chore(deps): bump the backend-minor-patch group with 3 updates (#861) (c423172)
- chore(deps): bump the frontend-minor-patch group in /frontend with 17 updates (#862) (07e372d)
- feat(agents): offer Borg verify/update in the reinstall dialog (#855) (1e536dc)
- fix(remote): pass the borg environment through sudo explicitly (#844) (76cff93)
- fix(remote): keep borg's output for remote backups, and stop logging the passphrase (#845) (208fedc)
- fix(backup-plans): omit unavailable schedule fields (#856) (0309d71)
- fix(agent): list Borg 2 archives without reading every archive's metadata (#854) (54ced7a)
- fix(repos): sync archive stats from the info dialog's listing (#853) (8d3f876)
- fix(borg2): stop sending --bypass-lock to a Borg that never had it (#852) (54ab2d7)
- docs(ssh): say where SSHFS pull mode needs FUSE access, and what it looks like when it is missing (#846) (d16aecc)
- fix(dashboard): surface prune, scheduled check, and restore runs in the activity timeline (#851) (5624594)
- fix(remote): classify borg warning exit codes as warnings, and record the resolved archive name (#843) (a632cc3)
- fix(scheduler): keep executor_type in the router repo snapshot (#850) (cacfa01)
- chore(deps): bump the frontend-minor-patch group in /frontend with 14 updates (#849) (b871dd3)
- chore(deps): bump the backend-minor-patch group with 7 updates (#848) (152b67e)
- fix(ci): recognise Borg release assets by their name shape (#840) (8631be0)
- chore(deps-dev): bump @testing-library/jest-dom to 7 (#830) (3b4de76)
- chore(deps): bump the backend-minor-patch group with 6 updates (8622641)
- chore(deps): bump the frontend-minor-patch group in /frontend with 8 updates (ba6b8ad)
- chore(deps): bump webauthn to 3 (#832) (c3d4a4b)
- chore(deps-dev): bump jsdom to 30 (and run the security job on a supported Node) (#831) (61215ab)
- feat(deps): migrate frontend to MUI 9 (material + icons in lockstep) (b39e8b3)
- docs(docker): explain supplementary group access (#829) (7a1fc57)
- docs: fix broken star history chart in README (#827) (0ba134e)
- style(frontend): restore prettier 3.9.6 formatting (unbreaks Code Quality on every PR) (#828) (8151b27)
Docker Images
Published to Docker Hub:
docker pull ainullcode/borg-ui:2.3.0-alpha.2
Install without Docker
Debian or Ubuntu host (bare metal, VM, or LXC):
curl -fsSLO https://github.com/karanhudia/borg-ui/releases/download/v2.3.0-alpha.2/install.sh
curl -fsSL https://github.com/karanhudia/borg-ui/releases/download/v2.3.0-alpha.2/install.sh.sha256 | sha256sum -c - \
&& sudo bash install.sh --version 2.3.0-alpha.2
Full Changelog: v2.3.0-alpha.1...v2.3.0-alpha.2