Skip to content

feat: close schema pipeline gap — full type coverage + tool schema maps#540

Merged
bokelley merged 2 commits intomainfrom
bokelley/schema-pipeline-gap
Apr 15, 2026
Merged

feat: close schema pipeline gap — full type coverage + tool schema maps#540
bokelley merged 2 commits intomainfrom
bokelley/schema-pipeline-gap

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Summary

Closes #538.

  • Extended generate-types.ts to compile all ~170 missing JSON schemas (enums, pricing options, asset types, brand protocol, governance helpers, collection types, signal definitions, etc.)
  • core.generated.ts: 195 → 376 exports; schemas.generated.ts: 508 Zod schemas
  • Added TOOL_REQUEST_SCHEMAS — Zod schemas keyed by tool name for server.tool(name, schema.shape, handler)
  • Exported TOOL_RESPONSE_SCHEMAS from index.ts (was internal-only)
  • Replaced 3 hand-written brand response schemas with generated ones
  • Added collection list tools to response schema map
  • Added -I timestamp flag to ci:schema-check for local/CI parity

Test plan

  • tsc --noEmit passes
  • npm run build succeeds
  • npm run generate-types produces stable output (no drift)
  • Pre-existing test suite unchanged (82 test files, 7 passing tests — same as main)
  • CI validates generated files are in sync with schemas

🤖 Generated with Claude Code

bokelley and others added 2 commits April 15, 2026 08:14
- Extend generate-types.ts to compile all ~170 missing JSON schemas
  (enums, pricing options, asset types, brand protocol, governance helpers,
  collection types, signal definitions, etc.)
- core.generated.ts: 195 → 376 exports, schemas.generated.ts: 508 Zod schemas
- Add TOOL_REQUEST_SCHEMAS (Zod map keyed by tool name) for MCP server.tool()
- Export TOOL_RESPONSE_SCHEMAS from index.ts (was internal-only)
- Replace 3 hand-written brand response schemas with generated ones
- Add collection list tools to response schema map
- Add -I timestamp flag to ci:schema-check for local parity with CI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 48c0501 into main Apr 15, 2026
13 checks passed
bokelley added a commit that referenced this pull request Apr 15, 2026
… schemas

Replace 40+ individual schema imports and hand-coded TOOL_META.schema
with TOOL_REQUEST_SCHEMAS from #540. Schema and hasAccount are now
derived from the canonical map at registration time.

