vikunja/veans/internal
Tink bot 9b8ad4d027 feat(veans): URL discovery on init, port of the frontend's heuristic
The previous init flow took whatever the user typed for --server and
called GET <url>/api/v1/info on it. If the user typed
"vikunja.example.com" (no scheme), or pasted the URL with /api/v1 in
it (double-suffix), or pointed at a localhost install on the default
:3456 port without typing the port, we'd hand back a raw HTTP error.

New `client.DiscoverServer` ports the frontend's
helpers/checkAndSetApiUrl.ts discovery: probe a small ordered set of
plausible bases for /api/v1/info, return the first one that returns
parseable Info. Candidate order:

  1. scheme://host[:port]/path           (as the user typed it)
  2. scheme://host:3456/path             (default API port)
  3. opposite scheme of (1)
  4. opposite scheme of (2)

Heuristics:
- Missing scheme → https for public hosts, http for localhost /
  127.0.0.1 / [::1] (matches most CLIs' behaviour)
- Trailing /api/v1 from a pasted URL is stripped before probing, so
  we don't double up to /api/v1/api/v1/info
- Trailing slashes normalized

Errors now list everything we tried + the last underlying network
error, so the user can see why a URL failed instead of just
"GET /info: connection refused":

  veans: VALIDATION_ERROR: couldn't find a Vikunja instance reachable
    from "vikunja.example.com" — tried:
    - https://vikunja.example.com/api/v1/info
    - https://vikunja.example.com:3456/api/v1/info
    - http://vikunja.example.com/api/v1/info
    - http://vikunja.example.com:3456/api/v1/info
    last error: dial tcp: lookup vikunja.example.com: no such host

bootstrap.Init now defers URL canonicalisation to DiscoverServer and
caches the matched info from the probe (no second /info round-trip).

Unit tests cover the candidate-builder across the common shapes:
bare hostname, localhost, /api/v1-suffixed paste, explicit port,
subpath install, 127.0.0.1:3456, trailing slash. e2e green.
2026-05-27 08:21:57 +00:00
..
auth feat(veans): install agent hooks during init instead of just printing 2026-05-27 08:21:57 +00:00
bootstrap feat(veans): URL discovery on init, port of the frontend's heuristic 2026-05-27 08:21:57 +00:00
client feat(veans): URL discovery on init, port of the frontend's heuristic 2026-05-27 08:21:57 +00:00
commands feat(veans): install agent hooks during init instead of just printing 2026-05-27 08:21:57 +00:00
config feat(veans): install agent hooks during init instead of just printing 2026-05-27 08:21:57 +00:00
credentials feat(veans): install agent hooks during init instead of just printing 2026-05-27 08:21:57 +00:00
output feat(veans): install agent hooks during init instead of just printing 2026-05-27 08:21:57 +00:00
status feat(veans): match existing bucket titles via case-insensitive alias table 2026-05-27 08:21:57 +00:00