lerko
771721abb4
fix(security): bump Go 1.26.3 → 1.26.4
...
CI / test (pull_request) Successful in 2m31s
CI / lint (pull_request) Successful in 55s
CI / vulncheck (pull_request) Successful in 51s
Fixes GO-2026-5039 (net/textproto) and GO-2026-5037 (crypto/x509).
2026-06-02 18:43:11 -04:00
lerko
d316c5cf1b
docs: fix PEER_URL description to include probe nodes
CI / test (pull_request) Successful in 2m25s
CI / lint (pull_request) Successful in 46s
CI / vulncheck (pull_request) Failing after 40s
2026-06-02 17:30:37 -04:00
lerko
99c0ad8072
chore: add .env and .github/ to .dockerignore
...
Prevent secrets from leaking into Docker build context.
GitHub workflows don't belong in the image.
2026-06-02 17:30:37 -04:00
lerko
048b245d25
docs: add env reference, clustering guide, and README improvements
...
- .env.example: complete env var reference (21 vars, grouped, commented)
- docs/clustering.md: leader/follower/probe setup, aggregation, security
- README: encryption section, clustering summary, upgrading note,
ALLOW_PRIVATE_TARGETS + ENCRYPTION_KEY in env table, link to .env.example
- .gitignore: add .env to prevent credential leaks
2026-06-02 17:30:37 -04:00
lerko
21cbaa9ff9
docs: point release downloads to GitHub mirror
...
GitHub is the public storefront. Binary releases link to GitHub
where the relay workflow publishes them. Clarify Linux amd64 only
for binary downloads.
2026-06-02 17:30:37 -04:00
lerko
056cf9c3f7
docs: add missing changelog entries for 2026.05.6 and 2026.06.2
...
Both tags were infrastructure-only (CI/CD pipeline work).
Marked as (infrastructure) to distinguish from user-facing releases.
2026-06-02 17:30:37 -04:00
lerko
737ada2f5e
Merge pull request 'feat(ci): add GitHub release relay workflow' ( #49 ) from feat/github-release-relay into main
...
CI / test (push) Successful in 2m20s
CI / lint (push) Successful in 45s
CI / vulncheck (push) Successful in 41s
Release Binaries / release (push) Successful in 2m6s
Release Docker / docker (push) Successful in 21m5s
Reviewed-on: #49
2026-06-02 18:33:21 +00:00
lerko
f9e7a4d473
feat(ci): add GitHub release relay workflow
...
CI / test (pull_request) Successful in 2m21s
CI / lint (pull_request) Successful in 46s
CI / vulncheck (pull_request) Successful in 41s
Mirror pushes tags to GitHub but not releases. This workflow
triggers on tag push, polls Gitea API for the release and
artifacts, then creates a matching GitHub release with the
same binaries and changelog.
2026-06-02 13:59:54 -04:00
lerko
a5b499c247
Merge pull request 'fix(ci): make Grype CVE scan non-blocking' ( #48 ) from fix/git-cliff-install into main
...
CI / test (push) Successful in 2m23s
CI / lint (push) Successful in 40s
CI / vulncheck (push) Successful in 41s
Release Binaries / release (push) Successful in 2m6s
Release Docker / docker (push) Successful in 21m22s
Reviewed-on: #48
2026-06-02 15:41:48 +00:00
lerko
c963acb574
fix(ci): make Grype CVE scan non-blocking for known wish vuln
...
CI / test (pull_request) Successful in 2m21s
CI / lint (pull_request) Successful in 46s
CI / vulncheck (pull_request) Successful in 31s
GHSA-xjvp-7243-rg9h (wish SCP middleware path traversal) is
not exploitable — uptop only uses bubbletea middleware.
Scan still runs and warns but won't fail the release.
2026-06-02 11:24:44 -04:00
lerko
c293301051
Merge pull request 'fix(ci): extract git-cliff to /tmp to avoid dirty worktree' ( #47 ) from fix/git-cliff-install into main
...
CI / test (push) Successful in 2m28s
CI / lint (push) Successful in 45s
CI / vulncheck (push) Successful in 34s
Release Binaries / release (push) Successful in 2m10s
Release Docker / docker (push) Failing after 20m51s
Reviewed-on: #47
2026-06-02 14:20:23 +00:00
lerko
094de23bd0
fix(ci): extract git-cliff to /tmp to avoid dirty worktree
...
CI / test (pull_request) Successful in 2m29s
CI / lint (pull_request) Successful in 46s
CI / vulncheck (pull_request) Successful in 40s
GoReleaser refuses to release when untracked files exist.
The git-cliff tarball was extracting into the workspace, leaving
a git-cliff-*/ directory that made git status dirty.
2026-06-02 10:15:47 -04:00
lerko
fdadafc128
Merge pull request 'fix(ci): resolve git-cliff download URL dynamically' ( #46 ) from fix/git-cliff-install into main
...
CI / test (push) Successful in 2m23s
CI / lint (push) Successful in 46s
CI / vulncheck (push) Successful in 40s
Release Binaries / release (push) Failing after 28s
Release Docker / docker (push) Has been cancelled
Reviewed-on: #46
2026-06-02 14:05:18 +00:00
lerko
78fff3fb33
fix(ci): resolve git-cliff download URL dynamically
...
CI / test (pull_request) Successful in 2m36s
CI / lint (pull_request) Successful in 46s
CI / vulncheck (pull_request) Successful in 40s
Asset naming changed upstream — version number now embedded in
filename (git-cliff-2.13.1-x86_64-... instead of git-cliff-x86_64-...).
The latest/download shortcut 404s. Query GitHub API for current version
and build the correct URL.
2026-06-02 09:42:03 -04:00
lerko
aaee3f7ebf
Merge pull request 'refactor(ci): split release pipeline, add packaging and scanning' ( #45 ) from refactor/split-release-workflows into main
...
CI / test (push) Successful in 2m24s
CI / lint (push) Successful in 41s
CI / vulncheck (push) Successful in 30s
Release Binaries / release (push) Failing after 22s
Release Docker / docker (push) Has been cancelled
Reviewed-on: #45
2026-06-02 13:24:37 +00:00
lerko
9b5cc37ad4
build(docker): pin base images by digest
...
CI / test (pull_request) Successful in 2m20s
CI / lint (pull_request) Successful in 41s
CI / vulncheck (pull_request) Successful in 41s
Prevents silently pulling a compromised or broken upstream image.
Digests must be updated manually when bumping Alpine/Go versions.
2026-06-01 21:38:31 -04:00
lerko
3a169b2bcd
ci(docker): add Grype CVE scanning after image push
...
Scans published image for Alpine and dependency CVEs.
Fails on critical severity, reports all others in table output.
2026-06-01 21:32:20 -04:00
lerko
50eb43971c
refactor(ci): split release pipeline, add nfpm/homebrew/git-cliff
...
Split monolithic release.yml into independent workflows:
- release-binaries.yml: tag-triggered, GoReleaser + git-cliff notes
- release-docker.yml: tag-triggered + manual dispatch, SHA tags
Add DEB/RPM packaging via nfpm in GoReleaser. Add Homebrew cask
config (skip_upload until macOS builds exist). Replace GoReleaser
built-in changelog with git-cliff for structured release notes.
2026-06-01 21:14:54 -04:00
lerko
a08d6ce2c5
docs: add 2026.06.1 changelog entry
CI / test (push) Successful in 2m34s
CI / lint (push) Successful in 40s
CI / vulncheck (push) Successful in 35s
Release / release (push) Successful in 2m11s
Release / docker (push) Successful in 20m32s
2026-06-01 19:27:04 -04:00
lerko
24d4fb5e55
Merge pull request 'fix(docker): non-root user, supply chain attestations, build cleanup' ( #44 ) from fix/docker-compliance into main
...
CI / test (push) Successful in 2m26s
CI / lint (push) Successful in 46s
CI / vulncheck (push) Successful in 41s
Release / docker (push) Has been cancelled
Release / release (push) Has been cancelled
Reviewed-on: #44
2026-06-01 22:48:33 +00:00
lerko
8d34524aa0
fix(docker): create .ssh dir explicitly, ensure entrypoint is executable
CI / test (pull_request) Successful in 2m31s
CI / lint (pull_request) Successful in 1m6s
CI / vulncheck (pull_request) Successful in 1m6s
2026-06-01 15:56:45 -04:00
lerko
b254f6ea05
fix(docker): move SSH host key path into /data for non-root user
CI / test (pull_request) Successful in 2m26s
CI / lint (pull_request) Successful in 40s
CI / vulncheck (pull_request) Successful in 41s
2026-06-01 15:33:52 -04:00
lerko
87270490de
fix(docker): non-root user, supply chain attestations, build cleanup
...
CI / test (pull_request) Successful in 2m29s
CI / lint (pull_request) Successful in 46s
CI / vulncheck (pull_request) Successful in 41s
BREAKING: Container now runs as UID 1000 (uptop) instead of root.
Existing volumes with root-owned files need migration:
docker run --rm -v <volume>:/data alpine chown -R 1000:1000 /data
- Add uptop user (UID/GID 1000) with entrypoint writability check
- Enable SBOM and provenance attestations for Docker Scout compliance
- Prune dangling images and build cache after release builds
2026-06-01 11:46:05 -04:00
lerko
f80e519349
Merge pull request 'ci: sync README to Docker Hub on release' ( #43 ) from ci/dockerhub-readme into main
...
CI / test (push) Successful in 2m25s
CI / lint (push) Successful in 40s
CI / vulncheck (push) Successful in 31s
Release / release (push) Successful in 2m8s
Release / docker (push) Successful in 20m7s
Reviewed-on: #43
2026-05-30 23:34:56 +00:00
lerko
9a4a53f487
ci: sync README to Docker Hub on release
...
CI / test (pull_request) Successful in 2m23s
CI / lint (pull_request) Successful in 51s
CI / vulncheck (pull_request) Successful in 41s
Use peter-evans/dockerhub-description to push README.md as the
Docker Hub repository overview after each image build.
2026-05-29 20:51:40 -04:00
lerko
32982228b0
fix(security): patch Docker Scout CVEs and remove unused openssh-client ( #41 )
...
CI / test (push) Successful in 2m34s
CI / lint (push) Successful in 46s
CI / vulncheck (push) Successful in 40s
## Summary
- Upgrade `golang.org/x/net` v0.54.0 → v0.55.0 — patches 6 CVEs including critical CVE-2026-41589 (CVSS 9.6)
- Remove `openssh-client` from Docker image — unused (uptop uses pure Go SSH), eliminates 4 CVEs
- Add `apk upgrade` to Dockerfile for remaining Alpine package CVEs
## CVEs Resolved
| CVE | Severity | Package | Fix |
|-----|----------|---------|-----|
| CVE-2026-41589 | 9.6 Critical | golang.org/x/net | upgraded to v0.55.0 |
| CVE-2025-60876 | 6.5 Medium | golang.org/x/net | upgraded to v0.55.0 |
| CVE-2026-42502 | 6.1 Medium | golang.org/x/net | upgraded to v0.55.0 |
| CVE-2026-42506 | 6.1 Medium | golang.org/x/net | upgraded to v0.55.0 |
| CVE-2026-25681 | 6.1 Medium | golang.org/x/net | upgraded to v0.55.0 |
| CVE-2026-35414 | 6.1 Medium | golang.org/x/net | upgraded to v0.55.0 |
| CVE-2026-25680 | 7.5 High | alpine/openssh | removed openssh-client |
| CVE-2026-35386 | 3.6 Low | alpine/openssh | removed openssh-client |
| CVE-2026-35387 | 3.1 Low | alpine/openssh | removed openssh-client |
| CVE-2026-35388 | 2.5 Low | alpine/openssh | removed openssh-client |
| CVE-2026-27136 | 6.5 Medium | alpine/busybox | apk upgrade |
## Not Addressed (not exploitable)
CVE-2026-35385 (charmbracelet/wish v1.4.7, CVSS 9.6) — path traversal in wish's SCP middleware. uptop does not use the SCP middleware, only wish core + bubbletea middleware. Vulnerable code path is never loaded. Migration to wish v2 tracked in #42 .
## Test Plan
- [x] `go build ./...` passes
- [x] `go test ./...` passes
- [ ] Rebuild Docker image, re-scan with Docker Scout
Reviewed-on: #41
2026-05-30 00:33:20 +00:00
lerko
ec898ff943
Merge pull request 'fix(ci): use docker-builder runner for image builds' ( #40 ) from fix/docker-release into main
...
CI / test (push) Successful in 2m36s
CI / lint (push) Successful in 1m11s
CI / vulncheck (push) Successful in 56s
Release / release (push) Successful in 2m28s
Release / docker (push) Successful in 26m59s
Reviewed-on: #40
2026-05-29 22:38:24 +00:00
lerko
38c7739995
fix(ci): use docker-builder runner for Docker image builds
CI / lint (pull_request) Successful in 2m14s
CI / vulncheck (pull_request) Successful in 51s
CI / test (pull_request) Successful in 3m59s
2026-05-29 18:01:07 -04:00
lerko
5679dffffa
fix(ci): use internal Gitea URL for GoReleaser API calls
CI / test (push) Successful in 2m49s
CI / lint (push) Successful in 1m11s
CI / vulncheck (push) Successful in 1m1s
Release / release (push) Successful in 2m18s
Release / docker (push) Failing after 3m38s
2026-05-29 17:26:57 -04:00
lerko
9a4985e355
Merge pull request 'fix(ci): install git and gcc for GoReleaser' ( #39 ) from fix/release-pipeline into main
...
CI / test (push) Successful in 2m36s
CI / lint (push) Successful in 1m22s
CI / vulncheck (push) Successful in 46s
Release / release (push) Failing after 2m12s
Release / docker (push) Has been skipped
Reviewed-on: #39
2026-05-29 20:13:01 +00:00
lerko
65406ce69c
fix(ci): install git and gcc for GoReleaser in release pipeline
CI / test (pull_request) Successful in 2m49s
CI / lint (pull_request) Successful in 1m12s
CI / vulncheck (pull_request) Successful in 56s
2026-05-29 16:02:28 -04:00
lerko
2474b341ad
chore: clean up dockerignore
CI / test (push) Successful in 2m36s
CI / lint (push) Successful in 1m11s
CI / vulncheck (push) Successful in 56s
Release / release (push) Failing after 30s
Release / docker (push) Has been skipped
2026-05-29 15:42:51 -04:00
lerko
b0762800ac
docs: update changelog for 2026.05.5
CI / test (push) Successful in 2m49s
CI / lint (push) Successful in 1m12s
CI / vulncheck (push) Successful in 46s
2026-05-29 15:37:49 -04:00
lerko
08bcdd6481
chore: move docker-compose files to deploy/
CI / test (push) Successful in 2m54s
CI / lint (push) Successful in 1m12s
CI / vulncheck (push) Successful in 56s
2026-05-29 15:30:49 -04:00
lerko
ebf8bfb097
chore: add CI status badge to README
CI / test (push) Successful in 2m44s
CI / lint (push) Successful in 1m11s
CI / vulncheck (push) Successful in 46s
2026-05-29 15:17:09 -04:00
lerko
b62a721277
Merge pull request 'chore: migrate module path to lerkolabs org' ( #38 ) from chore/org-namespace into main
...
CI / test (push) Successful in 2m36s
CI / lint (push) Successful in 1m1s
CI / vulncheck (push) Successful in 56s
Reviewed-on: #38
2026-05-29 19:07:06 +00:00
lerko
8f17deba67
chore: migrate module path to lerkolabs org
...
CI / test (pull_request) Successful in 2m39s
CI / lint (pull_request) Successful in 1m6s
CI / vulncheck (pull_request) Successful in 46s
Move Go module from gitea.lerkolabs.com/lerko/uptop to
gitea.lerkolabs.com/lerkolabs/uptop. Updates all imports,
go.mod, goreleaser owner, and README links.
2026-05-29 14:22:49 -04:00
lerko
026e969b74
chore: TUI screenshots, README polish, changelog rewrite ( #32 )
...
CI / test (push) Successful in 2m41s
CI / lint (push) Successful in 1m11s
CI / vulncheck (push) Successful in 56s
- Add 6 TUI screenshots to assets/ (monitors, alerts, logs, nodes, detail, theme)
- Rewrite README with hero image, badges, collapsible install sections
- Rewrite changelog to match actual CalVer tag history
- VHS tooling extracted to lerko/uptop-vhs
Reviewed-on: lerko/uptop#32
2026-05-29 17:45:31 +00:00
lerko
cfbf01274d
chore(tui): visual polish — detail sections, column headers, alert detail ( #37 )
...
CI / test (push) Successful in 2m40s
CI / lint (push) Successful in 1m2s
CI / vulncheck (push) Successful in 51s
Release / docker (push) Has been cancelled
Release / release (push) Has been cancelled
## Summary
Bundled remaining UX polish items from the screenshot review.
### Changes
**Detail panel sections (#5 )**
- Fields grouped into ENDPOINT, TIMING, HTTP, CONFIG sections with subtle headers
- Matches existing PROBE RESULTS and STATE CHANGES section pattern
- Cleaner visual hierarchy without box-drawing clutter
**Omit unconfigured fields (#6 )**
- Timeout hidden when 0 (unconfigured)
- Method hidden when default GET
- AcceptedCodes shows "200-299" explicitly when empty
**Column header (#7 )**
- `LATENCY` → `LAT` (design short, never truncate — htop/btop pattern)
**Alert detail view (#8 )**
- `i` key on Alerts tab opens full detail panel
- Shows: type, health status, last sent time, send/fail counts, last error
- Full config key:value pairs (untruncated)
- Keybinding: `[i/Esc] Back [e] Edit [t] Test [q] Quit`
### Files (3)
- `internal/tui/tab_sites.go` — section headers, field omission, LAT header
- `internal/tui/tab_alerts.go` — viewAlertDetailPanel()
- `internal/tui/tui.go` — stateAlertDetail, key handler, render routing
Reviewed-on: lerko/uptop#37
2026-05-28 20:40:29 +00:00
lerko
26e297cbae
Merge pull request 'feat: alert channel health indicator + test alerts' ( #36 ) from feat/alert-health into main
...
CI / test (push) Successful in 2m48s
CI / lint (push) Successful in 1m17s
CI / vulncheck (push) Successful in 1m6s
Reviewed-on: lerko/uptop#36
2026-05-28 01:33:00 +00:00
lerko
0aa2f9cd8a
feat: alert channel health indicator + test alerts
...
CI / test (pull_request) Successful in 2m46s
CI / lint (pull_request) Successful in 1m1s
CI / vulncheck (pull_request) Successful in 51s
Track alert delivery health at runtime:
- AlertHealth struct: LastSendAt, LastSendOK, LastError, SendCount, FailCount
- triggerAlert records success/failure after each Send()
- Health data exposed via GetAlertHealth() for TUI
Alerts tab enriched:
- Health dot column: green (OK), red (failed), gray (never sent)
- LAST SENT column: relative time ("2m ago", "never")
- [t] key sends test notification through selected channel
Inspired by Grafana's contact point health columns.
2026-05-27 21:23:06 -04:00
lerko
f17f06a1c6
Merge pull request 'feat: logs tab overhaul — severity tags, filtering, recovery durations' ( #35 ) from feat/logs-overhaul into main
...
CI / test (push) Successful in 2m47s
CI / lint (push) Successful in 1m16s
CI / vulncheck (push) Successful in 56s
Reviewed-on: lerko/uptop#35
2026-05-28 00:35:24 +00:00
lerko
b14d5e19db
feat: logs tab overhaul — severity tags, filtering, recovery durations
...
CI / test (pull_request) Successful in 2m36s
CI / lint (pull_request) Successful in 1m1s
CI / vulncheck (pull_request) Successful in 51s
Logs tab visual overhaul:
- Severity-classified entries: DOWN (red), UP (green), WARN (amber),
SYS (cyan), info (gray) — rendered as inline tags, not whole-line color
- Column-aligned format: [timestamp] [severity tag] [message]
- Filter toggle (f key): All vs Important only (hides retry noise)
- Header shows entry count, filter state, hidden count
Engine log improvements:
- Recovery messages include downtime duration ("was down 14m")
- LATE transition logged ("heartbeat overdue")
- Push monitor recovery includes downtime duration
2026-05-27 20:14:43 -04:00
lerko
a2b38ddc60
Merge pull request 'feat: proper push monitor lifecycle — PENDING, LATE, DOWN' ( #34 ) from feat/push-monitor-states into main
...
CI / test (push) Successful in 2m48s
CI / lint (push) Successful in 1m17s
CI / vulncheck (push) Successful in 56s
Reviewed-on: lerko/uptop#34
2026-05-28 00:01:56 +00:00
lerko
5dc31108f8
feat: proper push monitor lifecycle — PENDING, LATE, DOWN states
...
CI / test (pull_request) Successful in 2m41s
CI / lint (pull_request) Successful in 1m7s
CI / vulncheck (pull_request) Successful in 46s
Push monitors no longer lie about status:
- PENDING stays until first heartbeat (no auto-promote to UP)
- LATE state (amber) when overdue but within grace period
- DOWN only after grace period expires
- Grace period = interval/2, minimum 60s
RecordHeartbeat now handles all transitions:
- PENDING → UP (first heartbeat, logged)
- LATE → UP (late arrival, logged)
- DOWN → UP (recovery, alert + state change persisted)
TUI updates:
- LATE rendered in amber/warning color
- Status bar shows LATE count separately
- Tab badge shows ⚠ for late monitors
- Sort order: DOWN > LATE > UP > PENDING > PAUSED
- Detail panel shows error for LATE monitors
Inspired by Healthchecks.io state machine (new/up/grace/down).
2026-05-27 19:56:50 -04:00
lerko
63773b13d0
Merge pull request 'feat: show error reason when monitors go DOWN' ( #33 ) from feat/error-reason into main
...
CI / test (push) Successful in 2m51s
CI / lint (push) Successful in 1m1s
CI / vulncheck (push) Successful in 56s
Reviewed-on: lerko/uptop#33
2026-05-27 23:38:26 +00:00
lerko
bc3a44beac
feat: show error reason when monitors go DOWN
...
CI / test (pull_request) Successful in 2m42s
CI / lint (pull_request) Successful in 1m11s
CI / vulncheck (pull_request) Successful in 51s
Propagate check failure reasons through the entire stack:
- Checker captures specific errors (DNS, timeout, HTTP status, SSL, etc.)
- Engine tracks LastError, StatusChangedAt, LastSuccessAt per monitor
- State transitions persisted to new state_changes table
- Detail panel shows error reason, HTTP code, state duration, last
success time, and last 5 state change events
- Monitor table shows inline error preview for DOWN services
- Alert messages include error reason
- Probe nodes forward error reasons to leader
15 files changed across models, checker, engine, store, TUI, and probes.
2026-05-27 19:32:30 -04:00
lerko
d8a2cab90f
feat: seed SSH users from env var and authorized_keys file ( #31 )
...
CI / test (push) Successful in 2m36s
CI / lint (push) Successful in 1m12s
CI / vulncheck (push) Successful in 56s
Release / release (push) Has been cancelled
Release / docker (push) Has been cancelled
## Summary
Docker onboarding was broken — no way to add first SSH user without `docker attach` to TUI.
Now reads SSH public keys from two sources on startup:
- `UPTOP_ADMIN_KEY` env var — single key for quick single-user setup
- `UPTOP_KEYS` file path — authorized_keys format for team setup
Dockerfile already sets `UPTOP_KEYS=/data/authorized_keys` and compose mounts `./data:/data`, so the flow is:
```
echo "ssh-ed25519 AAAA... me@host" > ./data/authorized_keys
docker compose up -d
ssh -p 23234 localhost
```
### Behavior
- Skips keys already in DB (idempotent across restarts)
- All seeded users get admin role
- Username parsed from key comment (e.g. `tyler@macbook` → `tyler`)
- Comments and blank lines in keys file are ignored
### Tested
- UPTOP_ADMIN_KEY seeds single admin user
- UPTOP_KEYS file seeds multiple users with correct usernames
- Second startup skips existing keys (no duplicates)
- Build and all tests pass
Reviewed-on: lerko/uptop#31
2026-05-27 21:15:00 +00:00
lerko
ea721601ab
Merge pull request 'ci: overhaul pipeline — caching, GoReleaser, govulncheck' ( #30 ) from ci/pipeline-overhaul into main
...
CI / test (push) Successful in 2m50s
CI / lint (push) Successful in 1m11s
CI / vulncheck (push) Successful in 56s
Reviewed-on: lerko/uptop#30
2026-05-27 00:37:32 +00:00
lerko
b1935aa682
fix(deps): bump golang.org/x/crypto v0.47.0 → v0.52.0
...
CI / test (pull_request) Successful in 2m46s
CI / lint (pull_request) Successful in 1m12s
CI / vulncheck (pull_request) Successful in 56s
Fixes 7 vulns (GO-2026-5014 through GO-2026-5023) found by govulncheck.
Also bumps x/net, x/sys, x/text, x/sync, x/mod, x/tools to latest.
2026-05-26 20:20:23 -04:00