Say which method each registration answers
Hanzo CI/CD / cicd (push) Failing after 6m22s
CI/CD / cicd (push) Failing after 6m23s

A registration that is not a typed operation is spelled Raw now, with the method
named, so opting out of the typed model reads as what it is.

The zip this pins also states the wire explicitly, which matters more than the
version gap suggests: JSON semantics follow the toolchain, so the older pin
answered with different bodies than the code was written against once the
builder moved.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-09-17 04:26:51 -07:00
co-authored by Hanzo Dev
parent 435c0eb107
commit a5460ed12e
4 changed files with 49 additions and 48 deletions
+21 -24
View File
@@ -18,22 +18,28 @@ require (
github.com/luxfi/log v1.5.0
github.com/luxfi/zap v1.2.7
github.com/robfig/cron/v3 v3.0.1
github.com/zap-proto/zip v1.36.9
github.com/zap-proto/zip v1.37.1
golang.org/x/time v0.15.0
)
require (
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/andybalholm/brotli v1.2.1 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gofiber/schema v1.7.1 // indirect
github.com/gofiber/utils/v2 v2.0.4 // indirect
github.com/google/uuid v1.6.1-0.20241114170450-2d3c2a9cc518 // indirect
github.com/gorilla/rpc v1.2.1 // indirect
github.com/grandcat/zeroconf v1.0.0 // indirect
github.com/hanzoai/csqlite v0.1.0 // indirect
github.com/hanzoai/sqlcipher v0.1.1 // indirect
github.com/holiman/uint256 v1.3.2 // indirect
github.com/klauspost/compress v1.18.6 // indirect
github.com/luxfi/accel v1.2.4 // indirect
github.com/luxfi/bft v0.1.5 // indirect
github.com/luxfi/cache v1.3.1 // indirect
github.com/luxfi/compress v0.1.1 // indirect
github.com/luxfi/concurrent v0.1.1 // indirect
@@ -49,20 +55,34 @@ require (
github.com/luxfi/metric v1.10.0 // indirect
github.com/luxfi/mock v0.1.1 // indirect
github.com/luxfi/p2p v1.22.1 // indirect
github.com/luxfi/pq v1.1.0 // indirect
github.com/luxfi/sampler v1.1.0 // indirect
github.com/luxfi/validators v1.3.1 // indirect
github.com/luxfi/version v1.0.1 // indirect
github.com/luxfi/warp v1.24.1 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
github.com/miekg/dns v1.1.72 // indirect
github.com/mr-tron/base58 v1.3.0 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/supranational/blst v0.3.16 // indirect
github.com/tinylib/msgp v1.6.4 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.70.0 // indirect
github.com/zap-proto/fiber/v3 v3.2.1 // indirect
github.com/zap-proto/go v1.8.3 // indirect
github.com/zap-proto/http v0.3.5 // indirect
github.com/zap-proto/mcp v1.0.5 // indirect
go.uber.org/mock v0.6.0 // indirect
golang.org/x/crypto v0.54.0 // indirect
golang.org/x/exp v0.0.0-20260529124908-c761662dc8c9 // indirect
golang.org/x/mod v0.37.0 // indirect
golang.org/x/net v0.56.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.40.0 // indirect
golang.org/x/tools v0.47.0 // indirect
gonum.org/v1/gonum v0.17.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
@@ -70,28 +90,5 @@ require (
modernc.org/libc v1.72.3 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)
require (
github.com/andybalholm/brotli v1.2.1 // indirect
github.com/gofiber/schema v1.7.1 // indirect
github.com/gofiber/utils/v2 v2.0.4 // indirect
github.com/hanzoai/csqlite v0.1.0 // indirect
github.com/hanzoai/sqlcipher v0.1.1 // indirect
github.com/luxfi/bft v0.1.5 // indirect
github.com/luxfi/pq v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/tinylib/msgp v1.6.4 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.70.0 // indirect
github.com/zap-proto/fiber/v3 v3.2.1 // indirect
github.com/zap-proto/go v1.3.0 // indirect
github.com/zap-proto/http v0.3.5 // indirect
github.com/zap-proto/mcp v1.0.5 // indirect
golang.org/x/net v0.56.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.40.0 // indirect
modernc.org/sqlite v1.51.0 // indirect
)
+4
View File
@@ -151,12 +151,16 @@ github.com/zap-proto/fiber/v3 v3.2.1 h1:k45oKyTwySPtGt8sPz2Ao8OUHc7pDEhai8Np2Ym6
github.com/zap-proto/fiber/v3 v3.2.1/go.mod h1:eDm2z+ufJrkuE4MeX0Mea4oc/p7/HpXiZjVB+BXCKOA=
github.com/zap-proto/go v1.3.0 h1:S3rMoawwhH/BbSZ4G8zG05hJoQnMSMDPzIq75diCTqE=
github.com/zap-proto/go v1.3.0/go.mod h1:914SNGTH6Rv3Yu1MweWJBPEN8FZlo5C39QyhaB0C7Q0=
github.com/zap-proto/go v1.8.3 h1:GWhb8y7ylgVcaVOR8XN/It56Xovm5Mkv+nQqiblnnoA=
github.com/zap-proto/go v1.8.3/go.mod h1:fbNeWcssRRbTkQEDCrmUmzqJA1gKcAlgi1z4QrtEFZg=
github.com/zap-proto/http v0.3.5 h1:ezSuUbF05jxFGpfmScBnzIVTeH1ZGhcDSm7d5yL8Byc=
github.com/zap-proto/http v0.3.5/go.mod h1:UYfGhDDCetgxs65XSev8Lpf65COg5vKQK+cWwZGh4zQ=
github.com/zap-proto/mcp v1.0.5 h1:1Hi0KNi4YlWW2zkQUMDK9n3jP3wZaRJ1rseMW9p9F0c=
github.com/zap-proto/mcp v1.0.5/go.mod h1:cYOsq+33NyW4X8nUVtIs/qtezVovYazw1s0V7mrQBYA=
github.com/zap-proto/zip v1.36.9 h1:8jQH9uolR4UaDzxSrEFrDGkFyTmMjRwrbukJ2KvH6R8=
github.com/zap-proto/zip v1.36.9/go.mod h1:k0CQcj6Ro+gfNdREF3WOc9/KeXidzI0WPVnzxUjVR/s=
github.com/zap-proto/zip v1.37.1 h1:kZyzyCGV2osT3QPBfFLPwAU+mBodPOCngFDYEwQXpgk=
github.com/zap-proto/zip v1.37.1/go.mod h1:mYE5BMXclZ14Wz4tw/3ir+QBI7A7DPpi3ROXgwnXpfU=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+15 -15
View File
@@ -48,19 +48,19 @@ func (e *Embedded) Surface() *zip.App {
// The addresses that stand on their own. The MCP endpoint and the event
// stream are NAMED here, because a route carries its address where a bare
// handler left the choice to whoever mounted it.
app.Get(root+"/settings", handle(e, func(rq call, _ *engine) answer { return settings(rq) }))
app.Get(root+"/namespaces", handle(e, namespaces))
app.Post(root+"/namespaces", handle(e, namespaces))
app.Get(root+"/nexus", handle(e, endpoints))
app.Get(root+"/cluster", alone(e.clusterStatus))
app.Get(root+"/cluster/health", alone(e.clusterHealth))
app.Post(root+"/mcp", alone(e.mcp))
app.Get(root+"/events", e.tail)
app.Raw(http.MethodGet, root+"/settings", handle(e, func(rq call, _ *engine) answer { return settings(rq) }))
app.Raw(http.MethodGet, root+"/namespaces", handle(e, namespaces))
app.Raw(http.MethodPost, root+"/namespaces", handle(e, namespaces))
app.Raw(http.MethodGet, root+"/nexus", handle(e, endpoints))
app.Raw(http.MethodGet, root+"/cluster", alone(e.clusterStatus))
app.Raw(http.MethodGet, root+"/cluster/health", alone(e.clusterHealth))
app.Raw(http.MethodPost, root+"/mcp", alone(e.mcp))
app.Raw(http.MethodGet, root+"/events", e.tail)
// One namespace, and the migration of one namespace.
app.Get(root+"/namespaces/:ns", named(e, namespace))
app.Delete(root+"/namespaces/:ns", named(e, namespace))
app.Post(root+"/namespaces/:ns/migrate", func(c *zip.Ctx) error {
app.Raw(http.MethodGet, root+"/namespaces/:ns", named(e, namespace))
app.Raw(http.MethodDelete, root+"/namespaces/:ns", named(e, namespace))
app.Raw(http.MethodPost, root+"/namespaces/:ns/migrate", func(c *zip.Ctx) error {
ns := c.Param("ns")
if a, ok := grammar(ns, nil); !ok {
return a.send(c)
@@ -95,7 +95,7 @@ func (e *Embedded) Surface() *zip.App {
// redirects to the tidied form before it matches anything, so a request
// like /namespaces//workflows reaches a route there and 404s here. That is
// a difference a caller can see, so it is reproduced rather than accepted.
app.All(root+"/*", func(c *zip.Ctx) error {
app.Raw(zip.MethodAll, root+"/*", func(c *zip.Ctx) error {
if to, dirty := tidy(c.Path()); dirty {
if q := string(c.Fiber().RequestCtx().URI().QueryString()); q != "" {
to += "?" + q
@@ -219,11 +219,11 @@ var contents = []row{
func on(app *zip.App, method, path string, h zip.Handler) {
switch method {
case get:
app.Get(path, h)
app.Raw(http.MethodGet, path, h)
case post:
app.Post(path, h)
app.Raw(http.MethodPost, path, h)
case del:
app.Delete(path, h)
app.Raw(http.MethodDelete, path, h)
default:
panic("tasks: no route method " + method)
}
+9 -9
View File
@@ -46,15 +46,15 @@ func FS() fs.FS {
// Handler returns an http.Handler that serves the embedded SPA.
//
// Behaviour:
// - Exact-match static assets (JS/CSS/images) ship with
// immutable cache hints because Vite hashes filenames.
// - Anything else rewrites to /index.html so the React router
// handles the route client-side. This is the standard SPA
// fallback and is the only way react-router's BrowserRouter
// survives a page reload on a deep link.
// - If the build hasn't run and index.html is missing, every
// request returns 503 so operators notice in staging before
// shipping a blank image to production.
// - Exact-match static assets (JS/CSS/images) ship with
// immutable cache hints because Vite hashes filenames.
// - Anything else rewrites to /index.html so the React router
// handles the route client-side. This is the standard SPA
// fallback and is the only way react-router's BrowserRouter
// survives a page reload on a deep link.
// - If the build hasn't run and index.html is missing, every
// request returns 503 so operators notice in staging before
// shipping a blank image to production.
func Handler() http.Handler {
root := FS()
fileServer := http.FileServer(http.FS(root))