@adcp/sdk 12.0.0 → 12.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/adapters/content-standards-adapter.mjs +0 -6
- package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
- package/dist/lib/adapters/derived-account-store.mjs +0 -6
- package/dist/lib/adapters/derived-account-store.mjs.map +1 -1
- package/dist/lib/adapters/governance-adapter.mjs +0 -6
- package/dist/lib/adapters/governance-adapter.mjs.map +1 -1
- package/dist/lib/adapters/implicit-account-store.mjs +0 -6
- package/dist/lib/adapters/implicit-account-store.mjs.map +1 -1
- package/dist/lib/adapters/index.mjs +0 -6
- package/dist/lib/adapters/index.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/index.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs.map +1 -1
- package/dist/lib/adapters/oauth-passthrough-resolver.mjs +0 -6
- package/dist/lib/adapters/oauth-passthrough-resolver.mjs.map +1 -1
- package/dist/lib/adapters/property-list-adapter.mjs +0 -6
- package/dist/lib/adapters/property-list-adapter.mjs.map +1 -1
- package/dist/lib/adapters/roster-account-store.mjs +0 -6
- package/dist/lib/adapters/roster-account-store.mjs.map +1 -1
- package/dist/lib/adapters/si-session-manager.mjs +0 -6
- package/dist/lib/adapters/si-session-manager.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/brand-fields.mjs +0 -6
- package/dist/lib/adapters/version/3.0/brand-fields.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/get-products.mjs +0 -6
- package/dist/lib/adapters/version/3.0/get-products.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/index.mjs +0 -6
- package/dist/lib/adapters/version/3.0/index.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/sync-accounts.mjs +0 -6
- package/dist/lib/adapters/version/3.0/sync-accounts.mjs.map +1 -1
- package/dist/lib/adapters/version/index.mjs +0 -6
- package/dist/lib/adapters/version/index.mjs.map +1 -1
- package/dist/lib/adapters/version/types.mjs +0 -6
- package/dist/lib/advanced.mjs +0 -6
- package/dist/lib/advanced.mjs.map +1 -1
- package/dist/lib/agents/index.generated.mjs +0 -6
- package/dist/lib/agents/index.generated.mjs.map +1 -1
- package/dist/lib/auth/index.mjs +0 -6
- package/dist/lib/auth/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/CLIFlowHandler.mjs +0 -6
- package/dist/lib/auth/oauth/CLIFlowHandler.mjs.map +1 -1
- package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +0 -6
- package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs.map +1 -1
- package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +0 -6
- package/dist/lib/auth/oauth/MCPOAuthProvider.mjs.map +1 -1
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +0 -6
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs.map +1 -1
- package/dist/lib/auth/oauth/authorization-required.mjs +0 -6
- package/dist/lib/auth/oauth/authorization-required.mjs.map +1 -1
- package/dist/lib/auth/oauth/diagnose.mjs +0 -6
- package/dist/lib/auth/oauth/diagnose.mjs.map +1 -1
- package/dist/lib/auth/oauth/diagnostics.mjs +0 -6
- package/dist/lib/auth/oauth/diagnostics.mjs.map +1 -1
- package/dist/lib/auth/oauth/discovery.mjs +0 -6
- package/dist/lib/auth/oauth/discovery.mjs.map +1 -1
- package/dist/lib/auth/oauth/file-storage.mjs +0 -6
- package/dist/lib/auth/oauth/file-storage.mjs.map +1 -1
- package/dist/lib/auth/oauth/index.mjs +0 -6
- package/dist/lib/auth/oauth/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/secret-resolver.mjs +0 -6
- package/dist/lib/auth/oauth/secret-resolver.mjs.map +1 -1
- package/dist/lib/auth/oauth/storage-registry.mjs +0 -6
- package/dist/lib/auth/oauth/storage-registry.mjs.map +1 -1
- package/dist/lib/auth/oauth/types.mjs +0 -6
- package/dist/lib/auth/oauth/types.mjs.map +1 -1
- package/dist/lib/auth/oauth/web-flow.mjs +0 -6
- package/dist/lib/auth/oauth/web-flow.mjs.map +1 -1
- package/dist/lib/brand/index.mjs +0 -6
- package/dist/lib/brand/index.mjs.map +1 -1
- package/dist/lib/canonical-references/index.mjs +6 -7
- package/dist/lib/canonical-references/index.mjs.map +1 -1
- package/dist/lib/client/index.mjs +0 -6
- package/dist/lib/client/index.mjs.map +1 -1
- package/dist/lib/compliance/index.mjs +0 -6
- package/dist/lib/compliance/index.mjs.map +1 -1
- package/dist/lib/compliance-fixtures/index.mjs +0 -6
- package/dist/lib/compliance-fixtures/index.mjs.map +1 -1
- package/dist/lib/compliance-fixtures/test-authorization-server.mjs +0 -6
- package/dist/lib/compliance-fixtures/test-authorization-server.mjs.map +1 -1
- package/dist/lib/conformance/index.mjs +0 -6
- package/dist/lib/conformance/index.mjs.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs +0 -6
- package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
- package/dist/lib/conformance/invariants/uniformErrorComparator.mjs +0 -6
- package/dist/lib/conformance/invariants/uniformErrorComparator.mjs.map +1 -1
- package/dist/lib/conformance/oracle.mjs +0 -6
- package/dist/lib/conformance/oracle.mjs.map +1 -1
- package/dist/lib/conformance/runConformance.mjs +0 -6
- package/dist/lib/conformance/runConformance.mjs.map +1 -1
- package/dist/lib/conformance/runners.mjs +0 -6
- package/dist/lib/conformance/runners.mjs.map +1 -1
- package/dist/lib/conformance/schemaArbitrary.mjs +0 -6
- package/dist/lib/conformance/schemaArbitrary.mjs.map +1 -1
- package/dist/lib/conformance/schemaLoader.mjs +5 -6
- package/dist/lib/conformance/schemaLoader.mjs.map +1 -1
- package/dist/lib/conformance/seeder.mjs +0 -6
- package/dist/lib/conformance/seeder.mjs.map +1 -1
- package/dist/lib/conformance/types.mjs +0 -6
- package/dist/lib/conformance/types.mjs.map +1 -1
- package/dist/lib/conformance/webhook.mjs +0 -6
- package/dist/lib/conformance/webhook.mjs.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.mjs +0 -6
- package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
- package/dist/lib/core/AgentClient.mjs +0 -6
- package/dist/lib/core/AgentClient.mjs.map +1 -1
- package/dist/lib/core/AsyncHandler.mjs +0 -6
- package/dist/lib/core/AsyncHandler.mjs.map +1 -1
- package/dist/lib/core/ConfigurationManager.mjs +0 -6
- package/dist/lib/core/ConfigurationManager.mjs.map +1 -1
- package/dist/lib/core/ConversationTypes.mjs +0 -6
- package/dist/lib/core/CreativeAgentClient.mjs +0 -6
- package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
- package/dist/lib/core/GovernanceMiddleware.mjs +0 -6
- package/dist/lib/core/GovernanceMiddleware.mjs.map +1 -1
- package/dist/lib/core/GovernanceTypes.mjs +0 -6
- package/dist/lib/core/GovernanceTypes.mjs.map +1 -1
- package/dist/lib/core/ProtocolResponseParser.mjs +0 -6
- package/dist/lib/core/ProtocolResponseParser.mjs.map +1 -1
- package/dist/lib/core/ResponseValidator.mjs +0 -6
- package/dist/lib/core/ResponseValidator.mjs.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +0 -6
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/core/TaskEventTypes.mjs +0 -6
- package/dist/lib/core/TaskEventTypes.mjs.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +0 -6
- package/dist/lib/core/TaskExecutor.mjs.map +1 -1
- package/dist/lib/core/match.mjs +0 -6
- package/dist/lib/core/match.mjs.map +1 -1
- package/dist/lib/core/task-status.mjs +0 -6
- package/dist/lib/core/task-status.mjs.map +1 -1
- package/dist/lib/core/webhook-url.mjs +0 -6
- package/dist/lib/core/webhook-url.mjs.map +1 -1
- package/dist/lib/discovery/adagents-redirects.mjs +0 -6
- package/dist/lib/discovery/adagents-redirects.mjs.map +1 -1
- package/dist/lib/discovery/agent-directory.mjs +0 -6
- package/dist/lib/discovery/agent-directory.mjs.map +1 -1
- package/dist/lib/discovery/inline-publisher-properties.mjs +0 -6
- package/dist/lib/discovery/inline-publisher-properties.mjs.map +1 -1
- package/dist/lib/discovery/network-consistency-checker.mjs +0 -6
- package/dist/lib/discovery/network-consistency-checker.mjs.map +1 -1
- package/dist/lib/discovery/property-crawler.mjs +0 -6
- package/dist/lib/discovery/property-crawler.mjs.map +1 -1
- package/dist/lib/discovery/property-index.mjs +0 -6
- package/dist/lib/discovery/property-index.mjs.map +1 -1
- package/dist/lib/discovery/publisher-property-selector.mjs +0 -6
- package/dist/lib/discovery/publisher-property-selector.mjs.map +1 -1
- package/dist/lib/discovery/resolve-agent-properties.mjs +0 -6
- package/dist/lib/discovery/resolve-agent-properties.mjs.map +1 -1
- package/dist/lib/discovery/types.mjs +0 -6
- package/dist/lib/discovery/validate-adagents.mjs +0 -6
- package/dist/lib/discovery/validate-adagents.mjs.map +1 -1
- package/dist/lib/enums.mjs +0 -6
- package/dist/lib/enums.mjs.map +1 -1
- package/dist/lib/errors/index.mjs +0 -6
- package/dist/lib/errors/index.mjs.map +1 -1
- package/dist/lib/express-mcp/index.mjs +0 -6
- package/dist/lib/express-mcp/index.mjs.map +1 -1
- package/dist/lib/governance/index.mjs +0 -6
- package/dist/lib/governance/index.mjs.map +1 -1
- package/dist/lib/handlers/types.mjs +0 -6
- package/dist/lib/handlers/types.mjs.map +1 -1
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +0 -6
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/media-buy/available-actions.mjs +0 -6
- package/dist/lib/media-buy/available-actions.mjs.map +1 -1
- package/dist/lib/media-buy/index.mjs +0 -6
- package/dist/lib/media-buy/index.mjs.map +1 -1
- package/dist/lib/media-buy/preflight.mjs +0 -6
- package/dist/lib/media-buy/preflight.mjs.map +1 -1
- package/dist/lib/media-buy/property-policy.mjs +0 -6
- package/dist/lib/media-buy/property-policy.mjs.map +1 -1
- package/dist/lib/media-buy/types.mjs +0 -6
- package/dist/lib/media-buy/types.mjs.map +1 -1
- package/dist/lib/media-buy/update-fields.generated.mjs +0 -6
- package/dist/lib/media-buy/update-fields.generated.mjs.map +1 -1
- package/dist/lib/mock-server/creative-ad-server/seed-data.mjs +0 -6
- package/dist/lib/mock-server/creative-ad-server/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/creative-ad-server/server.mjs +0 -6
- package/dist/lib/mock-server/creative-ad-server/server.mjs.map +1 -1
- package/dist/lib/mock-server/creative-template/seed-data.mjs +0 -6
- package/dist/lib/mock-server/creative-template/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/creative-template/server.mjs +0 -6
- package/dist/lib/mock-server/creative-template/server.mjs.map +1 -1
- package/dist/lib/mock-server/index.mjs +0 -6
- package/dist/lib/mock-server/index.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/recipe.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/recipe.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/server.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/server.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/server.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/server.mjs.map +1 -1
- package/dist/lib/mock-server/sales-social/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-social/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-social/server.mjs +0 -6
- package/dist/lib/mock-server/sales-social/server.mjs.map +1 -1
- package/dist/lib/mock-server/scenario.mjs +0 -6
- package/dist/lib/mock-server/scenario.mjs.map +1 -1
- package/dist/lib/mock-server/signal-marketplace/seed-data.mjs +0 -6
- package/dist/lib/mock-server/signal-marketplace/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/signal-marketplace/server.mjs +0 -6
- package/dist/lib/mock-server/signal-marketplace/server.mjs.map +1 -1
- package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sponsored-intelligence/server.mjs +0 -6
- package/dist/lib/mock-server/sponsored-intelligence/server.mjs.map +1 -1
- package/dist/lib/net/address-guards.mjs +0 -6
- package/dist/lib/net/address-guards.mjs.map +1 -1
- package/dist/lib/net/index.mjs +0 -6
- package/dist/lib/net/index.mjs.map +1 -1
- package/dist/lib/net/ssrf-fetch.mjs +0 -6
- package/dist/lib/net/ssrf-fetch.mjs.map +1 -1
- package/dist/lib/observability/index.mjs +0 -6
- package/dist/lib/observability/index.mjs.map +1 -1
- package/dist/lib/observability/tracing.mjs +6 -7
- package/dist/lib/observability/tracing.mjs.map +1 -1
- package/dist/lib/protocols/a2a.mjs +0 -6
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/protocols/abort.mjs +0 -6
- package/dist/lib/protocols/abort.mjs.map +1 -1
- package/dist/lib/protocols/index.mjs +0 -6
- package/dist/lib/protocols/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +0 -6
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/protocols/mcp-tasks.mjs +0 -6
- package/dist/lib/protocols/mcp-tasks.mjs.map +1 -1
- package/dist/lib/protocols/mcp.mjs +0 -6
- package/dist/lib/protocols/mcp.mjs.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.mjs +0 -6
- package/dist/lib/protocols/rawResponseCapture.mjs.map +1 -1
- package/dist/lib/protocols/responseSizeLimit.mjs +0 -6
- package/dist/lib/protocols/responseSizeLimit.mjs.map +1 -1
- package/dist/lib/protocols/transportDiagnostics.mjs +0 -6
- package/dist/lib/protocols/transportDiagnostics.mjs.map +1 -1
- package/dist/lib/registry/cursor-store.mjs +0 -6
- package/dist/lib/registry/cursor-store.mjs.map +1 -1
- package/dist/lib/registry/feed-stream.mjs +0 -6
- package/dist/lib/registry/feed-stream.mjs.map +1 -1
- package/dist/lib/registry/index.mjs +0 -6
- package/dist/lib/registry/index.mjs.map +1 -1
- package/dist/lib/registry/property-registry.mjs +0 -6
- package/dist/lib/registry/property-registry.mjs.map +1 -1
- package/dist/lib/registry/sync.mjs +0 -6
- package/dist/lib/registry/sync.mjs.map +1 -1
- package/dist/lib/registry/types.generated.mjs +0 -6
- package/dist/lib/registry/types.mjs +0 -6
- package/dist/lib/schemas/index.mjs +0 -6
- package/dist/lib/schemas/index.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/a2a-adapter.mjs +0 -6
- package/dist/lib/server/a2a-adapter.mjs.map +1 -1
- package/dist/lib/server/account-mode.mjs +0 -6
- package/dist/lib/server/account-mode.mjs.map +1 -1
- package/dist/lib/server/adcp-server.mjs +0 -6
- package/dist/lib/server/adcp-server.mjs.map +1 -1
- package/dist/lib/server/auth-introspection.mjs +0 -6
- package/dist/lib/server/auth-introspection.mjs.map +1 -1
- package/dist/lib/server/auth-signature.mjs +0 -6
- package/dist/lib/server/auth-signature.mjs.map +1 -1
- package/dist/lib/server/auth.mjs +0 -6
- package/dist/lib/server/auth.mjs.map +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +13 -0
- package/dist/lib/server/create-adcp-server.d.ts +13 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +3 -2
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +3 -8
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/credential-policy.mjs +0 -6
- package/dist/lib/server/credential-policy.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/memory.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/memory.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/pg.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/pg.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/redis.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/redis.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/index.mjs +0 -6
- package/dist/lib/server/ctx-metadata/index.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/store.mjs +0 -6
- package/dist/lib/server/ctx-metadata/store.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/wire-shape.mjs +0 -6
- package/dist/lib/server/ctx-metadata/wire-shape.mjs.map +1 -1
- package/dist/lib/server/decisioning/account.mjs +0 -6
- package/dist/lib/server/decisioning/account.mjs.map +1 -1
- package/dist/lib/server/decisioning/admin-router.mjs +0 -6
- package/dist/lib/server/decisioning/admin-router.mjs.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/async-outcome.mjs +0 -6
- package/dist/lib/server/decisioning/async-outcome.mjs.map +1 -1
- package/dist/lib/server/decisioning/buyer-agent.mjs +0 -6
- package/dist/lib/server/decisioning/buyer-agent.mjs.map +1 -1
- package/dist/lib/server/decisioning/capabilities.mjs +0 -6
- package/dist/lib/server/decisioning/capabilities.mjs.map +1 -1
- package/dist/lib/server/decisioning/compose.mjs +0 -6
- package/dist/lib/server/decisioning/compose.mjs.map +1 -1
- package/dist/lib/server/decisioning/context.mjs +0 -6
- package/dist/lib/server/decisioning/errors-typed.mjs +0 -6
- package/dist/lib/server/decisioning/errors-typed.mjs.map +1 -1
- package/dist/lib/server/decisioning/helpers.mjs +0 -6
- package/dist/lib/server/decisioning/helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.mjs +0 -6
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/pagination.mjs +0 -6
- package/dist/lib/server/decisioning/platform-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/platform-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/platform.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/dispatch.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/store.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/store.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
- package/dist/lib/server/decisioning/resolve-presets.mjs +0 -6
- package/dist/lib/server/decisioning/resolve-presets.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/observed-modes.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/observed-modes.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/validate-platform.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/validate-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/audiences.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/brand-rights.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/campaign-governance.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/content-standards.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/creative.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/lists.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/sales.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/signals.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.mjs +0 -6
- package/dist/lib/server/decisioning/start-time.mjs +0 -6
- package/dist/lib/server/decisioning/start-time.mjs.map +1 -1
- package/dist/lib/server/decisioning/status-changes.mjs +0 -6
- package/dist/lib/server/decisioning/status-changes.mjs.map +1 -1
- package/dist/lib/server/decisioning/status-mappers.mjs +0 -6
- package/dist/lib/server/decisioning/status-mappers.mjs.map +1 -1
- package/dist/lib/server/decisioning/tenant-registry.mjs +0 -6
- package/dist/lib/server/decisioning/tenant-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/tenant-store.mjs +0 -6
- package/dist/lib/server/decisioning/tenant-store.mjs.map +1 -1
- package/dist/lib/server/decisioning/validate-specialisms.mjs +0 -6
- package/dist/lib/server/decisioning/validate-specialisms.mjs.map +1 -1
- package/dist/lib/server/dynamic-registry.mjs +0 -6
- package/dist/lib/server/dynamic-registry.mjs.map +1 -1
- package/dist/lib/server/envelope-allowlist.mjs +0 -6
- package/dist/lib/server/envelope-allowlist.mjs.map +1 -1
- package/dist/lib/server/error-arm-tools.mjs +5 -6
- package/dist/lib/server/error-arm-tools.mjs.map +1 -1
- package/dist/lib/server/errors.mjs +0 -6
- package/dist/lib/server/errors.mjs.map +1 -1
- package/dist/lib/server/example-tld-guard.mjs +0 -6
- package/dist/lib/server/example-tld-guard.mjs.map +1 -1
- package/dist/lib/server/express-adapter.mjs +0 -6
- package/dist/lib/server/express-adapter.mjs.map +1 -1
- package/dist/lib/server/governance.mjs +0 -6
- package/dist/lib/server/governance.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/lazy.mjs +0 -6
- package/dist/lib/server/idempotency/backends/lazy.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/memory.mjs +0 -6
- package/dist/lib/server/idempotency/backends/memory.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/pg.mjs +0 -6
- package/dist/lib/server/idempotency/backends/pg.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/redis.mjs +0 -6
- package/dist/lib/server/idempotency/backends/redis.mjs.map +1 -1
- package/dist/lib/server/idempotency/index.mjs +0 -6
- package/dist/lib/server/idempotency/index.mjs.map +1 -1
- package/dist/lib/server/idempotency/store.mjs +0 -6
- package/dist/lib/server/idempotency/store.mjs.map +1 -1
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs +0 -6
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/legacy/v5/index.d.mts +1 -1
- package/dist/lib/server/legacy/v5/index.d.ts +1 -1
- package/dist/lib/server/legacy/v5/index.d.ts.map +1 -1
- package/dist/lib/server/legacy/v5/index.js.map +1 -1
- package/dist/lib/server/legacy/v5/index.mjs +0 -6
- package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
- package/dist/lib/server/mcp-modern-server.mjs +0 -6
- package/dist/lib/server/mcp-modern-server.mjs.map +1 -1
- package/dist/lib/server/media-buy-actions.mjs +0 -6
- package/dist/lib/server/media-buy-actions.mjs.map +1 -1
- package/dist/lib/server/media-buy-helpers.mjs +0 -6
- package/dist/lib/server/media-buy-helpers.mjs.map +1 -1
- package/dist/lib/server/media-buy-store.mjs +0 -6
- package/dist/lib/server/media-buy-store.mjs.map +1 -1
- package/dist/lib/server/normalize-errors.mjs +0 -6
- package/dist/lib/server/normalize-errors.mjs.map +1 -1
- package/dist/lib/server/operational-platform.mjs +0 -6
- package/dist/lib/server/operational-platform.mjs.map +1 -1
- package/dist/lib/server/pick-safe-details.mjs +0 -6
- package/dist/lib/server/pick-safe-details.mjs.map +1 -1
- package/dist/lib/server/pin-and-bind-fetch.mjs +0 -6
- package/dist/lib/server/pin-and-bind-fetch.mjs.map +1 -1
- package/dist/lib/server/postgres-state-store.mjs +0 -6
- package/dist/lib/server/postgres-state-store.mjs.map +1 -1
- package/dist/lib/server/postgres-task-store.mjs +0 -6
- package/dist/lib/server/postgres-task-store.mjs.map +1 -1
- package/dist/lib/server/product-defaults.mjs +0 -6
- package/dist/lib/server/product-defaults.mjs.map +1 -1
- package/dist/lib/server/redact.mjs +0 -6
- package/dist/lib/server/redact.mjs.map +1 -1
- package/dist/lib/server/responses.mjs +0 -6
- package/dist/lib/server/responses.mjs.map +1 -1
- package/dist/lib/server/serve.mjs +0 -6
- package/dist/lib/server/serve.mjs.map +1 -1
- package/dist/lib/server/socket-mode/conformance-client.mjs +0 -6
- package/dist/lib/server/socket-mode/conformance-client.mjs.map +1 -1
- package/dist/lib/server/socket-mode/index.mjs +0 -6
- package/dist/lib/server/socket-mode/index.mjs.map +1 -1
- package/dist/lib/server/socket-mode/ws-transport.mjs +0 -6
- package/dist/lib/server/socket-mode/ws-transport.mjs.map +1 -1
- package/dist/lib/server/state-machine.mjs +0 -6
- package/dist/lib/server/state-machine.mjs.map +1 -1
- package/dist/lib/server/state-store.mjs +0 -6
- package/dist/lib/server/state-store.mjs.map +1 -1
- package/dist/lib/server/structured-serialize.mjs +0 -6
- package/dist/lib/server/structured-serialize.mjs.map +1 -1
- package/dist/lib/server/targeting-helpers.mjs +0 -6
- package/dist/lib/server/targeting-helpers.mjs.map +1 -1
- package/dist/lib/server/tasks.mjs +0 -6
- package/dist/lib/server/tasks.mjs.map +1 -1
- package/dist/lib/server/test-controller-bridge.mjs +0 -6
- package/dist/lib/server/test-controller-bridge.mjs.map +1 -1
- package/dist/lib/server/test-controller.mjs +0 -6
- package/dist/lib/server/test-controller.mjs.map +1 -1
- package/dist/lib/server/upstream-helpers.mjs +0 -6
- package/dist/lib/server/upstream-helpers.mjs.map +1 -1
- package/dist/lib/server/webhook-emitter.mjs +0 -6
- package/dist/lib/server/webhook-emitter.mjs.map +1 -1
- package/dist/lib/server/wire-safe.mjs +0 -6
- package/dist/lib/server/wire-safe.mjs.map +1 -1
- package/dist/lib/server/wire-spec-fields.generated.mjs +0 -6
- package/dist/lib/server/wire-spec-fields.generated.mjs.map +1 -1
- package/dist/lib/server/wrap-envelope.mjs +0 -6
- package/dist/lib/server/wrap-envelope.mjs.map +1 -1
- package/dist/lib/signing/agent-context.mjs +0 -6
- package/dist/lib/signing/agent-context.mjs.map +1 -1
- package/dist/lib/signing/agent-fetch.mjs +0 -6
- package/dist/lib/signing/agent-fetch.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/canonicalize.mjs +0 -6
- package/dist/lib/signing/agent-resolver/canonicalize.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/capabilities-types.mjs +0 -6
- package/dist/lib/signing/agent-resolver/capabilities-types.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/consistency.mjs +0 -6
- package/dist/lib/signing/agent-resolver/consistency.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/errors.mjs +0 -6
- package/dist/lib/signing/agent-resolver/errors.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/etld.mjs +0 -6
- package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +0 -6
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/index.mjs +0 -6
- package/dist/lib/signing/agent-resolver/index.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/jwks-set.mjs +0 -6
- package/dist/lib/signing/agent-resolver/jwks-set.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +0 -6
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/select-agent.mjs +0 -6
- package/dist/lib/signing/agent-resolver/select-agent.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/strict-json.mjs +0 -6
- package/dist/lib/signing/agent-resolver/strict-json.mjs.map +1 -1
- package/dist/lib/signing/brand-jwks.mjs +0 -6
- package/dist/lib/signing/brand-jwks.mjs.map +1 -1
- package/dist/lib/signing/canonicalize.mjs +0 -6
- package/dist/lib/signing/canonicalize.mjs.map +1 -1
- package/dist/lib/signing/capability-cache.mjs +0 -6
- package/dist/lib/signing/capability-cache.mjs.map +1 -1
- package/dist/lib/signing/capability-priming.mjs +0 -6
- package/dist/lib/signing/capability-priming.mjs.map +1 -1
- package/dist/lib/signing/client.mjs +0 -6
- package/dist/lib/signing/client.mjs.map +1 -1
- package/dist/lib/signing/content-digest.mjs +0 -6
- package/dist/lib/signing/content-digest.mjs.map +1 -1
- package/dist/lib/signing/crypto.mjs +0 -6
- package/dist/lib/signing/crypto.mjs.map +1 -1
- package/dist/lib/signing/ecdsa-encoding.mjs +0 -6
- package/dist/lib/signing/ecdsa-encoding.mjs.map +1 -1
- package/dist/lib/signing/errors.mjs +0 -6
- package/dist/lib/signing/errors.mjs.map +1 -1
- package/dist/lib/signing/fetch-async.mjs +0 -6
- package/dist/lib/signing/fetch-async.mjs.map +1 -1
- package/dist/lib/signing/fetch.mjs +0 -6
- package/dist/lib/signing/fetch.mjs.map +1 -1
- package/dist/lib/signing/index.mjs +0 -6
- package/dist/lib/signing/index.mjs.map +1 -1
- package/dist/lib/signing/jwks-helpers.mjs +0 -6
- package/dist/lib/signing/jwks-helpers.mjs.map +1 -1
- package/dist/lib/signing/jwks-https.mjs +0 -6
- package/dist/lib/signing/jwks-https.mjs.map +1 -1
- package/dist/lib/signing/jwks.mjs +0 -6
- package/dist/lib/signing/jwks.mjs.map +1 -1
- package/dist/lib/signing/middleware.mjs +0 -6
- package/dist/lib/signing/middleware.mjs.map +1 -1
- package/dist/lib/signing/parser.mjs +0 -6
- package/dist/lib/signing/parser.mjs.map +1 -1
- package/dist/lib/signing/postgres-replay-store.mjs +0 -6
- package/dist/lib/signing/postgres-replay-store.mjs.map +1 -1
- package/dist/lib/signing/protocol-response.mjs +0 -6
- package/dist/lib/signing/protocol-response.mjs.map +1 -1
- package/dist/lib/signing/provider.mjs +0 -6
- package/dist/lib/signing/redis-replay-store.mjs +0 -6
- package/dist/lib/signing/redis-replay-store.mjs.map +1 -1
- package/dist/lib/signing/replay.mjs +0 -6
- package/dist/lib/signing/replay.mjs.map +1 -1
- package/dist/lib/signing/request-context.mjs +0 -6
- package/dist/lib/signing/request-context.mjs.map +1 -1
- package/dist/lib/signing/revocation-https.mjs +0 -6
- package/dist/lib/signing/revocation-https.mjs.map +1 -1
- package/dist/lib/signing/revocation.mjs +0 -6
- package/dist/lib/signing/revocation.mjs.map +1 -1
- package/dist/lib/signing/server.mjs +0 -6
- package/dist/lib/signing/server.mjs.map +1 -1
- package/dist/lib/signing/signer-async.mjs +0 -6
- package/dist/lib/signing/signer-async.mjs.map +1 -1
- package/dist/lib/signing/signer.mjs +0 -6
- package/dist/lib/signing/signer.mjs.map +1 -1
- package/dist/lib/signing/testing.mjs +0 -6
- package/dist/lib/signing/testing.mjs.map +1 -1
- package/dist/lib/signing/types.mjs +0 -6
- package/dist/lib/signing/types.mjs.map +1 -1
- package/dist/lib/signing/verifier.mjs +0 -6
- package/dist/lib/signing/verifier.mjs.map +1 -1
- package/dist/lib/signing/webhook-auth-detection.mjs +0 -6
- package/dist/lib/signing/webhook-auth-detection.mjs.map +1 -1
- package/dist/lib/signing/webhook-verifier.mjs +0 -6
- package/dist/lib/signing/webhook-verifier.mjs.map +1 -1
- package/dist/lib/storage/MemoryStorage.mjs +0 -6
- package/dist/lib/storage/MemoryStorage.mjs.map +1 -1
- package/dist/lib/storage/interfaces.mjs +0 -6
- package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs +0 -6
- package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs.map +1 -1
- package/dist/lib/substitution/encoder/index.mjs +0 -6
- package/dist/lib/substitution/encoder/index.mjs.map +1 -1
- package/dist/lib/substitution/index.mjs +0 -6
- package/dist/lib/substitution/index.mjs.map +1 -1
- package/dist/lib/substitution/observer/SubstitutionObserver.mjs +0 -6
- package/dist/lib/substitution/observer/SubstitutionObserver.mjs.map +1 -1
- package/dist/lib/substitution/observer/alignment.mjs +0 -6
- package/dist/lib/substitution/observer/alignment.mjs.map +1 -1
- package/dist/lib/substitution/observer/assertions.mjs +0 -6
- package/dist/lib/substitution/observer/assertions.mjs.map +1 -1
- package/dist/lib/substitution/observer/html-parser.mjs +0 -6
- package/dist/lib/substitution/observer/html-parser.mjs.map +1 -1
- package/dist/lib/substitution/observer/index.mjs +0 -6
- package/dist/lib/substitution/observer/index.mjs.map +1 -1
- package/dist/lib/substitution/observer/ssrf.mjs +0 -6
- package/dist/lib/substitution/observer/ssrf.mjs.map +1 -1
- package/dist/lib/substitution/rfc3986.mjs +0 -6
- package/dist/lib/substitution/rfc3986.mjs.map +1 -1
- package/dist/lib/substitution/translate.mjs +0 -6
- package/dist/lib/substitution/translate.mjs.map +1 -1
- package/dist/lib/substitution/types.mjs +0 -6
- package/dist/lib/substitution/vectors.mjs +0 -6
- package/dist/lib/substitution/vectors.mjs.map +1 -1
- package/dist/lib/testing/agent-tester.mjs +0 -6
- package/dist/lib/testing/agent-tester.mjs.map +1 -1
- package/dist/lib/testing/client.mjs +0 -6
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/compliance/briefs.mjs +0 -6
- package/dist/lib/testing/compliance/briefs.mjs.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +0 -6
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/compliance/index.mjs +0 -6
- package/dist/lib/testing/compliance/index.mjs.map +1 -1
- package/dist/lib/testing/compliance/spec-conformance.mjs +0 -6
- package/dist/lib/testing/compliance/spec-conformance.mjs.map +1 -1
- package/dist/lib/testing/compliance/storyboard-tracks.mjs +0 -6
- package/dist/lib/testing/compliance/storyboard-tracks.mjs.map +1 -1
- package/dist/lib/testing/compliance/summary.mjs +0 -6
- package/dist/lib/testing/compliance/summary.mjs.map +1 -1
- package/dist/lib/testing/compliance/types.mjs +0 -6
- package/dist/lib/testing/comply-controller.mjs +0 -6
- package/dist/lib/testing/comply-controller.mjs.map +1 -1
- package/dist/lib/testing/controller-assertions.mjs +0 -6
- package/dist/lib/testing/controller-assertions.mjs.map +1 -1
- package/dist/lib/testing/formatter.mjs +0 -6
- package/dist/lib/testing/formatter.mjs.map +1 -1
- package/dist/lib/testing/index.mjs +0 -6
- package/dist/lib/testing/index.mjs.map +1 -1
- package/dist/lib/testing/local-agent-runner.mjs +0 -6
- package/dist/lib/testing/local-agent-runner.mjs.map +1 -1
- package/dist/lib/testing/orchestrator.mjs +0 -6
- package/dist/lib/testing/orchestrator.mjs.map +1 -1
- package/dist/lib/testing/personas/index.mjs +0 -6
- package/dist/lib/testing/personas/index.mjs.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.mjs +0 -6
- package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
- package/dist/lib/testing/scenarios/capabilities.mjs +0 -6
- package/dist/lib/testing/scenarios/capabilities.mjs.map +1 -1
- package/dist/lib/testing/scenarios/creative.mjs +0 -6
- package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
- package/dist/lib/testing/scenarios/deterministic.mjs +0 -6
- package/dist/lib/testing/scenarios/deterministic.mjs.map +1 -1
- package/dist/lib/testing/scenarios/discovery.mjs +0 -6
- package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
- package/dist/lib/testing/scenarios/edge-cases.mjs +0 -6
- package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
- package/dist/lib/testing/scenarios/error-compliance.mjs +0 -6
- package/dist/lib/testing/scenarios/error-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/governance.mjs +0 -6
- package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/health.mjs +0 -6
- package/dist/lib/testing/scenarios/health.mjs.map +1 -1
- package/dist/lib/testing/scenarios/index.mjs +0 -6
- package/dist/lib/testing/scenarios/index.mjs.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.mjs +0 -6
- package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.mjs +0 -6
- package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/signals.mjs +0 -6
- package/dist/lib/testing/scenarios/signals.mjs.map +1 -1
- package/dist/lib/testing/scenarios/sponsored-intelligence.mjs +0 -6
- package/dist/lib/testing/scenarios/sponsored-intelligence.mjs.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.mjs +0 -6
- package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
- package/dist/lib/testing/seed-merge.mjs +0 -6
- package/dist/lib/testing/seed-merge.mjs.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.mjs +0 -6
- package/dist/lib/testing/storyboard/agent-routing.mjs.map +1 -1
- package/dist/lib/testing/storyboard/assertions.mjs +0 -6
- package/dist/lib/testing/storyboard/assertions.mjs.map +1 -1
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +0 -6
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs.map +1 -1
- package/dist/lib/testing/storyboard/compliance.mjs +5 -6
- package/dist/lib/testing/storyboard/compliance.mjs.map +1 -1
- package/dist/lib/testing/storyboard/context.mjs +0 -6
- package/dist/lib/testing/storyboard/context.mjs.map +1 -1
- package/dist/lib/testing/storyboard/default-invariants.mjs +0 -6
- package/dist/lib/testing/storyboard/default-invariants.mjs.map +1 -1
- package/dist/lib/testing/storyboard/index.mjs +0 -6
- package/dist/lib/testing/storyboard/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/junit.mjs +0 -6
- package/dist/lib/testing/storyboard/junit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/loader.mjs +0 -6
- package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/parallel-dispatch.mjs +0 -6
- package/dist/lib/testing/storyboard/parallel-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/path.mjs +0 -6
- package/dist/lib/testing/storyboard/path.mjs.map +1 -1
- package/dist/lib/testing/storyboard/probes.mjs +0 -6
- package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
- package/dist/lib/testing/storyboard/rate-limit-trip.mjs +0 -6
- package/dist/lib/testing/storyboard/rate-limit-trip.mjs.map +1 -1
- package/dist/lib/testing/storyboard/rejection-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/rejection-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.mjs +0 -6
- package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/probe.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/synthesize.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +0 -6
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/sandbox-entities.mjs +0 -6
- package/dist/lib/testing/storyboard/sandbox-entities.mjs.map +1 -1
- package/dist/lib/testing/storyboard/seeding.mjs +0 -6
- package/dist/lib/testing/storyboard/seeding.mjs.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs +0 -6
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/index.mjs +0 -6
- package/dist/lib/testing/storyboard/signer-grader/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/types.mjs +0 -6
- package/dist/lib/testing/storyboard/strict-validation-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/strict-validation-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/task-map.mjs +0 -6
- package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
- package/dist/lib/testing/storyboard/test-kit.mjs +0 -6
- package/dist/lib/testing/storyboard/test-kit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs +0 -6
- package/dist/lib/testing/storyboard/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +0 -6
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-assertions.mjs +0 -6
- package/dist/lib/testing/storyboard/webhook-assertions.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.mjs +0 -6
- package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
- package/dist/lib/testing/stubs/governance-agent-stub.mjs +0 -6
- package/dist/lib/testing/stubs/governance-agent-stub.mjs.map +1 -1
- package/dist/lib/testing/stubs/index.mjs +0 -6
- package/dist/lib/testing/stubs/index.mjs.map +1 -1
- package/dist/lib/testing/test-controller.mjs +0 -6
- package/dist/lib/testing/test-controller.mjs.map +1 -1
- package/dist/lib/testing/test-helpers.mjs +0 -6
- package/dist/lib/testing/test-helpers.mjs.map +1 -1
- package/dist/lib/testing/types.mjs +0 -6
- package/dist/lib/types/adcp.mjs +0 -6
- package/dist/lib/types/adcp.mjs.map +1 -1
- package/dist/lib/types/asset-instances.mjs +0 -6
- package/dist/lib/types/compat.mjs +0 -6
- package/dist/lib/types/compat.mjs.map +1 -1
- package/dist/lib/types/core.generated.mjs +0 -6
- package/dist/lib/types/enums.generated.mjs +0 -6
- package/dist/lib/types/enums.generated.mjs.map +1 -1
- package/dist/lib/types/error-codes.mjs +0 -6
- package/dist/lib/types/error-codes.mjs.map +1 -1
- package/dist/lib/types/error-details.aliases.mjs +0 -6
- package/dist/lib/types/error-details.aliases.mjs.map +1 -1
- package/dist/lib/types/format-asset-slots.mjs +0 -6
- package/dist/lib/types/forward-compat-error-codes.mjs +0 -6
- package/dist/lib/types/forward-compat-error-codes.mjs.map +1 -1
- package/dist/lib/types/index.mjs +0 -6
- package/dist/lib/types/index.mjs.map +1 -1
- package/dist/lib/types/inline-enums.aliases.mjs +0 -6
- package/dist/lib/types/inline-enums.aliases.mjs.map +1 -1
- package/dist/lib/types/inline-enums.generated.mjs +0 -6
- package/dist/lib/types/inline-enums.generated.mjs.map +1 -1
- package/dist/lib/types/manifest.generated.mjs +0 -6
- package/dist/lib/types/manifest.generated.mjs.map +1 -1
- package/dist/lib/types/schemas.generated.mjs +0 -6
- package/dist/lib/types/schemas.generated.mjs.map +1 -1
- package/dist/lib/types/server-payload-aliases.mjs +0 -6
- package/dist/lib/types/server-payload.mjs +0 -6
- package/dist/lib/types/sync-rows.mjs +0 -6
- package/dist/lib/types/tools.generated.mjs +0 -6
- package/dist/lib/types/v2-5/index.mjs +0 -6
- package/dist/lib/types/v2-5/index.mjs.map +1 -1
- package/dist/lib/types/v2-5/tools.generated.mjs +0 -6
- package/dist/lib/types/v3-1-beta/index.mjs +0 -6
- package/dist/lib/types/v3-1-beta/index.mjs.map +1 -1
- package/dist/lib/types/v3-1-beta/tools.generated.mjs +0 -6
- package/dist/lib/types/wellknown-schemas.generated.mjs +0 -6
- package/dist/lib/types/wellknown-schemas.generated.mjs.map +1 -1
- package/dist/lib/upstream-recorder/constants.mjs +0 -6
- package/dist/lib/upstream-recorder/constants.mjs.map +1 -1
- package/dist/lib/upstream-recorder/index.mjs +0 -6
- package/dist/lib/upstream-recorder/index.mjs.map +1 -1
- package/dist/lib/upstream-recorder/recorder.mjs +0 -6
- package/dist/lib/upstream-recorder/recorder.mjs.map +1 -1
- package/dist/lib/upstream-recorder/types.mjs +0 -6
- package/dist/lib/upstream-recorder/types.mjs.map +1 -1
- package/dist/lib/utils/a2a-artifacts.mjs +0 -6
- package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
- package/dist/lib/utils/a2a-discovery.mjs +0 -6
- package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
- package/dist/lib/utils/activation-key-builders.mjs +0 -6
- package/dist/lib/utils/activation-key-builders.mjs.map +1 -1
- package/dist/lib/utils/adcp-version-config.mjs +0 -6
- package/dist/lib/utils/adcp-version-config.mjs.map +1 -1
- package/dist/lib/utils/asset-builders.mjs +0 -6
- package/dist/lib/utils/asset-builders.mjs.map +1 -1
- package/dist/lib/utils/build-creative-return-builders.mjs +0 -6
- package/dist/lib/utils/build-creative-return-builders.mjs.map +1 -1
- package/dist/lib/utils/buyer-retry-policy.mjs +0 -6
- package/dist/lib/utils/buyer-retry-policy.mjs.map +1 -1
- package/dist/lib/utils/capabilities.mjs +0 -6
- package/dist/lib/utils/capabilities.mjs.map +1 -1
- package/dist/lib/utils/capability-rollups.mjs +0 -6
- package/dist/lib/utils/capability-rollups.mjs.map +1 -1
- package/dist/lib/utils/creative-adapter.mjs +0 -6
- package/dist/lib/utils/creative-adapter.mjs.map +1 -1
- package/dist/lib/utils/creative-delivery.mjs +0 -6
- package/dist/lib/utils/creative-delivery.mjs.map +1 -1
- package/dist/lib/utils/deprecation.mjs +0 -6
- package/dist/lib/utils/deprecation.mjs.map +1 -1
- package/dist/lib/utils/envelope-status-compat.mjs +0 -6
- package/dist/lib/utils/envelope-status-compat.mjs.map +1 -1
- package/dist/lib/utils/error-extraction.mjs +0 -6
- package/dist/lib/utils/error-extraction.mjs.map +1 -1
- package/dist/lib/utils/extract-result.mjs +0 -6
- package/dist/lib/utils/extract-result.mjs.map +1 -1
- package/dist/lib/utils/format-asset-slot-builders.mjs +0 -6
- package/dist/lib/utils/format-asset-slot-builders.mjs.map +1 -1
- package/dist/lib/utils/format-assets.mjs +0 -6
- package/dist/lib/utils/format-assets.mjs.map +1 -1
- package/dist/lib/utils/format-render-builders.mjs +0 -6
- package/dist/lib/utils/format-render-builders.mjs.map +1 -1
- package/dist/lib/utils/format-renders.mjs +0 -6
- package/dist/lib/utils/format-renders.mjs.map +1 -1
- package/dist/lib/utils/get-products-cache-scope.mjs +0 -6
- package/dist/lib/utils/get-products-cache-scope.mjs.map +1 -1
- package/dist/lib/utils/glob.mjs +0 -6
- package/dist/lib/utils/glob.mjs.map +1 -1
- package/dist/lib/utils/global-async-local-storage.mjs +0 -6
- package/dist/lib/utils/global-async-local-storage.mjs.map +1 -1
- package/dist/lib/utils/idempotency.mjs +0 -6
- package/dist/lib/utils/idempotency.mjs.map +1 -1
- package/dist/lib/utils/index.mjs +0 -6
- package/dist/lib/utils/index.mjs.map +1 -1
- package/dist/lib/utils/jcs.mjs +0 -6
- package/dist/lib/utils/jcs.mjs.map +1 -1
- package/dist/lib/utils/json-depth.mjs +0 -6
- package/dist/lib/utils/json-depth.mjs.map +1 -1
- package/dist/lib/utils/logger.mjs +0 -6
- package/dist/lib/utils/logger.mjs.map +1 -1
- package/dist/lib/utils/media-buy-delivery-notification-builders.mjs +0 -6
- package/dist/lib/utils/media-buy-delivery-notification-builders.mjs.map +1 -1
- package/dist/lib/utils/media-buy-status.mjs +0 -6
- package/dist/lib/utils/media-buy-status.mjs.map +1 -1
- package/dist/lib/utils/pagination.mjs +0 -6
- package/dist/lib/utils/pagination.mjs.map +1 -1
- package/dist/lib/utils/preview-creative-builders.mjs +0 -6
- package/dist/lib/utils/preview-creative-builders.mjs.map +1 -1
- package/dist/lib/utils/preview-normalizer.mjs +0 -6
- package/dist/lib/utils/preview-normalizer.mjs.map +1 -1
- package/dist/lib/utils/preview-utils.mjs +0 -6
- package/dist/lib/utils/preview-utils.mjs.map +1 -1
- package/dist/lib/utils/pricing-adapter.mjs +0 -6
- package/dist/lib/utils/pricing-adapter.mjs.map +1 -1
- package/dist/lib/utils/probe-policy.mjs +0 -6
- package/dist/lib/utils/probe-policy.mjs.map +1 -1
- package/dist/lib/utils/protocol-detection.mjs +0 -6
- package/dist/lib/utils/protocol-detection.mjs.map +1 -1
- package/dist/lib/utils/redact-secrets.mjs +0 -6
- package/dist/lib/utils/redact-secrets.mjs.map +1 -1
- package/dist/lib/utils/redis-default-prefix-warn.mjs +0 -6
- package/dist/lib/utils/redis-default-prefix-warn.mjs.map +1 -1
- package/dist/lib/utils/render-builders.mjs +0 -6
- package/dist/lib/utils/render-builders.mjs.map +1 -1
- package/dist/lib/utils/request-normalizer.mjs +0 -6
- package/dist/lib/utils/request-normalizer.mjs.map +1 -1
- package/dist/lib/utils/response-schemas.mjs +0 -6
- package/dist/lib/utils/response-schemas.mjs.map +1 -1
- package/dist/lib/utils/response-unwrapper.mjs +0 -6
- package/dist/lib/utils/response-unwrapper.mjs.map +1 -1
- package/dist/lib/utils/retry.mjs +0 -6
- package/dist/lib/utils/retry.mjs.map +1 -1
- package/dist/lib/utils/signal-discovery-helpers.mjs +0 -6
- package/dist/lib/utils/signal-discovery-helpers.mjs.map +1 -1
- package/dist/lib/utils/signal-id-builders.mjs +0 -6
- package/dist/lib/utils/signal-id-builders.mjs.map +1 -1
- package/dist/lib/utils/sync-creatives-adapter.mjs +0 -6
- package/dist/lib/utils/sync-creatives-adapter.mjs.map +1 -1
- package/dist/lib/utils/task-state.mjs +0 -6
- package/dist/lib/utils/task-state.mjs.map +1 -1
- package/dist/lib/utils/tool-request-schemas.mjs +0 -6
- package/dist/lib/utils/tool-request-schemas.mjs.map +1 -1
- package/dist/lib/utils/typeGuards.mjs +0 -6
- package/dist/lib/utils/typeGuards.mjs.map +1 -1
- package/dist/lib/utils/union-errors.mjs +0 -6
- package/dist/lib/utils/union-errors.mjs.map +1 -1
- package/dist/lib/utils/validate-user-agent.mjs +0 -6
- package/dist/lib/utils/validate-user-agent.mjs.map +1 -1
- package/dist/lib/v2/format-schema/fetch.mjs +0 -6
- package/dist/lib/v2/format-schema/fetch.mjs.map +1 -1
- package/dist/lib/v2/format-schema/index.mjs +0 -6
- package/dist/lib/v2/format-schema/index.mjs.map +1 -1
- package/dist/lib/v2/format-schema/regex-safety.mjs +0 -6
- package/dist/lib/v2/format-schema/regex-safety.mjs.map +1 -1
- package/dist/lib/v2/format-schema/resolver.mjs +7 -8
- package/dist/lib/v2/format-schema/resolver.mjs.map +1 -1
- package/dist/lib/v2/format-schema/sandbox-refs.mjs +0 -6
- package/dist/lib/v2/format-schema/sandbox-refs.mjs.map +1 -1
- package/dist/lib/v2/projection/augment-response.mjs +0 -6
- package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
- package/dist/lib/v2/projection/builders.mjs +0 -6
- package/dist/lib/v2/projection/builders.mjs.map +1 -1
- package/dist/lib/v2/projection/cache-versions.mjs +0 -6
- package/dist/lib/v2/projection/cache-versions.mjs.map +1 -1
- package/dist/lib/v2/projection/canonical-properties.mjs +5 -6
- package/dist/lib/v2/projection/canonical-properties.mjs.map +1 -1
- package/dist/lib/v2/projection/catalog.mjs +5 -6
- package/dist/lib/v2/projection/catalog.mjs.map +1 -1
- package/dist/lib/v2/projection/constants.mjs +0 -6
- package/dist/lib/v2/projection/constants.mjs.map +1 -1
- package/dist/lib/v2/projection/index.mjs +0 -6
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/v2/projection/registry.mjs +5 -6
- package/dist/lib/v2/projection/registry.mjs.map +1 -1
- package/dist/lib/v2/projection/types.mjs +0 -6
- package/dist/lib/v2/projection/v1-to-v2.mjs +0 -6
- package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.mjs +0 -6
- package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
- package/dist/lib/v2/projection/write-side.mjs +0 -6
- package/dist/lib/v2/projection/write-side.mjs.map +1 -1
- package/dist/lib/v2/publisher-catalog/formats.mjs +0 -6
- package/dist/lib/v2/publisher-catalog/formats.mjs.map +1 -1
- package/dist/lib/v2/publisher-catalog/index.mjs +0 -6
- package/dist/lib/v2/publisher-catalog/index.mjs.map +1 -1
- package/dist/lib/validation/client-hooks.mjs +0 -6
- package/dist/lib/validation/client-hooks.mjs.map +1 -1
- package/dist/lib/validation/hints.mjs +0 -6
- package/dist/lib/validation/hints.mjs.map +1 -1
- package/dist/lib/validation/index.mjs +0 -6
- package/dist/lib/validation/index.mjs.map +1 -1
- package/dist/lib/validation/schema-errors.mjs +0 -6
- package/dist/lib/validation/schema-errors.mjs.map +1 -1
- package/dist/lib/validation/schema-loader.mjs +5 -6
- package/dist/lib/validation/schema-loader.mjs.map +1 -1
- package/dist/lib/validation/schema-validator.mjs +0 -6
- package/dist/lib/validation/schema-validator.mjs.map +1 -1
- package/dist/lib/validation/sync-creatives.mjs +0 -6
- package/dist/lib/validation/sync-creatives.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -9
- package/dist/lib/version.mjs.map +1 -1
- package/dist/lib/webhooks/index.mjs +0 -6
- package/dist/lib/webhooks/index.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/index.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/index.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/sync.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/sync.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/types.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/webhook-notification.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { readFileSync, readdirSync, existsSync } from "fs";
|
|
8
2
|
import { join } from "path";
|
|
9
3
|
import { parse } from "yaml";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/sandbox-entities.ts"],"sourcesContent":["/**\n * Sandbox entity loader.\n *\n * Parses compliance test-kit YAML files and fictional-entities.yaml to produce\n * structured sandbox data for the AAO registry. The registry imports this\n * function so the YAML files remain the single source of truth — no seeding,\n * no copying, no drift. YAMLs are pulled from `compliance/cache/{version}/`\n * by `npm run sync-schemas`.\n */\n\nimport { readFileSync, readdirSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from './compliance';\nimport { BrandJsonSchema, type BrandJson } from '../../types/wellknown-schemas.generated';\n\nexport type { BrandJson } from '../../types/wellknown-schemas.generated';\n\n// ====== Public types ======\n\nexport interface SandboxBrand {\n domain: string;\n brand_name: string;\n brand_id: string;\n industry?: string;\n brand_json: BrandJson;\n sandbox: true;\n}\n\nexport interface SandboxAgent {\n domain: string;\n name: string;\n type: string;\n size?: string;\n sandbox: true;\n}\n\nexport interface SandboxEntities {\n brands: SandboxBrand[];\n agents: SandboxAgent[];\n}\n\n// ====== Internal helpers ======\n\nfunction loadTestKit(filePath: string): Record<string, unknown> {\n const content = readFileSync(filePath, 'utf-8');\n return parse(content) as Record<string, unknown>;\n}\n\nfunction loadFictionalEntities(universalDir: string): Record<string, unknown> | null {\n const filePath = join(universalDir, 'fictional-entities.yaml');\n if (!existsSync(filePath)) return null;\n const content = readFileSync(filePath, 'utf-8');\n return parse(content) as Record<string, unknown>;\n}\n\nfunction buildBrandJson(kit: Record<string, unknown>): BrandJson {\n const brand = kit.brand as Record<string, unknown> | undefined;\n const house = brand?.house as Record<string, unknown> | undefined;\n const houseDomain = house?.domain as string | undefined;\n\n if (!brand || !house || !houseDomain) {\n throw new Error(`Test kit \"${kit.id ?? kit.name}\" missing brand.house.domain`);\n }\n\n const id = (brand.brand_id as string) ?? (kit.id as string);\n const rawNames = brand.names as Array<Record<string, string>> | undefined;\n const names = rawNames ?? [{ en: (house.name as string) ?? (kit.name as string) }];\n\n const raw: Record<string, unknown> = {\n $schema: 'https://adcontextprotocol.org/schemas/brand.json',\n house: houseDomain,\n brands: [\n {\n id,\n names,\n ...(brand.keller_type != null && { keller_type: brand.keller_type }),\n ...(brand.description != null && { description: brand.description }),\n ...(brand.logos != null && { logos: brand.logos }),\n ...(brand.colors != null && { colors: brand.colors }),\n ...(brand.fonts != null && { fonts: brand.fonts }),\n ...(brand.tone != null && { tone: brand.tone }),\n },\n ],\n };\n\n return BrandJsonSchema.parse(raw);\n}\n\n// ====== Public API ======\n\nlet _cache: SandboxEntities | null = null;\n\n/**\n * Load all sandbox entities from bundled storyboard test kits and\n * fictional-entities.yaml. Results are cached after the first call.\n *\n * The registry calls this to serve sandbox brand.json and adagents.json\n * data without maintaining a separate copy.\n */\nexport function getSandboxEntities(): SandboxEntities {\n if (_cache) return _cache;\n\n const complianceDir = getComplianceCacheDir();\n const testKitDir = join(complianceDir, 'test-kits');\n const universalDir = join(complianceDir, 'universal');\n const brands: SandboxBrand[] = [];\n const agents: SandboxAgent[] = [];\n\n // Load brands from test kits (they have full brand identity data)\n if (existsSync(testKitDir)) {\n const files = readdirSync(testKitDir).filter(f => f.endsWith('.yaml'));\n for (const file of files) {\n const kit = loadTestKit(join(testKitDir, file));\n if (!kit.sandbox) continue;\n\n const brand = kit.brand as Record<string, unknown> | undefined;\n const house = brand?.house as Record<string, unknown> | undefined;\n const domain = house?.domain as string | undefined;\n if (!domain) continue;\n\n brands.push({\n domain,\n brand_name: (house?.name as string) ?? (kit.name as string),\n brand_id: (brand?.brand_id as string) ?? (kit.id as string),\n industry: (brand?.industry as string) ?? undefined,\n brand_json: buildBrandJson(kit),\n sandbox: true,\n });\n }\n }\n\n // Load additional brands and agents from universal/fictional-entities.yaml\n const entities = loadFictionalEntities(universalDir);\n if (entities) {\n // Advertisers without test kits still need brand entries\n const advertisers = entities.advertisers as Array<Record<string, unknown>> | undefined;\n if (advertisers) {\n for (const adv of advertisers) {\n const domain = adv.domain as string;\n // Skip if already loaded from a test kit\n if (brands.some(b => b.domain === domain)) continue;\n if (!adv.sandbox_brand) continue;\n brands.push({\n domain,\n brand_name: adv.name as string,\n brand_id: adv.id as string,\n industry: adv.industry as string | undefined,\n brand_json: BrandJsonSchema.parse({\n $schema: 'https://adcontextprotocol.org/schemas/brand.json',\n house: domain,\n brands: [{ id: adv.id, names: [{ en: adv.name }] }],\n }),\n sandbox: true,\n });\n }\n }\n\n // Publishers/platforms → sandbox agents\n const publishers = entities.publishers as Array<Record<string, unknown>> | undefined;\n if (publishers) {\n for (const pub of publishers) {\n const domain = pub.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: pub.name as string,\n type: (pub.type as string) ?? 'publisher',\n size: pub.size as string | undefined,\n sandbox: true,\n });\n }\n }\n\n // Agencies → sandbox agents\n const agencyList = entities.agencies as Array<Record<string, unknown>> | undefined;\n if (agencyList) {\n for (const agency of agencyList) {\n const domain = agency.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: agency.name as string,\n type: 'agency',\n size: agency.size as string | undefined,\n sandbox: true,\n });\n }\n }\n\n // Data providers → sandbox agents\n const providers = entities.data_providers as Array<Record<string, unknown>> | undefined;\n if (providers) {\n for (const prov of providers) {\n const domain = prov.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: prov.name as string,\n type: 'data_provider',\n size: prov.size as string | undefined,\n sandbox: true,\n });\n }\n }\n\n // Rights → sandbox agents\n const rights = entities.rights as Array<Record<string, unknown>> | undefined;\n if (rights) {\n for (const r of rights) {\n const domain = r.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: r.name as string,\n type: (r.type as string) ?? 'rights',\n size: r.size as string | undefined,\n sandbox: true,\n });\n }\n }\n }\n\n _cache = { brands, agents };\n return _cache;\n}\n\n/**\n * Get sandbox brands only (convenience for brand resolution).\n */\nexport function getSandboxBrands(): SandboxBrand[] {\n return getSandboxEntities().brands;\n}\n\n/**\n * Look up a single sandbox brand by domain.\n * Returns null if the domain is not a sandbox brand.\n */\nexport function getSandboxBrand(domain: string): SandboxBrand | null {\n return getSandboxBrands().find(b => b.domain === domain) ?? null;\n}\n\n/**\n * Check if a domain is a sandbox entity (brand or agent).\n */\nexport function isSandboxDomain(domain: string): boolean {\n const { brands, agents } = getSandboxEntities();\n return brands.some(b => b.domain === domain) || agents.some(a => a.domain === domain);\n}\n\n/**\n * Clear the cached sandbox entities. Primarily for testing.\n */\nexport function clearSandboxCache(): void {\n _cache = null;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/sandbox-entities.ts"],"sourcesContent":["/**\n * Sandbox entity loader.\n *\n * Parses compliance test-kit YAML files and fictional-entities.yaml to produce\n * structured sandbox data for the AAO registry. The registry imports this\n * function so the YAML files remain the single source of truth — no seeding,\n * no copying, no drift. YAMLs are pulled from `compliance/cache/{version}/`\n * by `npm run sync-schemas`.\n */\n\nimport { readFileSync, readdirSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { parse } from 'yaml';\nimport { getComplianceCacheDir } from './compliance';\nimport { BrandJsonSchema, type BrandJson } from '../../types/wellknown-schemas.generated';\n\nexport type { BrandJson } from '../../types/wellknown-schemas.generated';\n\n// ====== Public types ======\n\nexport interface SandboxBrand {\n domain: string;\n brand_name: string;\n brand_id: string;\n industry?: string;\n brand_json: BrandJson;\n sandbox: true;\n}\n\nexport interface SandboxAgent {\n domain: string;\n name: string;\n type: string;\n size?: string;\n sandbox: true;\n}\n\nexport interface SandboxEntities {\n brands: SandboxBrand[];\n agents: SandboxAgent[];\n}\n\n// ====== Internal helpers ======\n\nfunction loadTestKit(filePath: string): Record<string, unknown> {\n const content = readFileSync(filePath, 'utf-8');\n return parse(content) as Record<string, unknown>;\n}\n\nfunction loadFictionalEntities(universalDir: string): Record<string, unknown> | null {\n const filePath = join(universalDir, 'fictional-entities.yaml');\n if (!existsSync(filePath)) return null;\n const content = readFileSync(filePath, 'utf-8');\n return parse(content) as Record<string, unknown>;\n}\n\nfunction buildBrandJson(kit: Record<string, unknown>): BrandJson {\n const brand = kit.brand as Record<string, unknown> | undefined;\n const house = brand?.house as Record<string, unknown> | undefined;\n const houseDomain = house?.domain as string | undefined;\n\n if (!brand || !house || !houseDomain) {\n throw new Error(`Test kit \"${kit.id ?? kit.name}\" missing brand.house.domain`);\n }\n\n const id = (brand.brand_id as string) ?? (kit.id as string);\n const rawNames = brand.names as Array<Record<string, string>> | undefined;\n const names = rawNames ?? [{ en: (house.name as string) ?? (kit.name as string) }];\n\n const raw: Record<string, unknown> = {\n $schema: 'https://adcontextprotocol.org/schemas/brand.json',\n house: houseDomain,\n brands: [\n {\n id,\n names,\n ...(brand.keller_type != null && { keller_type: brand.keller_type }),\n ...(brand.description != null && { description: brand.description }),\n ...(brand.logos != null && { logos: brand.logos }),\n ...(brand.colors != null && { colors: brand.colors }),\n ...(brand.fonts != null && { fonts: brand.fonts }),\n ...(brand.tone != null && { tone: brand.tone }),\n },\n ],\n };\n\n return BrandJsonSchema.parse(raw);\n}\n\n// ====== Public API ======\n\nlet _cache: SandboxEntities | null = null;\n\n/**\n * Load all sandbox entities from bundled storyboard test kits and\n * fictional-entities.yaml. Results are cached after the first call.\n *\n * The registry calls this to serve sandbox brand.json and adagents.json\n * data without maintaining a separate copy.\n */\nexport function getSandboxEntities(): SandboxEntities {\n if (_cache) return _cache;\n\n const complianceDir = getComplianceCacheDir();\n const testKitDir = join(complianceDir, 'test-kits');\n const universalDir = join(complianceDir, 'universal');\n const brands: SandboxBrand[] = [];\n const agents: SandboxAgent[] = [];\n\n // Load brands from test kits (they have full brand identity data)\n if (existsSync(testKitDir)) {\n const files = readdirSync(testKitDir).filter(f => f.endsWith('.yaml'));\n for (const file of files) {\n const kit = loadTestKit(join(testKitDir, file));\n if (!kit.sandbox) continue;\n\n const brand = kit.brand as Record<string, unknown> | undefined;\n const house = brand?.house as Record<string, unknown> | undefined;\n const domain = house?.domain as string | undefined;\n if (!domain) continue;\n\n brands.push({\n domain,\n brand_name: (house?.name as string) ?? (kit.name as string),\n brand_id: (brand?.brand_id as string) ?? (kit.id as string),\n industry: (brand?.industry as string) ?? undefined,\n brand_json: buildBrandJson(kit),\n sandbox: true,\n });\n }\n }\n\n // Load additional brands and agents from universal/fictional-entities.yaml\n const entities = loadFictionalEntities(universalDir);\n if (entities) {\n // Advertisers without test kits still need brand entries\n const advertisers = entities.advertisers as Array<Record<string, unknown>> | undefined;\n if (advertisers) {\n for (const adv of advertisers) {\n const domain = adv.domain as string;\n // Skip if already loaded from a test kit\n if (brands.some(b => b.domain === domain)) continue;\n if (!adv.sandbox_brand) continue;\n brands.push({\n domain,\n brand_name: adv.name as string,\n brand_id: adv.id as string,\n industry: adv.industry as string | undefined,\n brand_json: BrandJsonSchema.parse({\n $schema: 'https://adcontextprotocol.org/schemas/brand.json',\n house: domain,\n brands: [{ id: adv.id, names: [{ en: adv.name }] }],\n }),\n sandbox: true,\n });\n }\n }\n\n // Publishers/platforms → sandbox agents\n const publishers = entities.publishers as Array<Record<string, unknown>> | undefined;\n if (publishers) {\n for (const pub of publishers) {\n const domain = pub.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: pub.name as string,\n type: (pub.type as string) ?? 'publisher',\n size: pub.size as string | undefined,\n sandbox: true,\n });\n }\n }\n\n // Agencies → sandbox agents\n const agencyList = entities.agencies as Array<Record<string, unknown>> | undefined;\n if (agencyList) {\n for (const agency of agencyList) {\n const domain = agency.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: agency.name as string,\n type: 'agency',\n size: agency.size as string | undefined,\n sandbox: true,\n });\n }\n }\n\n // Data providers → sandbox agents\n const providers = entities.data_providers as Array<Record<string, unknown>> | undefined;\n if (providers) {\n for (const prov of providers) {\n const domain = prov.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: prov.name as string,\n type: 'data_provider',\n size: prov.size as string | undefined,\n sandbox: true,\n });\n }\n }\n\n // Rights → sandbox agents\n const rights = entities.rights as Array<Record<string, unknown>> | undefined;\n if (rights) {\n for (const r of rights) {\n const domain = r.domain as string;\n if (!domain) continue;\n agents.push({\n domain,\n name: r.name as string,\n type: (r.type as string) ?? 'rights',\n size: r.size as string | undefined,\n sandbox: true,\n });\n }\n }\n }\n\n _cache = { brands, agents };\n return _cache;\n}\n\n/**\n * Get sandbox brands only (convenience for brand resolution).\n */\nexport function getSandboxBrands(): SandboxBrand[] {\n return getSandboxEntities().brands;\n}\n\n/**\n * Look up a single sandbox brand by domain.\n * Returns null if the domain is not a sandbox brand.\n */\nexport function getSandboxBrand(domain: string): SandboxBrand | null {\n return getSandboxBrands().find(b => b.domain === domain) ?? null;\n}\n\n/**\n * Check if a domain is a sandbox entity (brand or agent).\n */\nexport function isSandboxDomain(domain: string): boolean {\n const { brands, agents } = getSandboxEntities();\n return brands.some(b => b.domain === domain) || agents.some(a => a.domain === domain);\n}\n\n/**\n * Clear the cached sandbox entities. Primarily for testing.\n */\nexport function clearSandboxCache(): void {\n _cache = null;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { callControllerRaw } from "../test-controller.mjs";
|
|
8
2
|
const CONTROLLER_SEEDING_PHASE_ID = "__controller_seeding__";
|
|
9
3
|
function buildSeedCalls(fixtures) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/seeding.ts"],"sourcesContent":["/**\n * Pre-flight `comply_test_controller` seeding.\n *\n * Spec: adcontextprotocol/adcp#2585 (fixtures block + `controller_seeding`\n * flag) + adcontextprotocol/adcp#2584 (seed_* scenarios on\n * `comply_test_controller`). Storyboards such as `sales_non_guaranteed`,\n * `creative_ad_server`, `governance_delivery_monitor`,\n * `media_buy_governance_escalation`, and `governance_spend_authority`\n * reference fixture IDs (product_ids, pricing_option_ids, creative_ids,\n * plan_ids, media_buy_ids) that the seller must already hold before the\n * buyer-side flow runs. This module fires the `seed_*` scenarios derived\n * from the storyboard's top-level `fixtures:` block before the first real\n * phase, so the seller's buyer-agent ledger and catalog are populated ahead\n * of any `sync_accounts` / `create_media_buy` / `sync_creatives` / etc. call\n * that would otherwise fail or route through the wrong commercial-state gate.\n *\n * Failures here surface as a dedicated synthetic phase (`__controller_seeding__`)\n * so an implementor reading the report can distinguish \"setup broke\" from\n * \"buyer did something wrong\" — the runner short-circuits the rest of the\n * phases on any seed failure, emitting a cascade skip with reason\n * `controller_seeding_failed`.\n */\n\nimport type { TestClient } from '../client';\nimport { callControllerRaw } from '../test-controller';\nimport type {\n Storyboard,\n StoryboardContext,\n StoryboardFixtures,\n StoryboardPhaseResult,\n StoryboardRunOptions,\n StoryboardStepResult,\n} from './types';\n\n/** Synthetic phase id used in `StoryboardResult.phases[]` for the seed pass. */\nexport const CONTROLLER_SEEDING_PHASE_ID = '__controller_seeding__';\n\n/** Seed scenario names. Kept local — the server-side `SEED_SCENARIOS`\n * constant from `src/lib/server/test-controller.ts` is authoritative, but\n * importing it here would cross the testing ⇄ server module boundary. */\ntype SeedScenario =\n | 'seed_account'\n | 'seed_product'\n | 'seed_pricing_option'\n | 'seed_creative_format'\n | 'seed_creative'\n | 'seed_plan'\n | 'seed_media_buy';\ntype BuyerAgentSeedScenario = 'seed_buyer_agent';\n\ninterface SeedCall {\n step_id: string;\n title: string;\n scenario: SeedScenario | BuyerAgentSeedScenario;\n params: Record<string, unknown>;\n /** Authoring error (e.g. missing required id). When set, the call fails at\n * build time — no controller request is issued. */\n authoring_error?: string;\n}\n\n/**\n * Translate a storyboard `fixtures:` block into an ordered list of seed\n * calls. Each entry's id field(s) are lifted into the scenario params; every\n * remaining field rides in `params.fixture` verbatim. Missing required ids\n * produce an authoring-error marker the runner surfaces as a failed seed\n * step (rather than crashing or silently skipping).\n */\n// Top-level fixture keys are forwarded to the server verbatim inside\n// `params.fixture`. Prototype-pollution rejection (`__proto__`, `constructor`,\n// `prototype`) is enforced by the server-side `dispatchSeed` at a single\n// canonical point (`src/lib/server/test-controller.ts`), NOT re-guarded here:\n// surfacing the rejection through the normal seed-error path keeps one source\n// of truth for the check, and the server-side handler is where a seed request\n// can actually land from any client implementation. A future refactor that\n// removes the server check must add the client guard before removing it.\nexport function buildSeedCalls(fixtures: StoryboardFixtures | undefined): SeedCall[] {\n if (!fixtures) return [];\n const calls: SeedCall[] = [];\n\n (fixtures.accounts ?? []).forEach((entry, i) => {\n const { account_id, ...fixtureFields } = entry;\n const label = account_id ?? `#${i}`;\n if (typeof account_id !== 'string' || account_id.length === 0) {\n calls.push({\n step_id: `seed_account.${label}`,\n title: `Seed account ${label}`,\n scenario: 'seed_account',\n params: { fixture: seedFixtureFromFields(fixtureFields) },\n authoring_error: `fixtures.accounts[${i}] requires a non-empty string 'account_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_account.${account_id}`,\n title: `Seed account ${account_id}`,\n scenario: 'seed_account',\n params: { account_id, fixture: seedFixtureFromFields(fixtureFields) },\n });\n });\n\n (fixtures.buyer_agents ?? []).forEach((entry, i) => {\n const { agent_url, ...params } = entry;\n const label = agent_url ?? `#${i}`;\n if (typeof agent_url !== 'string' || agent_url.length === 0) {\n calls.push({\n step_id: `seed_buyer_agent.${label}`,\n title: `Seed buyer agent ${label}`,\n scenario: 'seed_buyer_agent',\n params,\n authoring_error: `fixtures.buyer_agents[${i}] requires a non-empty string 'agent_url'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_buyer_agent.${agent_url}`,\n title: `Seed buyer agent ${agent_url}`,\n scenario: 'seed_buyer_agent',\n params: { agent_url, ...params },\n });\n });\n\n (fixtures.products ?? []).forEach((entry, i) => {\n const { product_id, ...fixture } = entry;\n const label = product_id ?? `#${i}`;\n if (typeof product_id !== 'string' || product_id.length === 0) {\n calls.push({\n step_id: `seed_product.${label}`,\n title: `Seed product ${label}`,\n scenario: 'seed_product',\n params: { fixture },\n authoring_error: `fixtures.products[${i}] requires a non-empty string 'product_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_product.${product_id}`,\n title: `Seed product ${product_id}`,\n scenario: 'seed_product',\n params: { product_id, fixture },\n });\n });\n\n (fixtures.pricing_options ?? []).forEach((entry, i) => {\n const { product_id, pricing_option_id, ...fixture } = entry;\n const label =\n pricing_option_id && product_id\n ? `${product_id}:${pricing_option_id}`\n : (pricing_option_id ?? product_id ?? `#${i}`);\n const missing: string[] = [];\n if (typeof product_id !== 'string' || product_id.length === 0) missing.push('product_id');\n if (typeof pricing_option_id !== 'string' || pricing_option_id.length === 0) missing.push('pricing_option_id');\n if (missing.length > 0) {\n calls.push({\n step_id: `seed_pricing_option.${label}`,\n title: `Seed pricing option ${label}`,\n scenario: 'seed_pricing_option',\n params: { ...(product_id && { product_id }), ...(pricing_option_id && { pricing_option_id }), fixture },\n authoring_error: `fixtures.pricing_options[${i}] requires non-empty string(s) for: ${missing.join(', ')}`,\n });\n return;\n }\n calls.push({\n step_id: `seed_pricing_option.${product_id}.${pricing_option_id}`,\n title: `Seed pricing option ${pricing_option_id} on ${product_id}`,\n scenario: 'seed_pricing_option',\n params: { product_id, pricing_option_id, fixture },\n });\n });\n\n (fixtures.creative_formats ?? []).forEach((entry, i) => {\n const { format_id, ...fixtureFields } = entry;\n const label = format_id ?? `#${i}`;\n if (typeof format_id !== 'string' || format_id.length === 0) {\n calls.push({\n step_id: `seed_creative_format.${label}`,\n title: `Seed creative format ${label}`,\n scenario: 'seed_creative_format',\n params: { fixture: seedFixtureFromFields(fixtureFields) },\n authoring_error: `fixtures.creative_formats[${i}] requires a non-empty string 'format_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_creative_format.${format_id}`,\n title: `Seed creative format ${format_id}`,\n scenario: 'seed_creative_format',\n params: { format_id, fixture: seedFixtureFromFields(fixtureFields) },\n });\n });\n\n (fixtures.creatives ?? []).forEach((entry, i) => {\n const { creative_id, ...fixture } = entry;\n const label = creative_id ?? `#${i}`;\n if (typeof creative_id !== 'string' || creative_id.length === 0) {\n calls.push({\n step_id: `seed_creative.${label}`,\n title: `Seed creative ${label}`,\n scenario: 'seed_creative',\n params: { fixture },\n authoring_error: `fixtures.creatives[${i}] requires a non-empty string 'creative_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_creative.${creative_id}`,\n title: `Seed creative ${creative_id}`,\n scenario: 'seed_creative',\n params: { creative_id, fixture },\n });\n });\n\n (fixtures.plans ?? []).forEach((entry, i) => {\n const { plan_id, ...fixture } = entry;\n const label = plan_id ?? `#${i}`;\n if (typeof plan_id !== 'string' || plan_id.length === 0) {\n calls.push({\n step_id: `seed_plan.${label}`,\n title: `Seed plan ${label}`,\n scenario: 'seed_plan',\n params: { fixture },\n authoring_error: `fixtures.plans[${i}] requires a non-empty string 'plan_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_plan.${plan_id}`,\n title: `Seed plan ${plan_id}`,\n scenario: 'seed_plan',\n params: { plan_id, fixture },\n });\n });\n\n (fixtures.media_buys ?? []).forEach((entry, i) => {\n const { media_buy_id, ...fixture } = entry;\n const label = media_buy_id ?? `#${i}`;\n if (typeof media_buy_id !== 'string' || media_buy_id.length === 0) {\n calls.push({\n step_id: `seed_media_buy.${label}`,\n title: `Seed media buy ${label}`,\n scenario: 'seed_media_buy',\n params: { fixture },\n authoring_error: `fixtures.media_buys[${i}] requires a non-empty string 'media_buy_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_media_buy.${media_buy_id}`,\n title: `Seed media buy ${media_buy_id}`,\n scenario: 'seed_media_buy',\n params: { media_buy_id, fixture },\n });\n });\n\n return calls;\n}\n\nfunction seedFixtureFromFields(fields: Record<string, unknown>): unknown {\n if (Object.keys(fields).length === 1 && Object.hasOwn(fields, 'fixture')) {\n return fields.fixture;\n }\n return fields;\n}\n\nexport interface ControllerSeedingResult {\n /** Synthetic pre-flight phase to prepend to `StoryboardResult.phases[]`. */\n phase: StoryboardPhaseResult;\n /** True when every seed call succeeded; false means downstream phases must cascade-skip. */\n allPassed: boolean;\n /** Step counts to fold into the storyboard-level totals. */\n passedCount: number;\n failedCount: number;\n /**\n * Agent didn't advertise `comply_test_controller` — the storyboard can't\n * be graded against this seller. The runner cascade-skips real phases\n * with canonical `missing_test_controller` instead of the seeding-failed\n * path. Implements the spec's `fixture_seed_unsupported` not_applicable\n * grade (storyboard-schema.yaml `skip_reasons`).\n */\n missingController?: boolean;\n /**\n * Agent advertised `comply_test_controller`, but not one of the generated\n * seed_* scenarios this storyboard requires. This is a coverage gap, not\n * a failed agent behavior.\n */\n seedUnsupported?: boolean;\n}\n\n/**\n * Fire every seed call for this storyboard. Returns `null` when seeding is\n * not applicable (opt-out, no declaration, empty fixtures) so the runner can\n * treat a no-op identically to a non-seeding storyboard.\n */\nexport async function runControllerSeeding(\n client: TestClient,\n storyboard: Storyboard,\n options: StoryboardRunOptions,\n context: StoryboardContext\n): Promise<ControllerSeedingResult | null> {\n if (options.skip_controller_seeding === true) return null;\n if (storyboard.prerequisites?.controller_seeding !== true) return null;\n const calls = buildSeedCalls(storyboard.fixtures);\n if (calls.length === 0) return null;\n\n // If we can see the agent's tool list and `comply_test_controller` is\n // absent, grade as not_applicable rather than issuing calls that are\n // guaranteed to fail on the wire. Spec: `fixture_seed_unsupported` in\n // storyboard-schema.yaml — missing test-controller is a coverage gap, not\n // a setup break. `options.agentTools` is discovered from the agent profile\n // or passed explicitly by the caller; we don't enforce when it's absent\n // because some harnesses skip tool discovery.\n if (options.agentTools && !options.agentTools.includes('comply_test_controller')) {\n return buildMissingControllerResult(storyboard, calls, context);\n }\n\n const start = Date.now();\n const steps: StoryboardStepResult[] = [];\n let passedCount = 0;\n let failedCount = 0;\n let allPassed = true;\n const seedContext = { correlation_id: `${storyboardCorrelationPrefix(storyboard)}--__seeding__` };\n const authoringErrorResult = buildAuthoringErrorResult(storyboard, calls, context, start);\n if (authoringErrorResult) return authoringErrorResult;\n const unsupportedScenario = await findUnsupportedSeedScenario(client, calls, options, seedContext);\n if (unsupportedScenario) {\n return buildUnsupportedSeedResult(\n storyboard,\n calls,\n context,\n unsupportedScenario.scenario,\n unsupportedScenario.detail\n );\n }\n\n for (const call of calls) {\n const stepStart = Date.now();\n let passed = false;\n let error: string | undefined;\n\n if (call.authoring_error) {\n error = call.authoring_error;\n } else {\n try {\n const raw = await callControllerRaw(\n client,\n { scenario: call.scenario, params: call.params, context: seedContext },\n options\n );\n const data = raw.data as { success?: boolean; error?: string; error_detail?: string } | undefined;\n if (raw.success && data?.success === true) {\n passed = true;\n } else if (raw.success && data?.success === false && data.error === 'UNKNOWN_SCENARIO') {\n return buildUnsupportedSeedResult(storyboard, calls, context, call.scenario, data.error_detail);\n } else {\n error = formatControllerError(call.scenario, raw, data);\n }\n } catch (err) {\n error = err instanceof Error ? err.message : String(err);\n }\n }\n\n const step: StoryboardStepResult = {\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed,\n duration_ms: Date.now() - stepStart,\n validations: [],\n context,\n extraction: { path: 'none' },\n ...(error !== undefined && { error }),\n };\n steps.push(step);\n if (passed) {\n passedCount++;\n } else {\n failedCount++;\n allPassed = false;\n }\n }\n\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight)',\n passed: allPassed,\n steps,\n duration_ms: Date.now() - start,\n },\n allPassed,\n passedCount,\n failedCount,\n };\n}\n\nfunction storyboardCorrelationPrefix(storyboard: Storyboard): string {\n for (const phase of storyboard.phases) {\n for (const step of phase.steps) {\n const requestContext = step.sample_request?.context;\n if (!requestContext || typeof requestContext !== 'object' || Array.isArray(requestContext)) continue;\n const correlationId = (requestContext as { correlation_id?: unknown }).correlation_id;\n if (typeof correlationId !== 'string' || correlationId.length === 0) continue;\n const suffixSeparator = correlationId.lastIndexOf('--');\n return suffixSeparator > 0 ? correlationId.slice(0, suffixSeparator) : correlationId;\n }\n }\n return storyboard.id;\n}\n\nfunction buildAuthoringErrorResult(\n storyboard: Storyboard,\n calls: SeedCall[],\n context: StoryboardContext,\n start: number\n): ControllerSeedingResult | null {\n const authoringErrors = calls.filter((call): call is SeedCall & { authoring_error: string } =>\n Boolean(call.authoring_error)\n );\n if (authoringErrors.length === 0) return null;\n const steps: StoryboardStepResult[] = authoringErrors.map(call => ({\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed: false,\n duration_ms: 0,\n validations: [],\n context,\n extraction: { path: 'none' },\n error: call.authoring_error,\n }));\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight) — invalid storyboard fixtures',\n passed: false,\n steps,\n duration_ms: Date.now() - start,\n },\n allPassed: false,\n passedCount: 0,\n failedCount: steps.length,\n };\n}\n\nasync function findUnsupportedSeedScenario(\n client: TestClient,\n calls: SeedCall[],\n options: StoryboardRunOptions,\n seedContext: Record<string, unknown>\n): Promise<{ scenario: SeedScenario | BuyerAgentSeedScenario; detail: string } | null> {\n const requiredScenarios = [...new Set(calls.filter(call => !call.authoring_error).map(call => call.scenario))];\n if (requiredScenarios.length === 0) return null;\n\n let advertisedScenarios = controllerScenarioSetFromOptions(options);\n if (!advertisedScenarios) {\n advertisedScenarios = await fetchControllerScenarioSet(client, options, seedContext);\n }\n if (!advertisedScenarios) return null;\n\n for (const scenario of requiredScenarios) {\n if (!advertisedScenarios.has(scenario)) {\n return {\n scenario,\n detail: `list_scenarios did not advertise required seed scenario \"${scenario}\".`,\n };\n }\n }\n return null;\n}\n\nfunction controllerScenarioSetFromOptions(options: StoryboardRunOptions): Set<string> | null {\n const capabilities = options._controllerCapabilities;\n if (capabilities?.detected !== true) return null;\n return new Set((capabilities.scenarios as readonly string[]).filter(scenario => typeof scenario === 'string'));\n}\n\nasync function fetchControllerScenarioSet(\n client: TestClient,\n options: StoryboardRunOptions,\n seedContext: Record<string, unknown>\n): Promise<Set<string> | null> {\n try {\n const raw = await callControllerRaw(client, { scenario: 'list_scenarios', context: seedContext }, options);\n const data = raw.data as { success?: boolean; scenarios?: unknown } | undefined;\n if (!raw.success || data?.success !== true) return null;\n if (Array.isArray(data.scenarios)) {\n return new Set(data.scenarios.filter((scenario): scenario is string => typeof scenario === 'string'));\n }\n if (data.scenarios && typeof data.scenarios === 'object') {\n return new Set(Object.keys(data.scenarios));\n }\n return null;\n } catch {\n return null;\n }\n}\n\nconst UNSUPPORTED_SEED_DETAIL =\n 'Skipped: agent advertised comply_test_controller, but does not implement a seed_* scenario required by this storyboard (`fixture_seed_unsupported`). Storyboard grades not_applicable — the buyer-side flow depends on pre-seeded state the agent has no way to accept.';\n\nfunction buildUnsupportedSeedResult(\n storyboard: Storyboard,\n calls: Array<{ step_id: string; title: string }>,\n context: StoryboardContext,\n scenario: SeedScenario | BuyerAgentSeedScenario,\n detail?: string\n): ControllerSeedingResult {\n const skipDetail = detail\n ? `${UNSUPPORTED_SEED_DETAIL} Unsupported scenario ${scenario}: ${detail}`\n : `${UNSUPPORTED_SEED_DETAIL} Unsupported scenario: ${scenario}.`;\n const steps: StoryboardStepResult[] = calls.map(call => ({\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed: true,\n skipped: true,\n skip_reason: 'fixture_seed_unsupported',\n skip: { reason: 'not_applicable', detail: skipDetail },\n duration_ms: 0,\n validations: [],\n context,\n extraction: { path: 'none' },\n }));\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight) — agent lacks required seed scenario',\n passed: true,\n steps,\n duration_ms: 0,\n },\n allPassed: true,\n passedCount: 0,\n failedCount: 0,\n seedUnsupported: true,\n };\n}\n\nfunction formatControllerError(\n scenario: SeedScenario | BuyerAgentSeedScenario,\n raw: { success: boolean; error?: string },\n data: { success?: boolean; error?: string; error_detail?: string } | undefined\n): string {\n if (data?.error_detail) return data.error ? `${data.error}: ${data.error_detail}` : data.error_detail;\n if (data?.error) return data.error;\n return raw.error ?? `comply_test_controller ${scenario} call failed`;\n}\n\nconst MISSING_CONTROLLER_DETAIL =\n 'Skipped: agent did not advertise comply_test_controller, so fixture seeding (`fixture_seed_unsupported`) cannot run. Storyboard grades not_applicable — the buyer-side flow depends on pre-seeded state the agent has no way to accept.';\n\nfunction buildMissingControllerResult(\n storyboard: Storyboard,\n calls: Array<{ step_id: string; title: string }>,\n context: StoryboardContext\n): ControllerSeedingResult {\n const steps: StoryboardStepResult[] = calls.map(call => ({\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed: true,\n skipped: true,\n skip_reason: 'missing_test_controller',\n skip: { reason: 'missing_test_controller', detail: MISSING_CONTROLLER_DETAIL },\n duration_ms: 0,\n validations: [],\n context,\n extraction: { path: 'none' },\n }));\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight) — agent lacks comply_test_controller',\n passed: true,\n steps,\n duration_ms: 0,\n },\n allPassed: true,\n passedCount: 0,\n failedCount: 0,\n missingController: true,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/seeding.ts"],"sourcesContent":["/**\n * Pre-flight `comply_test_controller` seeding.\n *\n * Spec: adcontextprotocol/adcp#2585 (fixtures block + `controller_seeding`\n * flag) + adcontextprotocol/adcp#2584 (seed_* scenarios on\n * `comply_test_controller`). Storyboards such as `sales_non_guaranteed`,\n * `creative_ad_server`, `governance_delivery_monitor`,\n * `media_buy_governance_escalation`, and `governance_spend_authority`\n * reference fixture IDs (product_ids, pricing_option_ids, creative_ids,\n * plan_ids, media_buy_ids) that the seller must already hold before the\n * buyer-side flow runs. This module fires the `seed_*` scenarios derived\n * from the storyboard's top-level `fixtures:` block before the first real\n * phase, so the seller's buyer-agent ledger and catalog are populated ahead\n * of any `sync_accounts` / `create_media_buy` / `sync_creatives` / etc. call\n * that would otherwise fail or route through the wrong commercial-state gate.\n *\n * Failures here surface as a dedicated synthetic phase (`__controller_seeding__`)\n * so an implementor reading the report can distinguish \"setup broke\" from\n * \"buyer did something wrong\" — the runner short-circuits the rest of the\n * phases on any seed failure, emitting a cascade skip with reason\n * `controller_seeding_failed`.\n */\n\nimport type { TestClient } from '../client';\nimport { callControllerRaw } from '../test-controller';\nimport type {\n Storyboard,\n StoryboardContext,\n StoryboardFixtures,\n StoryboardPhaseResult,\n StoryboardRunOptions,\n StoryboardStepResult,\n} from './types';\n\n/** Synthetic phase id used in `StoryboardResult.phases[]` for the seed pass. */\nexport const CONTROLLER_SEEDING_PHASE_ID = '__controller_seeding__';\n\n/** Seed scenario names. Kept local — the server-side `SEED_SCENARIOS`\n * constant from `src/lib/server/test-controller.ts` is authoritative, but\n * importing it here would cross the testing ⇄ server module boundary. */\ntype SeedScenario =\n | 'seed_account'\n | 'seed_product'\n | 'seed_pricing_option'\n | 'seed_creative_format'\n | 'seed_creative'\n | 'seed_plan'\n | 'seed_media_buy';\ntype BuyerAgentSeedScenario = 'seed_buyer_agent';\n\ninterface SeedCall {\n step_id: string;\n title: string;\n scenario: SeedScenario | BuyerAgentSeedScenario;\n params: Record<string, unknown>;\n /** Authoring error (e.g. missing required id). When set, the call fails at\n * build time — no controller request is issued. */\n authoring_error?: string;\n}\n\n/**\n * Translate a storyboard `fixtures:` block into an ordered list of seed\n * calls. Each entry's id field(s) are lifted into the scenario params; every\n * remaining field rides in `params.fixture` verbatim. Missing required ids\n * produce an authoring-error marker the runner surfaces as a failed seed\n * step (rather than crashing or silently skipping).\n */\n// Top-level fixture keys are forwarded to the server verbatim inside\n// `params.fixture`. Prototype-pollution rejection (`__proto__`, `constructor`,\n// `prototype`) is enforced by the server-side `dispatchSeed` at a single\n// canonical point (`src/lib/server/test-controller.ts`), NOT re-guarded here:\n// surfacing the rejection through the normal seed-error path keeps one source\n// of truth for the check, and the server-side handler is where a seed request\n// can actually land from any client implementation. A future refactor that\n// removes the server check must add the client guard before removing it.\nexport function buildSeedCalls(fixtures: StoryboardFixtures | undefined): SeedCall[] {\n if (!fixtures) return [];\n const calls: SeedCall[] = [];\n\n (fixtures.accounts ?? []).forEach((entry, i) => {\n const { account_id, ...fixtureFields } = entry;\n const label = account_id ?? `#${i}`;\n if (typeof account_id !== 'string' || account_id.length === 0) {\n calls.push({\n step_id: `seed_account.${label}`,\n title: `Seed account ${label}`,\n scenario: 'seed_account',\n params: { fixture: seedFixtureFromFields(fixtureFields) },\n authoring_error: `fixtures.accounts[${i}] requires a non-empty string 'account_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_account.${account_id}`,\n title: `Seed account ${account_id}`,\n scenario: 'seed_account',\n params: { account_id, fixture: seedFixtureFromFields(fixtureFields) },\n });\n });\n\n (fixtures.buyer_agents ?? []).forEach((entry, i) => {\n const { agent_url, ...params } = entry;\n const label = agent_url ?? `#${i}`;\n if (typeof agent_url !== 'string' || agent_url.length === 0) {\n calls.push({\n step_id: `seed_buyer_agent.${label}`,\n title: `Seed buyer agent ${label}`,\n scenario: 'seed_buyer_agent',\n params,\n authoring_error: `fixtures.buyer_agents[${i}] requires a non-empty string 'agent_url'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_buyer_agent.${agent_url}`,\n title: `Seed buyer agent ${agent_url}`,\n scenario: 'seed_buyer_agent',\n params: { agent_url, ...params },\n });\n });\n\n (fixtures.products ?? []).forEach((entry, i) => {\n const { product_id, ...fixture } = entry;\n const label = product_id ?? `#${i}`;\n if (typeof product_id !== 'string' || product_id.length === 0) {\n calls.push({\n step_id: `seed_product.${label}`,\n title: `Seed product ${label}`,\n scenario: 'seed_product',\n params: { fixture },\n authoring_error: `fixtures.products[${i}] requires a non-empty string 'product_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_product.${product_id}`,\n title: `Seed product ${product_id}`,\n scenario: 'seed_product',\n params: { product_id, fixture },\n });\n });\n\n (fixtures.pricing_options ?? []).forEach((entry, i) => {\n const { product_id, pricing_option_id, ...fixture } = entry;\n const label =\n pricing_option_id && product_id\n ? `${product_id}:${pricing_option_id}`\n : (pricing_option_id ?? product_id ?? `#${i}`);\n const missing: string[] = [];\n if (typeof product_id !== 'string' || product_id.length === 0) missing.push('product_id');\n if (typeof pricing_option_id !== 'string' || pricing_option_id.length === 0) missing.push('pricing_option_id');\n if (missing.length > 0) {\n calls.push({\n step_id: `seed_pricing_option.${label}`,\n title: `Seed pricing option ${label}`,\n scenario: 'seed_pricing_option',\n params: { ...(product_id && { product_id }), ...(pricing_option_id && { pricing_option_id }), fixture },\n authoring_error: `fixtures.pricing_options[${i}] requires non-empty string(s) for: ${missing.join(', ')}`,\n });\n return;\n }\n calls.push({\n step_id: `seed_pricing_option.${product_id}.${pricing_option_id}`,\n title: `Seed pricing option ${pricing_option_id} on ${product_id}`,\n scenario: 'seed_pricing_option',\n params: { product_id, pricing_option_id, fixture },\n });\n });\n\n (fixtures.creative_formats ?? []).forEach((entry, i) => {\n const { format_id, ...fixtureFields } = entry;\n const label = format_id ?? `#${i}`;\n if (typeof format_id !== 'string' || format_id.length === 0) {\n calls.push({\n step_id: `seed_creative_format.${label}`,\n title: `Seed creative format ${label}`,\n scenario: 'seed_creative_format',\n params: { fixture: seedFixtureFromFields(fixtureFields) },\n authoring_error: `fixtures.creative_formats[${i}] requires a non-empty string 'format_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_creative_format.${format_id}`,\n title: `Seed creative format ${format_id}`,\n scenario: 'seed_creative_format',\n params: { format_id, fixture: seedFixtureFromFields(fixtureFields) },\n });\n });\n\n (fixtures.creatives ?? []).forEach((entry, i) => {\n const { creative_id, ...fixture } = entry;\n const label = creative_id ?? `#${i}`;\n if (typeof creative_id !== 'string' || creative_id.length === 0) {\n calls.push({\n step_id: `seed_creative.${label}`,\n title: `Seed creative ${label}`,\n scenario: 'seed_creative',\n params: { fixture },\n authoring_error: `fixtures.creatives[${i}] requires a non-empty string 'creative_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_creative.${creative_id}`,\n title: `Seed creative ${creative_id}`,\n scenario: 'seed_creative',\n params: { creative_id, fixture },\n });\n });\n\n (fixtures.plans ?? []).forEach((entry, i) => {\n const { plan_id, ...fixture } = entry;\n const label = plan_id ?? `#${i}`;\n if (typeof plan_id !== 'string' || plan_id.length === 0) {\n calls.push({\n step_id: `seed_plan.${label}`,\n title: `Seed plan ${label}`,\n scenario: 'seed_plan',\n params: { fixture },\n authoring_error: `fixtures.plans[${i}] requires a non-empty string 'plan_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_plan.${plan_id}`,\n title: `Seed plan ${plan_id}`,\n scenario: 'seed_plan',\n params: { plan_id, fixture },\n });\n });\n\n (fixtures.media_buys ?? []).forEach((entry, i) => {\n const { media_buy_id, ...fixture } = entry;\n const label = media_buy_id ?? `#${i}`;\n if (typeof media_buy_id !== 'string' || media_buy_id.length === 0) {\n calls.push({\n step_id: `seed_media_buy.${label}`,\n title: `Seed media buy ${label}`,\n scenario: 'seed_media_buy',\n params: { fixture },\n authoring_error: `fixtures.media_buys[${i}] requires a non-empty string 'media_buy_id'`,\n });\n return;\n }\n calls.push({\n step_id: `seed_media_buy.${media_buy_id}`,\n title: `Seed media buy ${media_buy_id}`,\n scenario: 'seed_media_buy',\n params: { media_buy_id, fixture },\n });\n });\n\n return calls;\n}\n\nfunction seedFixtureFromFields(fields: Record<string, unknown>): unknown {\n if (Object.keys(fields).length === 1 && Object.hasOwn(fields, 'fixture')) {\n return fields.fixture;\n }\n return fields;\n}\n\nexport interface ControllerSeedingResult {\n /** Synthetic pre-flight phase to prepend to `StoryboardResult.phases[]`. */\n phase: StoryboardPhaseResult;\n /** True when every seed call succeeded; false means downstream phases must cascade-skip. */\n allPassed: boolean;\n /** Step counts to fold into the storyboard-level totals. */\n passedCount: number;\n failedCount: number;\n /**\n * Agent didn't advertise `comply_test_controller` — the storyboard can't\n * be graded against this seller. The runner cascade-skips real phases\n * with canonical `missing_test_controller` instead of the seeding-failed\n * path. Implements the spec's `fixture_seed_unsupported` not_applicable\n * grade (storyboard-schema.yaml `skip_reasons`).\n */\n missingController?: boolean;\n /**\n * Agent advertised `comply_test_controller`, but not one of the generated\n * seed_* scenarios this storyboard requires. This is a coverage gap, not\n * a failed agent behavior.\n */\n seedUnsupported?: boolean;\n}\n\n/**\n * Fire every seed call for this storyboard. Returns `null` when seeding is\n * not applicable (opt-out, no declaration, empty fixtures) so the runner can\n * treat a no-op identically to a non-seeding storyboard.\n */\nexport async function runControllerSeeding(\n client: TestClient,\n storyboard: Storyboard,\n options: StoryboardRunOptions,\n context: StoryboardContext\n): Promise<ControllerSeedingResult | null> {\n if (options.skip_controller_seeding === true) return null;\n if (storyboard.prerequisites?.controller_seeding !== true) return null;\n const calls = buildSeedCalls(storyboard.fixtures);\n if (calls.length === 0) return null;\n\n // If we can see the agent's tool list and `comply_test_controller` is\n // absent, grade as not_applicable rather than issuing calls that are\n // guaranteed to fail on the wire. Spec: `fixture_seed_unsupported` in\n // storyboard-schema.yaml — missing test-controller is a coverage gap, not\n // a setup break. `options.agentTools` is discovered from the agent profile\n // or passed explicitly by the caller; we don't enforce when it's absent\n // because some harnesses skip tool discovery.\n if (options.agentTools && !options.agentTools.includes('comply_test_controller')) {\n return buildMissingControllerResult(storyboard, calls, context);\n }\n\n const start = Date.now();\n const steps: StoryboardStepResult[] = [];\n let passedCount = 0;\n let failedCount = 0;\n let allPassed = true;\n const seedContext = { correlation_id: `${storyboardCorrelationPrefix(storyboard)}--__seeding__` };\n const authoringErrorResult = buildAuthoringErrorResult(storyboard, calls, context, start);\n if (authoringErrorResult) return authoringErrorResult;\n const unsupportedScenario = await findUnsupportedSeedScenario(client, calls, options, seedContext);\n if (unsupportedScenario) {\n return buildUnsupportedSeedResult(\n storyboard,\n calls,\n context,\n unsupportedScenario.scenario,\n unsupportedScenario.detail\n );\n }\n\n for (const call of calls) {\n const stepStart = Date.now();\n let passed = false;\n let error: string | undefined;\n\n if (call.authoring_error) {\n error = call.authoring_error;\n } else {\n try {\n const raw = await callControllerRaw(\n client,\n { scenario: call.scenario, params: call.params, context: seedContext },\n options\n );\n const data = raw.data as { success?: boolean; error?: string; error_detail?: string } | undefined;\n if (raw.success && data?.success === true) {\n passed = true;\n } else if (raw.success && data?.success === false && data.error === 'UNKNOWN_SCENARIO') {\n return buildUnsupportedSeedResult(storyboard, calls, context, call.scenario, data.error_detail);\n } else {\n error = formatControllerError(call.scenario, raw, data);\n }\n } catch (err) {\n error = err instanceof Error ? err.message : String(err);\n }\n }\n\n const step: StoryboardStepResult = {\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed,\n duration_ms: Date.now() - stepStart,\n validations: [],\n context,\n extraction: { path: 'none' },\n ...(error !== undefined && { error }),\n };\n steps.push(step);\n if (passed) {\n passedCount++;\n } else {\n failedCount++;\n allPassed = false;\n }\n }\n\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight)',\n passed: allPassed,\n steps,\n duration_ms: Date.now() - start,\n },\n allPassed,\n passedCount,\n failedCount,\n };\n}\n\nfunction storyboardCorrelationPrefix(storyboard: Storyboard): string {\n for (const phase of storyboard.phases) {\n for (const step of phase.steps) {\n const requestContext = step.sample_request?.context;\n if (!requestContext || typeof requestContext !== 'object' || Array.isArray(requestContext)) continue;\n const correlationId = (requestContext as { correlation_id?: unknown }).correlation_id;\n if (typeof correlationId !== 'string' || correlationId.length === 0) continue;\n const suffixSeparator = correlationId.lastIndexOf('--');\n return suffixSeparator > 0 ? correlationId.slice(0, suffixSeparator) : correlationId;\n }\n }\n return storyboard.id;\n}\n\nfunction buildAuthoringErrorResult(\n storyboard: Storyboard,\n calls: SeedCall[],\n context: StoryboardContext,\n start: number\n): ControllerSeedingResult | null {\n const authoringErrors = calls.filter((call): call is SeedCall & { authoring_error: string } =>\n Boolean(call.authoring_error)\n );\n if (authoringErrors.length === 0) return null;\n const steps: StoryboardStepResult[] = authoringErrors.map(call => ({\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed: false,\n duration_ms: 0,\n validations: [],\n context,\n extraction: { path: 'none' },\n error: call.authoring_error,\n }));\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight) — invalid storyboard fixtures',\n passed: false,\n steps,\n duration_ms: Date.now() - start,\n },\n allPassed: false,\n passedCount: 0,\n failedCount: steps.length,\n };\n}\n\nasync function findUnsupportedSeedScenario(\n client: TestClient,\n calls: SeedCall[],\n options: StoryboardRunOptions,\n seedContext: Record<string, unknown>\n): Promise<{ scenario: SeedScenario | BuyerAgentSeedScenario; detail: string } | null> {\n const requiredScenarios = [...new Set(calls.filter(call => !call.authoring_error).map(call => call.scenario))];\n if (requiredScenarios.length === 0) return null;\n\n let advertisedScenarios = controllerScenarioSetFromOptions(options);\n if (!advertisedScenarios) {\n advertisedScenarios = await fetchControllerScenarioSet(client, options, seedContext);\n }\n if (!advertisedScenarios) return null;\n\n for (const scenario of requiredScenarios) {\n if (!advertisedScenarios.has(scenario)) {\n return {\n scenario,\n detail: `list_scenarios did not advertise required seed scenario \"${scenario}\".`,\n };\n }\n }\n return null;\n}\n\nfunction controllerScenarioSetFromOptions(options: StoryboardRunOptions): Set<string> | null {\n const capabilities = options._controllerCapabilities;\n if (capabilities?.detected !== true) return null;\n return new Set((capabilities.scenarios as readonly string[]).filter(scenario => typeof scenario === 'string'));\n}\n\nasync function fetchControllerScenarioSet(\n client: TestClient,\n options: StoryboardRunOptions,\n seedContext: Record<string, unknown>\n): Promise<Set<string> | null> {\n try {\n const raw = await callControllerRaw(client, { scenario: 'list_scenarios', context: seedContext }, options);\n const data = raw.data as { success?: boolean; scenarios?: unknown } | undefined;\n if (!raw.success || data?.success !== true) return null;\n if (Array.isArray(data.scenarios)) {\n return new Set(data.scenarios.filter((scenario): scenario is string => typeof scenario === 'string'));\n }\n if (data.scenarios && typeof data.scenarios === 'object') {\n return new Set(Object.keys(data.scenarios));\n }\n return null;\n } catch {\n return null;\n }\n}\n\nconst UNSUPPORTED_SEED_DETAIL =\n 'Skipped: agent advertised comply_test_controller, but does not implement a seed_* scenario required by this storyboard (`fixture_seed_unsupported`). Storyboard grades not_applicable — the buyer-side flow depends on pre-seeded state the agent has no way to accept.';\n\nfunction buildUnsupportedSeedResult(\n storyboard: Storyboard,\n calls: Array<{ step_id: string; title: string }>,\n context: StoryboardContext,\n scenario: SeedScenario | BuyerAgentSeedScenario,\n detail?: string\n): ControllerSeedingResult {\n const skipDetail = detail\n ? `${UNSUPPORTED_SEED_DETAIL} Unsupported scenario ${scenario}: ${detail}`\n : `${UNSUPPORTED_SEED_DETAIL} Unsupported scenario: ${scenario}.`;\n const steps: StoryboardStepResult[] = calls.map(call => ({\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed: true,\n skipped: true,\n skip_reason: 'fixture_seed_unsupported',\n skip: { reason: 'not_applicable', detail: skipDetail },\n duration_ms: 0,\n validations: [],\n context,\n extraction: { path: 'none' },\n }));\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight) — agent lacks required seed scenario',\n passed: true,\n steps,\n duration_ms: 0,\n },\n allPassed: true,\n passedCount: 0,\n failedCount: 0,\n seedUnsupported: true,\n };\n}\n\nfunction formatControllerError(\n scenario: SeedScenario | BuyerAgentSeedScenario,\n raw: { success: boolean; error?: string },\n data: { success?: boolean; error?: string; error_detail?: string } | undefined\n): string {\n if (data?.error_detail) return data.error ? `${data.error}: ${data.error_detail}` : data.error_detail;\n if (data?.error) return data.error;\n return raw.error ?? `comply_test_controller ${scenario} call failed`;\n}\n\nconst MISSING_CONTROLLER_DETAIL =\n 'Skipped: agent did not advertise comply_test_controller, so fixture seeding (`fixture_seed_unsupported`) cannot run. Storyboard grades not_applicable — the buyer-side flow depends on pre-seeded state the agent has no way to accept.';\n\nfunction buildMissingControllerResult(\n storyboard: Storyboard,\n calls: Array<{ step_id: string; title: string }>,\n context: StoryboardContext\n): ControllerSeedingResult {\n const steps: StoryboardStepResult[] = calls.map(call => ({\n storyboard_id: storyboard.id,\n step_id: call.step_id,\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n title: call.title,\n task: 'comply_test_controller',\n passed: true,\n skipped: true,\n skip_reason: 'missing_test_controller',\n skip: { reason: 'missing_test_controller', detail: MISSING_CONTROLLER_DETAIL },\n duration_ms: 0,\n validations: [],\n context,\n extraction: { path: 'none' },\n }));\n return {\n phase: {\n phase_id: CONTROLLER_SEEDING_PHASE_ID,\n phase_title: 'Controller seeding (pre-flight) — agent lacks comply_test_controller',\n passed: true,\n steps,\n duration_ms: 0,\n },\n allPassed: true,\n passedCount: 0,\n failedCount: 0,\n missingController: true,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
const HELPER_MIN_VERSION = {
|
|
8
2
|
buildCreativeResponse: "5.14.0",
|
|
9
3
|
listCreativesResponse: "5.10.0",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/shape-drift-hints.ts"],"sourcesContent":["/**\n * Structured shape-drift hint detection (issue #935).\n *\n * The runner emits one `ShapeDriftHint` per response when it recognizes a\n * common payload-shape mistake — bare arrays from list tools, platform-\n * native fields from `build_creative`, missing wrappers on `sync_creatives`\n * / `preview_creative`. Each hint carries the same prose the legacy\n * `detectShapeDriftHint` returned, plus structured fields (`tool`,\n * `observed_variant`, `expected_variant`, `instance_path`) so renderers\n * (CLI, Addie, JUnit, SARIF) can build per-case fix plans without re-\n * parsing the message.\n *\n * The string-only `detectShapeDriftHint` in `validations.ts` is a thin\n * shim over this detector — kept so existing unit tests and external\n * callers keep working, but the canonical path is structured.\n *\n * Fires unconditionally (regardless of step pass/fail) — same gate as\n * `ValidationResult.warning` carried previously. The caller (`runner.ts`)\n * merges the result into `StoryboardStepResult.hints[]`.\n */\nimport type { ShapeDriftHint } from './types';\n\n/**\n * Minimum @adcp/client version in which each server-side helper first shipped.\n * Used to suffix shape-drift hints when the agent reports an older SDK version.\n * Keys match the helper name referenced in the hint `message`.\n */\nconst HELPER_MIN_VERSION: Record<string, string> = {\n buildCreativeResponse: '5.14.0',\n listCreativesResponse: '5.10.0',\n listCreativeFormatsResponse: '5.10.0',\n listAccountsResponse: '5.10.0',\n productsResponse: '5.10.0',\n getMediaBuysResponse: '5.10.0',\n getSignalsResponse: '5.10.0',\n listPropertyListsResponse: '5.10.0',\n listCollectionListsResponse: '5.10.0',\n listContentStandardsResponse: '5.10.0',\n getPlanAuditLogsResponse: '5.10.0',\n syncCreativesResponse: '5.10.0',\n previewCreativeResponse: '5.10.0',\n};\n\n/**\n * Compare two semver strings using numeric segment ordering.\n * Returns true when `a` is strictly less than `b`.\n * Handles `@adcp/client@X.Y.Z` format by stripping the package prefix.\n */\nfunction semverLessThan(a: string, b: string): boolean {\n // Strip package prefix (e.g. \"@adcp/client@\") and pre-release suffix (e.g. \"-beta.1\")\n const normalize = (v: string) => v.replace(/^.*@/, '').replace(/-.*$/, '');\n const segs = (v: string) =>\n normalize(v)\n .split('.')\n .map(s => parseInt(s, 10) || 0);\n const [aMaj = 0, aMin = 0, aPatch = 0] = segs(a);\n const [bMaj = 0, bMin = 0, bPatch = 0] = segs(b);\n if (aMaj !== bMaj) return aMaj < bMaj;\n if (aMin !== bMin) return aMin < bMin;\n return aPatch < bPatch;\n}\n\n/**\n * List-shaped tools where handlers commonly return the bare inner array\n * (`[{...}]`) at the top level instead of wrapping it in the required\n * object envelope. Each entry names the wrapper key and the response\n * helper that builds the correct shape.\n *\n * Helper names aren't uniformly prefixed — `get_products` uses\n * `productsResponse` (no `get` prefix) while `get_media_buys` uses\n * `getMediaBuysResponse`. Names match the exports in\n * `src/lib/server/responses.ts` verbatim so a developer can grep\n * straight from the hint.\n */\nexport const LIST_WRAPPER_TOOLS: Record<string, { wrapperKey: string; helper: string }> = {\n list_creatives: { wrapperKey: 'creatives', helper: 'listCreativesResponse' },\n list_creative_formats: { wrapperKey: 'formats', helper: 'listCreativeFormatsResponse' },\n list_accounts: { wrapperKey: 'accounts', helper: 'listAccountsResponse' },\n get_products: { wrapperKey: 'products', helper: 'productsResponse' },\n get_media_buys: { wrapperKey: 'media_buys', helper: 'getMediaBuysResponse' },\n get_signals: { wrapperKey: 'signals', helper: 'getSignalsResponse' },\n list_property_lists: { wrapperKey: 'lists', helper: 'listPropertyListsResponse' },\n list_collection_lists: { wrapperKey: 'lists', helper: 'listCollectionListsResponse' },\n list_content_standards: { wrapperKey: 'standards', helper: 'listContentStandardsResponse' },\n get_plan_audit_logs: { wrapperKey: 'plans', helper: 'getPlanAuditLogsResponse' },\n};\n\n/**\n * Detect shape-drift and return the structured hints that apply (zero or\n * one — the detector emits at most one hint per response, but returns an\n * array so callers can spread it into `step.hints[]` without a guard).\n *\n * @param taskName — tool name (snake_case) the storyboard dispatched under\n * @param payload — raw response payload, after the runner's `_message`\n * pre-strip. `unknown` rather than `Record<string, unknown>` so bare-\n * array payloads are recognizable at the top level; object branches\n * guard internally.\n * @param libraryVersion — optional SDK version string the agent self-reported\n * in `get_adcp_capabilities` (e.g. `\"@adcp/client@4.16.2\"`). When present\n * and below the helper's minimum version, the hint message is suffixed with\n * an upgrade note so developers know to update their SDK dep.\n */\nexport function detectShapeDriftHints(taskName: string, payload: unknown, libraryVersion?: string): ShapeDriftHint[] {\n const hint = detect(taskName, payload);\n if (!hint) return [];\n if (libraryVersion) hint.message = appendVersionSuffix(hint.message, libraryVersion);\n return [hint];\n}\n\n/**\n * If the hint message references a helper that requires a minimum SDK\n * version and the agent's reported version is below it, append an upgrade\n * note to the message. Returns the message unchanged if no version data or\n * no match.\n */\nfunction appendVersionSuffix(message: string, libraryVersion: string): string {\n // Skip non-numeric version strings (e.g. \"local-dev\") to avoid spurious suffixes\n const stripped = libraryVersion.replace(/^.*@/, '').replace(/-.*$/, '');\n if (!/^\\d+\\.\\d+/.test(stripped)) return message;\n for (const [helper, minVersion] of Object.entries(HELPER_MIN_VERSION)) {\n if (message.includes(helper) && semverLessThan(libraryVersion, minVersion)) {\n return (\n message +\n ` (Note: your agent reports ${libraryVersion} — ${helper}() ships in @adcp/client ≥${minVersion}. Upgrade your SDK dep.)`\n );\n }\n }\n return message;\n}\n\nfunction detect(taskName: string, payload: unknown): ShapeDriftHint | undefined {\n if (Array.isArray(payload)) {\n const listMeta = LIST_WRAPPER_TOOLS[taskName];\n if (!listMeta) return undefined;\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'bare_array',\n expected_variant: `{ ${listMeta.wrapperKey}: [...] }`,\n instance_path: '',\n message:\n `${taskName} returned a bare array at the top level. ` +\n `Required: { ${listMeta.wrapperKey}: [...] }. ` +\n `Use ${listMeta.helper}() from @adcp/sdk/server.`,\n };\n }\n\n if (typeof payload !== 'object' || payload === null) return undefined;\n const p = payload as Record<string, unknown>;\n\n if (taskName === 'build_creative') {\n const hasManifest = 'creative_manifest' in p || 'creative_manifests' in p;\n const platformNativeKeys = ['tag_url', 'creative_id', 'media_type', 'tag_type'];\n const platformNativePresent = platformNativeKeys.filter(k => k in p);\n if (!hasManifest && platformNativePresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'platform_native_fields',\n expected_variant: '{ creative_manifest: { format_id, assets } }',\n instance_path: '',\n message:\n `build_creative returned platform-native fields at the top level (${platformNativePresent.join(', ')}). ` +\n `Required: { creative_manifest: { format_id, assets } }. ` +\n `Use buildCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n if (taskName === 'sync_creatives') {\n const hasValidWrapper = 'creatives' in p || 'errors' in p || 'task_id' in p;\n const perItemKeys = ['creative_id', 'platform_id', 'action'];\n const perItemPresent = perItemKeys.filter(k => k in p);\n if (!hasValidWrapper && perItemPresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'per_item_shape',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '',\n message:\n `sync_creatives returned a single creative's inner shape at the top level (${perItemPresent.join(', ')}). ` +\n `Required: { creatives: [{ creative_id, action, ... }] } (or { errors: [...] } / { status: 'submitted', task_id }). ` +\n `Use syncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n\n const results = p.results;\n if (!hasValidWrapper && Array.isArray(results) && results.length > 0) {\n const firstRow = results[0];\n const looksLikeCreativeRow =\n firstRow != null && typeof firstRow === 'object' && ('creative_id' in firstRow || 'action' in firstRow);\n if (looksLikeCreativeRow) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'wrong_wrapper_key',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '/results',\n message:\n `sync_creatives returned { results: [...] } instead of { creatives: [...] } — wrong wrapper key. ` +\n `Required: { creatives: [{ creative_id, action, ... }] }. ` +\n `Use syncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n }\n }\n\n if (taskName === 'preview_creative') {\n const hasValidWrapper = 'response_type' in p || 'previews' in p || 'results' in p;\n const rawRenderKeys = ['preview_url', 'preview_html', 'interactive_url'];\n const rawRenderPresent = rawRenderKeys.filter(k => k in p);\n const driftSignal = rawRenderPresent.filter(k => k !== 'interactive_url');\n if (!hasValidWrapper && driftSignal.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'raw_render_fields',\n expected_variant: \"{ response_type: 'single', previews: [{ renders: [...] }], expires_at }\",\n instance_path: '',\n message:\n `preview_creative returned raw render fields at the top level (${driftSignal.join(', ')}). ` +\n `Required: { response_type: 'single', previews: [{ renders: [{ preview_url | preview_html }] }], expires_at }. ` +\n `Use previewCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/shape-drift-hints.ts"],"sourcesContent":["/**\n * Structured shape-drift hint detection (issue #935).\n *\n * The runner emits one `ShapeDriftHint` per response when it recognizes a\n * common payload-shape mistake — bare arrays from list tools, platform-\n * native fields from `build_creative`, missing wrappers on `sync_creatives`\n * / `preview_creative`. Each hint carries the same prose the legacy\n * `detectShapeDriftHint` returned, plus structured fields (`tool`,\n * `observed_variant`, `expected_variant`, `instance_path`) so renderers\n * (CLI, Addie, JUnit, SARIF) can build per-case fix plans without re-\n * parsing the message.\n *\n * The string-only `detectShapeDriftHint` in `validations.ts` is a thin\n * shim over this detector — kept so existing unit tests and external\n * callers keep working, but the canonical path is structured.\n *\n * Fires unconditionally (regardless of step pass/fail) — same gate as\n * `ValidationResult.warning` carried previously. The caller (`runner.ts`)\n * merges the result into `StoryboardStepResult.hints[]`.\n */\nimport type { ShapeDriftHint } from './types';\n\n/**\n * Minimum @adcp/client version in which each server-side helper first shipped.\n * Used to suffix shape-drift hints when the agent reports an older SDK version.\n * Keys match the helper name referenced in the hint `message`.\n */\nconst HELPER_MIN_VERSION: Record<string, string> = {\n buildCreativeResponse: '5.14.0',\n listCreativesResponse: '5.10.0',\n listCreativeFormatsResponse: '5.10.0',\n listAccountsResponse: '5.10.0',\n productsResponse: '5.10.0',\n getMediaBuysResponse: '5.10.0',\n getSignalsResponse: '5.10.0',\n listPropertyListsResponse: '5.10.0',\n listCollectionListsResponse: '5.10.0',\n listContentStandardsResponse: '5.10.0',\n getPlanAuditLogsResponse: '5.10.0',\n syncCreativesResponse: '5.10.0',\n previewCreativeResponse: '5.10.0',\n};\n\n/**\n * Compare two semver strings using numeric segment ordering.\n * Returns true when `a` is strictly less than `b`.\n * Handles `@adcp/client@X.Y.Z` format by stripping the package prefix.\n */\nfunction semverLessThan(a: string, b: string): boolean {\n // Strip package prefix (e.g. \"@adcp/client@\") and pre-release suffix (e.g. \"-beta.1\")\n const normalize = (v: string) => v.replace(/^.*@/, '').replace(/-.*$/, '');\n const segs = (v: string) =>\n normalize(v)\n .split('.')\n .map(s => parseInt(s, 10) || 0);\n const [aMaj = 0, aMin = 0, aPatch = 0] = segs(a);\n const [bMaj = 0, bMin = 0, bPatch = 0] = segs(b);\n if (aMaj !== bMaj) return aMaj < bMaj;\n if (aMin !== bMin) return aMin < bMin;\n return aPatch < bPatch;\n}\n\n/**\n * List-shaped tools where handlers commonly return the bare inner array\n * (`[{...}]`) at the top level instead of wrapping it in the required\n * object envelope. Each entry names the wrapper key and the response\n * helper that builds the correct shape.\n *\n * Helper names aren't uniformly prefixed — `get_products` uses\n * `productsResponse` (no `get` prefix) while `get_media_buys` uses\n * `getMediaBuysResponse`. Names match the exports in\n * `src/lib/server/responses.ts` verbatim so a developer can grep\n * straight from the hint.\n */\nexport const LIST_WRAPPER_TOOLS: Record<string, { wrapperKey: string; helper: string }> = {\n list_creatives: { wrapperKey: 'creatives', helper: 'listCreativesResponse' },\n list_creative_formats: { wrapperKey: 'formats', helper: 'listCreativeFormatsResponse' },\n list_accounts: { wrapperKey: 'accounts', helper: 'listAccountsResponse' },\n get_products: { wrapperKey: 'products', helper: 'productsResponse' },\n get_media_buys: { wrapperKey: 'media_buys', helper: 'getMediaBuysResponse' },\n get_signals: { wrapperKey: 'signals', helper: 'getSignalsResponse' },\n list_property_lists: { wrapperKey: 'lists', helper: 'listPropertyListsResponse' },\n list_collection_lists: { wrapperKey: 'lists', helper: 'listCollectionListsResponse' },\n list_content_standards: { wrapperKey: 'standards', helper: 'listContentStandardsResponse' },\n get_plan_audit_logs: { wrapperKey: 'plans', helper: 'getPlanAuditLogsResponse' },\n};\n\n/**\n * Detect shape-drift and return the structured hints that apply (zero or\n * one — the detector emits at most one hint per response, but returns an\n * array so callers can spread it into `step.hints[]` without a guard).\n *\n * @param taskName — tool name (snake_case) the storyboard dispatched under\n * @param payload — raw response payload, after the runner's `_message`\n * pre-strip. `unknown` rather than `Record<string, unknown>` so bare-\n * array payloads are recognizable at the top level; object branches\n * guard internally.\n * @param libraryVersion — optional SDK version string the agent self-reported\n * in `get_adcp_capabilities` (e.g. `\"@adcp/client@4.16.2\"`). When present\n * and below the helper's minimum version, the hint message is suffixed with\n * an upgrade note so developers know to update their SDK dep.\n */\nexport function detectShapeDriftHints(taskName: string, payload: unknown, libraryVersion?: string): ShapeDriftHint[] {\n const hint = detect(taskName, payload);\n if (!hint) return [];\n if (libraryVersion) hint.message = appendVersionSuffix(hint.message, libraryVersion);\n return [hint];\n}\n\n/**\n * If the hint message references a helper that requires a minimum SDK\n * version and the agent's reported version is below it, append an upgrade\n * note to the message. Returns the message unchanged if no version data or\n * no match.\n */\nfunction appendVersionSuffix(message: string, libraryVersion: string): string {\n // Skip non-numeric version strings (e.g. \"local-dev\") to avoid spurious suffixes\n const stripped = libraryVersion.replace(/^.*@/, '').replace(/-.*$/, '');\n if (!/^\\d+\\.\\d+/.test(stripped)) return message;\n for (const [helper, minVersion] of Object.entries(HELPER_MIN_VERSION)) {\n if (message.includes(helper) && semverLessThan(libraryVersion, minVersion)) {\n return (\n message +\n ` (Note: your agent reports ${libraryVersion} — ${helper}() ships in @adcp/client ≥${minVersion}. Upgrade your SDK dep.)`\n );\n }\n }\n return message;\n}\n\nfunction detect(taskName: string, payload: unknown): ShapeDriftHint | undefined {\n if (Array.isArray(payload)) {\n const listMeta = LIST_WRAPPER_TOOLS[taskName];\n if (!listMeta) return undefined;\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'bare_array',\n expected_variant: `{ ${listMeta.wrapperKey}: [...] }`,\n instance_path: '',\n message:\n `${taskName} returned a bare array at the top level. ` +\n `Required: { ${listMeta.wrapperKey}: [...] }. ` +\n `Use ${listMeta.helper}() from @adcp/sdk/server.`,\n };\n }\n\n if (typeof payload !== 'object' || payload === null) return undefined;\n const p = payload as Record<string, unknown>;\n\n if (taskName === 'build_creative') {\n const hasManifest = 'creative_manifest' in p || 'creative_manifests' in p;\n const platformNativeKeys = ['tag_url', 'creative_id', 'media_type', 'tag_type'];\n const platformNativePresent = platformNativeKeys.filter(k => k in p);\n if (!hasManifest && platformNativePresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'platform_native_fields',\n expected_variant: '{ creative_manifest: { format_id, assets } }',\n instance_path: '',\n message:\n `build_creative returned platform-native fields at the top level (${platformNativePresent.join(', ')}). ` +\n `Required: { creative_manifest: { format_id, assets } }. ` +\n `Use buildCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n if (taskName === 'sync_creatives') {\n const hasValidWrapper = 'creatives' in p || 'errors' in p || 'task_id' in p;\n const perItemKeys = ['creative_id', 'platform_id', 'action'];\n const perItemPresent = perItemKeys.filter(k => k in p);\n if (!hasValidWrapper && perItemPresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'per_item_shape',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '',\n message:\n `sync_creatives returned a single creative's inner shape at the top level (${perItemPresent.join(', ')}). ` +\n `Required: { creatives: [{ creative_id, action, ... }] } (or { errors: [...] } / { status: 'submitted', task_id }). ` +\n `Use syncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n\n const results = p.results;\n if (!hasValidWrapper && Array.isArray(results) && results.length > 0) {\n const firstRow = results[0];\n const looksLikeCreativeRow =\n firstRow != null && typeof firstRow === 'object' && ('creative_id' in firstRow || 'action' in firstRow);\n if (looksLikeCreativeRow) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'wrong_wrapper_key',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '/results',\n message:\n `sync_creatives returned { results: [...] } instead of { creatives: [...] } — wrong wrapper key. ` +\n `Required: { creatives: [{ creative_id, action, ... }] }. ` +\n `Use syncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n }\n }\n\n if (taskName === 'preview_creative') {\n const hasValidWrapper = 'response_type' in p || 'previews' in p || 'results' in p;\n const rawRenderKeys = ['preview_url', 'preview_html', 'interactive_url'];\n const rawRenderPresent = rawRenderKeys.filter(k => k in p);\n const driftSignal = rawRenderPresent.filter(k => k !== 'interactive_url');\n if (!hasValidWrapper && driftSignal.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'raw_render_fields',\n expected_variant: \"{ response_type: 'single', previews: [{ renders: [...] }], expires_at }\",\n instance_path: '',\n message:\n `preview_creative returned raw render fields at the top level (${driftSignal.join(', ')}). ` +\n `Required: { response_type: 'single', previews: [{ renders: [{ preview_url | preview_html }] }], expires_at }. ` +\n `Use previewCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { readFile } from "node:fs/promises";
|
|
8
2
|
import { createPrivateKey, sign as nodeSign } from "node:crypto";
|
|
9
3
|
import {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/lib/testing/storyboard/signer-grader/grader.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { createPrivateKey, sign as nodeSign, type JsonWebKey } from 'node:crypto';\nimport {\n HttpsJwksResolver,\n InMemoryReplayStore,\n InMemoryRevocationStore,\n RequestSignatureError,\n signRequestAsync,\n verifyRequestSignature,\n type AdcpJsonWebKey,\n type AdcpSignAlg,\n type ContentDigestPolicy,\n type JwksResolver,\n type SigningProvider,\n} from '../../../signing';\nimport { ssrfSafeFetch } from '../../../net/ssrf-fetch';\nimport type { SignerGradeReport, SignerGradeStep } from './types';\n\nexport interface GradeSignerOptions {\n /** Agent URL of the signer being graded — used as `agent_url` in the report and as the host for the sample signed request. */\n agentUrl: string;\n /** `kid` the signer advertises in `Signature-Input`. Must match a JWK at the agent's `jwks_uri`. */\n kid: string;\n /** Algorithm the signer advertises. Must match `ALLOWED_ALGS` and the JWK's `alg`. */\n algorithm: AdcpSignAlg;\n /**\n * Local JWK file (must include the private scalar `d`). Pick this OR\n * `signerUrl` — the grader produces a `SigningProvider` from whichever\n * is set.\n */\n keyFilePath?: string;\n /**\n * HTTP signing-oracle endpoint for KMS-backed signers. The grader POSTs\n * `{ payload_b64, kid, alg }` and expects `{ signature_b64 }` back. The\n * payload is the canonical RFC 9421 signature base; the response is raw\n * wire-format signature bytes (Ed25519: 64-byte raw; ECDSA-P256:\n * 64-byte `r‖s` IEEE P1363, NOT DER).\n */\n signerUrl?: string;\n /** Optional `Authorization` header for the signer-url POSTs. */\n signerAuth?: string;\n /** JWKS endpoint to verify against. Required (no brand.json discovery in v1). */\n jwksUrl: string;\n /** AdCP operation to embed in the sample request body. Defaults to `create_media_buy`. */\n operation?: string;\n /**\n * Content-digest policy the operator's verifier advertises. The grader\n * exercises the same policy locally so a signer that fails to emit\n * `Content-Digest` against a `'required'` policy surfaces here as\n * `request_signature_components_incomplete` (step 6) — the same code a\n * real counterparty would reject with. Defaults to `'required'`, which\n * is the recommended posture for spend-committing operations.\n */\n coversContentDigest?: ContentDigestPolicy;\n /** Allow http:// signer / JWKS URLs for development. Off by default. */\n allowPrivateIp?: boolean;\n /** Per-probe timeout. Defaults to 10000 ms. */\n timeoutMs?: number;\n}\n\n/**\n * Grade a signer end-to-end: produce a sample signed AdCP request through\n * the operator's signer, verify the signature against the JWKS the\n * operator publishes, report verifier-pipeline results step-by-step.\n *\n * Useful before pushing live signed traffic from a KMS-backed signer —\n * surfaces algorithm-mismatch / kid-mismatch / DER-vs-P1363 / wrong-key\n * failures as specific verifier error codes (the same codes a real\n * counterparty would reject with), rather than a generic\n * `request_signature_invalid` from the seller's monitoring.\n */\nexport async function gradeSigner(options: GradeSignerOptions): Promise<SignerGradeReport> {\n const start = Date.now();\n const operation = options.operation ?? 'create_media_buy';\n const coversContentDigest = options.coversContentDigest ?? 'required';\n const sampleUrl = new URL(`/adcp/${operation}`, options.agentUrl).toString();\n const sampleBody = JSON.stringify({ probe: 'adcp-signer-grade', operation });\n const sample = {\n method: 'POST',\n url: sampleUrl,\n body: sampleBody,\n headers: {} as Record<string, string>,\n };\n\n let provider: SigningProvider;\n try {\n provider = await buildProviderFromOptions(options);\n } catch (err) {\n return failReport(options, sample, start, {\n status: 'fail',\n error_code: 'signer_setup_failed',\n diagnostic: err instanceof Error ? err.message : String(err),\n });\n }\n\n // Sign a sample request with the user's signer. Wire format is the\n // verifier's only contact surface — if this step throws, the user's\n // signer raised before producing a signature (e.g., KMS auth failure,\n // network timeout). When `coversContentDigest === 'required'` the signer\n // must emit a `Content-Digest` header; the verifier then exercises step\n // 11 (digest recompute) end-to-end.\n let signed;\n try {\n signed = await signRequestAsync(\n { method: 'POST', url: sampleUrl, headers: { 'Content-Type': 'application/json' }, body: sampleBody },\n provider,\n // Cover Content-Digest unless the operator's policy is `'forbidden'`,\n // matching `resolveCoverContentDigest`'s posture at the agent layer.\n { coverContentDigest: coversContentDigest !== 'forbidden' }\n );\n } catch (err) {\n return failReport(options, sample, start, {\n status: 'fail',\n error_code: 'signer_invocation_failed',\n diagnostic: err instanceof Error ? err.message : String(err),\n });\n }\n sample.headers = signed.headers;\n\n // Verify against the user's JWKS. The verifier returns step + code on\n // failure; pass that straight through to the report so the operator\n // sees exactly which spec check rejected. The capability passed here is\n // the operator's (not a permissive default) so digest-policy\n // misconfigurations surface as step 6 rejections.\n const jwks = buildJwksResolver(options);\n const replayStore = new InMemoryReplayStore();\n const revocationStore = new InMemoryRevocationStore();\n const verifyRequest = {\n method: sample.method,\n url: sample.url,\n headers: signed.headers,\n body: sample.body,\n };\n\n let step: SignerGradeStep;\n try {\n const result = await verifyRequestSignature(verifyRequest, {\n capability: { supported: true, covers_content_digest: coversContentDigest, required_for: [operation] },\n jwks,\n replayStore,\n revocationStore,\n operation,\n });\n if (result.status !== 'verified') {\n // Defensive — `signRequestAsync` always emits `Signature` /\n // `Signature-Input` so a successful sign-then-verify can't reach\n // here. Throw rather than silently report a custom code so an SDK\n // bug that produces empty headers surfaces loudly.\n throw new Error(\n `gradeSigner internal: verifier returned status='${result.status}' on a freshly-signed request — likely SDK bug`\n );\n }\n step = { status: 'pass', diagnostic: 'Signature verified end-to-end against JWKS.' };\n } catch (err) {\n if (err instanceof RequestSignatureError) {\n step = {\n status: 'fail',\n error_code: err.code,\n diagnostic: buildVerifierDiagnostic(err, options.algorithm),\n };\n } else {\n step = {\n status: 'fail',\n error_code: 'verifier_threw_unexpected',\n diagnostic: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n return {\n agent_url: options.agentUrl,\n jwks_uri: options.jwksUrl,\n kid: options.kid,\n algorithm: options.algorithm,\n duration_ms: Date.now() - start,\n passed: step.status === 'pass',\n step,\n sample,\n };\n}\n\n/**\n * Layer a hint on top of the verifier's raw error message for the\n * common KMS-adapter misconfigurations operators hit. Today the only\n * one with a unique signature is DER-vs-P1363 for ECDSA — the verifier\n * surfaces it as the generic `request_signature_invalid` at step 10,\n * but the most likely cause is a KMS adapter that didn't run output\n * through `derEcdsaToP1363`. Surfacing this inline is cheap and saves\n * an operator a debugging cycle.\n */\nfunction buildVerifierDiagnostic(err: RequestSignatureError, algorithm: AdcpSignAlg): string {\n const base = `step ${err.failedStep}: ${err.message}`;\n if (err.code === 'request_signature_invalid' && algorithm === 'ecdsa-p256-sha256') {\n return (\n `${base}\\n Common cause: signing oracle returned a DER-encoded signature.` +\n ` AdCP / RFC 9421 §3.3.1 require raw r‖s (IEEE P1363, 64 bytes for P-256).` +\n ` See \\`derEcdsaToP1363\\` in @adcp/sdk/signing.`\n );\n }\n return base;\n}\n\nfunction failReport(\n options: GradeSignerOptions,\n sample: SignerGradeReport['sample'],\n start: number,\n step: SignerGradeStep\n): SignerGradeReport {\n return {\n agent_url: options.agentUrl,\n jwks_uri: options.jwksUrl,\n kid: options.kid,\n algorithm: options.algorithm,\n duration_ms: Date.now() - start,\n passed: false,\n step,\n sample,\n };\n}\n\nasync function buildProviderFromOptions(options: GradeSignerOptions): Promise<SigningProvider> {\n const hasKey = options.keyFilePath !== undefined;\n const hasUrl = options.signerUrl !== undefined;\n if (hasKey === hasUrl) {\n throw new Error('gradeSigner: pass exactly one of --key-file or --signer-url');\n }\n if (hasKey) {\n return await keyFileProvider(options.keyFilePath as string, options.kid, options.algorithm);\n }\n return httpOracleProvider({\n url: options.signerUrl as string,\n authorization: options.signerAuth,\n kid: options.kid,\n algorithm: options.algorithm,\n timeoutMs: options.timeoutMs ?? 10_000,\n allowPrivateIp: options.allowPrivateIp ?? false,\n });\n}\n\nasync function keyFileProvider(filePath: string, kid: string, algorithm: AdcpSignAlg): Promise<SigningProvider> {\n const raw = await readFile(filePath, 'utf8');\n let jwk: AdcpJsonWebKey;\n try {\n jwk = JSON.parse(raw);\n } catch {\n throw new Error(`gradeSigner: --key-file ${filePath} is not valid JSON`);\n }\n if (!jwk.d) {\n throw new Error(`gradeSigner: --key-file ${filePath} is missing the private scalar 'd'`);\n }\n // Build a minimal in-process SigningProvider directly. We can't use\n // InMemorySigningProvider here because its production-NODE_ENV gate\n // would refuse to construct in a CI environment running the grader.\n // The grader is dev / pre-deployment tooling; bypass the gate\n // intentionally with a clear note.\n return {\n keyid: kid,\n algorithm,\n fingerprint: `key-file:${kid}`,\n async sign(payload: Uint8Array): Promise<Uint8Array> {\n const privateKey = createPrivateKey({ key: jwk as JsonWebKey, format: 'jwk' });\n const data = Buffer.from(payload);\n if (algorithm === 'ed25519') {\n return new Uint8Array(nodeSign(null, data, privateKey));\n }\n return new Uint8Array(nodeSign('sha256', data, { key: privateKey, dsaEncoding: 'ieee-p1363' }));\n },\n };\n}\n\ninterface HttpOracleOptions {\n url: string;\n authorization?: string;\n kid: string;\n algorithm: AdcpSignAlg;\n timeoutMs: number;\n allowPrivateIp: boolean;\n}\n\n/**\n * SigningProvider that delegates `sign(payload)` to an HTTP signing\n * oracle. The oracle protocol is intentionally minimal — bytes in,\n * bytes out — so any KMS-backed signer can put it in front of\n * `provider.sign()` without exposing the underlying KMS to the grader.\n *\n * Wire contract:\n * POST <url>\n * Content-Type: application/json\n * Authorization: <signerAuth?> // optional shared-secret\n * Body: { \"payload_b64\": \"...\",\n * \"kid\": \"...\",\n * \"alg\": \"ed25519\" | \"ecdsa-p256-sha256\" }\n *\n * Response:\n * 200 OK\n * Content-Type: application/json\n * Body: { \"signature_b64\": \"...\" } // raw wire-format bytes\n */\nfunction httpOracleProvider(options: HttpOracleOptions): SigningProvider {\n return {\n keyid: options.kid,\n algorithm: options.algorithm,\n fingerprint: `oracle:${options.url}#${options.kid}`,\n async sign(payload: Uint8Array): Promise<Uint8Array> {\n // Route through `ssrfSafeFetch` so the oracle POST inherits DNS\n // pinning, IMDS-block, manual-redirect (a hostile or compromised\n // oracle URL can't 302 the `Authorization: Bearer ...` header to\n // an attacker-controlled host), and a 64 KiB body cap. Plain\n // `fetch()` would re-introduce the SSRF / redirect-leak surface\n // every other counterparty-influenced URL in the SDK already\n // guards against.\n const headers: Record<string, string> = { 'content-type': 'application/json' };\n if (options.authorization) headers.authorization = options.authorization;\n const reqBody = JSON.stringify({\n payload_b64: Buffer.from(payload).toString('base64'),\n kid: options.kid,\n alg: options.algorithm,\n });\n const response = await ssrfSafeFetch(options.url, {\n method: 'POST',\n headers,\n body: reqBody,\n timeoutMs: options.timeoutMs,\n allowPrivateIp: options.allowPrivateIp,\n });\n if (response.status < 200 || response.status >= 300) {\n throw new Error(\n `signing oracle ${options.url} responded ${response.status} (manual-redirect; not following 3xx)`\n );\n }\n let parsed: { signature_b64?: unknown };\n try {\n parsed = JSON.parse(Buffer.from(response.body).toString('utf8'));\n } catch (err) {\n throw new Error(\n `signing oracle response was not valid JSON: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n if (typeof parsed.signature_b64 !== 'string') {\n throw new Error(`signing oracle response missing 'signature_b64' string field`);\n }\n return new Uint8Array(Buffer.from(parsed.signature_b64, 'base64'));\n },\n };\n}\n\nfunction buildJwksResolver(options: GradeSignerOptions): JwksResolver {\n return new HttpsJwksResolver(options.jwksUrl, {\n allowPrivateIp: options.allowPrivateIp ?? false,\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/testing/storyboard/signer-grader/grader.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { createPrivateKey, sign as nodeSign, type JsonWebKey } from 'node:crypto';\nimport {\n HttpsJwksResolver,\n InMemoryReplayStore,\n InMemoryRevocationStore,\n RequestSignatureError,\n signRequestAsync,\n verifyRequestSignature,\n type AdcpJsonWebKey,\n type AdcpSignAlg,\n type ContentDigestPolicy,\n type JwksResolver,\n type SigningProvider,\n} from '../../../signing';\nimport { ssrfSafeFetch } from '../../../net/ssrf-fetch';\nimport type { SignerGradeReport, SignerGradeStep } from './types';\n\nexport interface GradeSignerOptions {\n /** Agent URL of the signer being graded — used as `agent_url` in the report and as the host for the sample signed request. */\n agentUrl: string;\n /** `kid` the signer advertises in `Signature-Input`. Must match a JWK at the agent's `jwks_uri`. */\n kid: string;\n /** Algorithm the signer advertises. Must match `ALLOWED_ALGS` and the JWK's `alg`. */\n algorithm: AdcpSignAlg;\n /**\n * Local JWK file (must include the private scalar `d`). Pick this OR\n * `signerUrl` — the grader produces a `SigningProvider` from whichever\n * is set.\n */\n keyFilePath?: string;\n /**\n * HTTP signing-oracle endpoint for KMS-backed signers. The grader POSTs\n * `{ payload_b64, kid, alg }` and expects `{ signature_b64 }` back. The\n * payload is the canonical RFC 9421 signature base; the response is raw\n * wire-format signature bytes (Ed25519: 64-byte raw; ECDSA-P256:\n * 64-byte `r‖s` IEEE P1363, NOT DER).\n */\n signerUrl?: string;\n /** Optional `Authorization` header for the signer-url POSTs. */\n signerAuth?: string;\n /** JWKS endpoint to verify against. Required (no brand.json discovery in v1). */\n jwksUrl: string;\n /** AdCP operation to embed in the sample request body. Defaults to `create_media_buy`. */\n operation?: string;\n /**\n * Content-digest policy the operator's verifier advertises. The grader\n * exercises the same policy locally so a signer that fails to emit\n * `Content-Digest` against a `'required'` policy surfaces here as\n * `request_signature_components_incomplete` (step 6) — the same code a\n * real counterparty would reject with. Defaults to `'required'`, which\n * is the recommended posture for spend-committing operations.\n */\n coversContentDigest?: ContentDigestPolicy;\n /** Allow http:// signer / JWKS URLs for development. Off by default. */\n allowPrivateIp?: boolean;\n /** Per-probe timeout. Defaults to 10000 ms. */\n timeoutMs?: number;\n}\n\n/**\n * Grade a signer end-to-end: produce a sample signed AdCP request through\n * the operator's signer, verify the signature against the JWKS the\n * operator publishes, report verifier-pipeline results step-by-step.\n *\n * Useful before pushing live signed traffic from a KMS-backed signer —\n * surfaces algorithm-mismatch / kid-mismatch / DER-vs-P1363 / wrong-key\n * failures as specific verifier error codes (the same codes a real\n * counterparty would reject with), rather than a generic\n * `request_signature_invalid` from the seller's monitoring.\n */\nexport async function gradeSigner(options: GradeSignerOptions): Promise<SignerGradeReport> {\n const start = Date.now();\n const operation = options.operation ?? 'create_media_buy';\n const coversContentDigest = options.coversContentDigest ?? 'required';\n const sampleUrl = new URL(`/adcp/${operation}`, options.agentUrl).toString();\n const sampleBody = JSON.stringify({ probe: 'adcp-signer-grade', operation });\n const sample = {\n method: 'POST',\n url: sampleUrl,\n body: sampleBody,\n headers: {} as Record<string, string>,\n };\n\n let provider: SigningProvider;\n try {\n provider = await buildProviderFromOptions(options);\n } catch (err) {\n return failReport(options, sample, start, {\n status: 'fail',\n error_code: 'signer_setup_failed',\n diagnostic: err instanceof Error ? err.message : String(err),\n });\n }\n\n // Sign a sample request with the user's signer. Wire format is the\n // verifier's only contact surface — if this step throws, the user's\n // signer raised before producing a signature (e.g., KMS auth failure,\n // network timeout). When `coversContentDigest === 'required'` the signer\n // must emit a `Content-Digest` header; the verifier then exercises step\n // 11 (digest recompute) end-to-end.\n let signed;\n try {\n signed = await signRequestAsync(\n { method: 'POST', url: sampleUrl, headers: { 'Content-Type': 'application/json' }, body: sampleBody },\n provider,\n // Cover Content-Digest unless the operator's policy is `'forbidden'`,\n // matching `resolveCoverContentDigest`'s posture at the agent layer.\n { coverContentDigest: coversContentDigest !== 'forbidden' }\n );\n } catch (err) {\n return failReport(options, sample, start, {\n status: 'fail',\n error_code: 'signer_invocation_failed',\n diagnostic: err instanceof Error ? err.message : String(err),\n });\n }\n sample.headers = signed.headers;\n\n // Verify against the user's JWKS. The verifier returns step + code on\n // failure; pass that straight through to the report so the operator\n // sees exactly which spec check rejected. The capability passed here is\n // the operator's (not a permissive default) so digest-policy\n // misconfigurations surface as step 6 rejections.\n const jwks = buildJwksResolver(options);\n const replayStore = new InMemoryReplayStore();\n const revocationStore = new InMemoryRevocationStore();\n const verifyRequest = {\n method: sample.method,\n url: sample.url,\n headers: signed.headers,\n body: sample.body,\n };\n\n let step: SignerGradeStep;\n try {\n const result = await verifyRequestSignature(verifyRequest, {\n capability: { supported: true, covers_content_digest: coversContentDigest, required_for: [operation] },\n jwks,\n replayStore,\n revocationStore,\n operation,\n });\n if (result.status !== 'verified') {\n // Defensive — `signRequestAsync` always emits `Signature` /\n // `Signature-Input` so a successful sign-then-verify can't reach\n // here. Throw rather than silently report a custom code so an SDK\n // bug that produces empty headers surfaces loudly.\n throw new Error(\n `gradeSigner internal: verifier returned status='${result.status}' on a freshly-signed request — likely SDK bug`\n );\n }\n step = { status: 'pass', diagnostic: 'Signature verified end-to-end against JWKS.' };\n } catch (err) {\n if (err instanceof RequestSignatureError) {\n step = {\n status: 'fail',\n error_code: err.code,\n diagnostic: buildVerifierDiagnostic(err, options.algorithm),\n };\n } else {\n step = {\n status: 'fail',\n error_code: 'verifier_threw_unexpected',\n diagnostic: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n return {\n agent_url: options.agentUrl,\n jwks_uri: options.jwksUrl,\n kid: options.kid,\n algorithm: options.algorithm,\n duration_ms: Date.now() - start,\n passed: step.status === 'pass',\n step,\n sample,\n };\n}\n\n/**\n * Layer a hint on top of the verifier's raw error message for the\n * common KMS-adapter misconfigurations operators hit. Today the only\n * one with a unique signature is DER-vs-P1363 for ECDSA — the verifier\n * surfaces it as the generic `request_signature_invalid` at step 10,\n * but the most likely cause is a KMS adapter that didn't run output\n * through `derEcdsaToP1363`. Surfacing this inline is cheap and saves\n * an operator a debugging cycle.\n */\nfunction buildVerifierDiagnostic(err: RequestSignatureError, algorithm: AdcpSignAlg): string {\n const base = `step ${err.failedStep}: ${err.message}`;\n if (err.code === 'request_signature_invalid' && algorithm === 'ecdsa-p256-sha256') {\n return (\n `${base}\\n Common cause: signing oracle returned a DER-encoded signature.` +\n ` AdCP / RFC 9421 §3.3.1 require raw r‖s (IEEE P1363, 64 bytes for P-256).` +\n ` See \\`derEcdsaToP1363\\` in @adcp/sdk/signing.`\n );\n }\n return base;\n}\n\nfunction failReport(\n options: GradeSignerOptions,\n sample: SignerGradeReport['sample'],\n start: number,\n step: SignerGradeStep\n): SignerGradeReport {\n return {\n agent_url: options.agentUrl,\n jwks_uri: options.jwksUrl,\n kid: options.kid,\n algorithm: options.algorithm,\n duration_ms: Date.now() - start,\n passed: false,\n step,\n sample,\n };\n}\n\nasync function buildProviderFromOptions(options: GradeSignerOptions): Promise<SigningProvider> {\n const hasKey = options.keyFilePath !== undefined;\n const hasUrl = options.signerUrl !== undefined;\n if (hasKey === hasUrl) {\n throw new Error('gradeSigner: pass exactly one of --key-file or --signer-url');\n }\n if (hasKey) {\n return await keyFileProvider(options.keyFilePath as string, options.kid, options.algorithm);\n }\n return httpOracleProvider({\n url: options.signerUrl as string,\n authorization: options.signerAuth,\n kid: options.kid,\n algorithm: options.algorithm,\n timeoutMs: options.timeoutMs ?? 10_000,\n allowPrivateIp: options.allowPrivateIp ?? false,\n });\n}\n\nasync function keyFileProvider(filePath: string, kid: string, algorithm: AdcpSignAlg): Promise<SigningProvider> {\n const raw = await readFile(filePath, 'utf8');\n let jwk: AdcpJsonWebKey;\n try {\n jwk = JSON.parse(raw);\n } catch {\n throw new Error(`gradeSigner: --key-file ${filePath} is not valid JSON`);\n }\n if (!jwk.d) {\n throw new Error(`gradeSigner: --key-file ${filePath} is missing the private scalar 'd'`);\n }\n // Build a minimal in-process SigningProvider directly. We can't use\n // InMemorySigningProvider here because its production-NODE_ENV gate\n // would refuse to construct in a CI environment running the grader.\n // The grader is dev / pre-deployment tooling; bypass the gate\n // intentionally with a clear note.\n return {\n keyid: kid,\n algorithm,\n fingerprint: `key-file:${kid}`,\n async sign(payload: Uint8Array): Promise<Uint8Array> {\n const privateKey = createPrivateKey({ key: jwk as JsonWebKey, format: 'jwk' });\n const data = Buffer.from(payload);\n if (algorithm === 'ed25519') {\n return new Uint8Array(nodeSign(null, data, privateKey));\n }\n return new Uint8Array(nodeSign('sha256', data, { key: privateKey, dsaEncoding: 'ieee-p1363' }));\n },\n };\n}\n\ninterface HttpOracleOptions {\n url: string;\n authorization?: string;\n kid: string;\n algorithm: AdcpSignAlg;\n timeoutMs: number;\n allowPrivateIp: boolean;\n}\n\n/**\n * SigningProvider that delegates `sign(payload)` to an HTTP signing\n * oracle. The oracle protocol is intentionally minimal — bytes in,\n * bytes out — so any KMS-backed signer can put it in front of\n * `provider.sign()` without exposing the underlying KMS to the grader.\n *\n * Wire contract:\n * POST <url>\n * Content-Type: application/json\n * Authorization: <signerAuth?> // optional shared-secret\n * Body: { \"payload_b64\": \"...\",\n * \"kid\": \"...\",\n * \"alg\": \"ed25519\" | \"ecdsa-p256-sha256\" }\n *\n * Response:\n * 200 OK\n * Content-Type: application/json\n * Body: { \"signature_b64\": \"...\" } // raw wire-format bytes\n */\nfunction httpOracleProvider(options: HttpOracleOptions): SigningProvider {\n return {\n keyid: options.kid,\n algorithm: options.algorithm,\n fingerprint: `oracle:${options.url}#${options.kid}`,\n async sign(payload: Uint8Array): Promise<Uint8Array> {\n // Route through `ssrfSafeFetch` so the oracle POST inherits DNS\n // pinning, IMDS-block, manual-redirect (a hostile or compromised\n // oracle URL can't 302 the `Authorization: Bearer ...` header to\n // an attacker-controlled host), and a 64 KiB body cap. Plain\n // `fetch()` would re-introduce the SSRF / redirect-leak surface\n // every other counterparty-influenced URL in the SDK already\n // guards against.\n const headers: Record<string, string> = { 'content-type': 'application/json' };\n if (options.authorization) headers.authorization = options.authorization;\n const reqBody = JSON.stringify({\n payload_b64: Buffer.from(payload).toString('base64'),\n kid: options.kid,\n alg: options.algorithm,\n });\n const response = await ssrfSafeFetch(options.url, {\n method: 'POST',\n headers,\n body: reqBody,\n timeoutMs: options.timeoutMs,\n allowPrivateIp: options.allowPrivateIp,\n });\n if (response.status < 200 || response.status >= 300) {\n throw new Error(\n `signing oracle ${options.url} responded ${response.status} (manual-redirect; not following 3xx)`\n );\n }\n let parsed: { signature_b64?: unknown };\n try {\n parsed = JSON.parse(Buffer.from(response.body).toString('utf8'));\n } catch (err) {\n throw new Error(\n `signing oracle response was not valid JSON: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n if (typeof parsed.signature_b64 !== 'string') {\n throw new Error(`signing oracle response missing 'signature_b64' string field`);\n }\n return new Uint8Array(Buffer.from(parsed.signature_b64, 'base64'));\n },\n };\n}\n\nfunction buildJwksResolver(options: GradeSignerOptions): JwksResolver {\n return new HttpsJwksResolver(options.jwksUrl, {\n allowPrivateIp: options.allowPrivateIp ?? false,\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { gradeSigner } from "./grader.mjs";
|
|
8
2
|
export {
|
|
9
3
|
gradeSigner
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/lib/testing/storyboard/signer-grader/index.ts"],"sourcesContent":["export { gradeSigner, type GradeSignerOptions } from './grader';\nexport type { SignerGradeErrorCode, SignerGradeReport, SignerGradeStep, SignerGraderErrorCode } from './types';\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/testing/storyboard/signer-grader/index.ts"],"sourcesContent":["export { gradeSigner, type GradeSignerOptions } from './grader';\nexport type { SignerGradeErrorCode, SignerGradeReport, SignerGradeStep, SignerGraderErrorCode } from './types';\n"],"mappings":"AAAA,SAAS,mBAA4C;","names":[]}
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
//# sourceMappingURL=types.mjs.map
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
const MAX_FORMAT_HINTS = 5;
|
|
8
2
|
function detectStrictValidationHints(taskName, validations) {
|
|
9
3
|
const hints = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/strict-validation-hints.ts"],"sourcesContent":["/**\n * Structured hints derived from the strict (AJV) verdict attached to a\n * `response_schema` ValidationResult. Issue #935 moves the strict signal\n * from a prose-only `ValidationResult.warning` into per-issue structured\n * hints so renderers (CLI, Addie, JUnit) can build per-case fix plans.\n *\n * Two hint kinds are emitted:\n * - `MissingRequiredFieldHint` — one per parent path with one or more\n * missing required fields. AJV reports each missing field as its own\n * issue with `keyword: \"required\"`; we group them under the parent\n * instance_path so a seller filling out N required fields sees them\n * in one round.\n * - `FormatMismatchHint` — one per non-`required` strict issue\n * (`format`, `pattern`, `enum`, `minLength`, ...). Each carries the\n * pointer + keyword the renderer needs to write a verify recipe.\n *\n * The `ValidationResult.warning` prose stays populated for one minor for\n * back-compat with existing CLI / dashboard scrapers — see CHANGELOG.\n */\n\nimport type {\n FormatMismatchHint,\n MissingRequiredFieldHint,\n SchemaValidationError,\n StoryboardStepHint,\n ValidationResult,\n} from './types';\n\n/**\n * Per-validation cap on `format_mismatch` hints to keep `step.hints[]`\n * bounded on pathological responses (e.g. a list payload where every\n * `agent_url` field is malformed). When the cap trips, a sentinel\n * `format_mismatch` hint is appended so the surface self-documents the\n * truncation — operators see the elision rather than silently losing\n * context. The total `failed` count remains visible via\n * `StoryboardResult.strict_validation_summary`.\n */\nconst MAX_FORMAT_HINTS = 5;\n\n/**\n * Emit structured hints for every strict-AJV finding on a step's\n * validations. Walks each `response_schema` validation that carried a\n * `strict` verdict, partitions issues into required-keyword vs other,\n * and returns the structured hints ready to drop into `step.hints[]`.\n */\nexport function detectStrictValidationHints(\n taskName: string,\n validations: readonly ValidationResult[]\n): StoryboardStepHint[] {\n const hints: StoryboardStepHint[] = [];\n for (const v of validations) {\n if (v.check !== 'response_schema') continue;\n const strict = v.strict;\n if (!strict || strict.valid !== false) continue;\n const issues = strict.issues;\n if (!issues || issues.length === 0) continue;\n const required = issues.filter(i => i.keyword === 'required');\n const others = issues.filter(i => i.keyword !== 'required');\n\n for (const grouped of groupRequiredIssues(taskName, required, v.schema_url ?? undefined)) {\n hints.push(grouped);\n }\n const shown = others.slice(0, MAX_FORMAT_HINTS);\n const elided = others.length - shown.length;\n for (const issue of shown) {\n hints.push(formatHintFromIssue(taskName, issue, v.schema_url ?? undefined));\n }\n if (elided > 0) {\n // Sentinel hint surfaces the cap so consumers don't silently lose\n // signal. `keyword: 'truncated'` is a runner-internal pseudo-keyword\n // (no AJV equivalent); renderers branching on it can flag the\n // strict_validation_summary as the authoritative count.\n hints.push({\n kind: 'format_mismatch',\n tool: taskName,\n instance_path: '',\n schema_path: '',\n keyword: 'truncated',\n ...(v.schema_url ? { schema_url: v.schema_url } : {}),\n message: `${taskName} produced ${elided} additional strict issue${elided === 1 ? '' : 's'} not shown — see strict_validation_summary on the run result for the full count.`,\n });\n }\n }\n return hints;\n}\n\nfunction groupRequiredIssues(\n taskName: string,\n issues: SchemaValidationError[],\n schemaUrl: string | undefined\n): MissingRequiredFieldHint[] {\n const grouped = new Map<string, { schema_path: string; fields: string[] }>();\n for (const issue of issues) {\n const at = issue.instance_path || '';\n const match = issue.message.match(/required property ['\"]([^'\"]+)['\"]/);\n // When the regex doesn't match (e.g. compound AJV messages), skip rather\n // than falling back to raw AJV prose — missing_fields must contain only\n // clean field identifiers per its documented contract.\n if (!match) continue;\n const field = match[1];\n // TypeScript noUncheckedIndexedAccess types `match[1]` as `string |\n // undefined` even though a successful regex match with one capture\n // group always has it. Narrow defensively rather than assert.\n if (field === undefined) continue;\n const entry = grouped.get(at);\n if (entry) {\n entry.fields.push(field);\n } else {\n grouped.set(at, { schema_path: issue.schema_path, fields: [field] });\n }\n }\n const out: MissingRequiredFieldHint[] = [];\n for (const [at, { schema_path, fields }] of grouped) {\n out.push({\n kind: 'missing_required_field',\n tool: taskName,\n instance_path: at,\n schema_path,\n missing_fields: fields,\n ...(schemaUrl !== undefined ? { schema_url: schemaUrl } : {}),\n message: `${taskName} response missing required field${fields.length > 1 ? 's' : ''} at ${at || '/'}: ${fields.join(', ')}.`,\n });\n }\n return out;\n}\n\nfunction formatHintFromIssue(\n taskName: string,\n issue: SchemaValidationError,\n schemaUrl: string | undefined\n): FormatMismatchHint {\n const at = issue.instance_path || '/';\n return {\n kind: 'format_mismatch',\n tool: taskName,\n instance_path: issue.instance_path,\n schema_path: issue.schema_path,\n keyword: issue.keyword,\n ...(schemaUrl !== undefined ? { schema_url: schemaUrl } : {}),\n message: `${taskName} response failed strict ${issue.keyword} at ${at}: ${issue.message}`,\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/strict-validation-hints.ts"],"sourcesContent":["/**\n * Structured hints derived from the strict (AJV) verdict attached to a\n * `response_schema` ValidationResult. Issue #935 moves the strict signal\n * from a prose-only `ValidationResult.warning` into per-issue structured\n * hints so renderers (CLI, Addie, JUnit) can build per-case fix plans.\n *\n * Two hint kinds are emitted:\n * - `MissingRequiredFieldHint` — one per parent path with one or more\n * missing required fields. AJV reports each missing field as its own\n * issue with `keyword: \"required\"`; we group them under the parent\n * instance_path so a seller filling out N required fields sees them\n * in one round.\n * - `FormatMismatchHint` — one per non-`required` strict issue\n * (`format`, `pattern`, `enum`, `minLength`, ...). Each carries the\n * pointer + keyword the renderer needs to write a verify recipe.\n *\n * The `ValidationResult.warning` prose stays populated for one minor for\n * back-compat with existing CLI / dashboard scrapers — see CHANGELOG.\n */\n\nimport type {\n FormatMismatchHint,\n MissingRequiredFieldHint,\n SchemaValidationError,\n StoryboardStepHint,\n ValidationResult,\n} from './types';\n\n/**\n * Per-validation cap on `format_mismatch` hints to keep `step.hints[]`\n * bounded on pathological responses (e.g. a list payload where every\n * `agent_url` field is malformed). When the cap trips, a sentinel\n * `format_mismatch` hint is appended so the surface self-documents the\n * truncation — operators see the elision rather than silently losing\n * context. The total `failed` count remains visible via\n * `StoryboardResult.strict_validation_summary`.\n */\nconst MAX_FORMAT_HINTS = 5;\n\n/**\n * Emit structured hints for every strict-AJV finding on a step's\n * validations. Walks each `response_schema` validation that carried a\n * `strict` verdict, partitions issues into required-keyword vs other,\n * and returns the structured hints ready to drop into `step.hints[]`.\n */\nexport function detectStrictValidationHints(\n taskName: string,\n validations: readonly ValidationResult[]\n): StoryboardStepHint[] {\n const hints: StoryboardStepHint[] = [];\n for (const v of validations) {\n if (v.check !== 'response_schema') continue;\n const strict = v.strict;\n if (!strict || strict.valid !== false) continue;\n const issues = strict.issues;\n if (!issues || issues.length === 0) continue;\n const required = issues.filter(i => i.keyword === 'required');\n const others = issues.filter(i => i.keyword !== 'required');\n\n for (const grouped of groupRequiredIssues(taskName, required, v.schema_url ?? undefined)) {\n hints.push(grouped);\n }\n const shown = others.slice(0, MAX_FORMAT_HINTS);\n const elided = others.length - shown.length;\n for (const issue of shown) {\n hints.push(formatHintFromIssue(taskName, issue, v.schema_url ?? undefined));\n }\n if (elided > 0) {\n // Sentinel hint surfaces the cap so consumers don't silently lose\n // signal. `keyword: 'truncated'` is a runner-internal pseudo-keyword\n // (no AJV equivalent); renderers branching on it can flag the\n // strict_validation_summary as the authoritative count.\n hints.push({\n kind: 'format_mismatch',\n tool: taskName,\n instance_path: '',\n schema_path: '',\n keyword: 'truncated',\n ...(v.schema_url ? { schema_url: v.schema_url } : {}),\n message: `${taskName} produced ${elided} additional strict issue${elided === 1 ? '' : 's'} not shown — see strict_validation_summary on the run result for the full count.`,\n });\n }\n }\n return hints;\n}\n\nfunction groupRequiredIssues(\n taskName: string,\n issues: SchemaValidationError[],\n schemaUrl: string | undefined\n): MissingRequiredFieldHint[] {\n const grouped = new Map<string, { schema_path: string; fields: string[] }>();\n for (const issue of issues) {\n const at = issue.instance_path || '';\n const match = issue.message.match(/required property ['\"]([^'\"]+)['\"]/);\n // When the regex doesn't match (e.g. compound AJV messages), skip rather\n // than falling back to raw AJV prose — missing_fields must contain only\n // clean field identifiers per its documented contract.\n if (!match) continue;\n const field = match[1];\n // TypeScript noUncheckedIndexedAccess types `match[1]` as `string |\n // undefined` even though a successful regex match with one capture\n // group always has it. Narrow defensively rather than assert.\n if (field === undefined) continue;\n const entry = grouped.get(at);\n if (entry) {\n entry.fields.push(field);\n } else {\n grouped.set(at, { schema_path: issue.schema_path, fields: [field] });\n }\n }\n const out: MissingRequiredFieldHint[] = [];\n for (const [at, { schema_path, fields }] of grouped) {\n out.push({\n kind: 'missing_required_field',\n tool: taskName,\n instance_path: at,\n schema_path,\n missing_fields: fields,\n ...(schemaUrl !== undefined ? { schema_url: schemaUrl } : {}),\n message: `${taskName} response missing required field${fields.length > 1 ? 's' : ''} at ${at || '/'}: ${fields.join(', ')}.`,\n });\n }\n return out;\n}\n\nfunction formatHintFromIssue(\n taskName: string,\n issue: SchemaValidationError,\n schemaUrl: string | undefined\n): FormatMismatchHint {\n const at = issue.instance_path || '/';\n return {\n kind: 'format_mismatch',\n tool: taskName,\n instance_path: issue.instance_path,\n schema_path: issue.schema_path,\n keyword: issue.keyword,\n ...(schemaUrl !== undefined ? { schema_url: schemaUrl } : {}),\n message: `${taskName} response failed strict ${issue.keyword} at ${at}: ${issue.message}`,\n };\n}\n"],"mappings":"AAqCA,MAAM,mBAAmB;AAQlB,SAAS,4BACd,UACA,aACsB;AACtB,QAAM,QAA8B,CAAC;AACrC,aAAW,KAAK,aAAa;AAC3B,QAAI,EAAE,UAAU,kBAAmB;AACnC,UAAM,SAAS,EAAE;AACjB,QAAI,CAAC,UAAU,OAAO,UAAU,MAAO;AACvC,UAAM,SAAS,OAAO;AACtB,QAAI,CAAC,UAAU,OAAO,WAAW,EAAG;AACpC,UAAM,WAAW,OAAO,OAAO,OAAK,EAAE,YAAY,UAAU;AAC5D,UAAM,SAAS,OAAO,OAAO,OAAK,EAAE,YAAY,UAAU;AAE1D,eAAW,WAAW,oBAAoB,UAAU,UAAU,EAAE,cAAc,MAAS,GAAG;AACxF,YAAM,KAAK,OAAO;AAAA,IACpB;AACA,UAAM,QAAQ,OAAO,MAAM,GAAG,gBAAgB;AAC9C,UAAM,SAAS,OAAO,SAAS,MAAM;AACrC,eAAW,SAAS,OAAO;AACzB,YAAM,KAAK,oBAAoB,UAAU,OAAO,EAAE,cAAc,MAAS,CAAC;AAAA,IAC5E;AACA,QAAI,SAAS,GAAG;AAKd,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,eAAe;AAAA,QACf,aAAa;AAAA,QACb,SAAS;AAAA,QACT,GAAI,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,QACnD,SAAS,GAAG,QAAQ,aAAa,MAAM,2BAA2B,WAAW,IAAI,KAAK,GAAG;AAAA,MAC3F,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBACP,UACA,QACA,WAC4B;AAC5B,QAAM,UAAU,oBAAI,IAAuD;AAC3E,aAAW,SAAS,QAAQ;AAC1B,UAAM,KAAK,MAAM,iBAAiB;AAClC,UAAM,QAAQ,MAAM,QAAQ,MAAM,oCAAoC;AAItE,QAAI,CAAC,MAAO;AACZ,UAAM,QAAQ,MAAM,CAAC;AAIrB,QAAI,UAAU,OAAW;AACzB,UAAM,QAAQ,QAAQ,IAAI,EAAE;AAC5B,QAAI,OAAO;AACT,YAAM,OAAO,KAAK,KAAK;AAAA,IACzB,OAAO;AACL,cAAQ,IAAI,IAAI,EAAE,aAAa,MAAM,aAAa,QAAQ,CAAC,KAAK,EAAE,CAAC;AAAA,IACrE;AAAA,EACF;AACA,QAAM,MAAkC,CAAC;AACzC,aAAW,CAAC,IAAI,EAAE,aAAa,OAAO,CAAC,KAAK,SAAS;AACnD,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,eAAe;AAAA,MACf;AAAA,MACA,gBAAgB;AAAA,MAChB,GAAI,cAAc,SAAY,EAAE,YAAY,UAAU,IAAI,CAAC;AAAA,MAC3D,SAAS,GAAG,QAAQ,mCAAmC,OAAO,SAAS,IAAI,MAAM,EAAE,OAAO,MAAM,GAAG,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,IAC3H,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,oBACP,UACA,OACA,WACoB;AACpB,QAAM,KAAK,MAAM,iBAAiB;AAClC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,eAAe,MAAM;AAAA,IACrB,aAAa,MAAM;AAAA,IACnB,SAAS,MAAM;AAAA,IACf,GAAI,cAAc,SAAY,EAAE,YAAY,UAAU,IAAI,CAAC;AAAA,IAC3D,SAAS,GAAG,QAAQ,2BAA2B,MAAM,OAAO,OAAO,EAAE,KAAK,MAAM,OAAO;AAAA,EACzF;AACF;","names":[]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { isTerminalAdcpError, readExtractionPath } from "../../utils/response-unwrapper.mjs";
|
|
8
2
|
const TASK_TO_METHOD = {
|
|
9
3
|
// Account & audience
|