v0.11.3
GET / now says what this service can do
The root endpoint is what a caller reads to find out what is here — a shell script, or an
agent that found the port and nothing else. It listed six routes while thirteen were served:
/ui, /search, /projects, /export and /mcp were all reachable but undiscoverable
from the one place that exists to describe them.
It lists all thirteen now, and a new auth field states that a token is required everywhere
except the lines marked (no token). endpoints is still an array of strings, so anything
parsing it keeps working.
A test holds the list to the router
The list had drifted because it was a hand-written literal inside the handler — the same way
the MCP tool descriptions had drifted, and it gets the same treatment. It moves into a table,
and TestRootListsEveryRoute pins both sides:
- every path literal in
http.goandui.gomust be advertised, or named with a reason for
staying out. Routing here is a chain of path comparisons rather than a table, so those
literals are the only list of routes that exists — reading them out of the source means a
route added without a line in the list fails the build rather than going unnoticed. - every advertised line must answer, and must need a token exactly when it does not say
(no token).
The first version of that second check passed while the list advertised a route that does not
exist: an unknown path answers 401 to an anonymous request, because the auth gate runs
before the 404, so "gated" and "missing" look identical until a token is sent. It asks both
ways now. Verified by breaking it four ways — an unlisted route, a listed route that does not
exist, a public endpoint marked private, and a route listed with the wrong method. All four
fail the test.
Full changelog: v0.11.2...v0.11.3