socks5Greeting/Auth/Connect/UDPAssociate per docs/superpowers/specs/
2026-05-01-checker-design.md. RFC 1928 + RFC 1929 wire bytes, raw
reply bytes returned on every error path for RawHex display, ctx
deadline applied via SetDeadline, ctx.Err() joined into error chain
on cancellation. Sentinel errors and ErrSocks5Reply{Code} for code
matching via errors.Is.
Tests: 22 subtests with fake net.Listen server, table-driven per
primitive (happy paths, REP codes, short reads, bad version,
oversize input rejection without I/O, ctx-cancel mid-read).
go test -race -cover passes at 89.0%, go vet clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- app.go: App struct with stub bindings (RunCheck/StartEngine/
StopEngine/GetStatus/Version) — emits check:result, check:done,
engine:status, stats:update events. Real backend lands in Phase 1.
- run.go: wails.Run() with frameless 480x640 fixed window, Classic
dark bg matching theme.
- embed.go: //go:embed all:frontend/dist for the Vite build output.
- frontend/: Vite + React project derived from `wails init -t react`.
Removed default template assets and wired Classic variant from
docs/design/v2/.
- components/Classic.jsx: variant 1 with custom title bar
(drag region, sun/moon theme toggle, min/close hooked to
Wails WindowMinimise/Quit).
- components/shared.jsx: useDrover hook adapted to call Wails
bindings and listen on backend events instead of mock SCENARIOS.
Added IconSun + IconMoon for the title-bar toggle.
- App.jsx: owns mode state, wraps setMode in
document.startViewTransition so the title-bar toggle gives a
circle-reveal sweep from the cursor.
- style.css: clean reset (overflow hidden, no scrollbars, brand
background) — replaces the wails-react-template defaults.
- wailsjs/go/gui/App.js: hand-written bindings since our App
struct lives in package gui rather than the standard top-level
main; `wails generate module` would have written package main
bindings here.
- build/: standard wails artifacts (icon, manifest); will be
consumed by `wails build` once we wire it through CI.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a small, well-tested package that:
- Queries /api/v1/repos/root/drover-go/releases/latest (404 = no updates,
not an error).
- Compares the published tag against the running Version using
golang.org/x/mod/semver, so v0.1.0-rc.2 < v0.1.0. "dev" or any
semver-invalid current version is treated as "always update".
- Downloads the windows-amd64 asset + SHA256SUMS.txt, verifies the
sha256 of the binary against its line in the sums file (tolerates
the asterisk binary-mode prefix), and atomically swaps the running
exe via github.com/minio/selfupdate.
- Uses a 15s connect timeout with no overall request deadline, so
large asset downloads aren't truncated.
- Reports progress via an optional callback.
Public surface: Source interface + ForgejoSource implementation,
CheckForUpdate, ApplyUpdate, SetVersion. No GUI/cobra/Wails imports
in the package, so the same code is reusable from the CLI, the
Windows service, and the future tray UI.
Wires the package into "drover update" / "drover update --check-only"
in cmd/drover/main.go. --check-only exits 0 whether or not an update
is available; only network/sha/apply errors are non-zero.
Tests cover CheckForUpdate (table-driven incl. semver pre-release
ordering, dev fallthrough, source errors), parseSHA256Sums (text and
binary modes, CRLF, malformed lines, missing entries),
ForgejoSource.Latest (httptest with canned JSON, 404, 500, missing
asset, missing SHA256SUMS), and downloadAndVerify (success, sha
mismatch, HTTP 404, context cancellation). All run with -race.
Smoke-tested manually: built drover.exe and "drover update --check-only"
against git.okcu.io prints "No updates available" and exits 0 (no
releases yet).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>