sapedb-types --from <connection string>
The generator now takes a connection string as well as a file, connects, reads the live catalogue, and
writes the same .d.ts from it. Measured against a real daemon:
193 of 193 tests, 0 skipped.
The triage above still says Defer, and that is left standing on purpose rather than rewritten to look prescient. The rule is that a deferred issue may be picked up when it is cheap and adjacent — and this one became both, because the work already had a daemon running and the catalogue already answered the question. Deferred means "not required for the tag", not "forbidden".
One measurement trap is worth recording. The two paths — from a file, and from a server — produce output differing on 41 of 64 lines, and they differ for two entirely benign reasons: the header (provenance, with the connection string redacted) and the ordering of operations, because the store keys them by name. A comparison by length, or by line count, would have passed both files as equivalent while saying nothing at all. They were compared as sets of declarations instead.
sapedb-types, the type generator in packages/ecosy-sapedb, reads a
schema.json file from local disk (readFileSync, per its own usage comment at
src/types/index.ts:5-22) and produces a .d.ts from it. The server already
answers a richer version of the same question live: WhatIsHere
(internal/store/explore.go:207, sapedb) returns a Catalogue with every declared
collection and every declared operation, over the wire, from whatever a running daemon actually has
installed. Nothing connects the two. A client author generates types from a file they maintain by hand,
which can drift from what the server they are pointed at actually declares.
This is the same shape of gap as SAPE-11's: the server can already say what is installed, and the tooling that would consume that answer was never built.
src/types/index.ts:1-22's own header documents the intended usage as
npx sapedb-types schema.json > src/sapedb-schema.d.ts and
const source = typesFor(JSON.parse(readFileSync("schema.json", "utf8"))) — a local file
path, not a connection string, not a socket.internal/store/explore.go:195-207, sapedb: Catalogue{ Collections []Spec;
Operations []Operation }, filled by WhatIsHere from the store's live state — this
is exactly the input a generator would need to run against a server instead of a file, and it already
exists.WhatIsHere/Explore
response into sapedb-types' generator finds none. The generator's only documented input is
a file on disk.Does it lose data, break a promise on a public surface, or stop somebody installing and running? No. Nothing is documented as reading live from the server today, so nothing is broken — this is a capability nobody promised, not one that regressed.
Defer. It is a convenience feature layered on two surfaces (the generator,
WhatIsHere) that both already work independently. Building the bridge is additive and does
not touch a frozen surface.
Declare frame, or SAPE-14's
collection half, now shipped — has no path to a generated client type without somebody manually
copying its declaration into a local schema.json. The install can be live; the type
generation cannot.schema.json to generate from.WhatIsHere response instead of, or in
addition to, a file. The generator's transform logic does not need to change, only where its input
comes from. That estimate held — the transform was untouched.