- Eliminates dual source of truth (review item #5)
- hasAccount derived from schema ('account' in schema.shape)
- Tools not in TOOL_META still register if present in TOOL_REQUEST_SCHEMAS
- TOOL_META now only contains response builders and annotations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Apr 15, 2026
…lper (#541)

* feat: createAdcpServer — declarative server builder with domain-grouped handlers

Domain registration that wires handler types → input schemas → Zod validation
→ response formatting. Auto-generates get_adcp_capabilities from registered tools.

- Domain-grouped handlers: mediaBuy, signals, creative, governance, accounts,
  eventTracking, sponsoredIntelligence
- resolveAccount middleware: auto-resolves AccountReference on tools with account
  field, returns ACCOUNT_NOT_FOUND on failure
- Response builder auto-application: productsResponse, mediaBuyResponse (with
  revision/confirmed_at defaults), getSignalsResponse, etc.
- Tool annotations: readOnlyHint, destructiveHint, idempotentHint set per tool
- Tool coherence warnings: create_media_buy without get_products, etc.
- Unknown handler key warnings: catches typos like getProduct vs getProducts
- Handler error catching: try/catch returns SERVICE_UNAVAILABLE on unhandled errors
- checkGovernance composable helper: seller calls explicitly in financial handlers
- governanceDeniedError convenience: converts denial to COMPLIANCE_UNSATISFIED

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: add changeset for createAdcpServer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: pluggable state store for domain object persistence

AdcpStateStore interface with InMemoryStateStore (default) and
PostgresStateStore (production) implementations. Handlers receive
ctx.store for persisting media buys, accounts, creatives, etc.

- Generic document store: get/put/delete/list by collection + id
- InMemoryStateStore: nested Maps, filtering, pagination
- PostgresStateStore: JSONB table, containment queries, keyset pagination
- Shared across all domain handlers via ctx.store
- getAdcpStateMigration() for postgres table setup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: state store review fixes — cursor bug, patch, copy semantics, limit cap

- Fix InMemoryStateStore cursor tracking (was broken after filtering)
- Add patch() to interface and both implementations (JSONB || merge for postgres)
- get() returns a shallow copy (prevents mutation of store internals)
- list() returns copies and caps limit at 500
- Validate cursor format in PostgresStateStore
- Add tests for cursor roundtrip, patch, copy semantics

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: update all skills and guides for createAdcpServer framework

Updated 8 SKILL.md files, BUILD-AN-AGENT.md, and llms.txt to reference
createAdcpServer with domain-grouped handlers, ctx.store for state
persistence, and auto-applied response builders.

- Seller, signals, creative, governance, SI, brand rights, retail media,
  generative seller skills all show createAdcpServer patterns
- BUILD-AN-AGENT.md leads with createAdcpServer, demotes createTaskCapableServer
  to advanced/escape-hatch section
- llms.txt Quick Start updated with createAdcpServer example
- Common Mistakes tables updated across all skills
- SDK Quick Reference tables updated across all skills

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update_media_buy hasAccount → true (adcp#2179)

update_media_buy now has a required account field per adcp#2174.
This enables automated account resolution on the most financially
sensitive mutation tool.

preview_creative flattening (adcp#2175) will be picked up when
schemas are regenerated from the updated spec.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: derive hasAccount from schema, validate governance response, fix JSDoc

- hasAccount no longer hand-coded in TOOL_META — derived from Zod schema
  at init time via 'account' in schema.shape. Eliminates drift bugs
  (get_creative_delivery and get_signals were wrong).
- checkGovernance validates required fields before casting response
- Module JSDoc updated to remove resolveGovernance (now composable helper)
- genericResponse includes tool name instead of "OK"
- Add test for required account field on create_media_buy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: use TOOL_REQUEST_SCHEMAS as single source of truth for tool schemas

Replace 40+ individual schema imports and hand-coded TOOL_META.schema
with TOOL_REQUEST_SCHEMAS from #540. Schema and hasAccount are now
derived from the canonical map at registration time.

- Eliminates dual source of truth (review item #5)
- hasAccount derived from schema ('account' in schema.shape)
- Tools not in TOOL_META still register if present in TOOL_REQUEST_SCHEMAS
- TOOL_META now only contains response builders and annotations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: context passthrough in createAdcpServer handlers and capabilities

- Handler wrapper auto-injects params.context into response data before
  response builder wraps it. Handlers don't need to echo context manually.
- get_adcp_capabilities registered with actual schema (not empty {}) so
  context from request is received and echoed.
- Storyboard results: 5/6 signal_marketplace steps pass (remaining failure
  is signal_id null/undefined schema mismatch tracked in #542).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: align TypeScript types with Zod nullish, regenerate schemas

The #1 DX blocker: Zod schemas use .nullish() (null | undefined) but
TypeScript types used ? (undefined only). Every handler echoing
params.context hit type errors.

Fix: generate-types.ts now adds | null to optional TypeScript properties,
matching Zod .nullish() behavior. 25 internal call sites updated with
?? undefined to strip null where needed.

Also fixes ZodIntersection schemas (get_signals, etc.) that lost .shape
after regeneration — extractShape() traverses intersection _def.right.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove nullish workaround, fix intersection root cause

Root cause fixes for the two schema generation issues:

1. **Nullish removed**: postProcessForNullish was converting every
   .optional() to .nullish(), making Zod produce null|undefined while
   TypeScript types only had undefined. Removed the post-processor —
   Zod schemas now use .optional() matching TypeScript. Also removed
   alignOptionalWithNullish (TypeScript workaround) and
   postProcessLazyTypeAnnotations (cascading nullish fix).

2. **Intersections fixed**: postProcessRecordIntersections already
   handles most cases. The 5 remaining schemas (get_signals, etc.)
   are now clean z.object() with .shape. Only comply_test_controller
   remains a union (by design — multiple scenario types).

Reverted extractShape() workaround in createAdcpServer — schemas
have .shape directly now.

0 nullish, 2877 optional. Types and schemas match. 2972 tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use GOVERNANCE_DENIED instead of COMPLIANCE_UNSATISFIED

GOVERNANCE_DENIED (adcp#2194) is specific to governance agent denials.
COMPLIANCE_UNSATISFIED is broader (content standards, brand safety).
governanceDeniedError() now uses the correct code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: regen schemas from adcp#2194, add preview_creative to createAdcpServer

Pull in adcp#2194: GOVERNANCE_DENIED error code, flatten comply_test_controller,
context/ext on all schemas, require signal_id.

- preview_creative now flat z.object() — added to CreativeHandlers, TOOL_META,
  TOOL_REQUEST_SCHEMAS, and CREATIVE_ENTRIES
- Removed old PreviewCreative variant exports (no longer needed)
- Updated discriminated union tests for flat schema behavior
- signal_id now required on signals (should fix storyboard provenance check)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: fix CI — prettier formatting and regenerate agent docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: broken resolveAccount example in seller SKILL.md

resolveAccount callback referenced ctx.store which is not in scope.
Fixed to use stateStore (declared outside createAgent factory).
Added InMemoryStateStore import and declaration to make example
copy-paste correct.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

172 JSON schemas missing from type/Zod generation pipeline

1 participant