… API gate
Three changes, all about the docs telling the truth about the SDK.
1. Add @cipherstash/stack-supabase to the TypeDoc entry points.
Stack 1.0 split the Supabase adapter into its own package, and the entry points
were never updated, so NOTHING in it reached the generated reference —
encryptedSupabaseV3, the query builder, and the EQL-version constraints on its
encrypted operators were all absent. 19 pages now generate (763 total, up from
706), including the constraint that free-text and JSON operators are
"unavailable with EQL 3.0.2+" because PostgREST cannot express the required
eql_v3.query_* cast. That is now published automatically instead of relying on
someone reading the source.
2. Resolve a workspace package's subpath imports to source.
stack-supabase imports its sibling by package name (@cipherstash/stack,
/schema, /adapter-kit, ...), which resolves through that package's exports map
to ./dist — and the clone is never built, so all 42 imports were TS2307 and
every cross-package type would have documented as `any`. Derive the tsconfig
`paths` from the sibling's own exports map, rewriting ./dist/x.js to
./packages/<pkg>/src/x.ts, rather than hardcoding twelve subpaths that would
rot the next time Stack adds one. Two of them are not guessable
(`/types` -> types-public.ts, `/v3` -> encryption/v3.ts), which is the argument
for deriving rather than transcribing.
3. Say what the content API gate actually checks.
It printed "no deprecated or non-existent API found in documentation" while the
Supabase page taught `.contains()` for encrypted free-text, which raises. It is
a denylist of 7 patterns, not verification, so it now reports the rule count and
files scanned and states the limitation outright.
Deliberately NOT adding the version-diff denylist discussed: `contains()` was
repurposed rather than removed, so it is present in every tag and no
symbol-presence or signature diff fires on it. Catching that class needs the
examples typechecked against the SDK; the header now records that.
Also removes CLAUDE.md's "Required Skills" section. All six skills it mandated
(encryption, secrets, drizzle, supabase, dynamodb, update-docs) do not exist,
and its validation checklist was stale too — `switcher` appears in 0 files and
the "Good to know" callout in 1, versus <Callout> in 37. Its accurate items are
already covered by the Frontmatter, Code Blocks, and Formatting sections above.
Claude-Session: https://claude.ai/code/session_01NkuQNMvw9BpB4BWWeKtfV8
Three changes, all about the docs telling the truth about the SDK.
1. @cipherstash/stack-supabase is now in the TypeDoc entry points
Stack 1.0 split the Supabase adapter into its own package and the entry points were never updated, so nothing in it reached the generated reference — encryptedSupabaseV3, the query builder, and its EQL-version constraints were all absent. 19 pages now generate (763 total, up from 706).
The payoff is that constraints stop depending on someone reading the source. This is now published automatically:
2. Workspace subpath imports resolve to source
Adding the entry point alone produced 42 × TS2307. stack-supabase imports its sibling by package name (@cipherstash/stack, /schema, /adapter-kit, …), which resolves through that package's exports map to ./dist — and the clone is never built. Every cross-package type would have documented as any, the same failure #77 fixed for protect-ffi.
Fixed by deriving the tsconfig paths from the sibling's own exports map (./dist/x.js → ./packages/<pkg>/src/x.ts) rather than hardcoding twelve subpaths. Two aren't guessable — /types → types-public.ts, /v3 → encryption/v3.ts — which is the argument for deriving rather than transcribing, and it won't rot when Stack adds a subpath.
3. The content API gate no longer overstates itself
It printed ✓ no deprecated or non-existent API found in documentation while the Supabase page taught .contains() for encrypted free-text, which raises. It's a denylist of 7 patterns, not verification. Now:
On the version-diff denylist — I did not build it, and I think that's right
We agreed on deriving the denylist from removed/renamed symbols between Stack versions. Checking before building, it would not have caught the bug that motivated it:
contains() was repurposed, not removed — it's present in every tag, so no symbol-presence diff fires. A signature diff would in principle catch the changed type constraint, but the rename landed in 1.0.0-rc.0, whose predecessor is 0.18.0 — a different major where Supabase lived inside packages/stack. The signal would have been buried in the noise of the entire 1.0 restructure.
Building it anyway would have added a second check that reports confidence it can't back — the exact problem this PR is fixing. The file header now records the finding and points at what would actually work: typechecking the documented examples against the installed SDK, the way Rust compiles doctests. That catches contains()-on-a-text-column as a type error, and it's the only approach here that generalises. Happy to scope it as a follow-up — my suggestion is to start with the reference pages, where examples are most nearly complete, and opt pages in rather than boiling the ocean.
Also: CLAUDE.md's "Required Skills" section removed
All six skills it mandated — encryption, secrets, drizzle, supabase, dynamodb, update-docs — do not exist, so an instruction to "always use" them for API accuracy was unenforceable. Its validation checklist was stale too: switcher appears in 0 files and the "Good to know" callout in 1, versus <Callout> in 37. The accurate items are already covered by the Frontmatter, Code Blocks, and Formatting sections above it.
Verified
bun run build green: 0 TypeDoc errors (from 42), 763 pages, EQL drift clean, no broken links, all validators pass. biome check clean.
https://claude.ai/code/session_01NkuQNMvw9BpB4BWWeKtfV8