@usethrottle/mcp 0.2.0 → 0.2.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/README.md +9 -2
- package/dist/contract-index.json +1 -1
- package/dist/docs-index.json +1 -1
- package/dist/lib.cjs +1784 -153
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +58 -4
- package/dist/lib.d.ts +58 -4
- package/dist/lib.js +1784 -153
- package/dist/lib.js.map +1 -1
- package/dist/mcp.js +1784 -153
- package/dist/mcp.js.map +1 -1
- package/package.json +3 -3
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../../core-scopes/src/scopes.ts","../../core-scopes/src/events.ts","../../core-scopes/src/issuance.ts","../../action-catalog/src/actions.ts","../../action-catalog/src/triggers.ts","../../action-catalog/src/index.ts","../src/format.ts","../../errors/dist/index.js","../src/client.ts","../src/contract.ts","../src/docs.ts","../src/handlers.ts","../src/input.ts","../src/indexes.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { actionsForChannel, canRunAction, type ActionDefinition } from '@core/action-catalog';\nimport type { ThrottleClient } from './client';\nimport type { ContractIndex } from './contract';\nimport type { DocsIndex } from './docs';\nimport { formatError, formatResult } from './format';\nimport { HANDLERS, type HandlerContext, type Identity } from './handlers';\nimport { fieldsToZodShape } from './input';\n\n// Injected by tsup from package.json (see tsup.config.ts). Under vitest there is\n// no define step, so `typeof` guards the ReferenceError and tests read a dev\n// marker rather than a stale hard-coded number.\ndeclare const __THROTTLE_MCP_VERSION__: string | undefined;\nexport const VERSION =\n typeof __THROTTLE_MCP_VERSION__ === 'string' ? __THROTTLE_MCP_VERSION__ : '0.0.0-dev';\n\nexport interface RegistrationPolicy {\n identity: Identity;\n allowWrites: boolean;\n allowLiveWrites: boolean;\n}\n\n/**\n * Which tools this session gets. Pure and exported so the policy is testable\n * without standing up a transport.\n *\n * Four independent gates, in order of how expensive it is to get them wrong:\n *\n * 1. **Implemented.** `0.1.0` ships the read/sandbox half; the catalog describes\n * the money writes before this package implements them.\n * 2. **Scope.** Delegated to the catalog's `canRunAction`, which uses the API's own\n * `hasScope`. A tool the credential cannot execute is not registered at all,\n * rather than failing at call time — the model never sees an affordance it\n * cannot use.\n * 3. **Intent.** Holding a write scope means the credential *may* write; it does\n * not mean the operator intended this session to. That is `--allow-writes`.\n * 4. **Blast radius.** Against a production credential, writes need\n * `--allow-live-writes` on top. Sandbox-only actions invert the rule: they are\n * free in a non-production environment and forbidden in production regardless\n * of flags.\n */\nexport function registerableActions(policy: RegistrationPolicy): ActionDefinition[] {\n const isProduction = policy.identity.environment.providerEnvironment === 'production';\n return actionsForChannel('mcp').filter((action) => {\n if (!HANDLERS[action.id]) return false;\n if (!canRunAction(policy.identity.scopes, action)) return false;\n if (action.kind === 'read') return true;\n if (action.sandboxOnly) return !isProduction;\n if (!policy.allowWrites) return false;\n return !isProduction || policy.allowLiveWrites;\n });\n}\n\n/**\n * The server's `instructions`, which most clients put in front of the model before\n * it picks a tool. Leads with the environment because the single most damaging\n * mistake an agent can make here is not knowing whether it is looking at live data.\n */\nexport function buildInstructions(\n identity: Identity,\n actions: ActionDefinition[],\n policy: { allowWrites: boolean; allowLiveWrites: boolean },\n): string {\n const isProduction = identity.environment.providerEnvironment === 'production';\n const where = [\n identity.workspace?.name ?? identity.workspace?.slug ?? 'unknown workspace',\n identity.application?.name ?? identity.application?.slug ?? null,\n ]\n .filter(Boolean)\n .join(' / ');\n\n // Sandbox seeding is a write, but announcing it as \"irreversible and\n // buyer-visible\" would teach the model to be cautious about the one tool that is\n // free — and, worse, imply this session can move money when it cannot.\n const liveWrites = actions.filter((a) => a.kind === 'write' && !a.sandboxOnly);\n const sandboxWrites = actions.filter((a) => a.kind === 'write' && a.sandboxOnly);\n const lines = [\n `Throttle MCP ${VERSION}. Connected to ${where}, environment \"${identity.environment.slug}\" (${\n isProduction ? 'PRODUCTION — live data' : 'non-production — not live data'\n }).`,\n '',\n 'Conventions:',\n '- Every tool is scoped to this one workspace/application/environment; there is no way to switch from inside a tool call. Call whoami if you need to state where you are.',\n '- List tools return { data, pagination }. When pagination.hasMore is true, pass pagination.cursor back as \"cursor\" rather than raising \"limit\".',\n '- Amounts are integer minor units (2500 = $25.00).',\n '- Throttle rejects snake_case on public request bodies. Before writing integration code, confirm shapes with describe_endpoint and check bodies with validate_payload instead of guessing field names.',\n '- API errors come back as text with a stable code. On insufficient_scopes, tell the user which scope to add — do not retry.',\n ];\n\n if (liveWrites.length === 0) {\n lines.push(\n `- This session is READ-ONLY for real data${\n policy.allowWrites\n ? ' (no write tools are available to this credential)'\n : ' — writes were not enabled'\n }. Say so plainly if asked to change something.`,\n );\n if (sandboxWrites.length > 0) {\n lines.push(\n `- ${sandboxWrites\n .map((a) => a.id)\n .join(', ')} may create data, but only in this non-production environment.`,\n );\n }\n } else {\n lines.push(\n `- Write tools are enabled (${liveWrites\n .map((a) => a.id)\n .join(', ')}). They are irreversible and some are buyer-visible. Confirm with the user before calling one.`,\n );\n }\n return lines.join('\\n');\n}\n\nexport interface CreateServerOptions extends RegistrationPolicy {\n client: ThrottleClient;\n contract: ContractIndex;\n docs: DocsIndex;\n}\n\nexport function createServer(options: CreateServerOptions): McpServer {\n const actions = registerableActions(options);\n const server = new McpServer(\n { name: 'throttle', version: VERSION },\n { instructions: buildInstructions(options.identity, actions, options) },\n );\n\n const ctx: HandlerContext = {\n client: options.client,\n identity: options.identity,\n contract: options.contract,\n docs: options.docs,\n };\n\n for (const action of actions) {\n const handler = HANDLERS[action.id]!;\n server.tool(\n action.id,\n describeForModel(action),\n fieldsToZodShape(action.input),\n async (args: Record<string, unknown>) => {\n try {\n const result = await handler(ctx, args ?? {});\n return { content: [{ type: 'text' as const, text: formatResult(result) }] };\n } catch (error) {\n return {\n content: [{ type: 'text' as const, text: formatError(error) }],\n isError: true,\n };\n }\n },\n );\n }\n\n return server;\n}\n\n/** Guardrails ride along in the description so they reach the model, not just the reviewer. */\nfunction describeForModel(action: ActionDefinition): string {\n const parts = [action.description];\n if (action.guardrails && action.guardrails.length > 0) {\n parts.push(`Constraints: ${action.guardrails.join(' ')}`);\n }\n return parts.join(' ');\n}\n","/** True when the granted scope set covers the required scope.\n * Rules: '*' covers all; exact match; write→read on the same resource;\n * NO cross-resource implication. */\nexport function hasScope(granted: readonly string[], required: string): boolean {\n if (granted.includes('*')) return true;\n if (granted.includes(required)) return true;\n const sep = required.lastIndexOf(':');\n if (sep === -1) return false;\n const resource = required.slice(0, sep);\n const action = required.slice(sep + 1);\n if (action === 'read' && granted.includes(`${resource}:write`)) return true;\n return false;\n}\n\nexport interface ScopeDef {\n id: string;\n resource: string;\n action: 'read' | 'write' | 'install';\n group: string;\n label: string;\n sensitive: boolean;\n staffOnly: boolean;\n publishableAllowed: boolean;\n extensionAllowed: boolean;\n implies: string[];\n}\n\ntype Opts = {\n sensitive?: boolean;\n staffOnly?: boolean;\n publishableAllowed?: boolean;\n extensionAllowed?: boolean;\n};\n\nconst REG: Record<string, ScopeDef> = {};\n\n/** Register one resource with the given actions, generating read/write defs.\n * `write` auto-implies `read` when a read action is present. */\nfunction add(\n group: string,\n resource: string,\n actions: Array<'read' | 'write'>,\n labels: { read?: string; write?: string },\n opts: Opts = {},\n) {\n const hasRead = actions.includes('read');\n for (const action of actions) {\n const id = `${resource}:${action}`;\n const implies = action === 'write' && hasRead ? [`${resource}:read`] : [];\n REG[id] = {\n id,\n resource,\n action,\n group,\n label: (action === 'read' ? labels.read : labels.write) ?? `${action} ${resource}`,\n sensitive: opts.sensitive ?? false,\n staffOnly: opts.staffOnly ?? false,\n // publishable defaults false; only the curated set below is true\n publishableAllowed: opts.publishableAllowed ?? false,\n // extension default true for commerce scopes; Taxonomy B passes false\n extensionAllowed: opts.extensionAllowed ?? true,\n implies,\n };\n }\n}\n\n// ── Taxonomy A — integration / commerce ──────────────────────────────\nadd('Orders', 'orders', ['read', 'write'], { read: 'View orders', write: 'Manage orders' });\n// Sales quotes (B2B proposals) — unrelated to shipping_quotes / quote tokens.\nadd('Quotes', 'quotes', ['read', 'write'], { read: 'View quotes', write: 'Manage quotes' });\nadd('Orders', 'order_cancellations', ['write'], { write: 'Cancel orders' });\nadd('Orders', 'order_returns', ['read', 'write'], { read: 'View returns', write: 'Process returns' });\n\nadd('Payments', 'payments', ['read', 'write'], { read: 'View payments', write: 'Create payments' });\nadd('Payments', 'payment_authorizations', ['write'], { write: 'Authorize payments' });\nadd('Payments', 'payment_captures', ['write'], { write: 'Capture payments' });\nadd('Payments', 'payment_refunds', ['read', 'write'], { read: 'View refunds', write: 'Refund payments' }, { sensitive: true });\nadd('Payments', 'payment_voids', ['write'], { write: 'Void payments' }, { sensitive: true });\nadd('Payments', 'payment_disputes', ['read', 'write'], { read: 'View disputes', write: 'Handle disputes' }, { sensitive: true });\nadd('Payments', 'payment_methods', ['read', 'write'], { read: 'View payment methods', write: 'Tokenize payment methods' }, { sensitive: true });\n\nadd('Customers', 'customers', ['read', 'write'], { read: 'View customers', write: 'Manage customers' });\nadd('Customers', 'customer_pii', ['read'], { read: 'View customer PII' }, { sensitive: true });\nadd('Customers', 'customer_addresses', ['read', 'write'], { read: 'View addresses', write: 'Manage addresses' });\nadd('Customers', 'customer_payment_methods', ['read', 'write'], { read: 'View stored cards', write: 'Manage stored cards' }, { sensitive: true });\n\nadd('Carts', 'carts', ['read', 'write'], { read: 'View carts', write: 'Manage carts' });\nadd('Carts', 'cart_items', ['read', 'write'], { read: 'View line items', write: 'Manage line items' });\nadd('Carts', 'checkout_sessions', ['read', 'write'], { read: 'View checkout sessions', write: 'Manage checkout sessions' });\n\nadd('Discounts', 'discounts', ['read', 'write'], { read: 'View discounts', write: 'Manage discounts' });\n\nadd('Subscriptions', 'subscriptions', ['read', 'write'], { read: 'View subscriptions', write: 'Manage subscriptions' });\nadd('Subscriptions', 'subscription_pauses', ['write'], { write: 'Pause/resume subscriptions' });\nadd('Subscriptions', 'subscription_cancellations', ['write'], { write: 'Cancel subscriptions' });\nadd('Subscriptions', 'subscription_usage', ['read', 'write'], { read: 'View subscription usage', write: 'Report subscription usage' }, { extensionAllowed: false });\n\nadd('Fulfillments', 'fulfillments', ['read', 'write'], { read: 'View fulfillments', write: 'Manage fulfillments' });\nadd('Fulfillments', 'fulfillment_shipments', ['write'], { write: 'Update shipments' });\nadd('Fulfillments', 'fulfillment_digital', ['read', 'write'], { read: 'View digital delivery', write: 'Manage digital delivery' });\nadd('Fulfillments', 'fulfillment_access', ['write'], { write: 'Manage access credentials' });\nadd('Fulfillments', 'fulfillment_services', ['write'], { write: 'Manage service fulfillment' });\n\nadd('Invoices / AR', 'invoices', ['read'], { read: 'View invoices & aging' });\nadd('Invoices / AR', 'invoice_payments', ['write'], { write: 'Mark invoices paid' }, { sensitive: true });\nadd('Invoices / AR', 'invoice_dunning', ['write'], { write: 'Send dunning notices' });\n\nadd('Shipping & Tax', 'shipping_tax', ['read', 'write'], { read: 'View shipping/tax config', write: 'Edit shipping/tax config' });\nadd('Shipping & Tax', 'shipping_tax_publications', ['write'], { write: 'Publish shipping/tax config' });\nadd('Shipping & Tax', 'shipping_quotes', ['write'], { write: 'Request shipping quotes' }, { publishableAllowed: true });\nadd('Shipping & Tax', 'tax_calculations', ['write'], { write: 'Calculate tax' }, { publishableAllowed: true });\nadd('Shipping & Tax', 'shipping_tax_quote_tokens', ['read', 'write'], { read: 'View quote tokens', write: 'Manage quote tokens' });\nadd('Shipping & Tax', 'shipping_tax_snapshots', ['write'], { write: 'Accept external snapshots' });\n\nadd('Connectors', 'connectors', ['read', 'write'], { read: 'View connectors', write: 'Manage connectors' });\nadd('Connectors', 'connector_activations', ['write'], { write: 'Activate/deactivate connectors' });\n\nadd('Webhooks & Events', 'webhooks', ['read', 'write'], { read: 'View webhooks', write: 'Manage webhooks' });\nadd('Webhooks & Events', 'webhook_deliveries', ['read', 'write'], { read: 'View deliveries', write: 'Retry deliveries' });\nadd('Webhooks & Events', 'events', ['read'], { read: 'View events' });\nadd('Webhooks & Events', 'audit_logs', ['read'], { read: 'View audit log' });\n\nadd('Applications', 'applications', ['read', 'write'], { read: 'View applications', write: 'Manage applications' });\n\nadd('Workspace', 'merchant', ['read', 'write'], { read: 'View workspace settings', write: 'Edit workspace settings' });\nadd('Workspace', 'embed_config', ['read', 'write'], { read: 'View embed config', write: 'Edit embed config' });\nadd('Workspace', 'branding', ['write'], { write: 'Upload branding assets' });\n\n// ── Taxonomy B — human / admin (extensionAllowed: false) ─────────────\nconst HUMAN: Opts = { extensionAllowed: false };\nadd('Team', 'team_members', ['read', 'write'], { read: 'View members', write: 'Manage members' }, HUMAN);\nadd('Team', 'team_invites', ['read', 'write'], { read: 'View invites', write: 'Manage invites' }, HUMAN);\nadd('Platform billing', 'billing', ['read', 'write'], { read: 'View billing', write: 'Manage subscription' }, HUMAN);\nadd('Platform billing', 'billing_payment_methods', ['read', 'write'], { read: 'View billing cards', write: 'Manage billing cards' }, HUMAN);\nadd('Email', 'email_templates', ['read', 'write'], { read: 'View email templates', write: 'Edit email templates' }, HUMAN);\nadd('Email', 'email_settings', ['read', 'write'], { read: 'View email settings', write: 'Edit email settings' }, HUMAN);\nadd('Go-live', 'go_live', ['read', 'write'], { read: 'View go-live status', write: 'Submit go-live' }, HUMAN);\nadd('Partner', 'partner', ['read', 'write'], { read: 'View partner profile', write: 'Edit partner profile' }, HUMAN);\nadd('Partner', 'affiliates', ['read', 'write'], { read: 'View affiliates', write: 'Manage affiliates' }, HUMAN);\nadd('Notifications', 'notifications', ['write'], { write: 'Send notifications' }, HUMAN);\nadd('Notifications', 'preferences', ['read', 'write'], { read: 'View preferences', write: 'Edit preferences' }, HUMAN);\nadd('Integrations', 'integrations', ['read', 'write'], { read: 'View integrations', write: 'Manage integrations' }, HUMAN);\nadd('Support', 'support', ['read', 'write'], { read: 'View support tickets', write: 'Manage support tickets' }, HUMAN);\nadd('Admin (staff)', 'admin', ['read', 'write'], { read: 'View admin data', write: 'Perform admin actions' }, { sensitive: true, staffOnly: true, extensionAllowed: false });\n\n// Extensions management — admin taxonomy: extensions must never manage other extensions.\n// 'read' and 'write' are auto-generated by add(); write→read implication is handled by add().\n// 'install' is a CUSTOM action registered manually — it is independent: write does NOT imply install.\nadd('Extensions', 'extensions', ['read', 'write'],\n { read: 'View extensions & installs', write: 'Author, version & publish extensions' }, HUMAN);\n// 'install' is not auto-generated; add() only handles 'read'/'write'. Register it directly.\nREG['extensions:install'] = {\n id: 'extensions:install', resource: 'extensions', action: 'install',\n group: 'Extensions', label: 'Install, configure & manage extensions',\n sensitive: false, staffOnly: false, publishableAllowed: false, extensionAllowed: false, implies: [],\n};\n\n// ── wildcard ──────────────────────────────────────────────────────────\nREG['*'] = {\n id: '*', resource: '*', action: 'write', group: 'Global', label: 'Full access',\n sensitive: true, staffOnly: false, publishableAllowed: false, extensionAllowed: false, implies: [],\n};\n\nexport const SCOPE_REGISTRY: Readonly<Record<string, ScopeDef>> = REG;\nexport type ScopeId = string;\nexport const ALL_SCOPE_IDS: readonly string[] = Object.keys(REG);\n\n/** group label → ordered scope ids (for the picker + docs). */\nexport const SCOPE_GROUPS: Record<string, string[]> = (() => {\n const out: Record<string, string[]> = {};\n for (const def of Object.values(REG)) {\n if (def.id === '*') continue;\n (out[def.group] ??= []).push(def.id);\n }\n return out;\n})();\n","// packages/core-scopes/src/events.ts\n/** Canonical event catalog. Keep in sync with the webhook-types union\n * (a compile-time assertion in webhook-types guards this — see Task 3.3). */\nexport const ALL_EVENT_TYPES = [\n // cart\n 'cart.created', 'cart.updated', 'cart.item_added', 'cart.item_updated',\n 'cart.item_removed', 'cart.shipping_selected', 'cart.shipping_cleared',\n 'cart.discount_applied', 'cart.discount_removed', 'cart.tax_recomputed',\n 'cart.checkout_started', 'cart.converted', 'cart.abandoned', 'cart.merged',\n // checkout\n 'checkout.session.created', 'checkout.session.completed',\n // order\n 'order.created', 'order.updated', 'order.completed', 'order.cancelled',\n 'order.closed', 'order.sync_failed', 'order.sync_conflict',\n // return / RMA (#690)\n 'return.created', 'return.updated',\n // quote (sales quotes). All nine of spec §10.1 — quote.expired was emitted\n // by the expiry cron from the day it shipped but never registered here, so\n // subscribing to it 400'd and it could never be delivered.\n 'quote.requested', 'quote.proposed', 'quote.viewed', 'quote.comment_added',\n 'quote.revision_requested', 'quote.declined', 'quote.accepted', 'quote.converted',\n 'quote.expired',\n // payment\n // payment.authorization_failed / capture_failed / void_failed removed 2026-07-05:\n // no live code path emits them (Gr4vy adapter not wired into PaymentService).\n 'payment.pending', 'payment.authorized',\n 'payment.captured', 'payment.failed', 'payment.voided',\n 'payment.refunded', 'payment.partially_refunded',\n 'payment.refund_failed', 'payment.vaulted', 'payment.disputed', 'payment.dispute_cleared',\n // fulfillment\n 'fulfillment.created', 'fulfillment.completed', 'fulfillment.cancelled',\n 'fulfillment.shipment.shipped', 'fulfillment.shipment.delivered',\n 'fulfillment.digital.delivered',\n // subscription\n 'subscription.created', 'subscription.activated', 'subscription.updated',\n 'subscription.plan_changed', 'subscription.plan_change_scheduled',\n 'subscription.paused', 'subscription.resumed', 'subscription.cancelled',\n 'subscription.renewed', 'subscription.past_due', 'subscription.payment_failed',\n 'subscription.create_failed', 'subscription.trial_blocked',\n 'subscription.backup_pm_used',\n // discount\n 'discount.applied', 'discount.removed',\n // customer\n 'customer.created', 'customer.updated', 'customer.deleted',\n 'customer.payment_method_added', 'customer.payment_method_removed',\n // invoice / AR\n 'invoice.past_due',\n // shipping & tax\n 'shipping_tax.provider_connection.unhealthy',\n // workspace / platform-billing\n 'workspace.payment_method.added', 'workspace.payment_method.removed',\n 'workspace.payment_method.default_changed', 'workspace.payment_method.backup_set',\n 'workspace.payment_method.backup_used', 'workspace.platform_charge.succeeded',\n 'workspace.platform_charge.failed', 'workspace.trial_expired',\n // NOTE: extension.* removed from the outbound event catalog (2026-07-05) —\n // they remain in-app + email notifications, not deliverable webhooks.\n] as const;\n\nexport type EventType = (typeof ALL_EVENT_TYPES)[number];\n\n/** Exact-match overrides take priority over prefix rules. */\nconst EVENT_SCOPE_OVERRIDES: Record<string, string> = {\n 'payment.refunded': 'payment_refunds:read',\n 'payment.partially_refunded': 'payment_refunds:read',\n 'payment.refund_failed': 'payment_refunds:read',\n 'payment.disputed': 'payment_disputes:read',\n 'payment.dispute_cleared': 'payment_disputes:read',\n 'fulfillment.digital.delivered': 'fulfillment_digital:read',\n};\n\n// Exact-match overrides (EVENT_SCOPE_OVERRIDES) take priority over these prefix rules. Add fine-grained event→scope mappings there, not here.\n/** Ordered longest-prefix-first so `checkout.session.` beats `checkout.`. */\nconst PREFIX_RULES: Array<[string, string]> = [\n ['checkout.session.', 'carts:read'],\n ['cart.', 'carts:read'],\n ['order.', 'orders:read'],\n ['quote.', 'quotes:read'],\n ['return.', 'order_returns:read'],\n ['payment.', 'payments:read'],\n ['customer.', 'customers:read'],\n ['subscription.', 'subscriptions:read'],\n ['fulfillment.', 'fulfillments:read'],\n ['discount.', 'discounts:read'],\n ['invoice.', 'invoices:read'],\n ['shipping_tax.', 'shipping_tax:read'],\n ['workspace.', 'billing:read'],\n ['extension.', 'merchant:read'],\n];\n\n/** Map an event type to the read scope required to subscribe/receive it. */\nexport function eventReadScope(type: string): string {\n if (EVENT_SCOPE_OVERRIDES[type]) return EVENT_SCOPE_OVERRIDES[type];\n for (const [prefix, scope] of PREFIX_RULES) {\n if (type.startsWith(prefix)) return scope;\n }\n throw new Error(`Unknown event type: ${type}`);\n}\n","// packages/core-scopes/src/issuance.ts\nimport { SCOPE_REGISTRY } from './scopes';\nimport { expandLegacyScopes } from './legacy';\n\nexport interface ValidationResult { ok: boolean; invalid: string[]; }\n\n/** Validate scopes requested for an API key.\n * - legacy scopes are expanded first (migration-window safety)\n * - sk_: every scope must exist + not be staffOnly; '*' allowed\n * - pk_: every scope must be publishableAllowed; '*' NOT allowed */\nexport function validateScopesForKey(\n scopes: readonly string[],\n opts: { publishable: boolean },\n): ValidationResult {\n const expanded = expandLegacyScopes(scopes);\n const invalid: string[] = [];\n for (const id of expanded) {\n if (id === '*') {\n if (opts.publishable) invalid.push(id);\n continue;\n }\n const def = SCOPE_REGISTRY[id];\n if (!def) { invalid.push(id); continue; }\n if (opts.publishable) {\n if (!def.publishableAllowed) invalid.push(id);\n } else if (def.staffOnly) {\n invalid.push(id);\n }\n }\n return { ok: invalid.length === 0, invalid };\n}\n\n/** Validate scopes requested in an extension manifest:\n * every scope must exist + be extensionAllowed; '*' is never allowed. */\nexport function validateScopesForExtension(scopes: readonly string[]): ValidationResult {\n const expanded = expandLegacyScopes(scopes);\n const invalid: string[] = [];\n for (const id of expanded) {\n if (id === '*') { invalid.push(id); continue; }\n const def = SCOPE_REGISTRY[id];\n if (!def || !def.extensionAllowed) invalid.push(id);\n }\n return { ok: invalid.length === 0, invalid };\n}\n\n/** Scope ids a publishable key may hold (for the picker). */\nexport const PUBLISHABLE_SCOPES: string[] =\n Object.values(SCOPE_REGISTRY).filter((d) => d.publishableAllowed).map((d) => d.id);\n","import type { ActionDefinition } from './types';\n\n/**\n * The verbs, defined once.\n *\n * Curation, not coverage: each entry maps to a job somebody actually asks for.\n * Long-tail reads are served by `api_get`, which cannot mutate anything and is\n * still scope-enforced server-side, so the curated list never has to grow just\n * to reach another GET.\n *\n * Paths are the EFFECTIVE public paths. Route files that declare `/v1/...`\n * literals are registered under a `prefix: '/api'`, so both spellings resolve to\n * `/api/v1/...`; the catalog always records the resolved form.\n */\nexport const ACTIONS: readonly ActionDefinition[] = [\n // ---------------------------------------------------------------- identity\n {\n id: 'whoami',\n title: 'Identify the connected credential',\n description:\n 'Report which workspace, application and environment this credential is pinned to, and what it is allowed to do. Call this first when you need to know whether you are talking to production or a sandbox.',\n kind: 'read',\n scopes: [],\n input: [],\n requests: [{ method: 'GET', path: '/api/v1/whoami' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ------------------------------------------------------- local (no API call)\n {\n id: 'search_docs',\n title: 'Search the Throttle developer docs',\n description:\n 'Full-text search over the Throttle developer documentation. Returns titles, canonical docs.usethrottle.dev URLs, and matching excerpts. Prefer this over recalling API details from memory.',\n kind: 'read',\n scopes: [],\n input: [\n { name: 'query', type: 'string', required: true, description: 'What to search for.' },\n { name: 'limit', type: 'number', required: false, description: 'Maximum results.' },\n ],\n requests: [],\n channels: ['mcp'],\n },\n {\n id: 'describe_endpoint',\n title: 'Describe an API endpoint',\n description:\n 'Return the canonical request and response shape of a Throttle API endpoint from the published OpenAPI contract: path parameters, request body fields, required scope. Use before writing any integration code.',\n kind: 'read',\n scopes: [],\n input: [\n {\n name: 'path',\n type: 'string',\n required: true,\n description: 'Endpoint path or fragment, e.g. \"/api/v1/carts\" or \"carts\".',\n },\n {\n name: 'method',\n type: 'string',\n required: false,\n description: 'Narrow to one HTTP method.',\n enum: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'],\n },\n ],\n requests: [],\n channels: ['mcp'],\n },\n {\n id: 'validate_payload',\n title: 'Validate a request body against the API contract',\n description:\n 'Check a request body against the published contract before sending it. Names every unsupported field and gives its canonical replacement — Throttle is strict camelCase and rejects retired aliases such as line_items, unit_price, customer_id and storeId.',\n kind: 'read',\n scopes: [],\n input: [\n { name: 'method', type: 'string', required: true, description: 'HTTP method.' },\n { name: 'path', type: 'string', required: true, description: 'Endpoint path.' },\n { name: 'body', type: 'object', required: true, description: 'The request body to check.' },\n ],\n requests: [],\n channels: ['mcp'],\n },\n\n // ------------------------------------------------------------ generic reads\n {\n id: 'api_get',\n title: 'Read any Throttle API endpoint',\n description:\n 'Escape hatch for reads the curated tools do not cover: performs a GET against any /api/v1 path and returns the response. Cannot write. Confirm the path with describe_endpoint first if unsure.',\n kind: 'read',\n scopes: [],\n input: [\n {\n name: 'path',\n type: 'string',\n required: true,\n description: 'Path beginning with /api/v1, query string included.',\n },\n ],\n requests: [],\n channels: ['mcp'],\n guardrails: [\n 'GET only — reject any other method.',\n 'Reject paths outside /api/v1 so the tool cannot be pointed at another host or a non-versioned surface.',\n 'Server-side scope enforcement still applies; surface a 403 insufficient_scopes verbatim rather than retrying.',\n ],\n },\n\n // ------------------------------------------------------------------- orders\n {\n id: 'search_orders',\n title: 'Search orders',\n description: 'List orders, newest first, with optional free-text and status filters.',\n kind: 'read',\n scopes: ['orders:read'],\n input: [\n { name: 'q', type: 'string', required: false, description: 'Free-text search.' },\n { name: 'status', type: 'string', required: false, description: 'Order status filter.' },\n { name: 'paymentStatus', type: 'string', required: false, description: 'Payment status filter.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/orders' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_order',\n title: 'Get one order with its returns and fulfillments',\n description:\n 'Full picture of a single order: the order itself plus its payments, returns and fulfillments in one response.',\n kind: 'read',\n scopes: ['orders:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Order id.' }],\n requests: [\n { method: 'GET', path: '/api/v1/orders/:id' },\n { method: 'GET', path: '/api/v1/orders/:id/payments' },\n { method: 'GET', path: '/api/v1/orders/:id/returns' },\n { method: 'GET', path: '/api/v1/orders/:orderId/fulfillments' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Sub-reads need their own scopes (payments:read, order_returns:read, fulfillments:read). Skip a section the credential cannot read and say so in the result rather than failing the whole call.',\n ],\n },\n\n // ---------------------------------------------------------------- customers\n {\n id: 'search_customers',\n title: 'Search customers',\n description: 'Find customers by name, email or external id.',\n kind: 'read',\n scopes: ['customers:read'],\n input: [\n { name: 'q', type: 'string', required: false, description: 'Free-text search.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/customers' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_customer',\n title: 'Get one customer with subscriptions and addresses',\n description:\n 'Full picture of a single customer: the record plus their subscriptions and addresses in one response.',\n kind: 'read',\n scopes: ['customers:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Customer id.' }],\n requests: [\n { method: 'GET', path: '/api/v1/customers/:id' },\n { method: 'GET', path: '/api/v1/customers/:id/addresses' },\n { method: 'GET', path: '/api/v1/subscriptions' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Sub-reads need customer_addresses:read / subscriptions:read. Omit a section the credential cannot read instead of failing.',\n ],\n },\n\n // ------------------------------------------------------------- subscriptions\n {\n id: 'list_subscriptions',\n title: 'List subscriptions',\n description: 'List subscriptions with optional customer and status filters.',\n kind: 'read',\n scopes: ['subscriptions:read'],\n input: [\n { name: 'customerId', type: 'string', required: false, description: 'Filter by customer.' },\n { name: 'status', type: 'string', required: false, description: 'Filter by status.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/subscriptions' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_subscription',\n title: 'Get one subscription',\n description: 'Read a single subscription including its current period and pending changes.',\n kind: 'read',\n scopes: ['subscriptions:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Subscription id.' }],\n requests: [{ method: 'GET', path: '/api/v1/subscriptions/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ------------------------------------------------------------------- quotes\n {\n id: 'search_quotes',\n title: 'Search quotes',\n description: 'List quotes with optional status filter — useful for \"which quotes expire soon\".',\n kind: 'read',\n scopes: ['quotes:read'],\n input: [\n { name: 'status', type: 'string', required: false, description: 'Filter by quote status.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/quotes' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_quote',\n title: 'Get one quote',\n description: 'Read a single quote with its line items, revisions and buyer link state.',\n kind: 'read',\n scopes: ['quotes:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Quote id.' }],\n requests: [{ method: 'GET', path: '/api/v1/quotes/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ----------------------------------------------------------------- invoices\n {\n id: 'list_invoices',\n title: 'List invoices',\n description: 'List issued invoices with optional status filter.',\n kind: 'read',\n scopes: ['invoices:read'],\n input: [\n { name: 'status', type: 'string', required: false, description: 'Filter by invoice status.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/invoices' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'receivables_aging',\n title: 'Receivables aging',\n description: 'Outstanding receivables bucketed by age — answers \"what is overdue and by how long\".',\n kind: 'read',\n scopes: ['invoices:read'],\n input: [],\n requests: [{ method: 'GET', path: '/api/v1/invoices/aging' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // --------------------------------------------------------------- discounts\n {\n id: 'search_discounts',\n title: 'Search discounts',\n description: 'List discount codes with optional filters — type, active state, and creation date range.',\n kind: 'read',\n scopes: ['discounts:read'],\n input: [\n { name: 'q', type: 'string', required: false, description: 'Free-text search.' },\n { name: 'code', type: 'string', required: false, description: 'Exact code match.' },\n {\n name: 'type',\n type: 'string',\n required: false,\n description: 'Filter by discount type.',\n enum: ['percentage', 'fixed_amount'],\n },\n { name: 'isActive', type: 'boolean', required: false, description: 'Filter by active state.' },\n { name: 'createdAfter', type: 'string', required: false, description: 'ISO 8601 date lower bound.' },\n { name: 'createdBefore', type: 'string', required: false, description: 'ISO 8601 date upper bound.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/discounts' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_discount',\n title: 'Get one discount',\n description: 'Read a single discount code: value, conditions, usage limits and redemption count.',\n kind: 'read',\n scopes: ['discounts:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Discount id.' }],\n requests: [{ method: 'GET', path: '/api/v1/discounts/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ---------------------------------------------------------------- payments\n {\n id: 'search_payments',\n title: 'Search payments',\n description:\n 'List payments with optional filters — method, status, order, amount range, or a Net-N overdue bucket. Today payments are only reachable nested inside get_order; this is the standalone entry point.',\n kind: 'read',\n scopes: ['payments:read'],\n input: [\n { name: 'method', type: 'string', required: false, description: 'Filter by payment method.' },\n { name: 'status', type: 'string', required: false, description: 'Filter by payment status.' },\n { name: 'orderId', type: 'string', required: false, description: 'Filter to one order.' },\n {\n name: 'aging',\n type: 'string',\n required: false,\n description: 'Overdue bucket filter, Net-N payments only.',\n enum: ['0_30', '31_60', '61_90', '90_plus'],\n },\n { name: 'dueFrom', type: 'string', required: false, description: 'Due-date range start, YYYY-MM-DD.' },\n { name: 'dueTo', type: 'string', required: false, description: 'Due-date range end, YYYY-MM-DD.' },\n { name: 'amountMin', type: 'number', required: false, description: 'Minimum amount, minor units.' },\n { name: 'amountMax', type: 'number', required: false, description: 'Maximum amount, minor units.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/payments' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_payment',\n title: 'Get one payment with its transactions',\n description: 'Read a single payment plus its full transaction history (authorize/capture/refund/void attempts).',\n kind: 'read',\n scopes: ['payments:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Payment id.' }],\n requests: [\n { method: 'GET', path: '/api/v1/payments/:id' },\n { method: 'GET', path: '/api/v1/payments/:id/transactions' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'The transactions sub-read needs its own read of the same payment scope; report it as unavailable rather than failing the whole call if the underlying request errors.',\n ],\n },\n\n // ---------------------------------------------------------------- invoices\n {\n id: 'get_invoice',\n title: 'Get one invoice',\n description: 'Read a single issued invoice: line items, totals, status and the billing snapshot at issue time.',\n kind: 'read',\n scopes: ['invoices:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Invoice id.' }],\n requests: [{ method: 'GET', path: '/api/v1/invoices/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ------------------------------------------------------------------ carts\n {\n id: 'list_abandoned_carts',\n title: 'List abandoned carts',\n description: 'Carts that were started but never finalized, with recovery status — the abandoned-cart recovery list.',\n kind: 'read',\n scopes: ['carts:read'],\n input: [\n { name: 'sinceDays', type: 'number', required: false, description: 'How many days back to look.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/abandoned-carts' },\n { method: 'GET', path: '/api/v1/abandoned-carts/summary' },\n ],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: ['Report the summary as unavailable rather than failing the whole call if that sub-read errors.'],\n },\n\n // ---------------------------------------------------------------- debugging\n {\n id: 'search_events',\n title: 'Search the event log',\n description:\n 'Search the immutable event log by type or entity. The first stop when asking what actually happened to an order, cart or subscription.',\n kind: 'read',\n scopes: ['events:read'],\n input: [\n { name: 'type', type: 'string', required: false, description: 'Event type, e.g. order.created.' },\n { name: 'entityType', type: 'string', required: false, description: 'Entity type filter.' },\n { name: 'entityId', type: 'string', required: false, description: 'Entity id filter.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/events' }],\n channels: ['mcp', 'n8n'],\n },\n {\n id: 'list_webhook_deliveries',\n title: 'List webhook deliveries',\n description: 'Recent outbound webhook deliveries, filterable by endpoint and status.',\n kind: 'read',\n scopes: ['webhook_deliveries:read'],\n input: [\n { name: 'endpointId', type: 'string', required: false, description: 'Filter by endpoint.' },\n { name: 'status', type: 'string', required: false, description: 'Filter by delivery status.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/webhook-deliveries' }],\n channels: ['mcp', 'n8n'],\n },\n {\n id: 'get_webhook_delivery',\n title: 'Get one webhook delivery',\n description:\n 'Full delivery record: the signed payload we sent, the response we got back, and every attempt.',\n kind: 'read',\n scopes: ['webhook_deliveries:read'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Delivery id.' }],\n requests: [{ method: 'GET', path: '/api/v1/webhook-deliveries/:id' }],\n channels: ['mcp', 'n8n'],\n },\n {\n id: 'explain_checkout_failure',\n title: 'Explain why a checkout failed',\n description:\n 'Diagnose a failing checkout in one call: session state, its cart, the events it emitted, and any webhook deliveries that followed. Use this before asking the user to reproduce anything.',\n kind: 'read',\n scopes: ['checkout_sessions:read'],\n input: [\n {\n name: 'id',\n type: 'string',\n required: true,\n description: 'Checkout session id (or cart id — the tool resolves the session).',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/checkout-sessions/:id' },\n { method: 'GET', path: '/api/v1/checkout-sessions/:id/cart' },\n { method: 'GET', path: '/api/v1/events' },\n { method: 'GET', path: '/api/v1/webhook-deliveries' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Report which sections were unavailable rather than failing the call when a sub-read is unscoped.',\n ],\n },\n\n // ------------------------------------------------------------- extensions\n {\n id: 'list_extension_installations',\n title: 'List installed extensions',\n description: 'Extensions installed on this application, with status and configuration.',\n kind: 'read',\n scopes: ['extensions:read'],\n input: [\n {\n name: 'status',\n type: 'string',\n required: false,\n description: 'Filter by installation status.',\n enum: ['active', 'suspended', 'uninstalled'],\n },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n ],\n requests: [{ method: 'GET', path: '/api/v1/installations' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ------------------------------------------------------------- connectors\n {\n id: 'get_connector_routing',\n title: 'Payment routing and decline rules',\n description:\n 'Read the payment-routing cascade, active routing connectors, and card/other decline rules — what determines which processor handles a payment and what happens on a decline.',\n kind: 'read',\n scopes: ['connectors:read'],\n input: [],\n requests: [\n { method: 'GET', path: '/api/v1/payment-routing' },\n { method: 'GET', path: '/api/v1/routing-connectors' },\n { method: 'GET', path: '/api/v1/card-decline' },\n { method: 'GET', path: '/api/v1/other-decline' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Every sub-read proxies live to the payment provider\\'s routing API and none are guaranteed to succeed together; report any that fail as unavailable rather than failing the whole call.',\n ],\n },\n\n {\n id: 'get_integration_status',\n title: 'Integration readiness',\n description:\n 'Answers \"am I ready to go live?\" — active connectors, webhook endpoints and their recent delivery health, and the environment this credential is pinned to.',\n kind: 'read',\n scopes: [],\n input: [],\n requests: [\n { method: 'GET', path: '/api/v1/whoami' },\n { method: 'GET', path: '/api/v1/connectors' },\n { method: 'GET', path: '/api/v1/webhook-endpoints' },\n { method: 'GET', path: '/api/v1/webhook-endpoints/coverage' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Each section needs its own scope (connectors:read, webhooks:read). Report a section as \"not readable with this credential\" instead of failing.',\n ],\n },\n // --------------------------------------------------------------- workspace\n {\n id: 'get_workspace_settings',\n title: 'Get workspace settings',\n description:\n 'Read this workspace\\'s identity and settings: name, slug, branding, onboarding state, and the default Net-N payment terms.',\n kind: 'read',\n scopes: ['merchant:read'],\n input: [],\n requests: [{ method: 'GET', path: '/api/v1/merchants/me' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_audit_log',\n title: 'Get the workspace audit log',\n description:\n 'Recent admin actions taken on this workspace — invites, billing changes, key rotation, suspensions.',\n kind: 'read',\n scopes: ['audit_logs:read'],\n input: [\n { name: 'limit', type: 'number', required: false, description: 'Maximum entries (1-200).', default: 100 },\n ],\n requests: [{ method: 'GET', path: '/api/v1/audit-log' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_business_summary',\n title: 'Business summary',\n description:\n 'How are we doing? Orders/revenue, subscription MRR, receivables and quotes pipeline for a week/month/quarter, always compared to the immediately preceding period of equal length.',\n kind: 'read',\n scopes: [],\n input: [\n {\n name: 'period',\n type: 'string',\n required: false,\n description: 'Reporting window.',\n enum: ['week', 'month', 'quarter'],\n default: 'month',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/business-summary' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Each section needs its own scope (orders:read, subscriptions:read, invoices:read, quotes:read). A section without its scope is reported as omitted rather than failing the whole call.',\n ],\n },\n {\n id: 'get_attention_digest',\n title: 'Attention digest',\n description:\n 'What needs attention right now? Open disputes, subscriptions in dunning, overdue Net-N invoices, and webhooks with degraded delivery health — a point-in-time snapshot, not a time range.',\n kind: 'read',\n scopes: [],\n input: [],\n requests: [{ method: 'GET', path: '/api/v1/analytics/attention-digest' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Each section needs its own scope (payment_disputes:read, subscriptions:read, invoices:read, webhook_deliveries:read). A section without its scope is reported as omitted rather than failing the whole call.',\n ],\n },\n\n // ------------------------------------------------------------ sandbox write\n {\n id: 'seed_test_data',\n title: 'Seed test data (non-production only)',\n description:\n 'Create a realistic customer, cart, line items and a finalized draft order so an integration has something to read. Refuses to run against production.',\n kind: 'write',\n scopes: ['customers:write', 'carts:write', 'cart_items:write'],\n input: [\n { name: 'customerEmail', type: 'string', required: false, description: 'Email for the seeded customer.' },\n { name: 'lineItems', type: 'array', required: false, description: 'Line items; a sensible default set is used when omitted.' },\n ],\n requests: [\n { method: 'POST', path: '/api/v1/customers' },\n { method: 'POST', path: '/api/v1/carts' },\n { method: 'POST', path: '/api/v1/carts/:id/items' },\n { method: 'POST', path: '/api/v1/carts/:id/finalize' },\n ],\n channels: ['mcp'],\n sandboxOnly: true,\n idempotent: true,\n guardrails: [\n 'Hard-refuse when the credential resolves to a production environment, regardless of any allow-writes flag.',\n 'Seeds a finalized DRAFT order — it does not capture a payment, which needs a browser-side tokenised payment method.',\n ],\n },\n\n // -------------------------------------------------------------- money/mail\n {\n id: 'create_quote',\n title: 'Create a quote',\n description: 'Draft a quote for a customer with line items and terms. Does not send it — use send_quote.',\n kind: 'write',\n scopes: ['quotes:write'],\n input: [\n { name: 'customerId', type: 'string', required: true, description: 'Customer the quote is for.' },\n { name: 'items', type: 'array', required: true, description: 'Quote line items: { name, unitPrice, quantity }.' },\n { name: 'expiresAt', type: 'string', required: false, description: 'ISO 8601 expiry.' },\n { name: 'netN', type: 'number', required: false, description: 'Payment terms in days. Omit for pay-in-full.' },\n { name: 'notes', type: 'string', required: false, description: 'Buyer-visible notes.' },\n ],\n requests: [{ method: 'POST', path: '/api/v1/quotes' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n },\n {\n id: 'send_quote',\n title: 'Issue and send a quote',\n description:\n 'Issue a draft quote and email the buyer their quote link. This is buyer-visible — confirm with the user before calling it.',\n kind: 'write',\n scopes: ['quotes:write'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Quote id.' }],\n requests: [{ method: 'POST', path: '/api/v1/quotes/:id/issue' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: ['Sends mail to a real buyer. Never call it speculatively or to \"check\" a quote.'],\n },\n {\n id: 'refund_payment',\n title: 'Refund a payment',\n description:\n 'Refund a captured payment. The amount is required — never infer a full refund from an unspecified amount.',\n kind: 'write',\n scopes: ['payment_refunds:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Payment id.' },\n {\n name: 'amount',\n type: 'number',\n required: true,\n description: 'Amount to refund in minor units. Required — omitting it would refund the whole payment.',\n },\n { name: 'reason', type: 'string', required: false, description: 'Reason recorded on the refund.' },\n ],\n requests: [{ method: 'POST', path: '/api/v1/payments/:id/refund' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: [\n 'Moves money and is irreversible. Confirm with the user first.',\n 'The API treats an omitted amount as a FULL refund, so this action requires it explicitly.',\n ],\n },\n {\n id: 'manage_subscription',\n title: 'Pause or resume a subscription',\n description: 'Pause or resume an active subscription.',\n kind: 'write',\n scopes: ['subscription_pauses:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Subscription id.' },\n {\n name: 'action',\n type: 'string',\n required: true,\n description: 'What to do.',\n enum: ['pause', 'resume'],\n },\n ],\n requests: [\n { method: 'POST', path: '/api/v1/subscriptions/:id/pause' },\n { method: 'POST', path: '/api/v1/subscriptions/:id/resume' },\n ],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n },\n {\n id: 'cancel_subscription',\n title: 'Cancel a subscription',\n description: 'Cancel a subscription. Separate from pause/resume because it needs its own scope.',\n kind: 'write',\n scopes: ['subscription_cancellations:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Subscription id.' },\n {\n name: 'atPeriodEnd',\n type: 'boolean',\n required: false,\n description: 'Cancel at the end of the current period instead of immediately.',\n },\n ],\n requests: [{ method: 'POST', path: '/api/v1/subscriptions/:id/cancel' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: ['Ends billing for a paying customer. Confirm with the user first.'],\n },\n {\n id: 'replay_webhook_delivery',\n title: 'Replay a webhook delivery',\n description: 'Re-send a past webhook delivery to its endpoint — useful after fixing a broken handler.',\n kind: 'write',\n scopes: ['webhook_deliveries:write'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Delivery id.' }],\n requests: [{ method: 'POST', path: '/api/v1/webhook-deliveries/:id/replay' }],\n channels: ['mcp', 'n8n'],\n idempotent: true,\n guardrails: ['The receiving system will process the event again. Confirm it is idempotent first.'],\n },\n {\n id: 'send_test_webhook',\n title: 'Send a test webhook',\n description: 'Send a synthetic signed event to a webhook endpoint to verify signature handling and reachability.',\n kind: 'write',\n scopes: ['webhooks:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Endpoint id.' },\n { name: 'eventType', type: 'string', required: false, description: 'Event type to simulate.' },\n ],\n requests: [{ method: 'POST', path: '/api/v1/webhook-endpoints/:id/test' }],\n channels: ['mcp', 'n8n'],\n idempotent: true,\n },\n];\n","import { eventReadScope } from '@core/scopes';\nimport type { TriggerDefinition } from './types';\n\n/**\n * Event-backed triggers for the no-code channels.\n *\n * Scopes are DERIVED via `eventReadScope` rather than written out, so a change to\n * the event→scope mapping in `@core/scopes` can never leave a trigger claiming a\n * scope the API would not accept at subscription time.\n *\n * MCP is absent from every `channels` list on purpose: the protocol has no\n * subscription primitive, so an agent polls `search_events` instead.\n */\nconst NO_CODE: readonly ('zapier' | 'make' | 'n8n')[] = ['zapier', 'make', 'n8n'];\n\nfunction trigger(\n id: string,\n title: string,\n eventType: string,\n description: string,\n): TriggerDefinition {\n return { id, title, eventType, description, scope: eventReadScope(eventType), channels: NO_CODE };\n}\n\nexport const TRIGGERS: readonly TriggerDefinition[] = [\n trigger('new_order', 'New order', 'order.created', 'Fires when an order is created.'),\n trigger(\n 'payment_captured',\n 'Payment captured',\n 'payment.captured',\n 'Fires when a payment is successfully captured.',\n ),\n trigger(\n 'payment_failed',\n 'Payment failed',\n 'payment.failed',\n 'Fires when a payment attempt fails.',\n ),\n trigger(\n 'new_subscription',\n 'New subscription',\n 'subscription.created',\n 'Fires when a subscription is created.',\n ),\n trigger(\n 'subscription_cancelled',\n 'Subscription cancelled',\n 'subscription.cancelled',\n 'Fires when a subscription is cancelled.',\n ),\n trigger(\n 'quote_accepted',\n 'Quote accepted',\n 'quote.accepted',\n 'Fires when a buyer accepts a quote.',\n ),\n trigger(\n 'cart_abandoned',\n 'Cart abandoned',\n 'cart.abandoned',\n 'Fires when a cart is marked abandoned.',\n ),\n trigger(\n 'invoice_past_due',\n 'Invoice past due',\n 'invoice.past_due',\n 'Fires when an invoice passes its due date unpaid.',\n ),\n];\n","import { hasScope } from '@core/scopes';\nimport { ACTIONS } from './actions';\nimport { TRIGGERS } from './triggers';\nimport type { ActionDefinition, Channel, TriggerDefinition } from './types';\n\nexport * from './types';\nexport { ACTIONS } from './actions';\nexport { TRIGGERS } from './triggers';\n\nexport function actionById(id: string): ActionDefinition | undefined {\n return ACTIONS.find((a) => a.id === id);\n}\n\nexport function actionsForChannel(channel: Channel): ActionDefinition[] {\n return ACTIONS.filter((a) => a.channels.includes(channel));\n}\n\nexport function triggersForChannel(channel: Channel): TriggerDefinition[] {\n return TRIGGERS.filter((t) => t.channels.includes(channel));\n}\n\n/**\n * Can this credential run this action?\n *\n * Delegates to `@core/scopes.hasScope`, so the `*` wildcard and the\n * `resource:write ⇒ resource:read` implication behave exactly as the API's own\n * enforcement does — a projection must never be more permissive than the server,\n * and must not be needlessly stricter either.\n */\nexport function canRunAction(granted: readonly string[], action: ActionDefinition): boolean {\n return action.scopes.every((required) => hasScope(granted as string[], required));\n}\n\n/**\n * The actions a channel should expose for a given credential.\n *\n * `includeWrites` is the projection's intent gate (the MCP server's\n * `--allow-writes`): holding a write scope means the credential *may* write,\n * which is not the same as the operator intending it to.\n */\nexport function availableActions(\n channel: Channel,\n granted: readonly string[],\n options: { includeWrites?: boolean } = {},\n): ActionDefinition[] {\n const includeWrites = options.includeWrites ?? false;\n return actionsForChannel(channel).filter((action) => {\n if (action.kind === 'write' && !includeWrites) return false;\n return canRunAction(granted, action);\n });\n}\n","/** Result shaping. Compact JSON: agents read it fine and it costs far fewer tokens. */\n\nconst MAX_CHARS = 24_000;\n\n/** Drops undefined and null so a wide API row does not spend tokens on empty fields. */\nfunction prune(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(prune);\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [key, inner] of Object.entries(value as Record<string, unknown>)) {\n if (inner === undefined || inner === null) continue;\n out[key] = prune(inner);\n }\n return out;\n }\n return value;\n}\n\nexport function formatResult(value: unknown): string {\n const text = JSON.stringify(prune(value), null, 2) ?? 'null';\n if (text.length <= MAX_CHARS) return text;\n return `${text.slice(0, MAX_CHARS)}\\n\\n… truncated at ${MAX_CHARS} characters. Narrow the query (lower \"limit\", add a filter) or fetch a single record.`;\n}\n\n/**\n * Errors come back as tool text rather than transport failures: an agent can act\n * on \"missing scope orders:read\" but not on a dead connection. API error codes are\n * surfaced verbatim so the model does not paper over an auth problem by retrying.\n */\nexport function formatError(error: unknown): string {\n const e = error as { code?: string; message?: string; statusCode?: number; details?: unknown };\n if (e?.code && e?.message) {\n const detail = e.details ? `\\n\\ndetails: ${JSON.stringify(e.details)}` : '';\n return `Throttle API error ${e.code}${e.statusCode ? ` (HTTP ${e.statusCode})` : ''}: ${e.message}${detail}`;\n }\n return `Error: ${e?.message ?? String(error)}`;\n}\n","// src/index.ts\nvar ThrottleError = class extends Error {\n code;\n statusCode;\n details;\n body;\n constructor(args) {\n super(args.message);\n this.name = \"ThrottleError\";\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n this.body = args.body;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n};\nfunction isThrottleError(value) {\n return value instanceof ThrottleError;\n}\nexport {\n ThrottleError,\n isThrottleError\n};\n","import { ThrottleError } from '@usethrottle/errors';\n\nexport interface AuthCtx {\n apiKey: string;\n apiBaseUrl: string;\n}\n\nexport class ThrottleApiError extends ThrottleError {\n constructor(code: string, message: string, statusCode: number, details?: unknown) {\n super({ code, message, statusCode, details });\n this.name = 'ThrottleApiError';\n }\n}\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\n\nexport interface RequestOptions {\n body?: unknown;\n query?: Record<string, unknown>;\n /**\n * Sent as `Idempotency-Key`. Writes must pass one: an agent that retries is the\n * normal case, and the API dedupes on\n * `(workspace, application, environment, key, method, path)`.\n */\n idempotencyKey?: string;\n}\n\nexport interface Pagination {\n cursor: string | null;\n hasMore: boolean;\n}\n\nexport interface ListResult<T> {\n data: T[];\n pagination: Pagination | null;\n}\n\n/** Drops undefined/null/empty params so callers can spread optional args freely. */\nexport function buildQuery(query: Record<string, unknown> | undefined): string {\n if (!query) return '';\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null || value === '') continue;\n params.set(key, String(value));\n }\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n}\n\nexport type Fetcher = typeof fetch;\n\nexport class ThrottleClient {\n constructor(\n private readonly auth: AuthCtx,\n private readonly fetchImpl: Fetcher = fetch,\n ) {}\n\n private async requestJson(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<Record<string, unknown>> {\n const url = `${this.auth.apiBaseUrl.replace(/\\/$/, '')}${path}${buildQuery(options.query)}`;\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n 'x-api-key': this.auth.apiKey,\n };\n if (options.idempotencyKey) headers['idempotency-key'] = options.idempotencyKey;\n\n // A bodyless POST/PATCH/PUT advertising JSON would send an empty body that the\n // API's object-body schemas reject with `validation_error: body must be\n // object`, so default to `{}` (mirrors the CLI client).\n const sendsBody = method === 'POST' || method === 'PATCH' || method === 'PUT';\n const body =\n options.body !== undefined\n ? JSON.stringify(options.body)\n : sendsBody\n ? '{}'\n : undefined;\n\n const res = await this.fetchImpl(url, { method, headers, body });\n const text = await res.text();\n let parsed: Record<string, unknown> = {};\n try {\n parsed = text ? (JSON.parse(text) as Record<string, unknown>) : {};\n } catch {\n /* non-JSON body */\n }\n if (!res.ok) {\n const err = parsed.error as\n | { code?: string; message?: string; details?: unknown }\n | undefined;\n throw new ThrottleApiError(\n err?.code ?? `http_${res.status}`,\n err?.message ?? `Request failed (${res.status}): ${text.slice(0, 200)}`,\n res.status,\n err?.details,\n );\n }\n return parsed;\n }\n\n /** Unwraps the `{ data }` envelope. Key presence, not `??` — `{data: null}` unwraps to null. */\n async get<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n const body = await this.requestJson('GET', path, { query });\n return (body && typeof body === 'object' && 'data' in body ? body.data : body) as T;\n }\n\n async list<T>(path: string, query?: Record<string, unknown>): Promise<ListResult<T>> {\n const body = await this.requestJson('GET', path, { query });\n const data = ('data' in body ? body.data : body) as T[];\n const meta = body.meta as { pagination?: Pagination } | undefined;\n return { data: Array.isArray(data) ? data : [], pagination: meta?.pagination ?? null };\n }\n\n async post<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const body = await this.requestJson('POST', path, options);\n return (body && typeof body === 'object' && 'data' in body ? body.data : body) as T;\n }\n}\n\n/**\n * Runs a sub-read that the credential may not be scoped for.\n *\n * Composite tools (`get_order`, `explain_checkout_failure`,\n * `get_integration_status`) must not fail wholesale because one section is\n * unscoped or absent — an agent that gets a hard error learns nothing, whereas a\n * result that says which section was unavailable can still answer the question.\n */\nexport async function optional<T>(\n load: () => Promise<T>,\n): Promise<{ ok: true; value: T } | { ok: false; unavailable: string }> {\n try {\n return { ok: true, value: await load() };\n } catch (error) {\n const e = error as ThrottleApiError;\n const code = e?.code ?? 'error';\n const reason =\n code === 'insufficient_scopes'\n ? 'not readable with this credential (missing scope)'\n : code === 'not_found'\n ? 'not found'\n : `unavailable (${code})`;\n return { ok: false, unavailable: reason };\n }\n}\n","/**\n * `describe_endpoint` and `validate_payload`, answered from the OpenAPI contract\n * bundled at build time. No network, no API quota.\n *\n * Why this exists: Throttle's public API is strict camelCase and rejects the\n * retired snake_case aliases — and those aliases are exactly what a model writing\n * commerce code will guess, because that is what the rest of the internet's\n * examples look like. Naming the replacement turns a 400-debug loop into one call.\n */\n\nexport interface ContractField {\n name: string;\n type?: string;\n required: boolean;\n description?: string;\n enum?: string[];\n}\n\nexport interface ContractOperation {\n method: string;\n /** OpenAPI-style path, e.g. `/api/v1/customers/{customerId}/addresses/{id}`. */\n path: string;\n summary?: string;\n description?: string;\n pathParams: string[];\n queryParams: ContractField[];\n bodyFields: ContractField[] | null;\n}\n\nexport interface ContractIndex {\n generatedAt: string;\n operations: ContractOperation[];\n}\n\n/**\n * Retired public field names → canonical replacement.\n *\n * Only names the API actively rejects. Anything not listed still gets the generic\n * snake_case → camelCase suggestion below.\n */\nexport const RETIRED_FIELDS: Record<string, string> = {\n storeId: 'applicationId',\n store_id: 'applicationId',\n merchantId: 'workspaceId',\n merchant_id: 'workspaceId',\n customer_id: 'customerId',\n line_items: 'lineItems',\n unit_price: 'unitPrice',\n external_id: 'externalId',\n payment_method_id: 'paymentMethodId',\n first_name: 'firstName',\n last_name: 'lastName',\n net_n: 'netN',\n hosted_url: 'hostedUrl',\n embed_url: 'embedUrl',\n checkout_url: 'checkoutUrl',\n order_number: 'orderNumber',\n payment_status: 'paymentStatus',\n allowed_origins: 'allowedOrigins',\n enabled_events: 'enabledEvents',\n template_key: 'templateKey',\n request_id: 'requestId',\n signing_secret: 'signingSecret (returned once at creation; not accepted as input)',\n};\n\nexport function snakeToCamel(name: string): string {\n return name.replace(/_([a-z0-9])/g, (_, c: string) => c.toUpperCase());\n}\n\n/** Collapses parameter names so `/orders/{id}` and `/orders/:id` compare equal. */\nexport function normalizePath(path: string): string {\n return path\n .replace(/\\{[^}]+\\}/g, '{}')\n .replace(/:[A-Za-z0-9_]+/g, '{}')\n .replace(/\\/$/, '');\n}\n\nfunction segmentsOf(path: string): string[] {\n return path.split('?')[0].replace(/\\/$/, '').split('/').filter(Boolean);\n}\n\nfunction isParamSegment(segment: string): boolean {\n return /^\\{[^}]+\\}$/.test(segment) || /^:[A-Za-z0-9_]+$/.test(segment);\n}\n\n/**\n * Matches a caller-supplied path against a contract template.\n *\n * Callers pass CONCRETE paths — `/api/v1/carts/9f3a…/items`, straight out of the\n * conversation — so a template segment must be allowed to absorb a real id, not\n * just another placeholder. Comparing normalized strings alone silently failed on\n * every real path and sent the agent to \"no operation matched\".\n */\nexport function pathMatches(template: string, candidate: string): boolean {\n const t = segmentsOf(template);\n const c = segmentsOf(candidate);\n if (t.length !== c.length) return false;\n return t.every((segment, i) => isParamSegment(segment) || isParamSegment(c[i]) || segment === c[i]);\n}\n\n/** Fewer placeholders = a more specific template, so it wins when several match. */\nfunction paramCount(path: string): number {\n return segmentsOf(path).filter(isParamSegment).length;\n}\n\nexport function findOperations(\n index: ContractIndex,\n query: { path: string; method?: string },\n): ContractOperation[] {\n const method = query.method?.toUpperCase();\n const wanted = query.path.trim();\n const byMethod = (op: ContractOperation) => !method || op.method === method;\n\n const matched = index.operations\n .filter((op) => byMethod(op) && pathMatches(op.path, wanted))\n .sort((a, b) => paramCount(a.path) - paramCount(b.path));\n if (matched.length > 0) return matched;\n\n // Fragment search: \"carts\" or \"/carts/items\" should still find something.\n const needle = normalizePath(wanted).replace(/^\\/+/, '');\n return index.operations.filter((op) => byMethod(op) && normalizePath(op.path).includes(needle));\n}\n\nexport interface ValidationProblem {\n field: string;\n problem: string;\n suggestion?: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n matched: string | null;\n errors: ValidationProblem[];\n warnings: ValidationProblem[];\n note?: string;\n}\n\nexport function validatePayload(\n index: ContractIndex,\n input: { method: string; path: string; body: Record<string, unknown> },\n): ValidationResult {\n const errors: ValidationProblem[] = [];\n const warnings: ValidationProblem[] = [];\n const keys = Object.keys(input.body ?? {});\n\n // The retired-alias and snake_case checks do not need a schema, so they run\n // even for operations the snapshot documents without a request body.\n for (const key of keys) {\n const retired = RETIRED_FIELDS[key];\n if (retired) {\n errors.push({\n field: key,\n problem: 'retired public field name — the API rejects it',\n suggestion: `use \"${retired}\"`,\n });\n continue;\n }\n if (key.includes('_')) {\n errors.push({\n field: key,\n problem: 'snake_case is not accepted on public request bodies',\n suggestion: `use \"${snakeToCamel(key)}\"`,\n });\n }\n }\n\n const matches = findOperations(index, { path: input.path, method: input.method });\n const operation = matches[0];\n if (!operation) {\n return {\n ok: false,\n matched: null,\n errors: [\n ...errors,\n {\n field: input.path,\n problem: `no ${input.method.toUpperCase()} operation matches this path in the published contract`,\n suggestion: 'call describe_endpoint to find the right path',\n },\n ],\n warnings,\n };\n }\n\n if (!operation.bodyFields) {\n return {\n ok: errors.length === 0,\n matched: `${operation.method} ${operation.path}`,\n errors,\n warnings,\n note: 'The contract publishes no request-body schema for this operation, so field-level checks beyond naming could not run.',\n };\n }\n\n const known = new Map(operation.bodyFields.map((f) => [f.name, f]));\n for (const key of keys) {\n if (RETIRED_FIELDS[key] || key.includes('_')) continue; // already reported\n if (!known.has(key)) {\n warnings.push({\n field: key,\n problem: 'not documented on this operation — it will be rejected if the route validates strictly',\n });\n }\n }\n for (const field of operation.bodyFields) {\n const value = (input.body ?? {})[field.name];\n if (value === undefined) {\n if (field.required) errors.push({ field: field.name, problem: 'required field is missing' });\n continue;\n }\n // Closed sets are checked whenever a value is present — an optional field with\n // a bad enum value is still a 400, so skipping optionals hid real errors.\n if (field.enum && field.enum.length > 0 && typeof value === 'string' && !field.enum.includes(value)) {\n errors.push({\n field: field.name,\n problem: `value \"${value}\" is not allowed`,\n suggestion: `one of: ${field.enum.join(', ')}`,\n });\n }\n }\n\n return {\n ok: errors.length === 0,\n matched: `${operation.method} ${operation.path}`,\n errors,\n warnings,\n };\n}\n","/**\n * `search_docs`, answered from an index of `apps/docs` bundled at build time.\n *\n * Scoring mirrors the CLI's proven approach: title hits beat heading hits, which\n * beat body hits, and an exact phrase beats scattered terms. Deliberately simple —\n * the agent gets a title, a canonical docs.usethrottle.dev URL and an excerpt, then\n * fetches the page itself if its client can.\n */\n\nexport interface DocsEntry {\n title: string;\n route: string;\n headings: string[];\n text: string;\n}\n\nexport interface DocsIndex {\n generatedAt: string;\n entries: DocsEntry[];\n}\n\nexport interface DocsHit {\n title: string;\n url: string;\n score: number;\n excerpt: string;\n}\n\nconst DOCS_ORIGIN = 'https://docs.usethrottle.dev';\n\nfunction excerptAround(text: string, needle: string, radius = 160): string {\n const at = text.toLowerCase().indexOf(needle.toLowerCase());\n if (at < 0) return text.slice(0, radius * 2).trim();\n const start = Math.max(0, at - radius);\n const end = Math.min(text.length, at + needle.length + radius);\n return `${start > 0 ? '…' : ''}${text.slice(start, end).trim()}${end < text.length ? '…' : ''}`;\n}\n\nexport function searchDocs(\n index: DocsIndex,\n query: string,\n limit = 5,\n): DocsHit[] {\n const phrase = query.trim().toLowerCase();\n if (!phrase) return [];\n const terms = phrase.split(/\\s+/).filter((t) => t.length > 1);\n\n const scored = index.entries.map((entry) => {\n const title = entry.title.toLowerCase();\n const headings = entry.headings.join(' \u0000 ').toLowerCase();\n const body = entry.text.toLowerCase();\n\n let score = 0;\n if (title === phrase) score += 100;\n else if (title.startsWith(phrase)) score += 60;\n else if (title.includes(phrase)) score += 40;\n if (headings.includes(phrase)) score += 25;\n if (body.includes(phrase)) score += 15;\n\n for (const term of terms) {\n if (title.includes(term)) score += 8;\n if (headings.includes(term)) score += 4;\n if (body.includes(term)) score += 1;\n }\n\n return { entry, score };\n });\n\n return scored\n .filter((s) => s.score > 0)\n .sort((a, b) => b.score - a.score || a.entry.route.localeCompare(b.entry.route))\n .slice(0, Math.max(1, limit))\n .map(({ entry, score }) => ({\n title: entry.title,\n url: `${DOCS_ORIGIN}${entry.route}`,\n score,\n excerpt: excerptAround(entry.text, phrase),\n }));\n}\n","import { ACTIONS } from '@core/action-catalog';\nimport { optional, type ThrottleClient } from './client';\nimport {\n findOperations,\n normalizePath,\n validatePayload,\n type ContractIndex,\n type ContractOperation,\n} from './contract';\nimport { searchDocs, type DocsIndex } from './docs';\n\n/**\n * The OpenAPI snapshot does not carry each route's required scope, but the action\n * catalog does for the verbs it covers. Surfacing it here means `describe_endpoint`\n * can answer \"and what permission do I need?\" instead of leaving the agent to guess.\n */\nfunction coveringAction(\n operation: ContractOperation,\n): { tool?: string; requiredScopes?: readonly string[] } {\n const target = normalizePath(operation.path);\n for (const action of ACTIONS) {\n const hit = action.requests.some(\n (r) => r.method === operation.method && normalizePath(r.path) === target,\n );\n if (hit) return { tool: action.id, requiredScopes: action.scopes };\n }\n return {};\n}\n\nexport interface Identity {\n type: string;\n scopes: string[];\n workspace: { id: string; name: string | null; slug: string | null } | null;\n application: { id: string; name: string | null; slug: string | null } | null;\n environment: {\n id: string;\n slug: string;\n kind: string;\n providerEnvironment: 'sandbox' | 'production';\n };\n apiKey: { id: string; name: string; keyPrefix: string } | null;\n}\n\nexport interface HandlerContext {\n client: ThrottleClient;\n identity: Identity;\n contract: ContractIndex;\n docs: DocsIndex;\n}\n\nexport type Handler = (ctx: HandlerContext, args: Record<string, any>) => Promise<unknown>;\n\nconst page = (args: Record<string, any>) => ({ limit: args.limit, cursor: args.cursor });\n\n/**\n * Handlers for the 0.1.0 surface: reads, docs/contract lookups, and sandbox\n * seeding. Money-moving writes arrive in 0.2.0 with the idempotency layer — the\n * server only registers actions that have a handler here, so the catalog can\n * describe them before this file implements them.\n */\nexport const HANDLERS: Record<string, Handler> = {\n // ---------------------------------------------------------------- identity\n whoami: async (ctx) => ({\n ...ctx.identity,\n note:\n ctx.identity.environment.providerEnvironment === 'production'\n ? 'This credential is pinned to PRODUCTION. Reads return live data.'\n : 'This credential is pinned to a non-production environment. Nothing here is live data.',\n }),\n\n // ------------------------------------------------------- docs and contract\n search_docs: async (ctx, args) => {\n const hits = searchDocs(ctx.docs, String(args.query ?? ''), Number(args.limit ?? 5));\n return hits.length > 0\n ? { hits }\n : { hits: [], note: 'No documentation matched. Try fewer or more general terms.' };\n },\n\n describe_endpoint: async (ctx, args) => {\n const operations = findOperations(ctx.contract, {\n path: String(args.path ?? ''),\n method: args.method ? String(args.method) : undefined,\n });\n if (operations.length === 0) {\n return {\n operations: [],\n note: 'No operation matched. Paths look like /api/v1/orders; try a shorter fragment such as \"orders\".',\n };\n }\n return {\n operations: operations.slice(0, 8).map((op) => ({ ...op, ...coveringAction(op) })),\n truncated: operations.length > 8 ? operations.length - 8 : undefined,\n };\n },\n\n validate_payload: async (ctx, args) =>\n validatePayload(ctx.contract, {\n method: String(args.method ?? 'POST'),\n path: String(args.path ?? ''),\n body: (args.body ?? {}) as Record<string, unknown>,\n }),\n\n // ------------------------------------------------------------- generic read\n api_get: async (ctx, args) => {\n const path = String(args.path ?? '');\n if (!path.startsWith('/api/v1/')) {\n throw new Error(\n `Refusing to call \"${path}\". api_get only reads paths beginning with /api/v1/ on the configured Throttle host.`,\n );\n }\n return ctx.client.get(path);\n },\n\n // ------------------------------------------------------------------ orders\n search_orders: async (ctx, args) =>\n ctx.client.list('/api/v1/orders', {\n q: args.q,\n status: args.status,\n paymentStatus: args.paymentStatus,\n ...page(args),\n }),\n\n get_order: async (ctx, args) => {\n const id = String(args.id);\n const order = await ctx.client.get(`/api/v1/orders/${id}`);\n const [payments, returns, fulfillments] = await Promise.all([\n optional(() => ctx.client.list(`/api/v1/orders/${id}/payments`)),\n optional(() => ctx.client.list(`/api/v1/orders/${id}/returns`)),\n optional(() => ctx.client.list(`/api/v1/orders/${id}/fulfillments`)),\n ]);\n return {\n order,\n payments: payments.ok ? payments.value.data : payments.unavailable,\n returns: returns.ok ? returns.value.data : returns.unavailable,\n fulfillments: fulfillments.ok ? fulfillments.value.data : fulfillments.unavailable,\n };\n },\n\n // --------------------------------------------------------------- customers\n search_customers: async (ctx, args) =>\n ctx.client.list('/api/v1/customers', { q: args.q, ...page(args) }),\n\n get_customer: async (ctx, args) => {\n const id = String(args.id);\n const customer = await ctx.client.get(`/api/v1/customers/${id}`);\n const [addresses, subscriptions] = await Promise.all([\n optional(() => ctx.client.list(`/api/v1/customers/${id}/addresses`)),\n optional(() => ctx.client.list('/api/v1/subscriptions', { customerId: id })),\n ]);\n return {\n customer,\n addresses: addresses.ok ? addresses.value.data : addresses.unavailable,\n subscriptions: subscriptions.ok ? subscriptions.value.data : subscriptions.unavailable,\n };\n },\n\n // ----------------------------------------------------------- subscriptions\n list_subscriptions: async (ctx, args) =>\n ctx.client.list('/api/v1/subscriptions', {\n customerId: args.customerId,\n status: args.status,\n ...page(args),\n }),\n\n get_subscription: async (ctx, args) => ctx.client.get(`/api/v1/subscriptions/${String(args.id)}`),\n\n // ------------------------------------------------------------------ quotes\n search_quotes: async (ctx, args) =>\n ctx.client.list('/api/v1/quotes', { status: args.status, ...page(args) }),\n\n get_quote: async (ctx, args) => ctx.client.get(`/api/v1/quotes/${String(args.id)}`),\n\n // ---------------------------------------------------------------- invoices\n list_invoices: async (ctx, args) =>\n ctx.client.list('/api/v1/invoices', { status: args.status, ...page(args) }),\n\n receivables_aging: async (ctx) => ctx.client.get('/api/v1/invoices/aging'),\n\n // --------------------------------------------------------------- discounts\n search_discounts: async (ctx, args) =>\n ctx.client.list('/api/v1/discounts', {\n q: args.q,\n code: args.code,\n type: args.type,\n isActive: args.isActive,\n createdAfter: args.createdAfter,\n createdBefore: args.createdBefore,\n ...page(args),\n }),\n\n get_discount: async (ctx, args) => ctx.client.get(`/api/v1/discounts/${String(args.id)}`),\n\n // ---------------------------------------------------------------- payments\n search_payments: async (ctx, args) =>\n ctx.client.list('/api/v1/payments', {\n method: args.method,\n status: args.status,\n // The route only accepts these as snake_case query params -- confirmed\n // by reading its querystring schema directly, not assumed from the\n // platform's usual camelCase convention.\n order_id: args.orderId,\n aging: args.aging,\n due_from: args.dueFrom,\n due_to: args.dueTo,\n amount_min: args.amountMin,\n amount_max: args.amountMax,\n ...page(args),\n }),\n\n get_payment: async (ctx, args) => {\n const id = String(args.id);\n const payment = await ctx.client.get(`/api/v1/payments/${id}`);\n const transactions = await optional(() => ctx.client.list(`/api/v1/payments/${id}/transactions`));\n return {\n payment,\n transactions: transactions.ok ? transactions.value.data : transactions.unavailable,\n };\n },\n\n // ---------------------------------------------------------------- invoices\n get_invoice: async (ctx, args) => ctx.client.get(`/api/v1/invoices/${String(args.id)}`),\n\n // ------------------------------------------------------------------ carts\n list_abandoned_carts: async (ctx, args) => {\n const [carts, summary] = await Promise.all([\n optional(() => ctx.client.list('/api/v1/abandoned-carts', { ...page(args) })),\n optional(() => ctx.client.get('/api/v1/abandoned-carts/summary', { sinceDays: args.sinceDays })),\n ]);\n return {\n carts: carts.ok ? carts.value.data : carts.unavailable,\n summary: summary.ok ? summary.value : summary.unavailable,\n };\n },\n\n // --------------------------------------------------------------- debugging\n search_events: async (ctx, args) =>\n ctx.client.list('/api/v1/events', {\n type: args.type,\n entityType: args.entityType,\n entityId: args.entityId,\n ...page(args),\n }),\n\n list_webhook_deliveries: async (ctx, args) =>\n ctx.client.list('/api/v1/webhook-deliveries', {\n endpointId: args.endpointId,\n status: args.status,\n limit: args.limit,\n }),\n\n get_webhook_delivery: async (ctx, args) =>\n ctx.client.get(`/api/v1/webhook-deliveries/${String(args.id)}`),\n\n send_test_webhook: async (ctx, args) =>\n ctx.client.post(`/api/v1/webhook-endpoints/${String(args.id)}/test`, {\n body: { eventType: args.eventType },\n idempotencyKey: `mcp-send-test-webhook-${String(args.id)}-${Date.now()}`,\n }),\n\n replay_webhook_delivery: async (ctx, args) =>\n ctx.client.post(`/api/v1/webhook-deliveries/${String(args.id)}/replay`, {\n idempotencyKey: `mcp-replay-webhook-delivery-${String(args.id)}-${Date.now()}`,\n }),\n\n explain_checkout_failure: async (ctx, args) => {\n const id = String(args.id);\n const session = await optional(() => ctx.client.get<any>(`/api/v1/checkout-sessions/${id}`));\n if (!session.ok) {\n return {\n note: `No checkout session ${id} (${session.unavailable}). If this is a cart id, read the cart with api_get /api/v1/carts/${id} and search_events for its activity.`,\n };\n }\n const cartId = (session.value?.cartId as string | undefined) ?? undefined;\n const [cart, sessionEvents, cartEvents, deliveries] = await Promise.all([\n optional(() => ctx.client.get(`/api/v1/checkout-sessions/${id}/cart`)),\n optional(() => ctx.client.list('/api/v1/events', { entityId: id, limit: 25 })),\n cartId\n ? optional(() => ctx.client.list('/api/v1/events', { entityId: cartId, limit: 25 }))\n : Promise.resolve({ ok: true as const, value: { data: [], pagination: null } }),\n optional(() => ctx.client.list('/api/v1/webhook-deliveries', { limit: 15 })),\n ]);\n return {\n session: session.value,\n cart: cart.ok ? cart.value : cart.unavailable,\n events: [\n ...(sessionEvents.ok ? sessionEvents.value.data : []),\n ...(cartEvents.ok ? cartEvents.value.data : []),\n ],\n eventsUnavailable: sessionEvents.ok ? undefined : sessionEvents.unavailable,\n recentWebhookDeliveries: deliveries.ok ? deliveries.value.data : deliveries.unavailable,\n hint: 'Compare the session state against the events: a session that never emitted checkout_started usually means the browser SDK failed before submitting, not a payment decline.',\n };\n },\n\n // ------------------------------------------------------------ sandbox seed\n seed_test_data: async (ctx, args) => {\n // Belt and braces: the server also refuses to register this tool against a\n // production credential, but a guard at the call site means no future\n // registration change can turn it into a live-data generator.\n if (ctx.identity.environment.providerEnvironment === 'production') {\n throw new Error(\n 'seed_test_data refuses to run against a production environment. Use a non-production API key.',\n );\n }\n const stamp = Date.now();\n const customer = await ctx.client.post<any>('/api/v1/customers', {\n body: {\n email: String(args.customerEmail ?? `mcp-seed-${stamp}@example.test`),\n firstName: 'Seed',\n lastName: 'Customer',\n },\n idempotencyKey: `mcp-seed-customer-${stamp}`,\n });\n const cart = await ctx.client.post<any>('/api/v1/carts', {\n // Unlike /api/v1/customers, cart creation requires applicationId\n // explicitly in the body (it's cross-checked against the caller's own\n // authenticated application, not inferred) -- omitting it is a real\n // 400 missing_application_id from the live API, not a hypothetical.\n body: { applicationId: ctx.identity.application?.id, customerId: customer?.id },\n idempotencyKey: `mcp-seed-cart-${stamp}`,\n });\n const requested = Array.isArray(args.lineItems) && args.lineItems.length > 0\n ? (args.lineItems as Record<string, unknown>[])\n : [{ name: 'Seed widget', unitPrice: 2500, quantity: 2 }];\n const items: unknown[] = [];\n for (const [index, item] of requested.entries()) {\n items.push(\n await ctx.client.post(`/api/v1/carts/${cart?.id}/items`, {\n body: item,\n idempotencyKey: `mcp-seed-item-${stamp}-${index}`,\n }),\n );\n }\n const order = await ctx.client.post(`/api/v1/carts/${cart?.id}/finalize`, {\n idempotencyKey: `mcp-seed-finalize-${stamp}`,\n });\n return {\n environment: ctx.identity.environment.slug,\n customer,\n cart,\n lineItems: items,\n order,\n note: 'Seeded a finalized DRAFT order. No payment was captured — that needs a browser-tokenised payment method, which a server-side key cannot produce.',\n };\n },\n\n // -------------------------------------------------------------- money/mail\n manage_subscription: async (ctx, args) => {\n const id = String(args.id);\n const action = String(args.action);\n if (action !== 'pause' && action !== 'resume') {\n throw new Error(`manage_subscription: action must be \"pause\" or \"resume\", got \"${action}\".`);\n }\n return ctx.client.post(`/api/v1/subscriptions/${id}/${action}`, {\n idempotencyKey: `mcp-manage-subscription-${id}-${action}-${Date.now()}`,\n });\n },\n\n create_quote: async (ctx, args) =>\n // The real route's body shape differs from this tool's flatter,\n // model-facing input: line items are \"items\" (not \"lineItems\"), Net-N\n // terms are nested under paymentTerms.netN with an explicit mode (not a\n // flat \"netN\"), and the buyer-visible note field is \"buyerNote\" (not\n // \"notes\"). Confirmed against packages/platform-api/src/validation/quotes.ts's\n // actual zod schema after a live call 400'd with unrecognized_keys.\n ctx.client.post('/api/v1/quotes', {\n body: {\n customerId: args.customerId,\n items: args.items,\n expiresAt: args.expiresAt,\n paymentTerms:\n args.netN !== undefined ? { mode: 'net_terms', netN: args.netN } : undefined,\n buyerNote: args.notes,\n },\n idempotencyKey: `mcp-create-quote-${String(args.customerId)}-${Date.now()}`,\n }),\n\n get_business_summary: async (ctx, args) =>\n ctx.client.get('/api/v1/analytics/business-summary', { period: args.period }),\n\n get_attention_digest: async (ctx) => ctx.client.get('/api/v1/analytics/attention-digest'),\n\n // ------------------------------------------------------------- extensions\n list_extension_installations: async (ctx, args) =>\n ctx.client.list('/api/v1/installations', { status: args.status, ...page(args) }),\n\n // ------------------------------------------------------------- connectors\n get_connector_routing: async (ctx) => {\n const [paymentRouting, routingConnectors, cardDecline, otherDecline] = await Promise.all([\n optional(() => ctx.client.get('/api/v1/payment-routing')),\n optional(() => ctx.client.get('/api/v1/routing-connectors')),\n optional(() => ctx.client.get('/api/v1/card-decline')),\n optional(() => ctx.client.get('/api/v1/other-decline')),\n ]);\n return {\n paymentRouting: paymentRouting.ok ? paymentRouting.value : paymentRouting.unavailable,\n routingConnectors: routingConnectors.ok ? routingConnectors.value : routingConnectors.unavailable,\n cardDecline: cardDecline.ok ? cardDecline.value : cardDecline.unavailable,\n otherDecline: otherDecline.ok ? otherDecline.value : otherDecline.unavailable,\n };\n },\n\n get_integration_status: async (ctx) => {\n const [connectors, endpoints, coverage] = await Promise.all([\n optional(() => ctx.client.list('/api/v1/connectors')),\n optional(() => ctx.client.list('/api/v1/webhook-endpoints')),\n optional(() => ctx.client.get('/api/v1/webhook-endpoints/coverage')),\n ]);\n return {\n environment: ctx.identity.environment,\n workspace: ctx.identity.workspace,\n application: ctx.identity.application,\n connectors: connectors.ok ? connectors.value.data : connectors.unavailable,\n webhookEndpoints: endpoints.ok ? endpoints.value.data : endpoints.unavailable,\n unsubscribedEvents: coverage.ok ? coverage.value : coverage.unavailable,\n };\n },\n\n // --------------------------------------------------------------- workspace\n get_workspace_settings: async (ctx) => ctx.client.get('/api/v1/merchants/me'),\n\n get_audit_log: async (ctx, args) => ctx.client.list('/api/v1/audit-log', { limit: args.limit }),\n};\n","import { z, type ZodTypeAny } from 'zod';\nimport type { ActionField } from '@core/action-catalog';\n\n/**\n * Projects the catalog's portable field descriptors into a zod shape for the MCP\n * SDK. The catalog stays zod-free on purpose (Zapier and Make runtimes never need\n * it), so the derivation lives here — the one place that does.\n */\nexport function fieldsToZodShape(fields: readonly ActionField[]): Record<string, ZodTypeAny> {\n const shape: Record<string, ZodTypeAny> = {};\n for (const field of fields) {\n shape[field.name] = applyModifiers(field, baseType(field));\n }\n return shape;\n}\n\nfunction baseType(field: ActionField): ZodTypeAny {\n if (field.enum && field.enum.length > 0) {\n return z.enum([...field.enum] as [string, ...string[]]);\n }\n switch (field.type) {\n case 'string':\n return z.string();\n case 'number':\n return z.number();\n case 'boolean':\n return z.boolean();\n case 'array':\n return z.array(z.unknown());\n case 'object':\n return z.record(z.unknown());\n }\n}\n\nfunction applyModifiers(field: ActionField, type: ZodTypeAny): ZodTypeAny {\n const described = type.describe(field.description);\n if (field.required) return described;\n return field.default === undefined ? described.optional() : described.default(field.default);\n}\n","import { readFileSync } from 'node:fs';\nimport type { DocsIndex } from './docs';\nimport type { ContractIndex } from './contract';\n\n/**\n * Indexes are generated into `dist/` at build time and shipped in the tarball. A\n * missing index degrades that one tool instead of preventing boot — the API tools\n * are unaffected and the failure is legible on stderr.\n */\nfunction loadIndex<T extends { generatedAt: string }>(file: string, empty: T, label: string): T {\n try {\n return JSON.parse(readFileSync(new URL(`./${file}`, import.meta.url), 'utf8')) as T;\n } catch {\n process.stderr.write(\n `throttle-mcp: ${label} index missing (${file}); that tool will return no results. Run \"pnpm --filter @usethrottle/mcp build:indexes\".\\n`,\n );\n return empty;\n }\n}\n\nexport function loadDocsIndex(): DocsIndex {\n return loadIndex<DocsIndex>('docs-index.json', { generatedAt: '', entries: [] }, 'docs');\n}\n\nexport function loadContractIndex(): ContractIndex {\n return loadIndex<ContractIndex>('contract-index.json', { generatedAt: '', operations: [] }, 'contract');\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;;;ACGnB,SAAS,SAAS,SAA4B,UAA2B;AAC9E,MAAI,QAAQ,SAAS,GAAG,EAAG,QAAO;AAClC,MAAI,QAAQ,SAAS,QAAQ,EAAG,QAAO;AACvC,QAAM,MAAM,SAAS,YAAY,GAAG;AACpC,MAAI,QAAQ,GAAI,QAAO;AACvB,QAAM,WAAW,SAAS,MAAM,GAAG,GAAG;AACtC,QAAM,SAAS,SAAS,MAAM,MAAM,CAAC;AACrC,MAAI,WAAW,UAAU,QAAQ,SAAS,GAAG,QAAQ,QAAQ,EAAG,QAAO;AACvE,SAAO;AACT;AAsBA,IAAM,MAAgC,CAAC;AAIvC,SAAS,IACP,OACA,UACA,SACA,QACA,OAAa,CAAC,GACd;AACA,QAAM,UAAU,QAAQ,SAAS,MAAM;AACvC,aAAW,UAAU,SAAS;AAC5B,UAAM,KAAK,GAAG,QAAQ,IAAI,MAAM;AAChC,UAAM,UAAU,WAAW,WAAW,UAAU,CAAC,GAAG,QAAQ,OAAO,IAAI,CAAC;AACxE,QAAI,EAAE,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,WAAW,SAAS,OAAO,OAAO,OAAO,UAAU,GAAG,MAAM,IAAI,QAAQ;AAAA,MAChF,WAAW,KAAK,aAAa;AAAA,MAC7B,WAAW,KAAK,aAAa;AAAA;AAAA,MAE7B,oBAAoB,KAAK,sBAAsB;AAAA;AAAA,MAE/C,kBAAkB,KAAK,oBAAoB;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;AAGA,IAAI,UAAU,UAAU,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,eAAe,OAAO,gBAAgB,CAAC;AAE1F,IAAI,UAAU,UAAU,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,eAAe,OAAO,gBAAgB,CAAC;AAC1F,IAAI,UAAU,uBAAuB,CAAC,OAAO,GAAG,EAAE,OAAO,gBAAgB,CAAC;AAC1E,IAAI,UAAU,iBAAiB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,gBAAgB,OAAO,kBAAkB,CAAC;AAEpG,IAAI,YAAY,YAAY,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,iBAAiB,OAAO,kBAAkB,CAAC;AAClG,IAAI,YAAY,0BAA0B,CAAC,OAAO,GAAG,EAAE,OAAO,qBAAqB,CAAC;AACpF,IAAI,YAAY,oBAAoB,CAAC,OAAO,GAAG,EAAE,OAAO,mBAAmB,CAAC;AAC5E,IAAI,YAAY,mBAAmB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,gBAAgB,OAAO,kBAAkB,GAAG,EAAE,WAAW,KAAK,CAAC;AAC7H,IAAI,YAAY,iBAAiB,CAAC,OAAO,GAAG,EAAE,OAAO,gBAAgB,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3F,IAAI,YAAY,oBAAoB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,iBAAiB,OAAO,kBAAkB,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/H,IAAI,YAAY,mBAAmB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,wBAAwB,OAAO,2BAA2B,GAAG,EAAE,WAAW,KAAK,CAAC;AAE9I,IAAI,aAAa,aAAa,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,kBAAkB,OAAO,mBAAmB,CAAC;AACtG,IAAI,aAAa,gBAAgB,CAAC,MAAM,GAAG,EAAE,MAAM,oBAAoB,GAAG,EAAE,WAAW,KAAK,CAAC;AAC7F,IAAI,aAAa,sBAAsB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,kBAAkB,OAAO,mBAAmB,CAAC;AAC/G,IAAI,aAAa,4BAA4B,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,qBAAqB,OAAO,sBAAsB,GAAG,EAAE,WAAW,KAAK,CAAC;AAEhJ,IAAI,SAAS,SAAS,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,cAAc,OAAO,eAAe,CAAC;AACtF,IAAI,SAAS,cAAc,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,mBAAmB,OAAO,oBAAoB,CAAC;AACrG,IAAI,SAAS,qBAAqB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,0BAA0B,OAAO,2BAA2B,CAAC;AAE1H,IAAI,aAAa,aAAa,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,kBAAkB,OAAO,mBAAmB,CAAC;AAEtG,IAAI,iBAAiB,iBAAiB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,sBAAsB,OAAO,uBAAuB,CAAC;AACtH,IAAI,iBAAiB,uBAAuB,CAAC,OAAO,GAAG,EAAE,OAAO,6BAA6B,CAAC;AAC9F,IAAI,iBAAiB,8BAA8B,CAAC,OAAO,GAAG,EAAE,OAAO,uBAAuB,CAAC;AAC/F,IAAI,iBAAiB,sBAAsB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,2BAA2B,OAAO,4BAA4B,GAAG,EAAE,kBAAkB,MAAM,CAAC;AAElK,IAAI,gBAAgB,gBAAgB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,qBAAqB,OAAO,sBAAsB,CAAC;AAClH,IAAI,gBAAgB,yBAAyB,CAAC,OAAO,GAAG,EAAE,OAAO,mBAAmB,CAAC;AACrF,IAAI,gBAAgB,uBAAuB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,yBAAyB,OAAO,0BAA0B,CAAC;AACjI,IAAI,gBAAgB,sBAAsB,CAAC,OAAO,GAAG,EAAE,OAAO,4BAA4B,CAAC;AAC3F,IAAI,gBAAgB,wBAAwB,CAAC,OAAO,GAAG,EAAE,OAAO,6BAA6B,CAAC;AAE9F,IAAI,iBAAiB,YAAY,CAAC,MAAM,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC5E,IAAI,iBAAiB,oBAAoB,CAAC,OAAO,GAAG,EAAE,OAAO,qBAAqB,GAAG,EAAE,WAAW,KAAK,CAAC;AACxG,IAAI,iBAAiB,mBAAmB,CAAC,OAAO,GAAG,EAAE,OAAO,uBAAuB,CAAC;AAEpF,IAAI,kBAAkB,gBAAgB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,4BAA4B,OAAO,2BAA2B,CAAC;AAChI,IAAI,kBAAkB,6BAA6B,CAAC,OAAO,GAAG,EAAE,OAAO,8BAA8B,CAAC;AACtG,IAAI,kBAAkB,mBAAmB,CAAC,OAAO,GAAG,EAAE,OAAO,0BAA0B,GAAG,EAAE,oBAAoB,KAAK,CAAC;AACtH,IAAI,kBAAkB,oBAAoB,CAAC,OAAO,GAAG,EAAE,OAAO,gBAAgB,GAAG,EAAE,oBAAoB,KAAK,CAAC;AAC7G,IAAI,kBAAkB,6BAA6B,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,qBAAqB,OAAO,sBAAsB,CAAC;AACjI,IAAI,kBAAkB,0BAA0B,CAAC,OAAO,GAAG,EAAE,OAAO,4BAA4B,CAAC;AAEjG,IAAI,cAAc,cAAc,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,mBAAmB,OAAO,oBAAoB,CAAC;AAC1G,IAAI,cAAc,yBAAyB,CAAC,OAAO,GAAG,EAAE,OAAO,iCAAiC,CAAC;AAEjG,IAAI,qBAAqB,YAAY,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,iBAAiB,OAAO,kBAAkB,CAAC;AAC3G,IAAI,qBAAqB,sBAAsB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,mBAAmB,OAAO,mBAAmB,CAAC;AACxH,IAAI,qBAAqB,UAAU,CAAC,MAAM,GAAG,EAAE,MAAM,cAAc,CAAC;AACpE,IAAI,qBAAqB,cAAc,CAAC,MAAM,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3E,IAAI,gBAAgB,gBAAgB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,qBAAqB,OAAO,sBAAsB,CAAC;AAElH,IAAI,aAAa,YAAY,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,2BAA2B,OAAO,0BAA0B,CAAC;AACrH,IAAI,aAAa,gBAAgB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,qBAAqB,OAAO,oBAAoB,CAAC;AAC7G,IAAI,aAAa,YAAY,CAAC,OAAO,GAAG,EAAE,OAAO,yBAAyB,CAAC;AAG3E,IAAM,QAAc,EAAE,kBAAkB,MAAM;AAC9C,IAAI,QAAQ,gBAAgB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,gBAAgB,OAAO,iBAAiB,GAAG,KAAK;AACvG,IAAI,QAAQ,gBAAgB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,gBAAgB,OAAO,iBAAiB,GAAG,KAAK;AACvG,IAAI,oBAAoB,WAAW,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,gBAAgB,OAAO,sBAAsB,GAAG,KAAK;AACnH,IAAI,oBAAoB,2BAA2B,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,sBAAsB,OAAO,uBAAuB,GAAG,KAAK;AAC1I,IAAI,SAAS,mBAAmB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,wBAAwB,OAAO,uBAAuB,GAAG,KAAK;AACzH,IAAI,SAAS,kBAAkB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,uBAAuB,OAAO,sBAAsB,GAAG,KAAK;AACtH,IAAI,WAAW,WAAW,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,uBAAuB,OAAO,iBAAiB,GAAG,KAAK;AAC5G,IAAI,WAAW,WAAW,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,wBAAwB,OAAO,uBAAuB,GAAG,KAAK;AACnH,IAAI,WAAW,cAAc,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,mBAAmB,OAAO,oBAAoB,GAAG,KAAK;AAC9G,IAAI,iBAAiB,iBAAiB,CAAC,OAAO,GAAG,EAAE,OAAO,qBAAqB,GAAG,KAAK;AACvF,IAAI,iBAAiB,eAAe,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,oBAAoB,OAAO,mBAAmB,GAAG,KAAK;AACrH,IAAI,gBAAgB,gBAAgB,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,qBAAqB,OAAO,sBAAsB,GAAG,KAAK;AACzH,IAAI,WAAW,WAAW,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,wBAAwB,OAAO,yBAAyB,GAAG,KAAK;AACrH,IAAI,iBAAiB,SAAS,CAAC,QAAQ,OAAO,GAAG,EAAE,MAAM,mBAAmB,OAAO,wBAAwB,GAAG,EAAE,WAAW,MAAM,WAAW,MAAM,kBAAkB,MAAM,CAAC;AAK3K;AAAA,EAAI;AAAA,EAAc;AAAA,EAAc,CAAC,QAAQ,OAAO;AAAA,EAC9C,EAAE,MAAM,8BAA8B,OAAO,uCAAuC;AAAA,EAAG;AAAK;AAE9F,IAAI,oBAAoB,IAAI;AAAA,EAC1B,IAAI;AAAA,EAAsB,UAAU;AAAA,EAAc,QAAQ;AAAA,EAC1D,OAAO;AAAA,EAAc,OAAO;AAAA,EAC5B,WAAW;AAAA,EAAO,WAAW;AAAA,EAAO,oBAAoB;AAAA,EAAO,kBAAkB;AAAA,EAAO,SAAS,CAAC;AACpG;AAGA,IAAI,GAAG,IAAI;AAAA,EACT,IAAI;AAAA,EAAK,UAAU;AAAA,EAAK,QAAQ;AAAA,EAAS,OAAO;AAAA,EAAU,OAAO;AAAA,EACjE,WAAW;AAAA,EAAM,WAAW;AAAA,EAAO,oBAAoB;AAAA,EAAO,kBAAkB;AAAA,EAAO,SAAS,CAAC;AACnG;AAEO,IAAM,iBAAqD;AAE3D,IAAM,gBAAmC,OAAO,KAAK,GAAG;AAGxD,IAAM,gBAA0C,MAAM;AAC3D,QAAM,MAAgC,CAAC;AACvC,aAAW,OAAO,OAAO,OAAO,GAAG,GAAG;AACpC,QAAI,IAAI,OAAO,IAAK;AACpB,KAAC,IAAI,IAAI,KAAK,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE;AAAA,EACrC;AACA,SAAO;AACT,GAAG;;;AClHH,IAAM,wBAAgD;AAAA,EACpD,oBAAoB;AAAA,EACpB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,2BAA2B;AAAA,EAC3B,iCAAiC;AACnC;AAIA,IAAM,eAAwC;AAAA,EAC5C,CAAC,qBAAqB,YAAY;AAAA,EAClC,CAAC,SAAS,YAAY;AAAA,EACtB,CAAC,UAAU,aAAa;AAAA,EACxB,CAAC,UAAU,aAAa;AAAA,EACxB,CAAC,WAAW,oBAAoB;AAAA,EAChC,CAAC,YAAY,eAAe;AAAA,EAC5B,CAAC,aAAa,gBAAgB;AAAA,EAC9B,CAAC,iBAAiB,oBAAoB;AAAA,EACtC,CAAC,gBAAgB,mBAAmB;AAAA,EACpC,CAAC,aAAa,gBAAgB;AAAA,EAC9B,CAAC,YAAY,eAAe;AAAA,EAC5B,CAAC,iBAAiB,mBAAmB;AAAA,EACrC,CAAC,cAAc,cAAc;AAAA,EAC7B,CAAC,cAAc,eAAe;AAChC;AAGO,SAAS,eAAe,MAAsB;AACnD,MAAI,sBAAsB,IAAI,EAAG,QAAO,sBAAsB,IAAI;AAClE,aAAW,CAAC,QAAQ,KAAK,KAAK,cAAc;AAC1C,QAAI,KAAK,WAAW,MAAM,EAAG,QAAO;AAAA,EACtC;AACA,QAAM,IAAI,MAAM,uBAAuB,IAAI,EAAE;AAC/C;;;AClDO,IAAM,qBACX,OAAO,OAAO,cAAc,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;;;ACjC5E,IAAM,UAAuC;AAAA;AAAA,EAElD;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,iBAAiB,CAAC;AAAA,IACpD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,MACL,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,MAAM,aAAa,sBAAsB;AAAA,MACpF,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,mBAAmB;AAAA,IACpF;AAAA,IACA,UAAU,CAAC;AAAA,IACX,UAAU,CAAC,KAAK;AAAA,EAClB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM,CAAC,OAAO,QAAQ,SAAS,OAAO,QAAQ;AAAA,MAChD;AAAA,IACF;AAAA,IACA,UAAU,CAAC;AAAA,IACX,UAAU,CAAC,KAAK;AAAA,EAClB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,MACL,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,MAAM,aAAa,eAAe;AAAA,MAC9E,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,MAAM,aAAa,iBAAiB;AAAA,MAC9E,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,MAAM,aAAa,6BAA6B;AAAA,IAC5F;AAAA,IACA,UAAU,CAAC;AAAA,IACX,UAAU,CAAC,KAAK;AAAA,EAClB;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU,CAAC;AAAA,IACX,UAAU,CAAC,KAAK;AAAA,IAChB,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,aAAa;AAAA,IACtB,OAAO;AAAA,MACL,EAAE,MAAM,KAAK,MAAM,UAAU,UAAU,OAAO,aAAa,oBAAoB;AAAA,MAC/E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,uBAAuB;AAAA,MACvF,EAAE,MAAM,iBAAiB,MAAM,UAAU,UAAU,OAAO,aAAa,yBAAyB;AAAA,MAChG,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,iBAAiB,CAAC;AAAA,IACpD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,aAAa;AAAA,IACtB,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,YAAY,CAAC;AAAA,IAChF,UAAU;AAAA,MACR,EAAE,QAAQ,OAAO,MAAM,qBAAqB;AAAA,MAC5C,EAAE,QAAQ,OAAO,MAAM,8BAA8B;AAAA,MACrD,EAAE,QAAQ,OAAO,MAAM,6BAA6B;AAAA,MACpD,EAAE,QAAQ,OAAO,MAAM,uCAAuC;AAAA,IAChE;AAAA,IACA,UAAU,CAAC,KAAK;AAAA,IAChB,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,gBAAgB;AAAA,IACzB,OAAO;AAAA,MACL,EAAE,MAAM,KAAK,MAAM,UAAU,UAAU,OAAO,aAAa,oBAAoB;AAAA,MAC/E,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,oBAAoB,CAAC;AAAA,IACvD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,gBAAgB;AAAA,IACzB,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,eAAe,CAAC;AAAA,IACnF,UAAU;AAAA,MACR,EAAE,QAAQ,OAAO,MAAM,wBAAwB;AAAA,MAC/C,EAAE,QAAQ,OAAO,MAAM,kCAAkC;AAAA,MACzD,EAAE,QAAQ,OAAO,MAAM,wBAAwB;AAAA,IACjD;AAAA,IACA,UAAU,CAAC,KAAK;AAAA,IAChB,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,oBAAoB;AAAA,IAC7B,OAAO;AAAA,MACL,EAAE,MAAM,cAAc,MAAM,UAAU,UAAU,OAAO,aAAa,sBAAsB;AAAA,MAC1F,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,oBAAoB;AAAA,MACpF,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,wBAAwB,CAAC;AAAA,IAC3D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,oBAAoB;AAAA,IAC7B,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,mBAAmB,CAAC;AAAA,IACvF,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,4BAA4B,CAAC;AAAA,IAC/D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,aAAa;AAAA,IACtB,OAAO;AAAA,MACL,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,0BAA0B;AAAA,MAC1F,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,iBAAiB,CAAC;AAAA,IACpD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,aAAa;AAAA,IACtB,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,YAAY,CAAC;AAAA,IAChF,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,qBAAqB,CAAC;AAAA,IACxD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,eAAe;AAAA,IACxB,OAAO;AAAA,MACL,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,4BAA4B;AAAA,MAC5F,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,mBAAmB,CAAC;AAAA,IACtD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,eAAe;AAAA,IACxB,OAAO,CAAC;AAAA,IACR,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,yBAAyB,CAAC;AAAA,IAC5D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,gBAAgB;AAAA,IACzB,OAAO;AAAA,MACL,EAAE,MAAM,KAAK,MAAM,UAAU,UAAU,OAAO,aAAa,oBAAoB;AAAA,MAC/E,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,OAAO,aAAa,oBAAoB;AAAA,MAClF;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM,CAAC,cAAc,cAAc;AAAA,MACrC;AAAA,MACA,EAAE,MAAM,YAAY,MAAM,WAAW,UAAU,OAAO,aAAa,0BAA0B;AAAA,MAC7F,EAAE,MAAM,gBAAgB,MAAM,UAAU,UAAU,OAAO,aAAa,6BAA6B;AAAA,MACnG,EAAE,MAAM,iBAAiB,MAAM,UAAU,UAAU,OAAO,aAAa,6BAA6B;AAAA,MACpG,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,oBAAoB,CAAC;AAAA,IACvD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,gBAAgB;AAAA,IACzB,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,eAAe,CAAC;AAAA,IACnF,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,wBAAwB,CAAC;AAAA,IAC3D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,eAAe;AAAA,IACxB,OAAO;AAAA,MACL,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,4BAA4B;AAAA,MAC5F,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,4BAA4B;AAAA,MAC5F,EAAE,MAAM,WAAW,MAAM,UAAU,UAAU,OAAO,aAAa,uBAAuB;AAAA,MACxF;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM,CAAC,QAAQ,SAAS,SAAS,SAAS;AAAA,MAC5C;AAAA,MACA,EAAE,MAAM,WAAW,MAAM,UAAU,UAAU,OAAO,aAAa,oCAAoC;AAAA,MACrG,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,kCAAkC;AAAA,MACjG,EAAE,MAAM,aAAa,MAAM,UAAU,UAAU,OAAO,aAAa,+BAA+B;AAAA,MAClG,EAAE,MAAM,aAAa,MAAM,UAAU,UAAU,OAAO,aAAa,+BAA+B;AAAA,MAClG,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,mBAAmB,CAAC;AAAA,IACtD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,eAAe;AAAA,IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,cAAc,CAAC;AAAA,IAClF,UAAU;AAAA,MACR,EAAE,QAAQ,OAAO,MAAM,uBAAuB;AAAA,MAC9C,EAAE,QAAQ,OAAO,MAAM,oCAAoC;AAAA,IAC7D;AAAA,IACA,UAAU,CAAC,KAAK;AAAA,IAChB,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,eAAe;AAAA,IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,cAAc,CAAC;AAAA,IAClF,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,uBAAuB,CAAC;AAAA,IAC1D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,YAAY;AAAA,IACrB,OAAO;AAAA,MACL,EAAE,MAAM,aAAa,MAAM,UAAU,UAAU,OAAO,aAAa,8BAA8B;AAAA,MACjG,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU;AAAA,MACR,EAAE,QAAQ,OAAO,MAAM,0BAA0B;AAAA,MACjD,EAAE,QAAQ,OAAO,MAAM,kCAAkC;AAAA,IAC3D;AAAA,IACA,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY,CAAC,+FAA+F;AAAA,EAC9G;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,aAAa;AAAA,IACtB,OAAO;AAAA,MACL,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,OAAO,aAAa,kCAAkC;AAAA,MAChG,EAAE,MAAM,cAAc,MAAM,UAAU,UAAU,OAAO,aAAa,sBAAsB;AAAA,MAC1F,EAAE,MAAM,YAAY,MAAM,UAAU,UAAU,OAAO,aAAa,oBAAoB;AAAA,MACtF,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,iBAAiB,CAAC;AAAA,IACpD,UAAU,CAAC,OAAO,KAAK;AAAA,EACzB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,yBAAyB;AAAA,IAClC,OAAO;AAAA,MACL,EAAE,MAAM,cAAc,MAAM,UAAU,UAAU,OAAO,aAAa,sBAAsB;AAAA,MAC1F,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,6BAA6B;AAAA,MAC7F,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,IAC9E;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,6BAA6B,CAAC;AAAA,IAChE,UAAU,CAAC,OAAO,KAAK;AAAA,EACzB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,yBAAyB;AAAA,IAClC,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,eAAe,CAAC;AAAA,IACnF,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,iCAAiC,CAAC;AAAA,IACpE,UAAU,CAAC,OAAO,KAAK;AAAA,EACzB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,wBAAwB;AAAA,IACjC,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,EAAE,QAAQ,OAAO,MAAM,gCAAgC;AAAA,MACvD,EAAE,QAAQ,OAAO,MAAM,qCAAqC;AAAA,MAC5D,EAAE,QAAQ,OAAO,MAAM,iBAAiB;AAAA,MACxC,EAAE,QAAQ,OAAO,MAAM,6BAA6B;AAAA,IACtD;AAAA,IACA,UAAU,CAAC,KAAK;AAAA,IAChB,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,iBAAiB;AAAA,IAC1B,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM,CAAC,UAAU,aAAa,aAAa;AAAA,MAC7C;AAAA,MACA,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,aAAa;AAAA,MAC5E,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,qBAAqB;AAAA,IACvF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,wBAAwB,CAAC;AAAA,IAC3D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,iBAAiB;AAAA,IAC1B,OAAO,CAAC;AAAA,IACR,UAAU;AAAA,MACR,EAAE,QAAQ,OAAO,MAAM,0BAA0B;AAAA,MACjD,EAAE,QAAQ,OAAO,MAAM,6BAA6B;AAAA,MACpD,EAAE,QAAQ,OAAO,MAAM,uBAAuB;AAAA,MAC9C,EAAE,QAAQ,OAAO,MAAM,wBAAwB;AAAA,IACjD;AAAA,IACA,UAAU,CAAC,KAAK;AAAA,IAChB,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,UAAU;AAAA,MACR,EAAE,QAAQ,OAAO,MAAM,iBAAiB;AAAA,MACxC,EAAE,QAAQ,OAAO,MAAM,qBAAqB;AAAA,MAC5C,EAAE,QAAQ,OAAO,MAAM,4BAA4B;AAAA,MACnD,EAAE,QAAQ,OAAO,MAAM,qCAAqC;AAAA,IAC9D;AAAA,IACA,UAAU,CAAC,KAAK;AAAA,IAChB,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,eAAe;AAAA,IACxB,OAAO,CAAC;AAAA,IACR,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,uBAAuB,CAAC;AAAA,IAC1D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,iBAAiB;AAAA,IAC1B,OAAO;AAAA,MACL,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,4BAA4B,SAAS,IAAI;AAAA,IAC1G;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,oBAAoB,CAAC;AAAA,IACvD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM,CAAC,QAAQ,SAAS,SAAS;AAAA,QACjC,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,qCAAqC,CAAC;AAAA,IACxE,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,UAAU,CAAC,EAAE,QAAQ,OAAO,MAAM,qCAAqC,CAAC;AAAA,IACxE,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,mBAAmB,eAAe,kBAAkB;AAAA,IAC7D,OAAO;AAAA,MACL,EAAE,MAAM,iBAAiB,MAAM,UAAU,UAAU,OAAO,aAAa,iCAAiC;AAAA,MACxG,EAAE,MAAM,aAAa,MAAM,SAAS,UAAU,OAAO,aAAa,2DAA2D;AAAA,IAC/H;AAAA,IACA,UAAU;AAAA,MACR,EAAE,QAAQ,QAAQ,MAAM,oBAAoB;AAAA,MAC5C,EAAE,QAAQ,QAAQ,MAAM,gBAAgB;AAAA,MACxC,EAAE,QAAQ,QAAQ,MAAM,0BAA0B;AAAA,MAClD,EAAE,QAAQ,QAAQ,MAAM,6BAA6B;AAAA,IACvD;AAAA,IACA,UAAU,CAAC,KAAK;AAAA,IAChB,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,YAAY;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,cAAc;AAAA,IACvB,OAAO;AAAA,MACL,EAAE,MAAM,cAAc,MAAM,UAAU,UAAU,MAAM,aAAa,6BAA6B;AAAA,MAChG,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,MAAM,aAAa,mDAAmD;AAAA,MAChH,EAAE,MAAM,aAAa,MAAM,UAAU,UAAU,OAAO,aAAa,mBAAmB;AAAA,MACtF,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,OAAO,aAAa,+CAA+C;AAAA,MAC7G,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,OAAO,aAAa,uBAAuB;AAAA,IACxF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,QAAQ,MAAM,iBAAiB,CAAC;AAAA,IACrD,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,cAAc;AAAA,IACvB,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,YAAY,CAAC;AAAA,IAChF,UAAU,CAAC,EAAE,QAAQ,QAAQ,MAAM,2BAA2B,CAAC;AAAA,IAC/D,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY;AAAA,IACZ,YAAY,CAAC,gFAAgF;AAAA,EAC/F;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,QAAQ,CAAC,uBAAuB;AAAA,IAChC,OAAO;AAAA,MACL,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,cAAc;AAAA,MACzE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,OAAO,aAAa,iCAAiC;AAAA,IACnG;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,QAAQ,MAAM,8BAA8B,CAAC;AAAA,IAClE,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY;AAAA,IACZ,YAAY;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,2BAA2B;AAAA,IACpC,OAAO;AAAA,MACL,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,mBAAmB;AAAA,MAC9E;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM,CAAC,SAAS,QAAQ;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,EAAE,QAAQ,QAAQ,MAAM,kCAAkC;AAAA,MAC1D,EAAE,QAAQ,QAAQ,MAAM,mCAAmC;AAAA,IAC7D;AAAA,IACA,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,kCAAkC;AAAA,IAC3C,OAAO;AAAA,MACL,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,mBAAmB;AAAA,MAC9E;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,QAAQ,MAAM,mCAAmC,CAAC;AAAA,IACvE,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK;AAAA,IACzC,YAAY;AAAA,IACZ,YAAY,CAAC,kEAAkE;AAAA,EACjF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,0BAA0B;AAAA,IACnC,OAAO,CAAC,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,eAAe,CAAC;AAAA,IACnF,UAAU,CAAC,EAAE,QAAQ,QAAQ,MAAM,wCAAwC,CAAC;AAAA,IAC5E,UAAU,CAAC,OAAO,KAAK;AAAA,IACvB,YAAY;AAAA,IACZ,YAAY,CAAC,oFAAoF;AAAA,EACnG;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,gBAAgB;AAAA,IACzB,OAAO;AAAA,MACL,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,MAAM,aAAa,eAAe;AAAA,MAC1E,EAAE,MAAM,aAAa,MAAM,UAAU,UAAU,OAAO,aAAa,0BAA0B;AAAA,IAC/F;AAAA,IACA,UAAU,CAAC,EAAE,QAAQ,QAAQ,MAAM,qCAAqC,CAAC;AAAA,IACzE,UAAU,CAAC,OAAO,KAAK;AAAA,IACvB,YAAY;AAAA,EACd;AACF;;;ACpsBA,IAAM,UAAkD,CAAC,UAAU,QAAQ,KAAK;AAEhF,SAAS,QACP,IACA,OACA,WACA,aACmB;AACnB,SAAO,EAAE,IAAI,OAAO,WAAW,aAAa,OAAO,eAAe,SAAS,GAAG,UAAU,QAAQ;AAClG;AAEO,IAAM,WAAyC;AAAA,EACpD,QAAQ,aAAa,aAAa,iBAAiB,iCAAiC;AAAA,EACpF;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACvDO,SAAS,kBAAkB,SAAsC;AACtE,SAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS,OAAO,CAAC;AAC3D;AAcO,SAAS,aAAa,SAA4B,QAAmC;AAC1F,SAAO,OAAO,OAAO,MAAM,CAAC,aAAa,SAAS,SAAqB,QAAQ,CAAC;AAClF;;;AC7BA,IAAM,YAAY;AAGlB,SAAS,MAAM,OAAyB;AACtC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,KAAK;AAChD,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,MAA+B,CAAC;AACtC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAgC,GAAG;AAC3E,UAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,UAAI,GAAG,IAAI,MAAM,KAAK;AAAA,IACxB;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,aAAa,OAAwB;AACnD,QAAM,OAAO,KAAK,UAAU,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK;AACtD,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,SAAO,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;AAAA;AAAA,sBAAsB,SAAS;AACnE;AAOO,SAAS,YAAY,OAAwB;AAClD,QAAM,IAAI;AACV,MAAI,GAAG,QAAQ,GAAG,SAAS;AACzB,UAAM,SAAS,EAAE,UAAU;AAAA;AAAA,WAAgB,KAAK,UAAU,EAAE,OAAO,CAAC,KAAK;AACzE,WAAO,sBAAsB,EAAE,IAAI,GAAG,EAAE,aAAa,UAAU,EAAE,UAAU,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM;AAAA,EAC5G;AACA,SAAO,UAAU,GAAG,WAAW,OAAO,KAAK,CAAC;AAC9C;;;ACnCA,IAAI,gBAAgB,cAAc,MAAM;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,MAAM;AAChB,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,aAAa,KAAK;AACvB,SAAK,UAAU,KAAK;AACpB,SAAK,OAAO,KAAK;AACjB,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;;;ACRO,IAAM,mBAAN,cAA+B,cAAc;AAAA,EAClD,YAAY,MAAc,SAAiB,YAAoB,SAAmB;AAChF,UAAM,EAAE,MAAM,SAAS,YAAY,QAAQ,CAAC;AAC5C,SAAK,OAAO;AAAA,EACd;AACF;AAyBO,SAAS,WAAW,OAAoD;AAC7E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,GAAI;AAC3D,WAAO,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,EAC/B;AACA,QAAM,KAAK,OAAO,SAAS;AAC3B,SAAO,KAAK,IAAI,EAAE,KAAK;AACzB;AAIO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YACmB,MACA,YAAqB,OACtC;AAFiB;AACA;AAAA,EAChB;AAAA,EAEH,MAAc,YACZ,QACA,MACA,UAA0B,CAAC,GACO;AAClC,UAAM,MAAM,GAAG,KAAK,KAAK,WAAW,QAAQ,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,WAAW,QAAQ,KAAK,CAAC;AACzF,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,aAAa,KAAK,KAAK;AAAA,IACzB;AACA,QAAI,QAAQ,eAAgB,SAAQ,iBAAiB,IAAI,QAAQ;AAKjE,UAAM,YAAY,WAAW,UAAU,WAAW,WAAW,WAAW;AACxE,UAAM,OACJ,QAAQ,SAAS,SACb,KAAK,UAAU,QAAQ,IAAI,IAC3B,YACE,OACA;AAER,UAAM,MAAM,MAAM,KAAK,UAAU,KAAK,EAAE,QAAQ,SAAS,KAAK,CAAC;AAC/D,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,SAAkC,CAAC;AACvC,QAAI;AACF,eAAS,OAAQ,KAAK,MAAM,IAAI,IAAgC,CAAC;AAAA,IACnE,QAAQ;AAAA,IAER;AACA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM,OAAO;AAGnB,YAAM,IAAI;AAAA,QACR,KAAK,QAAQ,QAAQ,IAAI,MAAM;AAAA,QAC/B,KAAK,WAAW,mBAAmB,IAAI,MAAM,MAAM,KAAK,MAAM,GAAG,GAAG,CAAC;AAAA,QACrE,IAAI;AAAA,QACJ,KAAK;AAAA,MACP;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,IAAO,MAAc,OAA6C;AACtE,UAAM,OAAO,MAAM,KAAK,YAAY,OAAO,MAAM,EAAE,MAAM,CAAC;AAC1D,WAAQ,QAAQ,OAAO,SAAS,YAAY,UAAU,OAAO,KAAK,OAAO;AAAA,EAC3E;AAAA,EAEA,MAAM,KAAQ,MAAc,OAAyD;AACnF,UAAM,OAAO,MAAM,KAAK,YAAY,OAAO,MAAM,EAAE,MAAM,CAAC;AAC1D,UAAM,OAAQ,UAAU,OAAO,KAAK,OAAO;AAC3C,UAAM,OAAO,KAAK;AAClB,WAAO,EAAE,MAAM,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,YAAY,MAAM,cAAc,KAAK;AAAA,EACvF;AAAA,EAEA,MAAM,KAAQ,MAAc,UAA0B,CAAC,GAAe;AACpE,UAAM,OAAO,MAAM,KAAK,YAAY,QAAQ,MAAM,OAAO;AACzD,WAAQ,QAAQ,OAAO,SAAS,YAAY,UAAU,OAAO,KAAK,OAAO;AAAA,EAC3E;AACF;AAUA,eAAsB,SACpB,MACsE;AACtE,MAAI;AACF,WAAO,EAAE,IAAI,MAAM,OAAO,MAAM,KAAK,EAAE;AAAA,EACzC,SAAS,OAAO;AACd,UAAM,IAAI;AACV,UAAM,OAAO,GAAG,QAAQ;AACxB,UAAM,SACJ,SAAS,wBACL,sDACA,SAAS,cACP,cACA,gBAAgB,IAAI;AAC5B,WAAO,EAAE,IAAI,OAAO,aAAa,OAAO;AAAA,EAC1C;AACF;;;ACxGO,IAAM,iBAAyC;AAAA,EACpD,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc;AAAA,EACd,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAEO,SAAS,aAAa,MAAsB;AACjD,SAAO,KAAK,QAAQ,gBAAgB,CAAC,GAAG,MAAc,EAAE,YAAY,CAAC;AACvE;AAGO,SAAS,cAAc,MAAsB;AAClD,SAAO,KACJ,QAAQ,cAAc,IAAI,EAC1B,QAAQ,mBAAmB,IAAI,EAC/B,QAAQ,OAAO,EAAE;AACtB;AAEA,SAAS,WAAW,MAAwB;AAC1C,SAAO,KAAK,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AACxE;AAEA,SAAS,eAAe,SAA0B;AAChD,SAAO,cAAc,KAAK,OAAO,KAAK,mBAAmB,KAAK,OAAO;AACvE;AAUO,SAAS,YAAY,UAAkB,WAA4B;AACxE,QAAM,IAAI,WAAW,QAAQ;AAC7B,QAAM,IAAI,WAAW,SAAS;AAC9B,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,SAAO,EAAE,MAAM,CAAC,SAAS,MAAM,eAAe,OAAO,KAAK,eAAe,EAAE,CAAC,CAAC,KAAK,YAAY,EAAE,CAAC,CAAC;AACpG;AAGA,SAAS,WAAW,MAAsB;AACxC,SAAO,WAAW,IAAI,EAAE,OAAO,cAAc,EAAE;AACjD;AAEO,SAAS,eACd,OACA,OACqB;AACrB,QAAM,SAAS,MAAM,QAAQ,YAAY;AACzC,QAAM,SAAS,MAAM,KAAK,KAAK;AAC/B,QAAM,WAAW,CAAC,OAA0B,CAAC,UAAU,GAAG,WAAW;AAErE,QAAM,UAAU,MAAM,WACnB,OAAO,CAAC,OAAO,SAAS,EAAE,KAAK,YAAY,GAAG,MAAM,MAAM,CAAC,EAC3D,KAAK,CAAC,GAAG,MAAM,WAAW,EAAE,IAAI,IAAI,WAAW,EAAE,IAAI,CAAC;AACzD,MAAI,QAAQ,SAAS,EAAG,QAAO;AAG/B,QAAM,SAAS,cAAc,MAAM,EAAE,QAAQ,QAAQ,EAAE;AACvD,SAAO,MAAM,WAAW,OAAO,CAAC,OAAO,SAAS,EAAE,KAAK,cAAc,GAAG,IAAI,EAAE,SAAS,MAAM,CAAC;AAChG;AAgBO,SAAS,gBACd,OACA,OACkB;AAClB,QAAM,SAA8B,CAAC;AACrC,QAAM,WAAgC,CAAC;AACvC,QAAM,OAAO,OAAO,KAAK,MAAM,QAAQ,CAAC,CAAC;AAIzC,aAAW,OAAO,MAAM;AACtB,UAAM,UAAU,eAAe,GAAG;AAClC,QAAI,SAAS;AACX,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY,QAAQ,OAAO;AAAA,MAC7B,CAAC;AACD;AAAA,IACF;AACA,QAAI,IAAI,SAAS,GAAG,GAAG;AACrB,aAAO,KAAK;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY,QAAQ,aAAa,GAAG,CAAC;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,UAAU,eAAe,OAAO,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,OAAO,CAAC;AAChF,QAAM,YAAY,QAAQ,CAAC;AAC3B,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,GAAG;AAAA,QACH;AAAA,UACE,OAAO,MAAM;AAAA,UACb,SAAS,MAAM,MAAM,OAAO,YAAY,CAAC;AAAA,UACzC,YAAY;AAAA,QACd;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,YAAY;AACzB,WAAO;AAAA,MACL,IAAI,OAAO,WAAW;AAAA,MACtB,SAAS,GAAG,UAAU,MAAM,IAAI,UAAU,IAAI;AAAA,MAC9C;AAAA,MACA;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,QAAQ,IAAI,IAAI,UAAU,WAAW,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAClE,aAAW,OAAO,MAAM;AACtB,QAAI,eAAe,GAAG,KAAK,IAAI,SAAS,GAAG,EAAG;AAC9C,QAAI,CAAC,MAAM,IAAI,GAAG,GAAG;AACnB,eAAS,KAAK;AAAA,QACZ,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AACA,aAAW,SAAS,UAAU,YAAY;AACxC,UAAM,SAAS,MAAM,QAAQ,CAAC,GAAG,MAAM,IAAI;AAC3C,QAAI,UAAU,QAAW;AACvB,UAAI,MAAM,SAAU,QAAO,KAAK,EAAE,OAAO,MAAM,MAAM,SAAS,4BAA4B,CAAC;AAC3F;AAAA,IACF;AAGA,QAAI,MAAM,QAAQ,MAAM,KAAK,SAAS,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,KAAK,SAAS,KAAK,GAAG;AACnG,aAAO,KAAK;AAAA,QACV,OAAO,MAAM;AAAA,QACb,SAAS,UAAU,KAAK;AAAA,QACxB,YAAY,WAAW,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,OAAO,WAAW;AAAA,IACtB,SAAS,GAAG,UAAU,MAAM,IAAI,UAAU,IAAI;AAAA,IAC9C;AAAA,IACA;AAAA,EACF;AACF;;;ACvMA,IAAM,cAAc;AAEpB,SAAS,cAAc,MAAc,QAAgB,SAAS,KAAa;AACzE,QAAM,KAAK,KAAK,YAAY,EAAE,QAAQ,OAAO,YAAY,CAAC;AAC1D,MAAI,KAAK,EAAG,QAAO,KAAK,MAAM,GAAG,SAAS,CAAC,EAAE,KAAK;AAClD,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM;AACrC,QAAM,MAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,OAAO,SAAS,MAAM;AAC7D,SAAO,GAAG,QAAQ,IAAI,WAAM,EAAE,GAAG,KAAK,MAAM,OAAO,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,KAAK,SAAS,WAAM,EAAE;AAC/F;AAEO,SAAS,WACd,OACA,OACA,QAAQ,GACG;AACX,QAAM,SAAS,MAAM,KAAK,EAAE,YAAY;AACxC,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,QAAM,QAAQ,OAAO,MAAM,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAE5D,QAAM,SAAS,MAAM,QAAQ,IAAI,CAAC,UAAU;AAC1C,UAAM,QAAQ,MAAM,MAAM,YAAY;AACtC,UAAM,WAAW,MAAM,SAAS,KAAK,MAAK,EAAE,YAAY;AACxD,UAAM,OAAO,MAAM,KAAK,YAAY;AAEpC,QAAI,QAAQ;AACZ,QAAI,UAAU,OAAQ,UAAS;AAAA,aACtB,MAAM,WAAW,MAAM,EAAG,UAAS;AAAA,aACnC,MAAM,SAAS,MAAM,EAAG,UAAS;AAC1C,QAAI,SAAS,SAAS,MAAM,EAAG,UAAS;AACxC,QAAI,KAAK,SAAS,MAAM,EAAG,UAAS;AAEpC,eAAW,QAAQ,OAAO;AACxB,UAAI,MAAM,SAAS,IAAI,EAAG,UAAS;AACnC,UAAI,SAAS,SAAS,IAAI,EAAG,UAAS;AACtC,UAAI,KAAK,SAAS,IAAI,EAAG,UAAS;AAAA,IACpC;AAEA,WAAO,EAAE,OAAO,MAAM;AAAA,EACxB,CAAC;AAED,SAAO,OACJ,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EACzB,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,MAAM,cAAc,EAAE,MAAM,KAAK,CAAC,EAC9E,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC,EAC3B,IAAI,CAAC,EAAE,OAAO,MAAM,OAAO;AAAA,IAC1B,OAAO,MAAM;AAAA,IACb,KAAK,GAAG,WAAW,GAAG,MAAM,KAAK;AAAA,IACjC;AAAA,IACA,SAAS,cAAc,MAAM,MAAM,MAAM;AAAA,EAC3C,EAAE;AACN;;;AC9DA,SAAS,eACP,WACuD;AACvD,QAAM,SAAS,cAAc,UAAU,IAAI;AAC3C,aAAW,UAAU,SAAS;AAC5B,UAAM,MAAM,OAAO,SAAS;AAAA,MAC1B,CAAC,MAAM,EAAE,WAAW,UAAU,UAAU,cAAc,EAAE,IAAI,MAAM;AAAA,IACpE;AACA,QAAI,IAAK,QAAO,EAAE,MAAM,OAAO,IAAI,gBAAgB,OAAO,OAAO;AAAA,EACnE;AACA,SAAO,CAAC;AACV;AAyBA,IAAM,OAAO,CAAC,UAA+B,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AAQ/E,IAAM,WAAoC;AAAA;AAAA,EAE/C,QAAQ,OAAO,SAAS;AAAA,IACtB,GAAG,IAAI;AAAA,IACP,MACE,IAAI,SAAS,YAAY,wBAAwB,eAC7C,qEACA;AAAA,EACR;AAAA;AAAA,EAGA,aAAa,OAAO,KAAK,SAAS;AAChC,UAAM,OAAO,WAAW,IAAI,MAAM,OAAO,KAAK,SAAS,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC;AACnF,WAAO,KAAK,SAAS,IACjB,EAAE,KAAK,IACP,EAAE,MAAM,CAAC,GAAG,MAAM,6DAA6D;AAAA,EACrF;AAAA,EAEA,mBAAmB,OAAO,KAAK,SAAS;AACtC,UAAM,aAAa,eAAe,IAAI,UAAU;AAAA,MAC9C,MAAM,OAAO,KAAK,QAAQ,EAAE;AAAA,MAC5B,QAAQ,KAAK,SAAS,OAAO,KAAK,MAAM,IAAI;AAAA,IAC9C,CAAC;AACD,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO;AAAA,QACL,YAAY,CAAC;AAAA,QACb,MAAM;AAAA,MACR;AAAA,IACF;AACA,WAAO;AAAA,MACL,YAAY,WAAW,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,GAAG,eAAe,EAAE,EAAE,EAAE;AAAA,MACjF,WAAW,WAAW,SAAS,IAAI,WAAW,SAAS,IAAI;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,kBAAkB,OAAO,KAAK,SAC5B,gBAAgB,IAAI,UAAU;AAAA,IAC5B,QAAQ,OAAO,KAAK,UAAU,MAAM;AAAA,IACpC,MAAM,OAAO,KAAK,QAAQ,EAAE;AAAA,IAC5B,MAAO,KAAK,QAAQ,CAAC;AAAA,EACvB,CAAC;AAAA;AAAA,EAGH,SAAS,OAAO,KAAK,SAAS;AAC5B,UAAM,OAAO,OAAO,KAAK,QAAQ,EAAE;AACnC,QAAI,CAAC,KAAK,WAAW,UAAU,GAAG;AAChC,YAAM,IAAI;AAAA,QACR,qBAAqB,IAAI;AAAA,MAC3B;AAAA,IACF;AACA,WAAO,IAAI,OAAO,IAAI,IAAI;AAAA,EAC5B;AAAA;AAAA,EAGA,eAAe,OAAO,KAAK,SACzB,IAAI,OAAO,KAAK,kBAAkB;AAAA,IAChC,GAAG,KAAK;AAAA,IACR,QAAQ,KAAK;AAAA,IACb,eAAe,KAAK;AAAA,IACpB,GAAG,KAAK,IAAI;AAAA,EACd,CAAC;AAAA,EAEH,WAAW,OAAO,KAAK,SAAS;AAC9B,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,QAAQ,MAAM,IAAI,OAAO,IAAI,kBAAkB,EAAE,EAAE;AACzD,UAAM,CAAC,UAAU,SAAS,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC1D,SAAS,MAAM,IAAI,OAAO,KAAK,kBAAkB,EAAE,WAAW,CAAC;AAAA,MAC/D,SAAS,MAAM,IAAI,OAAO,KAAK,kBAAkB,EAAE,UAAU,CAAC;AAAA,MAC9D,SAAS,MAAM,IAAI,OAAO,KAAK,kBAAkB,EAAE,eAAe,CAAC;AAAA,IACrE,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,UAAU,SAAS,KAAK,SAAS,MAAM,OAAO,SAAS;AAAA,MACvD,SAAS,QAAQ,KAAK,QAAQ,MAAM,OAAO,QAAQ;AAAA,MACnD,cAAc,aAAa,KAAK,aAAa,MAAM,OAAO,aAAa;AAAA,IACzE;AAAA,EACF;AAAA;AAAA,EAGA,kBAAkB,OAAO,KAAK,SAC5B,IAAI,OAAO,KAAK,qBAAqB,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;AAAA,EAEnE,cAAc,OAAO,KAAK,SAAS;AACjC,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,WAAW,MAAM,IAAI,OAAO,IAAI,qBAAqB,EAAE,EAAE;AAC/D,UAAM,CAAC,WAAW,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,MACnD,SAAS,MAAM,IAAI,OAAO,KAAK,qBAAqB,EAAE,YAAY,CAAC;AAAA,MACnE,SAAS,MAAM,IAAI,OAAO,KAAK,yBAAyB,EAAE,YAAY,GAAG,CAAC,CAAC;AAAA,IAC7E,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,WAAW,UAAU,KAAK,UAAU,MAAM,OAAO,UAAU;AAAA,MAC3D,eAAe,cAAc,KAAK,cAAc,MAAM,OAAO,cAAc;AAAA,IAC7E;AAAA,EACF;AAAA;AAAA,EAGA,oBAAoB,OAAO,KAAK,SAC9B,IAAI,OAAO,KAAK,yBAAyB;AAAA,IACvC,YAAY,KAAK;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,GAAG,KAAK,IAAI;AAAA,EACd,CAAC;AAAA,EAEH,kBAAkB,OAAO,KAAK,SAAS,IAAI,OAAO,IAAI,yBAAyB,OAAO,KAAK,EAAE,CAAC,EAAE;AAAA;AAAA,EAGhG,eAAe,OAAO,KAAK,SACzB,IAAI,OAAO,KAAK,kBAAkB,EAAE,QAAQ,KAAK,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAC;AAAA,EAE1E,WAAW,OAAO,KAAK,SAAS,IAAI,OAAO,IAAI,kBAAkB,OAAO,KAAK,EAAE,CAAC,EAAE;AAAA;AAAA,EAGlF,eAAe,OAAO,KAAK,SACzB,IAAI,OAAO,KAAK,oBAAoB,EAAE,QAAQ,KAAK,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAC;AAAA,EAE5E,mBAAmB,OAAO,QAAQ,IAAI,OAAO,IAAI,wBAAwB;AAAA;AAAA,EAGzE,kBAAkB,OAAO,KAAK,SAC5B,IAAI,OAAO,KAAK,qBAAqB;AAAA,IACnC,GAAG,KAAK;AAAA,IACR,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,UAAU,KAAK;AAAA,IACf,cAAc,KAAK;AAAA,IACnB,eAAe,KAAK;AAAA,IACpB,GAAG,KAAK,IAAI;AAAA,EACd,CAAC;AAAA,EAEH,cAAc,OAAO,KAAK,SAAS,IAAI,OAAO,IAAI,qBAAqB,OAAO,KAAK,EAAE,CAAC,EAAE;AAAA;AAAA,EAGxF,iBAAiB,OAAO,KAAK,SAC3B,IAAI,OAAO,KAAK,oBAAoB;AAAA,IAClC,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA,IAIb,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK;AAAA,IACf,QAAQ,KAAK;AAAA,IACb,YAAY,KAAK;AAAA,IACjB,YAAY,KAAK;AAAA,IACjB,GAAG,KAAK,IAAI;AAAA,EACd,CAAC;AAAA,EAEH,aAAa,OAAO,KAAK,SAAS;AAChC,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,UAAU,MAAM,IAAI,OAAO,IAAI,oBAAoB,EAAE,EAAE;AAC7D,UAAM,eAAe,MAAM,SAAS,MAAM,IAAI,OAAO,KAAK,oBAAoB,EAAE,eAAe,CAAC;AAChG,WAAO;AAAA,MACL;AAAA,MACA,cAAc,aAAa,KAAK,aAAa,MAAM,OAAO,aAAa;AAAA,IACzE;AAAA,EACF;AAAA;AAAA,EAGA,aAAa,OAAO,KAAK,SAAS,IAAI,OAAO,IAAI,oBAAoB,OAAO,KAAK,EAAE,CAAC,EAAE;AAAA;AAAA,EAGtF,sBAAsB,OAAO,KAAK,SAAS;AACzC,UAAM,CAAC,OAAO,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,MACzC,SAAS,MAAM,IAAI,OAAO,KAAK,2BAA2B,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC;AAAA,MAC5E,SAAS,MAAM,IAAI,OAAO,IAAI,mCAAmC,EAAE,WAAW,KAAK,UAAU,CAAC,CAAC;AAAA,IACjG,CAAC;AACD,WAAO;AAAA,MACL,OAAO,MAAM,KAAK,MAAM,MAAM,OAAO,MAAM;AAAA,MAC3C,SAAS,QAAQ,KAAK,QAAQ,QAAQ,QAAQ;AAAA,IAChD;AAAA,EACF;AAAA;AAAA,EAGA,eAAe,OAAO,KAAK,SACzB,IAAI,OAAO,KAAK,kBAAkB;AAAA,IAChC,MAAM,KAAK;AAAA,IACX,YAAY,KAAK;AAAA,IACjB,UAAU,KAAK;AAAA,IACf,GAAG,KAAK,IAAI;AAAA,EACd,CAAC;AAAA,EAEH,yBAAyB,OAAO,KAAK,SACnC,IAAI,OAAO,KAAK,8BAA8B;AAAA,IAC5C,YAAY,KAAK;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK;AAAA,EACd,CAAC;AAAA,EAEH,sBAAsB,OAAO,KAAK,SAChC,IAAI,OAAO,IAAI,8BAA8B,OAAO,KAAK,EAAE,CAAC,EAAE;AAAA,EAEhE,mBAAmB,OAAO,KAAK,SAC7B,IAAI,OAAO,KAAK,6BAA6B,OAAO,KAAK,EAAE,CAAC,SAAS;AAAA,IACnE,MAAM,EAAE,WAAW,KAAK,UAAU;AAAA,IAClC,gBAAgB,yBAAyB,OAAO,KAAK,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;AAAA,EACxE,CAAC;AAAA,EAEH,yBAAyB,OAAO,KAAK,SACnC,IAAI,OAAO,KAAK,8BAA8B,OAAO,KAAK,EAAE,CAAC,WAAW;AAAA,IACtE,gBAAgB,+BAA+B,OAAO,KAAK,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;AAAA,EAC9E,CAAC;AAAA,EAEH,0BAA0B,OAAO,KAAK,SAAS;AAC7C,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,UAAU,MAAM,SAAS,MAAM,IAAI,OAAO,IAAS,6BAA6B,EAAE,EAAE,CAAC;AAC3F,QAAI,CAAC,QAAQ,IAAI;AACf,aAAO;AAAA,QACL,MAAM,uBAAuB,EAAE,KAAK,QAAQ,WAAW,qEAAqE,EAAE;AAAA,MAChI;AAAA,IACF;AACA,UAAM,SAAU,QAAQ,OAAO,UAAiC;AAChE,UAAM,CAAC,MAAM,eAAe,YAAY,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,MACtE,SAAS,MAAM,IAAI,OAAO,IAAI,6BAA6B,EAAE,OAAO,CAAC;AAAA,MACrE,SAAS,MAAM,IAAI,OAAO,KAAK,kBAAkB,EAAE,UAAU,IAAI,OAAO,GAAG,CAAC,CAAC;AAAA,MAC7E,SACI,SAAS,MAAM,IAAI,OAAO,KAAK,kBAAkB,EAAE,UAAU,QAAQ,OAAO,GAAG,CAAC,CAAC,IACjF,QAAQ,QAAQ,EAAE,IAAI,MAAe,OAAO,EAAE,MAAM,CAAC,GAAG,YAAY,KAAK,EAAE,CAAC;AAAA,MAChF,SAAS,MAAM,IAAI,OAAO,KAAK,8BAA8B,EAAE,OAAO,GAAG,CAAC,CAAC;AAAA,IAC7E,CAAC;AACD,WAAO;AAAA,MACL,SAAS,QAAQ;AAAA,MACjB,MAAM,KAAK,KAAK,KAAK,QAAQ,KAAK;AAAA,MAClC,QAAQ;AAAA,QACN,GAAI,cAAc,KAAK,cAAc,MAAM,OAAO,CAAC;AAAA,QACnD,GAAI,WAAW,KAAK,WAAW,MAAM,OAAO,CAAC;AAAA,MAC/C;AAAA,MACA,mBAAmB,cAAc,KAAK,SAAY,cAAc;AAAA,MAChE,yBAAyB,WAAW,KAAK,WAAW,MAAM,OAAO,WAAW;AAAA,MAC5E,MAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,gBAAgB,OAAO,KAAK,SAAS;AAInC,QAAI,IAAI,SAAS,YAAY,wBAAwB,cAAc;AACjE,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,WAAW,MAAM,IAAI,OAAO,KAAU,qBAAqB;AAAA,MAC/D,MAAM;AAAA,QACJ,OAAO,OAAO,KAAK,iBAAiB,YAAY,KAAK,eAAe;AAAA,QACpE,WAAW;AAAA,QACX,UAAU;AAAA,MACZ;AAAA,MACA,gBAAgB,qBAAqB,KAAK;AAAA,IAC5C,CAAC;AACD,UAAM,OAAO,MAAM,IAAI,OAAO,KAAU,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA,MAKvD,MAAM,EAAE,eAAe,IAAI,SAAS,aAAa,IAAI,YAAY,UAAU,GAAG;AAAA,MAC9E,gBAAgB,iBAAiB,KAAK;AAAA,IACxC,CAAC;AACD,UAAM,YAAY,MAAM,QAAQ,KAAK,SAAS,KAAK,KAAK,UAAU,SAAS,IACtE,KAAK,YACN,CAAC,EAAE,MAAM,eAAe,WAAW,MAAM,UAAU,EAAE,CAAC;AAC1D,UAAM,QAAmB,CAAC;AAC1B,eAAW,CAAC,OAAO,IAAI,KAAK,UAAU,QAAQ,GAAG;AAC/C,YAAM;AAAA,QACJ,MAAM,IAAI,OAAO,KAAK,iBAAiB,MAAM,EAAE,UAAU;AAAA,UACvD,MAAM;AAAA,UACN,gBAAgB,iBAAiB,KAAK,IAAI,KAAK;AAAA,QACjD,CAAC;AAAA,MACH;AAAA,IACF;AACA,UAAM,QAAQ,MAAM,IAAI,OAAO,KAAK,iBAAiB,MAAM,EAAE,aAAa;AAAA,MACxE,gBAAgB,qBAAqB,KAAK;AAAA,IAC5C,CAAC;AACD,WAAO;AAAA,MACL,aAAa,IAAI,SAAS,YAAY;AAAA,MACtC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,qBAAqB,OAAO,KAAK,SAAS;AACxC,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,SAAS,OAAO,KAAK,MAAM;AACjC,QAAI,WAAW,WAAW,WAAW,UAAU;AAC7C,YAAM,IAAI,MAAM,iEAAiE,MAAM,IAAI;AAAA,IAC7F;AACA,WAAO,IAAI,OAAO,KAAK,yBAAyB,EAAE,IAAI,MAAM,IAAI;AAAA,MAC9D,gBAAgB,2BAA2B,EAAE,IAAI,MAAM,IAAI,KAAK,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOxB,IAAI,OAAO,KAAK,kBAAkB;AAAA,MAChC,MAAM;AAAA,QACJ,YAAY,KAAK;AAAA,QACjB,OAAO,KAAK;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,cACE,KAAK,SAAS,SAAY,EAAE,MAAM,aAAa,MAAM,KAAK,KAAK,IAAI;AAAA,QACrE,WAAW,KAAK;AAAA,MAClB;AAAA,MACA,gBAAgB,oBAAoB,OAAO,KAAK,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC;AAAA,IAC3E,CAAC;AAAA;AAAA,EAEH,sBAAsB,OAAO,KAAK,SAChC,IAAI,OAAO,IAAI,sCAAsC,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EAE9E,sBAAsB,OAAO,QAAQ,IAAI,OAAO,IAAI,oCAAoC;AAAA;AAAA,EAGxF,8BAA8B,OAAO,KAAK,SACxC,IAAI,OAAO,KAAK,yBAAyB,EAAE,QAAQ,KAAK,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAC;AAAA;AAAA,EAGjF,uBAAuB,OAAO,QAAQ;AACpC,UAAM,CAAC,gBAAgB,mBAAmB,aAAa,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvF,SAAS,MAAM,IAAI,OAAO,IAAI,yBAAyB,CAAC;AAAA,MACxD,SAAS,MAAM,IAAI,OAAO,IAAI,4BAA4B,CAAC;AAAA,MAC3D,SAAS,MAAM,IAAI,OAAO,IAAI,sBAAsB,CAAC;AAAA,MACrD,SAAS,MAAM,IAAI,OAAO,IAAI,uBAAuB,CAAC;AAAA,IACxD,CAAC;AACD,WAAO;AAAA,MACL,gBAAgB,eAAe,KAAK,eAAe,QAAQ,eAAe;AAAA,MAC1E,mBAAmB,kBAAkB,KAAK,kBAAkB,QAAQ,kBAAkB;AAAA,MACtF,aAAa,YAAY,KAAK,YAAY,QAAQ,YAAY;AAAA,MAC9D,cAAc,aAAa,KAAK,aAAa,QAAQ,aAAa;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,wBAAwB,OAAO,QAAQ;AACrC,UAAM,CAAC,YAAY,WAAW,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC1D,SAAS,MAAM,IAAI,OAAO,KAAK,oBAAoB,CAAC;AAAA,MACpD,SAAS,MAAM,IAAI,OAAO,KAAK,2BAA2B,CAAC;AAAA,MAC3D,SAAS,MAAM,IAAI,OAAO,IAAI,oCAAoC,CAAC;AAAA,IACrE,CAAC;AACD,WAAO;AAAA,MACL,aAAa,IAAI,SAAS;AAAA,MAC1B,WAAW,IAAI,SAAS;AAAA,MACxB,aAAa,IAAI,SAAS;AAAA,MAC1B,YAAY,WAAW,KAAK,WAAW,MAAM,OAAO,WAAW;AAAA,MAC/D,kBAAkB,UAAU,KAAK,UAAU,MAAM,OAAO,UAAU;AAAA,MAClE,oBAAoB,SAAS,KAAK,SAAS,QAAQ,SAAS;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA,EAGA,wBAAwB,OAAO,QAAQ,IAAI,OAAO,IAAI,sBAAsB;AAAA,EAE5E,eAAe,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,qBAAqB,EAAE,OAAO,KAAK,MAAM,CAAC;AAChG;;;ACtaA,SAAS,SAA0B;AAQ5B,SAAS,iBAAiB,QAA4D;AAC3F,QAAM,QAAoC,CAAC;AAC3C,aAAW,SAAS,QAAQ;AAC1B,UAAM,MAAM,IAAI,IAAI,eAAe,OAAO,SAAS,KAAK,CAAC;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,SAAS,OAAgC;AAChD,MAAI,MAAM,QAAQ,MAAM,KAAK,SAAS,GAAG;AACvC,WAAO,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAA0B;AAAA,EACxD;AACA,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,EAAE,OAAO;AAAA,IAClB,KAAK;AACH,aAAO,EAAE,OAAO;AAAA,IAClB,KAAK;AACH,aAAO,EAAE,QAAQ;AAAA,IACnB,KAAK;AACH,aAAO,EAAE,MAAM,EAAE,QAAQ,CAAC;AAAA,IAC5B,KAAK;AACH,aAAO,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EAC/B;AACF;AAEA,SAAS,eAAe,OAAoB,MAA8B;AACxE,QAAM,YAAY,KAAK,SAAS,MAAM,WAAW;AACjD,MAAI,MAAM,SAAU,QAAO;AAC3B,SAAO,MAAM,YAAY,SAAY,UAAU,SAAS,IAAI,UAAU,QAAQ,MAAM,OAAO;AAC7F;;;AbzBO,IAAM,UACX,OAAO,6BAA6B,WAAW,2BAA2B;AA2BrE,SAAS,oBAAoB,QAAgD;AAClF,QAAM,eAAe,OAAO,SAAS,YAAY,wBAAwB;AACzE,SAAO,kBAAkB,KAAK,EAAE,OAAO,CAAC,WAAW;AACjD,QAAI,CAAC,SAAS,OAAO,EAAE,EAAG,QAAO;AACjC,QAAI,CAAC,aAAa,OAAO,SAAS,QAAQ,MAAM,EAAG,QAAO;AAC1D,QAAI,OAAO,SAAS,OAAQ,QAAO;AACnC,QAAI,OAAO,YAAa,QAAO,CAAC;AAChC,QAAI,CAAC,OAAO,YAAa,QAAO;AAChC,WAAO,CAAC,gBAAgB,OAAO;AAAA,EACjC,CAAC;AACH;AAOO,SAAS,kBACd,UACA,SACA,QACQ;AACR,QAAM,eAAe,SAAS,YAAY,wBAAwB;AAClE,QAAM,QAAQ;AAAA,IACZ,SAAS,WAAW,QAAQ,SAAS,WAAW,QAAQ;AAAA,IACxD,SAAS,aAAa,QAAQ,SAAS,aAAa,QAAQ;AAAA,EAC9D,EACG,OAAO,OAAO,EACd,KAAK,KAAK;AAKb,QAAM,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,CAAC,EAAE,WAAW;AAC7E,QAAM,gBAAgB,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,WAAW;AAC/E,QAAM,QAAQ;AAAA,IACZ,gBAAgB,OAAO,kBAAkB,KAAK,kBAAkB,SAAS,YAAY,IAAI,MACvF,eAAe,gCAA2B,qCAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,UAAM;AAAA,MACJ,4CACE,OAAO,cACH,uDACA,iCACN;AAAA,IACF;AACA,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM;AAAA,QACJ,KAAK,cACF,IAAI,CAAC,MAAM,EAAE,EAAE,EACf,KAAK,IAAI,CAAC;AAAA,MACf;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ,8BAA8B,WAC3B,IAAI,CAAC,MAAM,EAAE,EAAE,EACf,KAAK,IAAI,CAAC;AAAA,IACf;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAQO,SAAS,aAAa,SAAyC;AACpE,QAAM,UAAU,oBAAoB,OAAO;AAC3C,QAAM,SAAS,IAAI;AAAA,IACjB,EAAE,MAAM,YAAY,SAAS,QAAQ;AAAA,IACrC,EAAE,cAAc,kBAAkB,QAAQ,UAAU,SAAS,OAAO,EAAE;AAAA,EACxE;AAEA,QAAM,MAAsB;AAAA,IAC1B,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,IAClB,MAAM,QAAQ;AAAA,EAChB;AAEA,aAAW,UAAU,SAAS;AAC5B,UAAM,UAAU,SAAS,OAAO,EAAE;AAClC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,iBAAiB,MAAM;AAAA,MACvB,iBAAiB,OAAO,KAAK;AAAA,MAC7B,OAAO,SAAkC;AACvC,YAAI;AACF,gBAAM,SAAS,MAAM,QAAQ,KAAK,QAAQ,CAAC,CAAC;AAC5C,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,aAAa,MAAM,EAAE,CAAC,EAAE;AAAA,QAC5E,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,YAAY,KAAK,EAAE,CAAC;AAAA,YAC7D,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,iBAAiB,QAAkC;AAC1D,QAAM,QAAQ,CAAC,OAAO,WAAW;AACjC,MAAI,OAAO,cAAc,OAAO,WAAW,SAAS,GAAG;AACrD,UAAM,KAAK,gBAAgB,OAAO,WAAW,KAAK,GAAG,CAAC,EAAE;AAAA,EAC1D;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;;;AcpKA,SAAS,oBAAoB;AAS7B,SAAS,UAA6C,MAAc,OAAU,OAAkB;AAC9F,MAAI;AACF,WAAO,KAAK,MAAM,aAAa,IAAI,IAAI,KAAK,IAAI,IAAI,YAAY,GAAG,GAAG,MAAM,CAAC;AAAA,EAC/E,QAAQ;AACN,YAAQ,OAAO;AAAA,MACb,iBAAiB,KAAK,mBAAmB,IAAI;AAAA;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBAA2B;AACzC,SAAO,UAAqB,mBAAmB,EAAE,aAAa,IAAI,SAAS,CAAC,EAAE,GAAG,MAAM;AACzF;AAEO,SAAS,oBAAmC;AACjD,SAAO,UAAyB,uBAAuB,EAAE,aAAa,IAAI,YAAY,CAAC,EAAE,GAAG,UAAU;AACxG;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../../core-scopes/src/scopes.ts","../../core-scopes/src/events.ts","../../core-scopes/src/issuance.ts","../../core-scopes/src/shopper-pii.ts","../../action-catalog/src/actions.ts","../../action-catalog/src/triggers.ts","../../action-catalog/src/index.ts","../src/format.ts","../../errors/dist/index.js","../src/client.ts","../src/contract.ts","../src/docs.ts","../src/handlers.ts","../src/input.ts","../src/projection.ts","../src/indexes.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { actionsForChannel, canRunAction, type ActionDefinition } from '@core/action-catalog';\nimport { hasScope, redactShopperPii, validateScopesForOAuth } from '@core/scopes';\nimport type { ThrottleClient } from './client';\nimport type { ContractIndex } from './contract';\nimport type { DocsIndex } from './docs';\nimport { formatError, formatResult } from './format';\nimport { HANDLERS, type HandlerContext, type Identity } from './handlers';\nimport { fieldsToZodShape } from './input';\nimport { OAUTH_PROJECTIONS, project } from './projection';\n\n// Injected by tsup from package.json (see tsup.config.ts). Under vitest there is\n// no define step, so `typeof` guards the ReferenceError and tests read a dev\n// marker rather than a stale hard-coded number.\ndeclare const __THROTTLE_MCP_VERSION__: string | undefined;\nexport const VERSION =\n typeof __THROTTLE_MCP_VERSION__ === 'string' ? __THROTTLE_MCP_VERSION__ : '0.0.0-dev';\n\nexport interface RegistrationPolicy {\n identity: Identity;\n allowWrites: boolean;\n allowLiveWrites: boolean;\n /**\n * Whether sandbox-only writes (`seed_test_data`) register without\n * `allowWrites`. Defaults to true — the documented CLI behaviour, where\n * seeding a non-production environment needs no flag. The hosted remote\n * server passes false: it is published as strictly read-only, and a\n * directory reviewer connecting with a non-production credential must not\n * find a tool that creates customers and orders.\n */\n allowSandboxWrites?: boolean;\n /**\n * Whether `credentialScoped` actions (`api_get`) register. Defaults to true\n * for the CLI. The hosted server passes false: on an OAuth surface every\n * tool declares the scopes it asks consent for, and a tool that reads any\n * path cannot.\n */\n allowCredentialScoped?: boolean;\n}\n\n/**\n * Which tools this session gets. Pure and exported so the policy is testable\n * without standing up a transport.\n *\n * Four independent gates, in order of how expensive it is to get them wrong:\n *\n * 1. **Implemented.** `0.1.0` ships the read/sandbox half; the catalog describes\n * the money writes before this package implements them.\n * 2. **Scope.** Delegated to the catalog's `canRunAction`, which uses the API's own\n * `hasScope`. A tool the credential cannot execute is not registered at all,\n * rather than failing at call time — the model never sees an affordance it\n * cannot use.\n * 3. **Intent.** Holding a write scope means the credential *may* write; it does\n * not mean the operator intended this session to. That is `--allow-writes`.\n * 4. **Blast radius.** Against a production credential, writes need\n * `--allow-live-writes` on top. Sandbox-only actions invert the rule: they are\n * free in a non-production environment and forbidden in production regardless\n * of flags.\n */\nexport function registerableActions(policy: RegistrationPolicy): ActionDefinition[] {\n const isProduction = policy.identity.environment.providerEnvironment === 'production';\n return actionsForChannel('mcp').filter((action) => {\n if (!HANDLERS[action.id]) return false;\n if (action.credentialScoped && policy.allowCredentialScoped === false) return false;\n if (!canRunAction(policy.identity.scopes, action)) return false;\n if (action.kind === 'read') return true;\n if (action.sandboxOnly) return !isProduction && (policy.allowSandboxWrites ?? true);\n if (!policy.allowWrites) return false;\n return !isProduction || policy.allowLiveWrites;\n });\n}\n\n/**\n * The server's `instructions`, which most clients put in front of the model before\n * it picks a tool. Leads with the environment because the single most damaging\n * mistake an agent can make here is not knowing whether it is looking at live data.\n */\nexport function buildInstructions(\n identity: Identity,\n actions: ActionDefinition[],\n policy: { allowWrites: boolean; allowLiveWrites: boolean },\n): string {\n const isProduction = identity.environment.providerEnvironment === 'production';\n const where = [\n identity.workspace?.name ?? identity.workspace?.slug ?? 'unknown workspace',\n identity.application?.name ?? identity.application?.slug ?? null,\n ]\n .filter(Boolean)\n .join(' / ');\n\n // Sandbox seeding is a write, but announcing it as \"irreversible and\n // buyer-visible\" would teach the model to be cautious about the one tool that is\n // free — and, worse, imply this session can move money when it cannot.\n const liveWrites = actions.filter((a) => a.kind === 'write' && !a.sandboxOnly);\n const sandboxWrites = actions.filter((a) => a.kind === 'write' && a.sandboxOnly);\n const lines = [\n `Throttle MCP ${VERSION}. Connected to ${where}, environment \"${identity.environment.slug}\" (${\n isProduction ? 'PRODUCTION — live data' : 'non-production — not live data'\n }).`,\n '',\n 'Conventions:',\n '- The workspace and environment are fixed for this session and cannot be switched from inside a tool call. Call whoami if you need to state where you are.',\n '- The application can vary per call: pass \"applicationId\" on a read or analytics tool to reach a different application in this workspace, and call list_applications to see which ones this connection can reach. Omitting applicationId uses the application this connection was authorized for.',\n '- Every analytics result covers exactly ONE application and names it in `application`. Say which application a figure describes. If the user asks about their business as a whole and this connection reaches more than one application, do not answer from the default alone — call list_applications, then query each and add them up, or ask which application they mean.',\n '- List tools return { data, pagination }. When pagination.hasMore is true, pass pagination.cursor back as \"cursor\" rather than raising \"limit\".',\n '- Amounts are integer minor units (2500 = $25.00).',\n '- Throttle rejects snake_case on public request bodies. Before writing integration code, confirm shapes with describe_endpoint and check bodies with validate_payload instead of guessing field names.',\n '- API errors come back as text with a stable code. On insufficient_scopes, tell the user which scope to add — do not retry.',\n '- Analytics results may mark a section `omitted`. That means UNKNOWN, never zero. When `grantable` is false the data cannot be read over this connection at all — say so rather than reporting an absence.',\n ];\n\n if (liveWrites.length === 0) {\n lines.push(\n `- This session is READ-ONLY for real data${\n policy.allowWrites\n ? ' (no write tools are available to this credential)'\n : ' — writes were not enabled'\n }. Say so plainly if asked to change something.`,\n );\n if (sandboxWrites.length > 0) {\n lines.push(\n `- ${sandboxWrites\n .map((a) => a.id)\n .join(', ')} may create data, but only in this non-production environment.`,\n );\n }\n } else {\n lines.push(\n `- Write tools are enabled (${liveWrites\n .map((a) => a.id)\n .join(', ')}). They are irreversible and some are buyer-visible. Confirm with the user before calling one.`,\n );\n }\n return lines.join('\\n');\n}\n\nexport interface CreateServerOptions extends RegistrationPolicy {\n client: ThrottleClient;\n contract: ContractIndex;\n docs: DocsIndex;\n /**\n * The `WWW-Authenticate` challenge value the hosting transport advertises\n * (RFC 9728 `Bearer resource_metadata=\"...\"`). When set, a tool call that\n * fails because the REST API rejected the credential (HTTP 401 — an expired\n * or revoked OAuth access token) carries it back as\n * `_meta[\"mcp/www_authenticate\"]`, which is what ChatGPT and other remote\n * clients key their re-authorization UI on. The stdio CLI leaves it unset:\n * its operator-provided key has no re-auth flow to trigger.\n */\n authChallenge?: string;\n}\n\n/**\n * OpenAI's per-tool `securitySchemes` (their extension to `tools/list`; not\n * in the MCP SDK's `registerTool` config as of 1.30.0, whose list handler\n * emits a fixed set of fields). ChatGPT shows its OAuth linking UI for a\n * tool only when the resource metadata, this declaration AND the\n * `_meta[\"mcp/www_authenticate\"]` error are all present, so on the hosted\n * server every tool declares `oauth2` with the scopes the action needs.\n *\n * Implemented by wrapping the SDK's own `tools/list` handler rather than\n * rebuilding the list: the SDK still owns schema conversion; this only adds\n * one field per tool. `setRequestHandler` replaces the previous handler for\n * the method, and the previous one is read back from the protocol's handler\n * map — the one private touch, covered by a test that fails loudly if an SDK\n * upgrade moves it.\n */\nfunction declareSecuritySchemes(server: McpServer, actions: ActionDefinition[]): void {\n const inner = server.server;\n const handlers = (inner as unknown as { _requestHandlers?: Map<string, (request: unknown, extra: unknown) => Promise<unknown>> })\n ._requestHandlers;\n const original = handlers?.get('tools/list');\n if (!original) return;\n // Section scopes are declared too, but only those an OAuth grant can hold:\n // /oauth/authorize refuses a request naming any other, so a client asking\n // for everything a tool declares would otherwise fail to connect at all.\n const schemes = new Map(\n actions.map((a) => [\n a.id,\n [{\n type: 'oauth2',\n scopes: [...new Set([...a.scopes, ...(a.sectionScopes ?? [])])].filter((scope) => validateScopesForOAuth([scope]).ok),\n }],\n ]),\n );\n inner.setRequestHandler(ListToolsRequestSchema, async (request, extra) => {\n const result = (await original(request, extra)) as { tools: Array<{ name: string }> };\n return {\n ...result,\n tools: result.tools.map((tool) => ({ ...tool, securitySchemes: schemes.get(tool.name) ?? [{ type: 'oauth2', scopes: [] }] })),\n };\n });\n}\n\nexport function createServer(options: CreateServerOptions): McpServer {\n // Over OAuth a tool returns only the fields its projection names\n // (projection.ts). A tool with no projection is not registered at all:\n // failing closed means a new tool cannot reach ChatGPT or Claude with its\n // whole REST response until someone has decided what it may return.\n const redactPii =\n options.identity.type === 'oauth_token' && !hasScope(options.identity.scopes, 'customer_pii:read');\n const actions = registerableActions(options).filter((a) => !redactPii || OAUTH_PROJECTIONS[a.id] !== undefined);\n const server = new McpServer(\n { name: 'throttle', version: VERSION },\n { instructions: buildInstructions(options.identity, actions, options) },\n );\n\n const ctx: HandlerContext = {\n client: options.client,\n identity: options.identity,\n contract: options.contract,\n docs: options.docs,\n };\n\n // The key-based redactor runs after the projection as a second layer. It is\n // the same rule the REST API applies to OAuth tokens (apps/server\n // auth/oauth-pii.ts), and it matters here because some tools also read\n // public routes (the checkout-session pair) where the API resolves no\n // credential.\n\n for (const action of actions) {\n const handler = HANDLERS[action.id]!;\n server.registerTool(\n action.id,\n {\n title: action.title,\n description: describeForModel(action),\n inputSchema: fieldsToZodShape(action.input),\n // Every hint is an explicit boolean: directory reviews (OpenAI's in\n // particular) read a missing value as \"unknown\", not as false.\n annotations: {\n title: action.title,\n readOnlyHint: action.kind === 'read',\n destructiveHint: action.kind === 'write' && Boolean(action.destructive),\n idempotentHint: Boolean(action.idempotent),\n // Every tool is bounded to the connected workspace; none reaches the\n // public internet or an open-ended set of external entities.\n openWorldHint: false,\n },\n },\n async (args: Record<string, unknown>) => {\n try {\n // Everything a customer text search could match (name, email, phone,\n // the merchant's external id) is withheld over OAuth, and a match or\n // no-match would still say whether that person is a customer.\n if (redactPii && action.id === 'search_customers' && typeof args?.q === 'string' && args.q.trim() !== '') {\n return {\n content: [{ type: 'text' as const, text: 'Customer text search is not available over this connection, because names, emails, phone numbers and external ids are withheld. List customers by creation date (createdAfter/createdBefore), or open one by its Throttle id from an order, quote or subscription.' }],\n isError: true,\n };\n }\n const result = await handler(ctx, args ?? {});\n const shown = redactPii ? redactShopperPii(project(result, OAUTH_PROJECTIONS[action.id]!)) : result;\n return { content: [{ type: 'text' as const, text: formatResult(shown) }] };\n } catch (error) {\n return {\n content: [{ type: 'text' as const, text: formatError(error) }],\n isError: true,\n ...(options.authChallenge && isCredentialRejection(error)\n ? {\n _meta: {\n 'mcp/www_authenticate': [\n `${options.authChallenge}, error=\"invalid_token\", error_description=\"The connected credential was rejected. Sign in again to continue.\"`,\n ],\n },\n }\n : {}),\n };\n }\n },\n );\n }\n\n if (options.authChallenge) declareSecuritySchemes(server, actions);\n\n return server;\n}\n\n/** The REST API refused the credential itself (not a scope or a missing record). */\nfunction isCredentialRejection(error: unknown): boolean {\n return (error as { statusCode?: unknown } | null)?.statusCode === 401;\n}\n\n/** Guardrails ride along in the description so they reach the model, not just the reviewer. */\nfunction describeForModel(action: ActionDefinition): string {\n const parts = [action.description];\n if (action.guardrails && action.guardrails.length > 0) {\n parts.push(`Constraints: ${action.guardrails.join(' ')}`);\n }\n return parts.join(' ');\n}\n","/** True when the granted scope set covers the required scope.\n * Rules: '*' covers all; exact match; write→read on the same resource;\n * NO cross-resource implication. */\nexport function hasScope(granted: readonly string[], required: string): boolean {\n if (granted.includes('*')) return true;\n if (granted.includes(required)) return true;\n const sep = required.lastIndexOf(':');\n if (sep === -1) return false;\n const resource = required.slice(0, sep);\n const action = required.slice(sep + 1);\n if (action === 'read' && granted.includes(`${resource}:write`)) return true;\n return false;\n}\n\nexport interface ScopeDef {\n id: string;\n resource: string;\n action: 'read' | 'write' | 'install';\n group: string;\n label: string;\n sensitive: boolean;\n staffOnly: boolean;\n // `publishableAllowed` means \"may appear on a pk_ key\" (in addition to sk_).\n // `publishableOnly` means \"may appear on NOTHING ELSE\" — it makes a pk_ the\n // only key type this scope can be minted onto, because the plane it gates\n // (e.g. /v1/storefront) refuses every other key type regardless of scopes.\n // A scope with publishableOnly: true must also have publishableAllowed: true.\n publishableAllowed: boolean;\n publishableOnly: boolean;\n extensionAllowed: boolean;\n implies: string[];\n}\n\ntype Opts = {\n sensitive?: boolean;\n staffOnly?: boolean;\n publishableAllowed?: boolean;\n publishableOnly?: boolean;\n extensionAllowed?: boolean;\n};\n\nconst REG: Record<string, ScopeDef> = {};\n\n/** Register one resource with the given actions, generating read/write defs.\n * `write` auto-implies `read` when a read action is present. */\nfunction add(\n group: string,\n resource: string,\n actions: Array<'read' | 'write'>,\n labels: { read?: string; write?: string },\n opts: Opts = {},\n) {\n const hasRead = actions.includes('read');\n for (const action of actions) {\n const id = `${resource}:${action}`;\n const implies = action === 'write' && hasRead ? [`${resource}:read`] : [];\n REG[id] = {\n id,\n resource,\n action,\n group,\n label: (action === 'read' ? labels.read : labels.write) ?? `${action} ${resource}`,\n sensitive: opts.sensitive ?? false,\n staffOnly: opts.staffOnly ?? false,\n // publishable defaults false; only the curated set below is true\n publishableAllowed: opts.publishableAllowed ?? false,\n // publishableOnly defaults false; only customer_accounts:write sets it\n publishableOnly: opts.publishableOnly ?? false,\n // extension default true for commerce scopes; Taxonomy B passes false\n extensionAllowed: opts.extensionAllowed ?? true,\n implies,\n };\n }\n}\n\n// ── Taxonomy A — integration / commerce ──────────────────────────────\nadd('Orders', 'orders', ['read', 'write'], { read: 'View orders', write: 'Manage orders' });\n// Sales quotes (B2B proposals) — unrelated to shipping_quotes / quote tokens.\nadd('Quotes', 'quotes', ['read', 'write'], { read: 'View quotes', write: 'Manage quotes' });\nadd('Orders', 'order_cancellations', ['write'], { write: 'Cancel orders' });\nadd('Orders', 'order_returns', ['read', 'write'], { read: 'View returns', write: 'Process returns' });\n// A write-off button. Separate from orders:write because an integration that\n// creates orders has no business zeroing their revenue.\nadd('Orders', 'order_comps', ['write'], { write: 'Comp orders (write off the balance)' }, { sensitive: true });\n// Freezing the fulfilment queue is its own authority: a fraud reviewer needs it\n// without being able to edit orders, and an integration with broad write access\n// should not gain it by accident.\nadd('Orders', 'order_holds', ['write'], { write: 'Freeze and unfreeze orders' });\n\n// Bulk import of a merchant's own historical customers and orders from an\n// export file. `extensionAllowed: false` because an import writes thousands of\n// rows with side effects suppressed — that is merchant-and-staff authority, not\n// something a third-party extension should hold. Not publishable for the same\n// reason: publishable keys are limited to stateless computes.\nadd(\n 'Imports',\n 'imports',\n ['read', 'write'],\n { read: 'View data imports', write: 'Run and undo data imports' },\n { extensionAllowed: false },\n);\n\nadd('Payments', 'payments', ['read', 'write'], { read: 'View payments', write: 'Create payments' });\nadd('Payments', 'payment_authorizations', ['write'], { write: 'Authorize payments' });\nadd('Payments', 'payment_captures', ['write'], { write: 'Capture payments' });\nadd('Payments', 'payment_refunds', ['read', 'write'], { read: 'View refunds', write: 'Refund payments' }, { sensitive: true });\nadd('Payments', 'payment_voids', ['write'], { write: 'Void payments' }, { sensitive: true });\n// Recording money that arrived outside Throttle's rails. Separate from\n// payments:write because it asserts a fact about the real world that no\n// processor will ever contradict.\nadd('Payments', 'payment_records', ['write'], { write: 'Record payments received outside Throttle' }, { sensitive: true });\nadd('Payments', 'payment_disputes', ['read', 'write'], { read: 'View disputes', write: 'Handle disputes' }, { sensitive: true });\nadd('Payments', 'payment_methods', ['read', 'write'], { read: 'View payment methods', write: 'Tokenize payment methods' }, { sensitive: true });\n\nadd('Customers', 'customers', ['read', 'write'], { read: 'View customers', write: 'Manage customers' });\nadd('Customers', 'customer_pii', ['read'], { read: 'View customer PII' }, { sensitive: true });\nadd('Customers', 'customer_addresses', ['read', 'write'], { read: 'View addresses', write: 'Manage addresses' });\nadd('Customers', 'customer_payment_methods', ['read', 'write'], { read: 'View stored cards', write: 'Manage stored cards' }, { sensitive: true });\n\n// Buyer accounts on a merchant's storefront (the `/v1/storefront` plane).\n// ONE action, not a read/write pair: a read-only buyer key cannot authenticate,\n// because logging in is itself a POST. `publishableAllowed` because this scope\n// exists precisely to be held by the browser-side pk_ the storefront ships.\n// `publishableOnly` because makeResolveApplication (platform-storefront) 401s\n// any key where `!key.publishable` — a secret key holding this scope would\n// pass the picker and validation yet do nothing on the one plane it gates.\nadd(\n 'Customer accounts',\n 'customer_accounts',\n ['write'],\n { write: 'Let shoppers register, sign in and manage their account' },\n { publishableAllowed: true, publishableOnly: true, extensionAllowed: false },\n);\n\nadd('Carts', 'carts', ['read', 'write'], { read: 'View carts', write: 'Manage carts' });\nadd('Carts', 'cart_items', ['write'], { write: 'Manage line items' });\nadd('Carts', 'checkout_sessions', ['read', 'write'], { read: 'View checkout sessions', write: 'Manage checkout sessions' });\n\nadd('Discounts', 'discounts', ['read', 'write'], { read: 'View discounts', write: 'Manage discounts' });\n\nadd('Subscriptions', 'subscriptions', ['read', 'write'], { read: 'View subscriptions', write: 'Manage subscriptions' });\nadd('Subscriptions', 'subscription_pauses', ['write'], { write: 'Pause/resume subscriptions' });\nadd('Subscriptions', 'subscription_cancellations', ['write'], { write: 'Cancel subscriptions' });\nadd('Subscriptions', 'subscription_usage', ['read', 'write'], { read: 'View subscription usage', write: 'Report subscription usage' }, { extensionAllowed: false });\n\nadd('Fulfillments', 'fulfillments', ['read', 'write'], { read: 'View fulfillments', write: 'Manage fulfillments' });\nadd('Fulfillments', 'fulfillment_shipments', ['write'], { write: 'Update shipments' });\nadd('Fulfillments', 'fulfillment_digital', ['read', 'write'], { read: 'View digital delivery', write: 'Manage digital delivery' });\nadd('Fulfillments', 'fulfillment_access', ['write'], { write: 'Manage access credentials' });\nadd('Fulfillments', 'fulfillment_services', ['write'], { write: 'Manage service fulfillment' });\n\nadd('Invoices / AR', 'invoices', ['read'], { read: 'View invoices & aging' });\nadd('Invoices / AR', 'invoice_payments', ['write'], { write: 'Mark invoices paid' }, { sensitive: true });\nadd('Invoices / AR', 'invoice_dunning', ['write'], { write: 'Send dunning notices' });\n\nadd('Shipping & Tax', 'shipping_tax', ['read', 'write'], { read: 'View shipping/tax config', write: 'Edit shipping/tax config' });\nadd('Shipping & Tax', 'shipping_tax_publications', ['write'], { write: 'Publish shipping/tax config' });\nadd('Shipping & Tax', 'shipping_quotes', ['write'], { write: 'Request shipping quotes' }, { publishableAllowed: true });\nadd('Shipping & Tax', 'tax_calculations', ['write'], { write: 'Calculate tax' }, { publishableAllowed: true });\nadd('Shipping & Tax', 'shipping_tax_quote_tokens', ['read', 'write'], { read: 'View quote tokens', write: 'Manage quote tokens' });\nadd('Shipping & Tax', 'shipping_tax_snapshots', ['write'], { write: 'Accept external snapshots' });\n\n// Storefront script loading. Publishable-allowed on purpose: the manifest is\n// fetched by @usethrottle/scripts from the buyer's browser on the merchant's\n// own origin, where only a pk_ key can safely live. It is read-only and\n// exposes nothing that is not already public — the script sources it points at\n// are served unauthenticated and execute in every buyer's browser. Authoring\n// scripts stays on application_scripts:write, which is not publishable-allowed.\nadd(\n 'Scripts',\n 'storefront_scripts',\n ['read', 'write'],\n {\n read: 'Load storefront scripts',\n // `write` covers exactly one thing: reporting a script's own load outcome\n // from the merchant's storefront, so the health panel stops being\n // hosted-checkout-only. On checkout the session id in the URL is the\n // capability that scopes that write; a storefront page has no session, so\n // the pk it already holds is what scopes it instead. It writes nothing but\n // load telemetry — authoring stays on `application_scripts:write`, which\n // is not publishable-allowed.\n write: 'Report storefront script load outcomes',\n },\n { publishableAllowed: true },\n);\n\n// Authoring buyer-facing scripts is its own privilege, deliberately NOT part of\n// `applications:write`.\n//\n// Writing a script means injecting JavaScript into a buyer's checkout. Leaving\n// that inside `applications:write` meant an integration granted the ability to\n// rename an application silently also gained the ability to run code on a\n// payment page — a grant nobody would knowingly make, and one no consent screen\n// described. Splitting it also makes the useful narrow grant possible: a tag\n// manager can hold script write and nothing else.\n//\n// `extensionAllowed: false` on all four: an app manages its OWN scripts with\n// its developer's key, and has no business reaching a merchant's.\nadd('Scripts', 'application_scripts', ['read', 'write'], {\n read: 'View merchant-authored scripts',\n write: 'Create, edit and disable merchant-authored scripts',\n}, { extensionAllowed: false });\n\nadd('Scripts', 'extension_scripts', ['read', 'write'], {\n read: \"View an extension's buyer-facing scripts\",\n write: \"Create, edit and delete an extension's buyer-facing scripts\",\n}, { extensionAllowed: false });\n\nadd('Connectors', 'connectors', ['read', 'write'], { read: 'View connectors', write: 'Manage connectors' });\n\nadd('Webhooks & Events', 'webhooks', ['read', 'write'], { read: 'View webhooks', write: 'Manage webhooks' });\nadd('Webhooks & Events', 'webhook_deliveries', ['read', 'write'], { read: 'View deliveries', write: 'Retry deliveries' });\nadd('Webhooks & Events', 'events', ['read'], { read: 'View events' });\nadd('Webhooks & Events', 'audit_logs', ['read'], { read: 'View audit log' });\n\nadd('Applications', 'applications', ['read', 'write'], { read: 'View applications', write: 'Manage applications' });\n\nadd('Workspace', 'merchant', ['read', 'write'], { read: 'View workspace settings', write: 'Edit workspace settings' });\nadd('Workspace', 'embed_config', ['read', 'write'], { read: 'View embed config', write: 'Edit embed config' });\nadd('Workspace', 'branding', ['write'], { write: 'Upload branding assets' });\n\n// ── Taxonomy B — human / admin (extensionAllowed: false) ─────────────\nconst HUMAN: Opts = { extensionAllowed: false };\nadd('Team', 'team_members', ['read', 'write'], { read: 'View members', write: 'Manage members' }, HUMAN);\nadd('Team', 'team_invites', ['read', 'write'], { read: 'View invites', write: 'Manage invites' }, HUMAN);\nadd('Platform billing', 'billing', ['read', 'write'], { read: 'View billing', write: 'Manage subscription' }, HUMAN);\nadd('Platform billing', 'billing_payment_methods', ['read', 'write'], { read: 'View billing cards', write: 'Manage billing cards' }, HUMAN);\nadd('Email', 'email_templates', ['read', 'write'], { read: 'View email templates', write: 'Edit email templates' }, HUMAN);\nadd('Email', 'email_settings', ['read', 'write'], { read: 'View email settings', write: 'Edit email settings' }, HUMAN);\nadd('Go-live', 'go_live', ['write'], { write: 'Submit go-live' }, HUMAN);\nadd('Partner', 'partner', ['read', 'write'], { read: 'View partner profile', write: 'Edit partner profile' }, HUMAN);\nadd('Partner', 'affiliates', ['read', 'write'], { read: 'View affiliates', write: 'Manage affiliates' }, HUMAN);\nadd('Notifications', 'notifications', ['write'], { write: 'Send notifications' }, HUMAN);\nadd('Notifications', 'preferences', ['read', 'write'], { read: 'View preferences', write: 'Edit preferences' }, HUMAN);\nadd('Integrations', 'integrations', ['read', 'write'], { read: 'View integrations', write: 'Manage integrations' }, HUMAN);\nadd('Support', 'support', ['read', 'write'], { read: 'View support tickets', write: 'Manage support tickets' }, HUMAN);\nadd('Admin (staff)', 'admin', ['read', 'write'], { read: 'View admin data', write: 'Perform admin actions' }, { sensitive: true, staffOnly: true, extensionAllowed: false });\n\n// Extensions management — admin taxonomy: extensions must never manage other extensions.\n// 'read' and 'write' are auto-generated by add(); write→read implication is handled by add().\n// 'install' is a CUSTOM action registered manually — it is independent: write does NOT imply install.\nadd('Extensions', 'extensions', ['read', 'write'],\n { read: 'View extensions & installs', write: 'Author, version & publish extensions' }, HUMAN);\n// 'install' is not auto-generated; add() only handles 'read'/'write'. Register it directly.\nREG['extensions:install'] = {\n id: 'extensions:install', resource: 'extensions', action: 'install',\n group: 'Extensions', label: 'Install, configure & manage extensions',\n sensitive: false, staffOnly: false, publishableAllowed: false, publishableOnly: false, extensionAllowed: false, implies: [],\n};\n\n// ── wildcard ──────────────────────────────────────────────────────────\nREG['*'] = {\n id: '*', resource: '*', action: 'write', group: 'Global', label: 'Full access',\n sensitive: true, staffOnly: false, publishableAllowed: false, publishableOnly: false, extensionAllowed: false, implies: [],\n};\n\nexport const SCOPE_REGISTRY: Readonly<Record<string, ScopeDef>> = REG;\nexport type ScopeId = string;\nexport const ALL_SCOPE_IDS: readonly string[] = Object.keys(REG);\n\n/** group label → ordered scope ids (for the picker + docs). */\nexport const SCOPE_GROUPS: Record<string, string[]> = (() => {\n const out: Record<string, string[]> = {};\n for (const def of Object.values(REG)) {\n if (def.id === '*') continue;\n (out[def.group] ??= []).push(def.id);\n }\n return out;\n})();\n","// packages/core-scopes/src/events.ts\n/** Canonical event catalog. Keep in sync with the webhook-types union\n * (a compile-time assertion in webhook-types guards this — see Task 3.3). */\nexport const ALL_EVENT_TYPES = [\n // cart\n 'cart.created', 'cart.updated', 'cart.item_added', 'cart.item_updated',\n 'cart.item_removed', 'cart.shipping_selected', 'cart.shipping_cleared',\n 'cart.discount_applied', 'cart.discount_removed', 'cart.tax_recomputed',\n 'cart.checkout_started', 'cart.converted', 'cart.abandoned', 'cart.merged',\n // checkout\n // NOTE: checkout.session.created / .completed removed from the catalog\n // 2026-08-10 — no code path has ever emitted them, and prod has zero of each.\n // They were subscribable (VALID_EVENT_TYPES derives from this list), so an\n // Buyer-facing script outcomes, one per script per page load. An app\n // shipping a pixel to a hundred merchants otherwise has no way to learn it\n // stopped working on one of them — that is only visible today in a dashboard\n // the app's developer cannot see.\n //\n // `script.loaded` is HIGH VOLUME by nature (every script, every page load).\n // Delivery is opt-in per endpoint, so the cost lands only on someone who\n // asked for it; `script.blocked` and `script.error` are the ones worth\n // subscribing to for monitoring.\n 'script.loaded', 'script.blocked', 'script.error',\n // extension could register for them, pass every check, and then simply never\n // receive anything. That silent dead-end cost the first third-party extension\n // author a day. Removing them makes the subscription fail at registration\n // instead. If checkout-session eventing is wanted, add the types back in the\n // same change that adds the emit sites — never before.\n // order\n 'order.created', 'order.updated', 'order.fulfilled', 'order.cancelled',\n 'order.closed', 'order.sync_failed', 'order.sync_conflict',\n // Money written off, and that write-off undone. Emitted by the comp writers\n // in @commerce/orders — a comp changes what the buyer owes without any\n // processor involvement, so no payment.* event covers it.\n 'order.comped', 'order.comp_reversed',\n 'order.held', 'order.hold_released',\n // return / RMA (#690)\n 'return.created', 'return.updated',\n // quote (sales quotes). All nine of spec §10.1 — quote.expired was emitted\n // by the expiry cron from the day it shipped but never registered here, so\n // subscribing to it 400'd and it could never be delivered.\n 'quote.requested', 'quote.proposed', 'quote.viewed', 'quote.comment_added',\n 'quote.revision_requested', 'quote.declined', 'quote.accepted', 'quote.converted',\n 'quote.expired',\n // payment\n // payment.authorization_failed / capture_failed / void_failed removed 2026-07-05:\n // no live code path emits them (Gr4vy adapter not wired into PaymentService).\n 'payment.pending', 'payment.authorized',\n // The provider has neither approved nor declined yet — a 3DS challenge, a\n // redirect method, a bank debit still settling. Before slice 3 these were\n // written as `failed`, so a buyer mid-challenge looked like a dead card.\n 'payment.processing',\n 'payment.captured', 'payment.failed', 'payment.voided',\n // An authorization we can no longer expect to capture. Gr4vy does not\n // reliably notify on expiry, so this is our own sweep saying so.\n 'payment.expired',\n 'payment.refunded', 'payment.partially_refunded',\n 'payment.refund_failed', 'payment.vaulted', 'payment.disputed', 'payment.dispute_cleared',\n // Money that arrived outside Throttle (cash, bank transfer, cheque), recorded\n // by the merchant. Distinct from payment.captured: no processor moved it.\n 'payment.recorded',\n // fulfillment\n 'fulfillment.created', 'fulfillment.completed', 'fulfillment.cancelled',\n 'fulfillment.shipment.shipped', 'fulfillment.shipment.delivered',\n 'fulfillment.digital.delivered',\n // subscription\n 'subscription.created', 'subscription.activated', 'subscription.updated',\n 'subscription.plan_changed', 'subscription.plan_change_scheduled',\n 'subscription.paused', 'subscription.resumed', 'subscription.cancelled', 'subscription.completed',\n 'subscription.renewed', 'subscription.past_due', 'subscription.payment_failed',\n 'subscription.create_failed', 'subscription.trial_blocked',\n 'subscription.backup_pm_used',\n // A cycle's money went back. Distinct from payment.refunded: that one says a\n // payment moved, this one says WHICH billing period the buyer was made whole\n // for, and whether the subscription was ended along with it.\n 'subscription.invoice_refunded',\n // discount\n 'discount.applied', 'discount.removed',\n // customer\n 'customer.created', 'customer.updated', 'customer.deleted',\n 'customer.payment_method_added', 'customer.payment_method_removed',\n // Buyer authentication (storefront customer accounts, spec 2026-09-12).\n 'customer.registered', 'customer.email_verified',\n 'customer.password_changed', 'customer.sessions_revoked',\n // Deliberately NO 'customer.password_reset_requested' event: the reset email is\n // sent imperatively via emails.sendTransactional, so no catalog entry is needed,\n // and adding one would make a password-reset trigger subscribable by extensions.\n // invoice / AR\n 'invoice.past_due',\n // import (bulk data import)\n 'import.completed',\n // shipping & tax\n 'shipping_tax.provider_connection.unhealthy',\n // workspace / platform-billing\n 'workspace.payment_method.added', 'workspace.payment_method.removed',\n 'workspace.payment_method.default_changed', 'workspace.payment_method.backup_set',\n 'workspace.payment_method.backup_used', 'workspace.platform_charge.succeeded',\n 'workspace.platform_charge.failed', 'workspace.trial_expired',\n // NOTE: extension.* review/publishing events were removed from the outbound\n // event catalog (2026-07-05) — they remain in-app + email notifications, not\n // deliverable webhooks. Installation lifecycle is (app, env)-bound and IS\n // delivered: the uninstalled installation's own endpoint receives it with no\n // subscription, so an extension never needs to (and cannot) subscribe to it.\n 'extension.uninstalled',\n 'extension.webhook_secret_rotated',\n] as const;\n\nexport type EventType = (typeof ALL_EVENT_TYPES)[number];\n\n/** Exact-match overrides take priority over prefix rules. */\nconst EVENT_SCOPE_OVERRIDES: Record<string, string> = {\n 'payment.refunded': 'payment_refunds:read',\n 'payment.partially_refunded': 'payment_refunds:read',\n 'payment.refund_failed': 'payment_refunds:read',\n // Money returned, so it belongs with the other refund events rather than\n // behind the broad subscriptions:read the `subscription.` prefix would give.\n 'subscription.invoice_refunded': 'payment_refunds:read',\n 'payment.disputed': 'payment_disputes:read',\n 'payment.dispute_cleared': 'payment_disputes:read',\n 'fulfillment.digital.delivered': 'fulfillment_digital:read',\n};\n\n// Exact-match overrides (EVENT_SCOPE_OVERRIDES) take priority over these prefix rules. Add fine-grained event→scope mappings there, not here.\n/** Ordered longest-prefix-first so `checkout.session.` beats `checkout.`. */\nconst PREFIX_RULES: Array<[string, string]> = [\n ['checkout.session.', 'carts:read'],\n ['cart.', 'carts:read'],\n ['order.', 'orders:read'],\n ['quote.', 'quotes:read'],\n ['return.', 'order_returns:read'],\n ['payment.', 'payments:read'],\n ['customer.', 'customers:read'],\n ['subscription.', 'subscriptions:read'],\n ['fulfillment.', 'fulfillments:read'],\n ['discount.', 'discounts:read'],\n ['invoice.', 'invoices:read'],\n ['import.', 'imports:read'],\n ['shipping_tax.', 'shipping_tax:read'],\n ['workspace.', 'billing:read'],\n // `extensions:read` is a human scope (extensions must never watch other\n // extensions), so only a workspace endpoint can SUBSCRIBE to this family.\n // The uninstalled installation's own endpoint is addressed directly by the\n // uninstall path and needs no subscription at all.\n ['extension.', 'extensions:read'],\n // Subscribing to script outcomes needs script read — the payload names the\n // script key and its hash, which is the merchant's script inventory.\n ['script.', 'application_scripts:read'],\n];\n\n/** Map an event type to the read scope required to subscribe/receive it. */\nexport function eventReadScope(type: string): string {\n if (EVENT_SCOPE_OVERRIDES[type]) return EVENT_SCOPE_OVERRIDES[type];\n for (const [prefix, scope] of PREFIX_RULES) {\n if (type.startsWith(prefix)) return scope;\n }\n throw new Error(`Unknown event type: ${type}`);\n}\n","// packages/core-scopes/src/issuance.ts\nimport { SCOPE_REGISTRY } from './scopes';\nimport { expandLegacyScopes } from './legacy';\n\nexport interface ValidationResult { ok: boolean; invalid: string[]; }\n\n/** Validate scopes requested for an API key.\n * - legacy scopes are expanded first (migration-window safety)\n * - sk_: every scope must exist + not be staffOnly or publishableOnly; '*' allowed\n * - pk_: every scope must be publishableAllowed; '*' NOT allowed */\nexport function validateScopesForKey(\n scopes: readonly string[],\n opts: { publishable: boolean },\n): ValidationResult {\n const expanded = expandLegacyScopes(scopes);\n const invalid: string[] = [];\n for (const id of expanded) {\n if (id === '*') {\n if (opts.publishable) invalid.push(id);\n continue;\n }\n const def = SCOPE_REGISTRY[id];\n if (!def) { invalid.push(id); continue; }\n if (opts.publishable) {\n if (!def.publishableAllowed) invalid.push(id);\n } else if (def.staffOnly || def.publishableOnly) {\n invalid.push(id);\n }\n }\n return { ok: invalid.length === 0, invalid };\n}\n\n/** Validate scopes requested in an extension manifest:\n * every scope must exist + be extensionAllowed; '*' is never allowed. */\nexport function validateScopesForExtension(scopes: readonly string[]): ValidationResult {\n const expanded = expandLegacyScopes(scopes);\n const invalid: string[] = [];\n for (const id of expanded) {\n if (id === '*') { invalid.push(id); continue; }\n const def = SCOPE_REGISTRY[id];\n if (!def || !def.extensionAllowed) invalid.push(id);\n }\n return { ok: invalid.length === 0, invalid };\n}\n\n/** Scope ids a publishable key may hold (for the picker). */\nexport const PUBLISHABLE_SCOPES: string[] =\n Object.values(SCOPE_REGISTRY).filter((d) => d.publishableAllowed).map((d) => d.id);\n\n/**\n * OAuth grants are minted only by the post-granular authorization server, so a\n * legacy coarse scope can never appear on one. Validate the LITERAL ids only.\n *\n * Expanding first (as the api-key path must, for pre-granular keys) rejected\n * several non-sensitive scopes because they double as LEGACY_SCOPE_EXPANSION\n * keys whose supersets contain sensitive children. Examples:\n * - `customers:read` (non-sensitive) expands to `{customer_pii:read,\n * customer_payment_methods:read}` (both sensitive)\n * - `payments:read` (non-sensitive) expands to `{payment_refunds:read,\n * payment_disputes:read}` (both sensitive)\n * - `customers:write` (non-sensitive) expands to `{customer_payment_methods:write}`\n * (sensitive)\n * - `payments:write` (non-sensitive) expands to `{payment_refunds:write,\n * payment_voids:write, payment_disputes:write, payment_methods:write}` (sensitive)\n *\n * The oauth_token auth branch in core-auth/src/middleware.ts assigns\n * `scopes: claims.scopes` with **no expansion**, so a grant carrying\n * `customers:read` gets exactly `customers:read` only, never the sensitive\n * children. All non-sensitive scopes are grantable, checked per-id against the\n * registry. The runtime grant carries the literal scope only.\n *\n * Separately, `scopes_supported` in the OAuth discovery endpoint is narrowed by\n * filtering to scopes declared by MCP-channel actions only, so `payments:write`\n * (declared by no MCP tool) will never appear in the advertised list even though\n * it is grantable to custom OAuth clients requesting it on the consent screen.\n */\n/**\n * Sensitive scopes an automation connector (a client registered for the REST\n * API audience — Zapier, Make) may still be granted, because the merchant is\n * deliberately piping their own customer records into another tool. The\n * consent screen names it. AI assistants (the MCP audience) never get it, and\n * no money-moving scope is on this list.\n */\nexport const CONNECTOR_GRANTABLE_SENSITIVE_SCOPES: readonly string[] = ['customer_pii:read'];\n\nexport function validateScopesForOAuth(\n scopes: readonly string[],\n opts: { connector?: boolean } = {},\n): ValidationResult {\n const invalid: string[] = [];\n for (const id of scopes) {\n if (id === '*') { invalid.push(id); continue; }\n const def = SCOPE_REGISTRY[id];\n if (!def || def.staffOnly) { invalid.push(id); continue; }\n if (def.sensitive && !(opts.connector && CONNECTOR_GRANTABLE_SENSITIVE_SCOPES.includes(id))) invalid.push(id);\n }\n return { ok: invalid.length === 0, invalid };\n}\n","/**\n * Deep redaction of a shopper's personal data from any API response, for\n * callers that may not see it: an OAuth connection (ChatGPT, Claude) can never\n * hold `customer_pii:read`.\n *\n * Route-by-route redaction (`redactCustomerPii` in platform-api) covers the\n * customer routes, but the same person reaches a response through many other\n * shapes — `order.customer`, cart and order addresses, `subscription\n * .taxAddressSnapshot`, `invoice.billingSnapshot.customer`, `quote\n * .customerEmail`, quote comment authors, event `previousData`, audit-log\n * metadata, the raw processor response on a payment. Chasing each route missed\n * most of them, so this works on keys instead, anywhere in the tree:\n *\n * - contact and name fields are nulled wherever they appear;\n * - `name` is nulled only inside a `customer`/`buyer` object, because product,\n * application and workspace names are not personal data;\n * - an address keeps city, region, postal code and country (what shipping\n * and tax reporting need) and loses the street lines and company;\n * - `processorResponse` (the payment vendor's raw record, which carries the\n * buyer) and `shareToken` (a buyer's capability link to a quote) are nulled;\n * - free-form fields are nulled whole: `metadata`, notes, reasons, quote\n * comment bodies, acceptance records, client context (IP, user agent) and\n * tax ids. A name or email can sit anywhere inside free text or under any\n * metadata key, so no key list can find it there — the only honest option\n * is not to return the field;\n * - the merchant's own identifiers (`externalId`, `externalCustomerId`) and\n * `company` are nulled: merchants key customers by email or name often\n * enough, and no pattern can prove a given value is opaque.\n *\n * This is the REST API's second line. The hosted MCP server, which is what\n * actually reaches an assistant, returns only allowlisted fields\n * (`packages/mcp/src/projection.ts`) and runs this after them.\n *\n * Only plain objects and arrays are walked; Dates and other instances pass\n * through untouched. Returns a copy; the input is not modified.\n */\nconst PERSON_KEYS = new Set([\n 'email', 'customerEmail', 'billingEmail', 'buyerEmail', 'authorEmail', 'authorName',\n 'phone', 'firstName', 'lastName', 'addressLine1', 'addressLine2', 'billingAddressLines',\n 'processorResponse', 'shareToken', 'company', 'externalId', 'externalCustomerId',\n // Free-form: contents cannot be inspected for a person, so the field goes.\n 'metadata', 'notes', 'internalNotes', 'buyerNote', 'buyerReference', 'changeSummary',\n 'declinedReason', 'compReason', 'holdReason', 'body', 'acceptance', 'acceptanceSelections',\n 'clientContext', 'ipAddress', 'userAgent', 'vatNumber', 'buyerVatNumber', 'taxExemptionNumber',\n]);\nconst PERSON_CONTAINERS = new Set(['customer', 'buyer']);\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nfunction walk(value: unknown, parentKey: string | null, depth: number): unknown {\n if (depth > 32) return value;\n if (Array.isArray(value)) return value.map((item) => walk(item, parentKey, depth + 1));\n if (!isPlainObject(value)) return value;\n const out: Record<string, unknown> = {};\n const isPerson = parentKey !== null && PERSON_CONTAINERS.has(parentKey);\n for (const [key, child] of Object.entries(value)) {\n if (PERSON_KEYS.has(key) || (isPerson && key === 'name')) {\n out[key] = child === undefined ? child : null;\n } else {\n out[key] = walk(child, key, depth + 1);\n }\n }\n return out;\n}\n\nexport function redactShopperPii<T>(value: T): T {\n return walk(value, null, 0) as T;\n}\n","import type { ActionDefinition } from './types';\n\n/**\n * What an OAuth connection (ChatGPT, Claude) does not get back from the\n * records these tools read — the hosted server returns allowlisted fields only\n * (`packages/mcp/src/projection.ts`). Stated on each tool so the assistant\n * says \"withheld\" instead of \"none on file\".\n */\nconst OAUTH_WITHHELD =\n 'Over an OAuth connection (ChatGPT, Claude) these are withheld, because a buyer can type them: line-item and quote-item names, SKUs and reference ids; company; every address line except the country; the merchant\\'s external ids; notes, messages, reasons and metadata. Describe items by quantity and amount, and say the rest is withheld rather than missing.';\n\n/**\n * The verbs, defined once.\n *\n * Curation, not coverage: each entry maps to a job somebody actually asks for.\n * Long-tail reads are served by `api_get`, which cannot mutate anything and is\n * still scope-enforced server-side, so the curated list never has to grow just\n * to reach another GET.\n *\n * Paths are the EFFECTIVE public paths. Route files that declare `/v1/...`\n * literals are registered under a `prefix: '/api'`, so both spellings resolve to\n * `/api/v1/...`; the catalog always records the resolved form.\n */\nexport const ACTIONS: readonly ActionDefinition[] = [\n // ---------------------------------------------------------------- identity\n {\n id: 'whoami',\n title: 'Identify the connected credential',\n description:\n 'Report which workspace, application and environment this credential is pinned to, and what it is allowed to do. Call this first when you need to know whether you are talking to production or a sandbox.',\n kind: 'read',\n scopes: [],\n input: [],\n requests: [{ method: 'GET', path: '/api/v1/whoami' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ------------------------------------------------------- local (no API call)\n {\n id: 'search_docs',\n title: 'Search the Throttle developer docs',\n description:\n 'Full-text search over the Throttle developer documentation. Returns titles, canonical usethrottle.dev/docs URLs, and matching excerpts. Prefer this over recalling API details from memory.',\n kind: 'read',\n scopes: [],\n input: [\n { name: 'query', type: 'string', required: true, description: 'What to search for.' },\n { name: 'limit', type: 'number', required: false, description: 'Maximum results.' },\n ],\n requests: [],\n channels: ['mcp'],\n },\n {\n id: 'describe_endpoint',\n title: 'Describe an API endpoint',\n description:\n 'Return the canonical request and response shape of a Throttle API endpoint from the published OpenAPI contract: path parameters, request body fields, required scope. Use before writing any integration code.',\n kind: 'read',\n scopes: [],\n input: [\n {\n name: 'path',\n type: 'string',\n required: true,\n description: 'Endpoint path or fragment, e.g. \"/api/v1/carts\" or \"carts\".',\n },\n {\n name: 'method',\n type: 'string',\n required: false,\n description: 'Narrow to one HTTP method.',\n enum: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'],\n },\n ],\n requests: [],\n channels: ['mcp'],\n },\n {\n id: 'validate_payload',\n title: 'Validate a request body against the API contract',\n description:\n 'Check a request body against the published contract before sending it. Names every unsupported field and gives its canonical replacement — Throttle is strict camelCase and rejects retired aliases such as line_items, unit_price, customer_id and storeId. Full reference: https://usethrottle.dev/docs/developers/api-reference.',\n kind: 'read',\n scopes: [],\n input: [\n { name: 'method', type: 'string', required: true, description: 'HTTP method.' },\n { name: 'path', type: 'string', required: true, description: 'Endpoint path.' },\n { name: 'body', type: 'object', required: true, description: 'The request body to check.' },\n ],\n requests: [],\n channels: ['mcp'],\n },\n\n // ------------------------------------------------------------ generic reads\n {\n id: 'api_get',\n title: 'Read any Throttle API endpoint',\n description:\n 'Escape hatch for reads the curated tools do not cover: performs a GET against any /api/v1 path and returns the response. Cannot write. Confirm the path with describe_endpoint first if unsure. Full reference: https://usethrottle.dev/docs/developers/api-reference.',\n kind: 'read',\n scopes: [],\n credentialScoped: true,\n input: [\n {\n name: 'path',\n type: 'string',\n required: true,\n description: 'Path beginning with /api/v1, query string included.',\n },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [],\n channels: ['mcp'],\n guardrails: [\n 'GET only — reject any other method.',\n 'Reject paths outside /api/v1 so the tool cannot be pointed at another host or a non-versioned surface.',\n 'Server-side scope enforcement still applies; surface a 403 insufficient_scopes verbatim rather than retrying.',\n ],\n },\n\n // ------------------------------------------------------------------- orders\n {\n id: 'search_orders',\n title: 'Search orders',\n description: 'List orders, newest first, with optional free-text and status filters.',\n kind: 'read',\n scopes: ['orders:read'],\n input: [\n { name: 'q', type: 'string', required: false, description: 'Free-text search.' },\n { name: 'status', type: 'string', required: false, description: 'Order status filter.' },\n { name: 'paymentStatus', type: 'string', required: false, description: 'Payment status filter.' },\n {\n name: 'createdAfter',\n type: 'string',\n required: false,\n description: 'ISO 8601 lower bound on creation time, exclusive. For a single day, pass that day\\'s midnight and the next day\\'s midnight.',\n },\n {\n name: 'createdBefore',\n type: 'string',\n required: false,\n description: 'ISO 8601 upper bound on creation time, exclusive.',\n },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/orders' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n OAUTH_WITHHELD,\n 'Over an OAuth connection, q matches the order id, order number and status fields only.',\n ],\n },\n {\n id: 'get_order',\n title: 'Get one order with its returns and fulfillments',\n description:\n 'Full picture of a single order: the order itself plus its payments, returns and fulfillments in one response.',\n kind: 'read',\n scopes: ['orders:read'],\n sectionScopes: ['payments:read', 'order_returns:read', 'fulfillments:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Order id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/orders/:id' },\n { method: 'GET', path: '/api/v1/orders/:id/payments' },\n { method: 'GET', path: '/api/v1/orders/:id/returns' },\n { method: 'GET', path: '/api/v1/orders/:orderId/fulfillments' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Sub-reads need their own scopes (payments:read, order_returns:read, fulfillments:read). Skip a section the credential cannot read and say so in the result rather than failing the whole call.',\n OAUTH_WITHHELD,\n ],\n },\n\n // ---------------------------------------------------------------- customers\n {\n id: 'search_customers',\n title: 'Search customers',\n description:\n 'Find customers by name, email or external id, or list them by creation date. Over an OAuth connection (ChatGPT, Claude) text search is not available — list by date instead — because every field it could match is withheld there.',\n kind: 'read',\n scopes: ['customers:read'],\n input: [\n { name: 'q', type: 'string', required: false, description: 'Free-text search.' },\n {\n name: 'createdAfter',\n type: 'string',\n required: false,\n description: 'ISO 8601 lower bound on creation time, exclusive. For a single day, pass that day\\'s midnight and the next day\\'s midnight.',\n },\n {\n name: 'createdBefore',\n type: 'string',\n required: false,\n description: 'ISO 8601 upper bound on creation time, exclusive.',\n },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/customers' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'email, phone, firstName, lastName, name and metadata are withheld (null, or absent from the result) unless the credential holds customer_pii:read, which OAuth connections cannot hold. Over an OAuth connection company, externalId and externalCustomerId are withheld too, and q is refused. Do not describe a missing name/email as \"no name on file\"; say it is withheld.',\n ],\n },\n {\n id: 'get_customer',\n title: 'Get one customer with subscriptions and addresses',\n description:\n 'Full picture of a single customer: the record plus their subscriptions and addresses in one response.',\n kind: 'read',\n scopes: ['customers:read'],\n sectionScopes: ['customer_addresses:read', 'subscriptions:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Customer id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/customers/:id' },\n { method: 'GET', path: '/api/v1/customers/:id/addresses' },\n { method: 'GET', path: '/api/v1/subscriptions' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Sub-reads need customer_addresses:read / subscriptions:read. Omit a section the credential cannot read instead of failing.',\n 'email, phone, firstName, lastName, name and metadata on the customer record are withheld (null, or absent from the result) unless the credential holds customer_pii:read, which OAuth connections cannot hold. Say PII is redacted rather than reporting the buyer as anonymous.',\n OAUTH_WITHHELD,\n ],\n },\n\n // ------------------------------------------------------------- subscriptions\n {\n id: 'list_subscriptions',\n title: 'List subscriptions',\n description: 'List subscriptions with optional customer and status filters.',\n kind: 'read',\n scopes: ['subscriptions:read'],\n input: [\n { name: 'customerId', type: 'string', required: false, description: 'Filter by customer.' },\n { name: 'status', type: 'string', required: false, description: 'Filter by status.' },\n {\n name: 'createdAfter',\n type: 'string',\n required: false,\n description: 'ISO 8601 lower bound on creation time, exclusive. For a single day, pass that day\\'s midnight and the next day\\'s midnight.',\n },\n {\n name: 'createdBefore',\n type: 'string',\n required: false,\n description: 'ISO 8601 upper bound on creation time, exclusive.',\n },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/subscriptions' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_subscription',\n title: 'Get one subscription',\n description: 'Read a single subscription including its current period and pending changes.',\n kind: 'read',\n scopes: ['subscriptions:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Subscription id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/subscriptions/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ------------------------------------------------------------------- quotes\n {\n id: 'search_quotes',\n title: 'Search quotes',\n description: 'List quotes with optional status filter — useful for \"which quotes expire soon\".',\n kind: 'read',\n scopes: ['quotes:read'],\n input: [\n { name: 'status', type: 'string', required: false, description: 'Filter by quote status.' },\n {\n name: 'createdAfter',\n type: 'string',\n required: false,\n description: 'ISO 8601 lower bound on creation time, exclusive. For a single day, pass that day\\'s midnight and the next day\\'s midnight.',\n },\n {\n name: 'createdBefore',\n type: 'string',\n required: false,\n description: 'ISO 8601 upper bound on creation time, exclusive.',\n },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/quotes' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_quote',\n title: 'Get one quote',\n description: 'Read a single quote: status, totals, and each revision with its line items and payment terms.',\n kind: 'read',\n scopes: ['quotes:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Quote id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/quotes/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [OAUTH_WITHHELD],\n },\n\n // ----------------------------------------------------------------- invoices\n {\n id: 'list_invoices',\n title: 'List invoices',\n description: 'List issued invoices with optional status filter.',\n kind: 'read',\n scopes: ['invoices:read'],\n input: [\n { name: 'status', type: 'string', required: false, description: 'Filter by invoice status.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/invoices' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [OAUTH_WITHHELD],\n },\n {\n id: 'receivables_aging',\n title: 'Receivables aging',\n description: 'Outstanding receivables bucketed by age — answers \"what is overdue and by how long\".',\n kind: 'read',\n scopes: ['invoices:read'],\n input: [\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/invoices/aging' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // --------------------------------------------------------------- discounts\n {\n id: 'search_discounts',\n title: 'Search discounts',\n description: 'List discount codes with optional filters — type, active state, and creation date range.',\n kind: 'read',\n scopes: ['discounts:read'],\n input: [\n { name: 'q', type: 'string', required: false, description: 'Free-text search.' },\n { name: 'code', type: 'string', required: false, description: 'Exact code match.' },\n {\n name: 'type',\n type: 'string',\n required: false,\n description: 'Filter by discount type.',\n enum: ['percentage', 'fixed_amount'],\n },\n { name: 'isActive', type: 'boolean', required: false, description: 'Filter by active state.' },\n { name: 'createdAfter', type: 'string', required: false, description: 'ISO 8601 date lower bound.' },\n { name: 'createdBefore', type: 'string', required: false, description: 'ISO 8601 date upper bound.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/discounts' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_discount',\n title: 'Get one discount',\n description: 'Read a single discount code: value, conditions, usage limits and redemption count.',\n kind: 'read',\n scopes: ['discounts:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Discount id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/discounts/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ---------------------------------------------------------------- payments\n {\n id: 'search_payments',\n title: 'Search payments',\n description:\n 'List payments with optional filters — method, status, order, amount range, or a Net-N overdue bucket. Today payments are only reachable nested inside get_order; this is the standalone entry point.',\n kind: 'read',\n scopes: ['payments:read'],\n input: [\n { name: 'method', type: 'string', required: false, description: 'Filter by payment method.' },\n { name: 'status', type: 'string', required: false, description: 'Filter by payment status.' },\n { name: 'orderId', type: 'string', required: false, description: 'Filter to one order.' },\n {\n name: 'aging',\n type: 'string',\n required: false,\n description: 'Overdue bucket filter, Net-N payments only.',\n enum: ['0_30', '31_60', '61_90', '90_plus'],\n },\n { name: 'dueFrom', type: 'string', required: false, description: 'Due-date range start, YYYY-MM-DD.' },\n { name: 'dueTo', type: 'string', required: false, description: 'Due-date range end, YYYY-MM-DD.' },\n { name: 'amountMin', type: 'number', required: false, description: 'Minimum amount, minor units.' },\n { name: 'amountMax', type: 'number', required: false, description: 'Maximum amount, minor units.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/payments' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_payment',\n title: 'Get one payment with its transactions',\n description: 'Read a single payment plus its full transaction history (authorize/capture/refund/void attempts).',\n kind: 'read',\n scopes: ['payments:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Payment id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/payments/:id' },\n { method: 'GET', path: '/api/v1/payments/:id/transactions' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'The transactions sub-read needs its own read of the same payment scope; report it as unavailable rather than failing the whole call if the underlying request errors.',\n ],\n },\n\n // ---------------------------------------------------------------- invoices\n {\n id: 'get_invoice',\n title: 'Get one invoice',\n description: 'Read a single issued invoice: line items, totals, status and the billing snapshot at issue time.',\n kind: 'read',\n scopes: ['invoices:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Invoice id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/invoices/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [OAUTH_WITHHELD],\n },\n\n // ------------------------------------------------------------------ carts\n {\n id: 'list_abandoned_carts',\n title: 'List abandoned carts',\n description: 'Carts that were started but never finalized, with recovery status — the abandoned-cart recovery list.',\n kind: 'read',\n scopes: ['carts:read'],\n input: [\n { name: 'sinceDays', type: 'number', required: false, description: 'How many days back to look.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/abandoned-carts' },\n { method: 'GET', path: '/api/v1/abandoned-carts/summary' },\n ],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: ['Report the summary as unavailable rather than failing the whole call if that sub-read errors.'],\n },\n\n // ---------------------------------------------------------------- debugging\n {\n id: 'search_events',\n title: 'Search the event log',\n description:\n 'Search the immutable event log by type or entity. The first stop when asking what actually happened to an order, cart or subscription.',\n kind: 'read',\n scopes: ['events:read'],\n input: [\n { name: 'type', type: 'string', required: false, description: 'Event type, e.g. order.created.' },\n { name: 'entityType', type: 'string', required: false, description: 'Entity type filter.' },\n { name: 'entityId', type: 'string', required: false, description: 'Entity id filter.' },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/events' }],\n channels: ['mcp', 'n8n'],\n },\n {\n id: 'list_webhook_deliveries',\n title: 'List webhook deliveries',\n description:\n 'Recent outbound webhook deliveries, filterable by endpoint, status and event type.',\n kind: 'read',\n scopes: ['webhook_deliveries:read'],\n input: [\n { name: 'endpointId', type: 'string', required: false, description: 'Filter by endpoint.' },\n {\n name: 'status',\n type: 'string',\n required: false,\n description: 'Filter by delivery status: pending, delivered, failed or dead_letter.',\n },\n {\n name: 'eventType',\n type: 'string',\n required: false,\n description: 'Filter by exact event type, e.g. payment.failed.',\n },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/webhook-deliveries' }],\n channels: ['mcp', 'n8n'],\n },\n {\n id: 'get_webhook_delivery',\n title: 'Get one webhook delivery',\n description:\n 'Full delivery record: the signed payload we sent, the response we got back, and every attempt.',\n kind: 'read',\n scopes: ['webhook_deliveries:read'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Delivery id.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/webhook-deliveries/:id' }],\n channels: ['mcp', 'n8n'],\n },\n {\n id: 'explain_checkout_failure',\n title: 'Explain why a checkout failed',\n description:\n 'Diagnose a failing checkout in one call: session state, its cart, the events it emitted, and any webhook deliveries that followed. Use this before asking the user to reproduce anything.',\n kind: 'read',\n scopes: ['checkout_sessions:read'],\n sectionScopes: ['events:read', 'webhook_deliveries:read'],\n input: [\n {\n name: 'id',\n type: 'string',\n required: true,\n description: 'Checkout session id (or cart id — the tool resolves the session).',\n },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/checkout-sessions/:id' },\n { method: 'GET', path: '/api/v1/checkout-sessions/:id/cart' },\n { method: 'GET', path: '/api/v1/events' },\n { method: 'GET', path: '/api/v1/webhook-deliveries' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Report which sections were unavailable rather than failing the call when a sub-read is unscoped.',\n OAUTH_WITHHELD,\n ],\n },\n\n // ------------------------------------------------------------- extensions\n {\n id: 'list_extension_installations',\n title: 'List installed extensions',\n description: 'Extensions installed on this application, with status and configuration.',\n kind: 'read',\n scopes: ['extensions:read'],\n input: [\n {\n name: 'status',\n type: 'string',\n required: false,\n description: 'Filter by installation status.',\n enum: ['active', 'suspended', 'uninstalled'],\n },\n { name: 'limit', type: 'number', required: false, description: 'Page size.' },\n { name: 'cursor', type: 'string', required: false, description: 'Pagination cursor.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/installations' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n\n // ------------------------------------------------------------- connectors\n {\n id: 'get_connector_routing',\n title: 'Payment routing and decline rules',\n description:\n 'Read the payment-routing cascade, active routing connectors, and card/other decline rules — what determines which processor handles a payment and what happens on a decline.',\n kind: 'read',\n scopes: ['connectors:read'],\n input: [\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/payment-routing' },\n { method: 'GET', path: '/api/v1/routing-connectors' },\n { method: 'GET', path: '/api/v1/card-decline' },\n { method: 'GET', path: '/api/v1/other-decline' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Every sub-read proxies live to the payment provider\\'s routing API and none are guaranteed to succeed together; report any that fail as unavailable rather than failing the whole call.',\n ],\n },\n\n {\n id: 'get_integration_status',\n title: 'Integration readiness',\n description:\n 'Answers \"am I ready to go live?\" — active connectors, webhook endpoints and their recent delivery health, and the environment this credential is pinned to.',\n kind: 'read',\n scopes: [],\n sectionScopes: ['connectors:read', 'webhooks:read'],\n input: [\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [\n { method: 'GET', path: '/api/v1/whoami' },\n { method: 'GET', path: '/api/v1/connectors' },\n { method: 'GET', path: '/api/v1/webhook-endpoints' },\n { method: 'GET', path: '/api/v1/webhook-endpoints/coverage' },\n ],\n channels: ['mcp'],\n guardrails: [\n 'Each section needs its own scope (connectors:read, webhooks:read). Report a section as \"not readable with this credential\" instead of failing.',\n ],\n },\n // --------------------------------------------------------------- workspace\n {\n id: 'get_workspace_settings',\n title: 'Get workspace settings',\n description:\n 'Read this workspace\\'s identity: name, slug, branding and onboarding state. Payment terms are set per application and environment, not here.',\n kind: 'read',\n scopes: ['merchant:read'],\n input: [],\n requests: [{ method: 'GET', path: '/api/v1/merchants/me' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_audit_log',\n title: 'Get the workspace audit log',\n description:\n 'Recent admin actions taken on this workspace — invites, billing changes, key rotation, suspensions.',\n kind: 'read',\n scopes: ['audit_logs:read'],\n input: [\n { name: 'limit', type: 'number', required: false, description: 'Maximum entries (1-200).', default: 100 },\n ],\n requests: [{ method: 'GET', path: '/api/v1/audit-log' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'list_applications',\n title: 'List applications in this workspace',\n description:\n 'List every application in this workspace you have access to, so you can pass one of their ids as applicationId on other read and analytics tools. Note: the underlying route is the legacy-named /v1/stores (kept for contract stability) — the resource it returns is applications, not a separate \"stores\" concept.',\n kind: 'read',\n scopes: ['applications:read'],\n input: [],\n requests: [{ method: 'GET', path: '/api/v1/stores' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n },\n {\n id: 'get_sales_timeseries',\n title: 'Sales over time',\n description:\n 'Order count and gross revenue bucketed by day, week or month over any date range, in the merchant\\'s timezone, optionally compared to the previous period or the same range last year. Use this for \"how much did we sell on/last/between…\" instead of paging search_orders and adding it up.',\n kind: 'read',\n scopes: ['orders:read'],\n input: [\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range, exclusive. Defaults to 30 days before \"to\".' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range, exclusive. Defaults to now.' },\n { name: 'groupBy', type: 'string', required: false, description: 'Bucket size.', enum: ['day', 'week', 'month'], default: 'day' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for bucket boundaries, e.g. America/New_York. Defaults to UTC — ask the user rather than assuming UTC when the answer depends on day boundaries.' },\n { name: 'compareTo', type: 'string', required: false, description: 'Add a comparison total.', enum: ['previous_period', 'previous_year', 'none'], default: 'none' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/orders-timeseries' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Revenue is GROSS. Refunds are not deducted, because that needs payment_refunds:read, which OAuth connections cannot hold. Never describe the figure as net.',\n ],\n },\n {\n id: 'get_business_summary',\n title: 'Business summary',\n description:\n 'How are we doing? Orders/revenue, subscription MRR, receivables and quotes pipeline over a date range, compared to the immediately preceding window of equal length. Note: period=week|month|quarter means the TRAILING 7/30/90 days, not a calendar period — pass from/to for calendar months.',\n kind: 'read',\n scopes: [],\n sectionScopes: ['orders:read', 'subscriptions:read', 'invoices:read', 'quotes:read'],\n input: [\n {\n name: 'period',\n type: 'string',\n required: false,\n description: 'Reporting window.',\n enum: ['week', 'month', 'quarter'],\n default: 'month',\n },\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range. Overrides period.' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range. Defaults to now.' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for period boundaries. Defaults to UTC.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/business-summary' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Each section needs its own scope (orders:read, subscriptions:read, invoices:read, quotes:read). A section without its scope is reported as omitted rather than failing the whole call.',\n ],\n },\n {\n id: 'get_top_products',\n title: 'Top products',\n description:\n \"Best-selling products over a date range, by revenue or units sold. Line items come from the merchant's own cart payload, so a product is identified by its external reference id when present and by name otherwise. The response carries both the top-N rows (by the chosen sort) and range-wide totals across every matching product, so you can compute what share of total revenue/units the top N represent.\",\n kind: 'read',\n scopes: ['orders:read'],\n input: [\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range, exclusive. Defaults to 30 days before \"to\".' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range, exclusive. Defaults to now.' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for range boundaries. Defaults to UTC.' },\n { name: 'by', type: 'string', required: false, description: 'Sort key.', enum: ['revenue', 'units'], default: 'revenue' },\n { name: 'limit', type: 'number', required: false, description: 'Max rows to return (1-100). Defaults to 20.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/products' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Revenue is GROSS. Refunds are not deducted, because that needs payment_refunds:read, which OAuth connections cannot hold. Never describe the figure as net.',\n ],\n },\n {\n id: 'get_attention_digest',\n title: 'Attention digest',\n description:\n 'What needs attention right now? Open disputes, subscriptions in dunning, overdue Net-N invoices, and webhooks with degraded delivery health — a point-in-time snapshot, not a time range.',\n kind: 'read',\n scopes: [],\n sectionScopes: ['payment_disputes:read', 'subscriptions:read', 'invoices:read', 'webhook_deliveries:read'],\n input: [\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/attention-digest' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Each section needs its own scope (payment_disputes:read, subscriptions:read, invoices:read, webhook_deliveries:read). A section without its scope is reported as omitted rather than failing the whole call.',\n ],\n },\n {\n id: 'get_customer_growth',\n title: 'Customer growth',\n description:\n 'Customer growth over a date range: signups per day/week/month, how many orders came from first-time versus returning customers, and the highest-value customers in the window.',\n kind: 'read',\n scopes: ['customers:read'],\n input: [\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range, exclusive. Defaults to 30 days before \"to\".' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range, exclusive. Defaults to now.' },\n { name: 'groupBy', type: 'string', required: false, description: 'Signup series bucket size.', enum: ['day', 'week', 'month'], default: 'day' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for bucket boundaries. Defaults to UTC.' },\n { name: 'topBy', type: 'string', required: false, description: 'Sort key for top customers.', enum: ['revenue', 'orders'], default: 'revenue' },\n { name: 'topLimit', type: 'number', required: false, description: 'Max top-customers rows to return (1-50). Defaults to 10.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/customers' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Revenue is GROSS. Refunds are not deducted, because that needs payment_refunds:read, which OAuth connections cannot hold. Never describe the figure as net.',\n 'topCustomers is a top-N list; use the accompanying totals for range-wide customer/order/revenue counts instead of summing the returned rows.',\n 'topCustomers[].email and .name come back null unless the credential holds customer_pii:read, which OAuth connections cannot hold. Identify a top customer by id, not by a null name.',\n ],\n },\n {\n id: 'get_revenue_breakdown',\n title: 'Revenue breakdown',\n description:\n 'Revenue split by one dimension over a date range — payment method, order source, or currency. Amounts are gross; refunds are not deducted.',\n kind: 'read',\n scopes: ['orders:read'],\n input: [\n {\n name: 'dimension',\n type: 'string',\n required: true,\n description: 'Breakdown dimension.',\n enum: ['paymentMethod', 'source', 'currency'],\n },\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range, exclusive. Defaults to 30 days before \"to\".' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range, exclusive. Defaults to now.' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for range boundaries. Defaults to UTC.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/revenue-breakdown' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Revenue is GROSS. Refunds are not deducted, because that needs payment_refunds:read, which OAuth connections cannot hold. Never describe the figure as net.',\n 'dimension is required; it is never defaulted, so omitting it fails the call instead of silently picking a dimension.',\n 'For dimension=paymentMethod, an order paid via more than one method can appear in more than one row, so rows can sum to more than totals (a separate whole-range aggregate over orders alone).',\n ],\n },\n {\n id: 'get_funnel_conversion',\n title: 'Checkout funnel',\n description:\n 'Checkout funnel over a date range: carts created, checkout sessions started, orders completed, with the drop-off between each stage.',\n kind: 'read',\n scopes: ['carts:read'],\n input: [\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range, exclusive. Defaults to 30 days before \"to\".' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range, exclusive. Defaults to now.' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for range boundaries. Defaults to UTC.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/funnel' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'Each stage needs its own scope (carts:read, checkout_sessions:read, orders:read), checked independently — an OAuth grant carries literal scopes with no legacy expansion, so a credential can hold carts:read without the other two. An omitted stage is reported as such rather than failing the whole call.',\n 'conversionRate and dropOff[].ratePct are null (unknown) when a stage they depend on is omitted, and 0 only when the stage was readable with a true zero count. Never treat a null here as 0.',\n 'dropOff[].ratePct is the percentage of \"from\" that did NOT reach \"to\" (loss), not a conversion rate. The step-conversion rate is 100 - ratePct.',\n ],\n },\n {\n id: 'get_subscription_movement',\n title: 'Subscription movement',\n description:\n 'Subscription movement over a date range: new subscriptions, cancellations and net MRR change per day/week/month. Figures are reconstructed from subscription timestamps, not a stored historical snapshot.',\n kind: 'read',\n scopes: ['subscriptions:read'],\n input: [\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range, exclusive. Defaults to 30 days before \"to\".' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range, exclusive. Defaults to now.' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for bucket boundaries. Defaults to UTC.' },\n { name: 'groupBy', type: 'string', required: false, description: 'Bucket size.', enum: ['day', 'week', 'month'], default: 'day' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/subscriptions' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'newSubscriptions, churnedSubscriptions and mrrDeltaCents are reconstructed per bucket from subscription created_at/cancelled_at timestamps, not a stored historical MRR snapshot — never present this series as an audited historical MRR ledger.',\n 'mrrDeltaCents for a bucket only credits subscriptions created in that bucket that are still active right now, and only debits subscriptions cancelled in that bucket that already existed when it started. A subscription created AND cancelled inside the same bucket still counts toward both newSubscriptions and churnedSubscriptions but contributes 0 to mrrDeltaCents.',\n 'totals is the sum over the full series (the series is never truncated), so totals.newSubscriptions/.churnedSubscriptions/.netMrrDeltaCents always equal the corresponding sums of series[].',\n ],\n },\n {\n id: 'get_discount_performance',\n title: 'Discount performance',\n description:\n 'Discount code performance over a date range: redemption count, revenue on discounted orders, and total discount given per code.',\n kind: 'read',\n scopes: ['discounts:read'],\n input: [\n { name: 'from', type: 'string', required: false, description: 'ISO 8601 start of range, exclusive. Defaults to 30 days before \"to\".' },\n { name: 'to', type: 'string', required: false, description: 'ISO 8601 end of range, exclusive. Defaults to now.' },\n { name: 'timezone', type: 'string', required: false, description: 'IANA timezone for range boundaries. Defaults to UTC.' },\n { name: 'limit', type: 'number', required: false, description: 'Max rows to return. Defaults to 20.' },\n {\n name: 'applicationId',\n type: 'string',\n required: false,\n description: 'Application to read from. Defaults to the one this connection was authorized for. Call list_applications to see the others.',\n },\n ],\n requests: [{ method: 'GET', path: '/api/v1/analytics/discounts' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n guardrails: [\n 'discountedRevenueCents and discountGivenCents are DIFFERENT measures: discountedRevenueCents is the gross order total on orders that redeemed the code; discountGivenCents is the discount amount taken off those same orders. Never describe discountedRevenueCents as \"given away\" or discountGivenCents as revenue.',\n 'Only orders with status <> draft and a gross-eligible payment_status are counted; refunds are not deducted from discountedRevenueCents, because that needs payment_refunds:read.',\n 'rows are the top N codes by discount given; totals is a SEPARATE whole-range aggregate (not a reduction over rows), so totals.redemptions / totals.discountGivenCents stay valid even when rows is truncated by limit.',\n ],\n },\n\n // ------------------------------------------------------------ sandbox write\n {\n id: 'seed_test_data',\n title: 'Seed test data (non-production only)',\n description:\n 'Create a realistic customer, cart, line items and a finalized draft order so an integration has something to read. Refuses to run against production.',\n kind: 'write',\n scopes: ['customers:write', 'carts:write', 'cart_items:write'],\n input: [\n { name: 'customerEmail', type: 'string', required: false, description: 'Email for the seeded customer.' },\n { name: 'lineItems', type: 'array', required: false, description: 'Line items; a sensible default set is used when omitted.' },\n ],\n requests: [\n { method: 'POST', path: '/api/v1/customers' },\n { method: 'POST', path: '/api/v1/carts' },\n { method: 'POST', path: '/api/v1/carts/:id/items' },\n { method: 'POST', path: '/api/v1/carts/:id/finalize' },\n ],\n channels: ['mcp'],\n sandboxOnly: true,\n idempotent: true,\n guardrails: [\n 'Hard-refuse when the credential resolves to a production environment, regardless of any allow-writes flag.',\n 'Seeds a finalized DRAFT order — it does not capture a payment, which needs a browser-side tokenised payment method.',\n ],\n },\n\n // ---------------------------------------------------------- inbound writes\n // The no-code channels are mostly used in the \"something happened elsewhere,\n // put it into Throttle\" direction — a form submission, a new CRM contact, a\n // spreadsheet row. These three are that direction.\n {\n id: 'create_customer',\n title: 'Create a customer',\n description:\n 'Create a customer record. Use search_customers first if the buyer may already exist — this does not de-duplicate by email.',\n kind: 'write',\n scopes: ['customers:write'],\n input: [\n { name: 'email', type: 'string', required: true, description: \"The buyer's email address.\" },\n { name: 'firstName', type: 'string', required: false, description: 'Given name.' },\n { name: 'lastName', type: 'string', required: false, description: 'Family name.' },\n { name: 'phone', type: 'string', required: false, description: 'Contact phone number.' },\n { name: 'company', type: 'string', required: false, description: \"The buyer's company.\" },\n {\n name: 'externalId',\n type: 'string',\n required: false,\n description: \"This customer's id in your own system. Resolvable later via get_customer.\",\n },\n {\n name: 'netN',\n type: 'number',\n required: false,\n description:\n 'Invoice terms in days for this customer specifically, 0-365. Omit to use the workspace default; 0 means due on issue.',\n },\n {\n name: 'acceptsMarketing',\n type: 'boolean',\n required: false,\n description: 'Whether the buyer opted into marketing email.',\n default: false,\n },\n ],\n requests: [{ method: 'POST', path: '/api/v1/customers' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: [\n 'The created record is echoed back with email, phone, firstName, lastName and name nulled unless the credential holds customer_pii:read, which OAuth connections cannot hold — the customer is still created with the values sent, only the response is redacted.',\n ],\n },\n {\n id: 'update_customer',\n title: 'Update a customer',\n description:\n 'Change fields on an existing customer. Only the fields supplied are touched; everything else is left alone.',\n kind: 'write',\n scopes: ['customers:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Customer id.' },\n { name: 'email', type: 'string', required: false, description: \"The buyer's email address.\" },\n { name: 'firstName', type: 'string', required: false, description: 'Given name.' },\n { name: 'lastName', type: 'string', required: false, description: 'Family name.' },\n { name: 'phone', type: 'string', required: false, description: 'Contact phone number.' },\n { name: 'company', type: 'string', required: false, description: \"The buyer's company.\" },\n {\n name: 'externalId',\n type: 'string',\n required: false,\n description: \"This customer's id in your own system. Pass null to clear it.\",\n },\n {\n name: 'netN',\n type: 'number',\n required: false,\n description: 'Invoice terms in days for this customer specifically, 0-365.',\n },\n {\n name: 'acceptsMarketing',\n type: 'boolean',\n required: false,\n description: 'Whether the buyer opted into marketing email.',\n },\n ],\n requests: [{ method: 'PATCH', path: '/api/v1/customers/:id' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: [\n 'The updated record is echoed back with email, phone, firstName, lastName and name nulled unless the credential holds customer_pii:read, which OAuth connections cannot hold — the update still applied, only the response is redacted.',\n ],\n },\n {\n id: 'create_checkout_link',\n title: 'Create a checkout link',\n description:\n 'Build a cart from line items and return a hosted checkout URL the buyer can pay at. Prices are in minor units (2500 = $25.00).',\n kind: 'write',\n scopes: ['carts:write', 'cart_items:write', 'checkout_sessions:write'],\n input: [\n {\n name: 'lineItems',\n type: 'array',\n required: true,\n description:\n 'What the buyer is paying for: { name, unitPrice, quantity }. unitPrice is an integer in minor units.',\n },\n {\n name: 'returnUrl',\n type: 'string',\n required: true,\n description: 'Absolute URL the buyer lands on after paying.',\n },\n {\n name: 'cancelUrl',\n type: 'string',\n required: true,\n description: 'Absolute URL the buyer lands on if they abandon checkout.',\n },\n {\n name: 'customerId',\n type: 'string',\n required: false,\n description: 'Attach the cart to an existing customer.',\n },\n {\n name: 'customerEmail',\n type: 'string',\n required: false,\n description: 'Pre-fill the buyer email without needing a customer record.',\n },\n {\n name: 'discountCode',\n type: 'string',\n required: false,\n description: 'Discount code to apply to the session.',\n },\n {\n name: 'netN',\n type: 'number',\n required: false,\n description: 'Invoice terms in days for this cart, 0-365. Omit to pay in full at checkout.',\n },\n ],\n // Three calls: the API has no single \"checkout link\" endpoint, and a\n // checkout session requires a cart that already holds its line items.\n requests: [\n { method: 'POST', path: '/api/v1/carts' },\n { method: 'POST', path: '/api/v1/carts/:id/items' },\n { method: 'POST', path: '/api/v1/checkout/sessions' },\n ],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: [\n 'The returned URL is buyer-facing and takes real payment in a production environment.',\n ],\n },\n\n // -------------------------------------------------------------- money/mail\n {\n id: 'create_quote',\n title: 'Create a quote',\n description: 'Draft a quote for a customer with line items and terms. Does not send it — use send_quote.',\n kind: 'write',\n scopes: ['quotes:write'],\n input: [\n { name: 'customerId', type: 'string', required: true, description: 'Customer the quote is for.' },\n { name: 'items', type: 'array', required: true, description: 'Quote line items: { name, unitPrice, quantity }.' },\n { name: 'expiresAt', type: 'string', required: false, description: 'ISO 8601 expiry.' },\n { name: 'netN', type: 'number', required: false, description: 'Payment terms in days. Omit for pay-in-full.' },\n { name: 'notes', type: 'string', required: false, description: 'Buyer-visible notes.' },\n ],\n requests: [{ method: 'POST', path: '/api/v1/quotes' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n },\n {\n id: 'send_quote',\n title: 'Issue and send a quote',\n description:\n 'Issue a draft quote and email the buyer their quote link. This is buyer-visible — confirm with the user before calling it.',\n kind: 'write',\n scopes: ['quotes:write'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Quote id.' }],\n requests: [{ method: 'POST', path: '/api/v1/quotes/:id/issue' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: ['Sends mail to a real buyer. Never call it speculatively or to \"check\" a quote.'],\n destructive: true,\n },\n {\n id: 'refund_payment',\n title: 'Refund a payment',\n description:\n 'Refund a captured payment. The amount is required — never infer a full refund from an unspecified amount.',\n kind: 'write',\n scopes: ['payment_refunds:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Payment id.' },\n {\n name: 'amount',\n type: 'number',\n required: true,\n description: 'Amount to refund in minor units. Required — omitting it would refund the whole payment.',\n },\n { name: 'reason', type: 'string', required: false, description: 'Reason recorded on the refund.' },\n ],\n requests: [{ method: 'POST', path: '/api/v1/payments/:id/refund' }],\n // NOT zapier/make. `payment_refunds:write` is `sensitive` in the scope\n // registry, and `validateScopesForOAuth` rejects every sensitive scope — so\n // an OAuth grant, which is the only credential a public Zapier or Make app\n // can hold, can never carry it. Listing the action on those channels would\n // ship a connector action that 403s on every call. MCP and n8n keep it:\n // both authenticate with an `sk_` key, which CAN hold the scope.\n // `oauth-grantable-scopes` in the catalog tests enforces this.\n channels: ['mcp', 'n8n'],\n idempotent: true,\n guardrails: [\n 'Moves money and is irreversible. Confirm with the user first.',\n 'The API treats an omitted amount as a FULL refund, so this action requires it explicitly.',\n ],\n destructive: true,\n },\n {\n id: 'manage_subscription',\n title: 'Pause or resume a subscription',\n description: 'Pause or resume an active subscription.',\n kind: 'write',\n scopes: ['subscription_pauses:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Subscription id.' },\n {\n name: 'action',\n type: 'string',\n required: true,\n description: 'What to do.',\n enum: ['pause', 'resume'],\n },\n ],\n requests: [\n { method: 'POST', path: '/api/v1/subscriptions/:id/pause' },\n { method: 'POST', path: '/api/v1/subscriptions/:id/resume' },\n ],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n },\n {\n id: 'cancel_subscription',\n title: 'Cancel a subscription',\n description: 'Cancel a subscription. Separate from pause/resume because it needs its own scope.',\n kind: 'write',\n scopes: ['subscription_cancellations:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Subscription id.' },\n {\n name: 'atPeriodEnd',\n type: 'boolean',\n required: false,\n description: 'Cancel at the end of the current period instead of immediately.',\n },\n ],\n requests: [{ method: 'POST', path: '/api/v1/subscriptions/:id/cancel' }],\n channels: ['mcp', 'zapier', 'make', 'n8n'],\n idempotent: true,\n guardrails: ['Ends billing for a paying customer. Confirm with the user first.'],\n destructive: true,\n },\n {\n id: 'replay_webhook_delivery',\n title: 'Replay a webhook delivery',\n description: 'Re-send a past webhook delivery to its endpoint — useful after fixing a broken handler.',\n kind: 'write',\n scopes: ['webhook_deliveries:write'],\n input: [{ name: 'id', type: 'string', required: true, description: 'Delivery id.' }],\n requests: [{ method: 'POST', path: '/api/v1/webhook-deliveries/:id/replay' }],\n channels: ['mcp', 'n8n'],\n idempotent: true,\n guardrails: ['The receiving system will process the event again. Confirm it is idempotent first.'],\n destructive: true,\n },\n {\n id: 'send_test_webhook',\n title: 'Send a test webhook',\n description: 'Send a synthetic signed event to a webhook endpoint to verify signature handling and reachability.',\n kind: 'write',\n scopes: ['webhooks:write'],\n input: [\n { name: 'id', type: 'string', required: true, description: 'Endpoint id.' },\n { name: 'eventType', type: 'string', required: false, description: 'Event type to simulate.' },\n ],\n requests: [{ method: 'POST', path: '/api/v1/webhook-endpoints/:id/test' }],\n channels: ['mcp', 'n8n'],\n idempotent: true,\n destructive: true,\n },\n];\n","import { eventReadScope } from '@core/scopes';\nimport type { TriggerDefinition } from './types';\n\n/**\n * Event-backed triggers for the no-code channels.\n *\n * Scopes are DERIVED via `eventReadScope` rather than written out, so a change to\n * the event→scope mapping in `@core/scopes` can never leave a trigger claiming a\n * scope the API would not accept at subscription time.\n *\n * MCP is absent from every `channels` list on purpose: the protocol has no\n * subscription primitive, so an agent polls `search_events` instead.\n */\nconst NO_CODE: readonly ('zapier' | 'make' | 'n8n')[] = ['zapier', 'make', 'n8n'];\n\nfunction trigger(\n id: string,\n title: string,\n eventType: string,\n description: string,\n): TriggerDefinition {\n return { id, title, eventType, description, scope: eventReadScope(eventType), channels: NO_CODE };\n}\n\nexport const TRIGGERS: readonly TriggerDefinition[] = [\n trigger('new_order', 'New order', 'order.created', 'Fires when an order is created.'),\n trigger(\n 'payment_captured',\n 'Payment captured',\n 'payment.captured',\n 'Fires when a payment is successfully captured.',\n ),\n trigger(\n 'payment_failed',\n 'Payment failed',\n 'payment.failed',\n 'Fires when a payment attempt fails.',\n ),\n trigger(\n 'new_subscription',\n 'New subscription',\n 'subscription.created',\n 'Fires when a subscription is created.',\n ),\n trigger(\n 'subscription_cancelled',\n 'Subscription cancelled',\n 'subscription.cancelled',\n 'Fires when a subscription is cancelled.',\n ),\n trigger(\n 'quote_accepted',\n 'Quote accepted',\n 'quote.accepted',\n 'Fires when a buyer accepts a quote.',\n ),\n trigger(\n 'cart_abandoned',\n 'Cart abandoned',\n 'cart.abandoned',\n 'Fires when a cart is marked abandoned.',\n ),\n trigger(\n 'invoice_past_due',\n 'Invoice past due',\n 'invoice.past_due',\n 'Fires when an invoice passes its due date unpaid.',\n ),\n];\n","import { hasScope } from '@core/scopes';\nimport { ACTIONS } from './actions';\nimport { TRIGGERS } from './triggers';\nimport type { ActionDefinition, Channel, TriggerDefinition } from './types';\n\nexport * from './types';\nexport { ACTIONS } from './actions';\nexport { TRIGGERS } from './triggers';\n\nexport function actionById(id: string): ActionDefinition | undefined {\n return ACTIONS.find((a) => a.id === id);\n}\n\nexport function actionsForChannel(channel: Channel): ActionDefinition[] {\n return ACTIONS.filter((a) => a.channels.includes(channel));\n}\n\nexport function triggersForChannel(channel: Channel): TriggerDefinition[] {\n return TRIGGERS.filter((t) => t.channels.includes(channel));\n}\n\n/**\n * Can this credential run this action?\n *\n * Delegates to `@core/scopes.hasScope`, so the `*` wildcard and the\n * `resource:write ⇒ resource:read` implication behave exactly as the API's own\n * enforcement does — a projection must never be more permissive than the server,\n * and must not be needlessly stricter either.\n */\nexport function canRunAction(granted: readonly string[], action: ActionDefinition): boolean {\n return action.scopes.every((required) => hasScope(granted as string[], required));\n}\n\n/**\n * The actions a channel should expose for a given credential.\n *\n * `includeWrites` is the projection's intent gate (the MCP server's\n * `--allow-writes`): holding a write scope means the credential *may* write,\n * which is not the same as the operator intending it to.\n */\nexport function availableActions(\n channel: Channel,\n granted: readonly string[],\n options: { includeWrites?: boolean } = {},\n): ActionDefinition[] {\n const includeWrites = options.includeWrites ?? false;\n return actionsForChannel(channel).filter((action) => {\n if (action.kind === 'write' && !includeWrites) return false;\n return canRunAction(granted, action);\n });\n}\n","/** Result shaping. Compact JSON: agents read it fine and it costs far fewer tokens. */\n\nconst MAX_CHARS = 24_000;\n\n/** Drops undefined and null so a wide API row does not spend tokens on empty fields. */\nfunction prune(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(prune);\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [key, inner] of Object.entries(value as Record<string, unknown>)) {\n if (inner === undefined || inner === null) continue;\n out[key] = prune(inner);\n }\n return out;\n }\n return value;\n}\n\nexport function formatResult(value: unknown): string {\n const text = JSON.stringify(prune(value), null, 2) ?? 'null';\n if (text.length <= MAX_CHARS) return text;\n return `${text.slice(0, MAX_CHARS)}\\n\\n… truncated at ${MAX_CHARS} characters. Narrow the query (lower \"limit\", add a filter) or fetch a single record.`;\n}\n\n/**\n * Errors come back as tool text rather than transport failures: an agent can act\n * on \"missing scope orders:read\" but not on a dead connection. API error codes are\n * surfaced verbatim so the model does not paper over an auth problem by retrying.\n */\nexport function formatError(error: unknown): string {\n const e = error as { code?: string; message?: string; statusCode?: number; details?: unknown };\n if (e?.code && e?.message) {\n const detail = e.details ? `\\n\\ndetails: ${JSON.stringify(e.details)}` : '';\n return `Throttle API error ${e.code}${e.statusCode ? ` (HTTP ${e.statusCode})` : ''}: ${e.message}${detail}`;\n }\n return `Error: ${e?.message ?? String(error)}`;\n}\n","// src/index.ts\nvar ThrottleError = class extends Error {\n code;\n statusCode;\n details;\n body;\n requestId;\n constructor(args) {\n super(args.message);\n this.name = \"ThrottleError\";\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n this.body = args.body;\n const fromBody = args.body?.meta?.requestId;\n const fromHeader = typeof args.responseHeaders?.get === \"function\" ? args.responseHeaders.get(\"x-request-id\") : args.responseHeaders?.[\"x-request-id\"];\n this.requestId = args.requestId ?? (typeof fromBody === \"string\" ? fromBody : void 0) ?? (typeof fromHeader === \"string\" ? fromHeader : void 0);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n};\nfunction isThrottleError(value) {\n return value instanceof ThrottleError;\n}\nexport {\n ThrottleError,\n isThrottleError\n};\n","import { ThrottleError, type ThrottleErrorArgs } from '@usethrottle/errors';\n\nexport interface AuthCtx {\n apiKey: string;\n apiBaseUrl: string;\n}\n\nexport class ThrottleApiError extends ThrottleError {\n constructor(\n code: string,\n message: string,\n statusCode: number,\n details?: unknown,\n responseHeaders?: ThrottleErrorArgs['responseHeaders'],\n ) {\n super({ code, message, statusCode, details, responseHeaders });\n this.name = 'ThrottleApiError';\n }\n}\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\n\nexport interface RequestOptions {\n body?: unknown;\n query?: Record<string, unknown>;\n /**\n * Sent as `Idempotency-Key`. Writes must pass one: an agent that retries is the\n * normal case, and the API dedupes on\n * `(workspace, application, environment, key, method, path)`.\n */\n idempotencyKey?: string;\n /**\n * Sent as `X-Throttle-Application-Id` on this one request only — see\n * `PerCallOptions`.\n */\n applicationId?: string;\n}\n\nexport interface PerCallOptions {\n /**\n * Overrides which application a single `get`/`list` call reads from (the\n * `oauth_token` auth branch validates this against the grant's own\n * workspace membership; see `resolveOAuthApplication`). Scoped to this one\n * request — never stored on the client instance — so concurrent calls with\n * different application ids cannot bleed into each other.\n */\n applicationId?: string;\n}\n\nexport interface Pagination {\n cursor: string | null;\n hasMore: boolean;\n}\n\nexport interface ListResult<T> {\n data: T[];\n pagination: Pagination | null;\n}\n\n/** Drops undefined/null/empty params so callers can spread optional args freely. */\nexport function buildQuery(query: Record<string, unknown> | undefined): string {\n if (!query) return '';\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null || value === '') continue;\n params.set(key, String(value));\n }\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n}\n\nexport type Fetcher = typeof fetch;\n\n// Matches the auth middleware's own definition of an API-key-shaped bearer\n// token (`packages/core-auth/src/middleware.ts`: `/^(sk_|pk_)/`). The server\n// 400s `header_scope_conflict` on ANY request carrying both a literal\n// `X-API-Key` header and `X-Throttle-Application-Id` — and `requestJson`\n// below always sends `x-api-key` on every call, for both credential shapes.\n// The `X-Throttle-Application-Id` override only makes sense for an OAuth\n// access token in the first place (an sk_/pk_ key is already pinned to one\n// application; there is no sibling to switch to), so silently dropping it\n// here for an sk_/pk_ credential matches both the server's own invariant and\n// the feature's actual semantics — it never turns a real API-key call into a\n// hard 400 just because a caller passed `applicationId`.\nconst API_KEY_PREFIX_RE = /^(sk_|pk_)/;\n\nexport class ThrottleClient {\n constructor(\n private auth: AuthCtx,\n private readonly fetchImpl: Fetcher = fetch,\n ) {}\n\n /**\n * Swap the credential every later request is sent with. The hosted remote\n * server builds one client per MCP session at `initialize`, but an OAuth\n * access token lives one hour and the MCP client refreshes it underneath\n * the session — each request then arrives with a newer bearer than the one\n * the session was opened with. Without this, the session keeps calling the\n * REST API with the token it was born with and every tool fails with a 401\n * the moment that first token expires, even though the caller is still\n * perfectly authenticated.\n */\n setApiKey(apiKey: string): void {\n this.auth = { ...this.auth, apiKey };\n }\n\n private async requestJson(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<Record<string, unknown>> {\n const url = `${this.auth.apiBaseUrl.replace(/\\/$/, '')}${path}${buildQuery(options.query)}`;\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n 'x-api-key': this.auth.apiKey,\n // Also sent as Authorization: Bearer — required for an OAuth access\n // token (the remote server's oauth_token sessions), which the auth\n // middleware only ever recognizes via this header (peeked by issuer),\n // never via x-api-key. For an sk_/pk_ key this is a no-op: the\n // middleware already treats `Authorization: Bearer sk_.../pk_...`\n // identically to `X-API-Key`, so existing stdio-CLI callers are\n // unaffected.\n Authorization: `Bearer ${this.auth.apiKey}`,\n };\n if (options.idempotencyKey) headers['idempotency-key'] = options.idempotencyKey;\n if (options.applicationId && !API_KEY_PREFIX_RE.test(this.auth.apiKey)) {\n headers['x-throttle-application-id'] = options.applicationId;\n }\n\n // A bodyless POST/PATCH/PUT advertising JSON would send an empty body that the\n // API's object-body schemas reject with `validation_error: body must be\n // object`, so default to `{}` (mirrors the CLI client).\n const sendsBody = method === 'POST' || method === 'PATCH' || method === 'PUT';\n const body =\n options.body !== undefined\n ? JSON.stringify(options.body)\n : sendsBody\n ? '{}'\n : undefined;\n\n const res = await this.fetchImpl(url, { method, headers, body });\n const text = await res.text();\n let parsed: Record<string, unknown> = {};\n try {\n parsed = text ? (JSON.parse(text) as Record<string, unknown>) : {};\n } catch {\n /* non-JSON body */\n }\n if (!res.ok) {\n const err = parsed.error as\n | { code?: string; message?: string; details?: unknown }\n | undefined;\n throw new ThrottleApiError(\n err?.code ?? `http_${res.status}`,\n err?.message ?? `Request failed (${res.status}): ${text.slice(0, 200)}`,\n res.status,\n err?.details,\n res.headers,\n );\n }\n return parsed;\n }\n\n /** Unwraps the `{ data }` envelope. Key presence, not `??` — `{data: null}` unwraps to null. */\n async get<T>(path: string, query?: Record<string, unknown>, options?: PerCallOptions): Promise<T> {\n const body = await this.requestJson('GET', path, { query, applicationId: options?.applicationId });\n return (body && typeof body === 'object' && 'data' in body ? body.data : body) as T;\n }\n\n async list<T>(\n path: string,\n query?: Record<string, unknown>,\n options?: PerCallOptions,\n ): Promise<ListResult<T>> {\n const body = await this.requestJson('GET', path, { query, applicationId: options?.applicationId });\n const data = ('data' in body ? body.data : body) as T[];\n const meta = body.meta as { pagination?: Pagination } | undefined;\n return { data: Array.isArray(data) ? data : [], pagination: meta?.pagination ?? null };\n }\n\n async post<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const body = await this.requestJson('POST', path, options);\n return (body && typeof body === 'object' && 'data' in body ? body.data : body) as T;\n }\n\n async patch<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const body = await this.requestJson('PATCH', path, options);\n return (body && typeof body === 'object' && 'data' in body ? body.data : body) as T;\n }\n}\n\n/**\n * Runs a sub-read that the credential may not be scoped for.\n *\n * Composite tools (`get_order`, `explain_checkout_failure`,\n * `get_integration_status`) must not fail wholesale because one section is\n * unscoped or absent — an agent that gets a hard error learns nothing, whereas a\n * result that says which section was unavailable can still answer the question.\n */\nexport async function optional<T>(\n load: () => Promise<T>,\n): Promise<{ ok: true; value: T } | { ok: false; unavailable: string }> {\n try {\n return { ok: true, value: await load() };\n } catch (error) {\n const e = error as ThrottleApiError;\n const code = e?.code ?? 'error';\n const reason =\n code === 'insufficient_scopes'\n ? 'not readable with this credential (missing scope)'\n : code === 'not_found'\n ? 'not found'\n : `unavailable (${code})`;\n return { ok: false, unavailable: reason };\n }\n}\n","/**\n * `describe_endpoint` and `validate_payload`, answered from the OpenAPI contract\n * bundled at build time. No network, no API quota.\n *\n * Why this exists: Throttle's public API is strict camelCase and rejects the\n * retired snake_case aliases — and those aliases are exactly what a model writing\n * commerce code will guess, because that is what the rest of the internet's\n * examples look like. Naming the replacement turns a 400-debug loop into one call.\n */\n\nexport interface ContractField {\n name: string;\n type?: string;\n required: boolean;\n description?: string;\n enum?: string[];\n}\n\nexport interface ContractOperation {\n method: string;\n /** OpenAPI-style path, e.g. `/api/v1/customers/{customerId}/addresses/{id}`. */\n path: string;\n summary?: string;\n description?: string;\n pathParams: string[];\n queryParams: ContractField[];\n bodyFields: ContractField[] | null;\n}\n\nexport interface ContractIndex {\n generatedAt: string;\n operations: ContractOperation[];\n}\n\n/**\n * Retired public field names → canonical replacement.\n *\n * Only names the API actively rejects. Anything not listed still gets the generic\n * snake_case → camelCase suggestion below.\n */\nexport const RETIRED_FIELDS: Record<string, string> = {\n storeId: 'applicationId',\n store_id: 'applicationId',\n merchantId: 'workspaceId',\n merchant_id: 'workspaceId',\n customer_id: 'customerId',\n line_items: 'lineItems',\n unit_price: 'unitPrice',\n external_id: 'externalId',\n payment_method_id: 'paymentMethodId',\n first_name: 'firstName',\n last_name: 'lastName',\n net_n: 'netN',\n hosted_url: 'hostedUrl',\n embed_url: 'embedUrl',\n checkout_url: 'checkoutUrl',\n order_number: 'orderNumber',\n payment_status: 'paymentStatus',\n allowed_origins: 'allowedOrigins',\n enabled_events: 'enabledEvents',\n template_key: 'templateKey',\n request_id: 'requestId',\n signing_secret: 'signingSecret (returned once at creation; not accepted as input)',\n};\n\nexport function snakeToCamel(name: string): string {\n return name.replace(/_([a-z0-9])/g, (_, c: string) => c.toUpperCase());\n}\n\n/** Collapses parameter names so `/orders/{id}` and `/orders/:id` compare equal. */\nexport function normalizePath(path: string): string {\n return path\n .replace(/\\{[^}]+\\}/g, '{}')\n .replace(/:[A-Za-z0-9_]+/g, '{}')\n .replace(/\\/$/, '');\n}\n\nfunction segmentsOf(path: string): string[] {\n return path.split('?')[0].replace(/\\/$/, '').split('/').filter(Boolean);\n}\n\nfunction isParamSegment(segment: string): boolean {\n return /^\\{[^}]+\\}$/.test(segment) || /^:[A-Za-z0-9_]+$/.test(segment);\n}\n\n/**\n * Matches a caller-supplied path against a contract template.\n *\n * Callers pass CONCRETE paths — `/api/v1/carts/9f3a…/items`, straight out of the\n * conversation — so a template segment must be allowed to absorb a real id, not\n * just another placeholder. Comparing normalized strings alone silently failed on\n * every real path and sent the agent to \"no operation matched\".\n */\nexport function pathMatches(template: string, candidate: string): boolean {\n const t = segmentsOf(template);\n const c = segmentsOf(candidate);\n if (t.length !== c.length) return false;\n return t.every((segment, i) => isParamSegment(segment) || isParamSegment(c[i]) || segment === c[i]);\n}\n\n/** Fewer placeholders = a more specific template, so it wins when several match. */\nfunction paramCount(path: string): number {\n return segmentsOf(path).filter(isParamSegment).length;\n}\n\nexport function findOperations(\n index: ContractIndex,\n query: { path: string; method?: string },\n): ContractOperation[] {\n const method = query.method?.toUpperCase();\n const wanted = query.path.trim();\n const byMethod = (op: ContractOperation) => !method || op.method === method;\n\n const matched = index.operations\n .filter((op) => byMethod(op) && pathMatches(op.path, wanted))\n .sort((a, b) => paramCount(a.path) - paramCount(b.path));\n if (matched.length > 0) return matched;\n\n // Fragment search: \"carts\" or \"/carts/items\" should still find something.\n const needle = normalizePath(wanted).replace(/^\\/+/, '');\n return index.operations.filter((op) => byMethod(op) && normalizePath(op.path).includes(needle));\n}\n\nexport interface ValidationProblem {\n field: string;\n problem: string;\n suggestion?: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n matched: string | null;\n errors: ValidationProblem[];\n warnings: ValidationProblem[];\n note?: string;\n}\n\nexport function validatePayload(\n index: ContractIndex,\n input: { method: string; path: string; body: Record<string, unknown> },\n): ValidationResult {\n const errors: ValidationProblem[] = [];\n const warnings: ValidationProblem[] = [];\n const keys = Object.keys(input.body ?? {});\n\n // The retired-alias and snake_case checks do not need a schema, so they run\n // even for operations the snapshot documents without a request body.\n for (const key of keys) {\n const retired = RETIRED_FIELDS[key];\n if (retired) {\n errors.push({\n field: key,\n problem: 'retired public field name — the API rejects it',\n suggestion: `use \"${retired}\"`,\n });\n continue;\n }\n if (key.includes('_')) {\n errors.push({\n field: key,\n problem: 'snake_case is not accepted on public request bodies',\n suggestion: `use \"${snakeToCamel(key)}\"`,\n });\n }\n }\n\n const matches = findOperations(index, { path: input.path, method: input.method });\n const operation = matches[0];\n if (!operation) {\n return {\n ok: false,\n matched: null,\n errors: [\n ...errors,\n {\n field: input.path,\n problem: `no ${input.method.toUpperCase()} operation matches this path in the published contract`,\n suggestion: 'call describe_endpoint to find the right path',\n },\n ],\n warnings,\n };\n }\n\n if (!operation.bodyFields) {\n return {\n ok: errors.length === 0,\n matched: `${operation.method} ${operation.path}`,\n errors,\n warnings,\n note: 'The contract publishes no request-body schema for this operation, so field-level checks beyond naming could not run.',\n };\n }\n\n const known = new Map(operation.bodyFields.map((f) => [f.name, f]));\n for (const key of keys) {\n if (RETIRED_FIELDS[key] || key.includes('_')) continue; // already reported\n if (!known.has(key)) {\n warnings.push({\n field: key,\n problem: 'not documented on this operation — it will be rejected if the route validates strictly',\n });\n }\n }\n for (const field of operation.bodyFields) {\n const value = (input.body ?? {})[field.name];\n if (value === undefined) {\n if (field.required) errors.push({ field: field.name, problem: 'required field is missing' });\n continue;\n }\n // Closed sets are checked whenever a value is present — an optional field with\n // a bad enum value is still a 400, so skipping optionals hid real errors.\n if (field.enum && field.enum.length > 0 && typeof value === 'string' && !field.enum.includes(value)) {\n errors.push({\n field: field.name,\n problem: `value \"${value}\" is not allowed`,\n suggestion: `one of: ${field.enum.join(', ')}`,\n });\n }\n }\n\n return {\n ok: errors.length === 0,\n matched: `${operation.method} ${operation.path}`,\n errors,\n warnings,\n };\n}\n","/**\n * `search_docs`, answered from an index of the docs pages in `apps/web`,\n * bundled at build time.\n *\n * Scoring mirrors the CLI's proven approach: title hits beat heading hits, which\n * beat body hits, and an exact phrase beats scattered terms. Deliberately simple —\n * the agent gets a title, a canonical docs.usethrottle.dev URL and an excerpt, then\n * fetches the page itself if its client can.\n */\n\nexport interface DocsEntry {\n title: string;\n route: string;\n headings: string[];\n text: string;\n}\n\nexport interface DocsIndex {\n generatedAt: string;\n entries: DocsEntry[];\n}\n\nexport interface DocsHit {\n title: string;\n url: string;\n score: number;\n excerpt: string;\n}\n\nconst DOCS_ORIGIN = 'https://usethrottle.dev/docs';\n\nfunction excerptAround(text: string, needle: string, radius = 160): string {\n const at = text.toLowerCase().indexOf(needle.toLowerCase());\n if (at < 0) return text.slice(0, radius * 2).trim();\n const start = Math.max(0, at - radius);\n const end = Math.min(text.length, at + needle.length + radius);\n return `${start > 0 ? '…' : ''}${text.slice(start, end).trim()}${end < text.length ? '…' : ''}`;\n}\n\nexport function searchDocs(\n index: DocsIndex,\n query: string,\n limit = 5,\n): DocsHit[] {\n const phrase = query.trim().toLowerCase();\n if (!phrase) return [];\n const terms = phrase.split(/\\s+/).filter((t) => t.length > 1);\n\n const scored = index.entries.map((entry) => {\n const title = entry.title.toLowerCase();\n const headings = entry.headings.join(' \u0000 ').toLowerCase();\n const body = entry.text.toLowerCase();\n\n let score = 0;\n if (title === phrase) score += 100;\n else if (title.startsWith(phrase)) score += 60;\n else if (title.includes(phrase)) score += 40;\n if (headings.includes(phrase)) score += 25;\n if (body.includes(phrase)) score += 15;\n\n for (const term of terms) {\n if (title.includes(term)) score += 8;\n if (headings.includes(term)) score += 4;\n if (body.includes(term)) score += 1;\n }\n\n return { entry, score };\n });\n\n return scored\n .filter((s) => s.score > 0)\n .sort((a, b) => b.score - a.score || a.entry.route.localeCompare(b.entry.route))\n .slice(0, Math.max(1, limit))\n .map(({ entry, score }) => ({\n title: entry.title,\n url: `${DOCS_ORIGIN}${entry.route}`,\n score,\n excerpt: excerptAround(entry.text, phrase),\n }));\n}\n","import { ACTIONS } from '@core/action-catalog';\nimport { optional, type ThrottleClient } from './client';\nimport {\n findOperations,\n normalizePath,\n validatePayload,\n type ContractIndex,\n type ContractOperation,\n} from './contract';\nimport { searchDocs, type DocsIndex } from './docs';\n\n/**\n * The OpenAPI snapshot does not carry each route's required scope, but the action\n * catalog does for the verbs it covers. Surfacing it here means `describe_endpoint`\n * can answer \"and what permission do I need?\" instead of leaving the agent to guess.\n */\nfunction coveringAction(\n operation: ContractOperation,\n): { tool?: string; requiredScopes?: readonly string[] } {\n const target = normalizePath(operation.path);\n for (const action of ACTIONS) {\n const hit = action.requests.some(\n (r) => r.method === operation.method && normalizePath(r.path) === target,\n );\n if (hit) return { tool: action.id, requiredScopes: action.scopes };\n }\n return {};\n}\n\nexport interface Identity {\n type: string;\n scopes: string[];\n workspace: { id: string; name: string | null; slug: string | null } | null;\n application: { id: string; name: string | null; slug: string | null } | null;\n environment: {\n id: string;\n slug: string;\n kind: string;\n providerEnvironment: 'sandbox' | 'production';\n };\n apiKey: { id: string; name: string; keyPrefix: string } | null;\n}\n\nexport interface HandlerContext {\n client: ThrottleClient;\n identity: Identity;\n contract: ContractIndex;\n docs: DocsIndex;\n}\n\nexport type Handler = (ctx: HandlerContext, args: Record<string, any>) => Promise<unknown>;\n\nconst page = (args: Record<string, any>) => ({ limit: args.limit, cursor: args.cursor });\n\n/**\n * Handlers for the 0.1.0 surface: reads, docs/contract lookups, and sandbox\n * seeding. Money-moving writes arrive in 0.2.0 with the idempotency layer — the\n * server only registers actions that have a handler here, so the catalog can\n * describe them before this file implements them.\n */\nexport const HANDLERS: Record<string, Handler> = {\n // ---------------------------------------------------------------- identity\n whoami: async (ctx) => ({\n ...ctx.identity,\n note:\n ctx.identity.environment.providerEnvironment === 'production'\n ? 'This credential is pinned to PRODUCTION. Reads return live data.'\n : 'This credential is pinned to a non-production environment. Nothing here is live data.',\n }),\n\n // ------------------------------------------------------- docs and contract\n search_docs: async (ctx, args) => {\n const hits = searchDocs(ctx.docs, String(args.query ?? ''), Number(args.limit ?? 5));\n return hits.length > 0\n ? { hits }\n : { hits: [], note: 'No documentation matched. Try fewer or more general terms.' };\n },\n\n describe_endpoint: async (ctx, args) => {\n const operations = findOperations(ctx.contract, {\n path: String(args.path ?? ''),\n method: args.method ? String(args.method) : undefined,\n });\n if (operations.length === 0) {\n return {\n operations: [],\n note: 'No operation matched. Paths look like /api/v1/orders; try a shorter fragment such as \"orders\".',\n };\n }\n return {\n operations: operations.slice(0, 8).map((op) => ({ ...op, ...coveringAction(op) })),\n truncated: operations.length > 8 ? operations.length - 8 : undefined,\n };\n },\n\n validate_payload: async (ctx, args) =>\n validatePayload(ctx.contract, {\n method: String(args.method ?? 'POST'),\n path: String(args.path ?? ''),\n body: (args.body ?? {}) as Record<string, unknown>,\n }),\n\n // ------------------------------------------------------------- generic read\n api_get: async (ctx, args) => {\n const path = String(args.path ?? '');\n // The prefix check alone is not enough: fetch resolves `.`/`..` segments\n // (including percent-encoded ones, and `\\` as `/`) before sending, so the\n // resolved path is what has to stay under /api/v1/.\n const resolved = new URL(path, 'https://throttle.invalid').pathname;\n if (!path.startsWith('/api/v1/') || !resolved.startsWith('/api/v1/') || /(^|[\\/\\\\])\\.(\\.)?([\\/\\\\?#]|$)|%2e/i.test(path)) {\n throw new Error(\n `Refusing to call \"${path}\". api_get only reads paths beginning with /api/v1/ on the configured Throttle host.`,\n );\n }\n return ctx.client.get(path, undefined, { applicationId: args.applicationId });\n },\n\n // ------------------------------------------------------------------ orders\n search_orders: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/orders',\n {\n q: args.q,\n status: args.status,\n paymentStatus: args.paymentStatus,\n createdAfter: args.createdAfter,\n createdBefore: args.createdBefore,\n ...page(args),\n },\n { applicationId: args.applicationId },\n ),\n\n get_order: async (ctx, args) => {\n const id = String(args.id);\n const opts = { applicationId: args.applicationId };\n const order = await ctx.client.get(`/api/v1/orders/${id}`, undefined, opts);\n const [payments, returns, fulfillments] = await Promise.all([\n optional(() => ctx.client.list(`/api/v1/orders/${id}/payments`, undefined, opts)),\n optional(() => ctx.client.list(`/api/v1/orders/${id}/returns`, undefined, opts)),\n optional(() => ctx.client.list(`/api/v1/orders/${id}/fulfillments`, undefined, opts)),\n ]);\n return {\n order,\n payments: payments.ok ? payments.value.data : payments.unavailable,\n returns: returns.ok ? returns.value.data : returns.unavailable,\n fulfillments: fulfillments.ok ? fulfillments.value.data : fulfillments.unavailable,\n };\n },\n\n // --------------------------------------------------------------- customers\n search_customers: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/customers',\n {\n q: args.q,\n createdAfter: args.createdAfter,\n createdBefore: args.createdBefore,\n ...page(args),\n },\n { applicationId: args.applicationId },\n ),\n\n get_customer: async (ctx, args) => {\n const id = String(args.id);\n const opts = { applicationId: args.applicationId };\n const customer = await ctx.client.get(`/api/v1/customers/${id}`, undefined, opts);\n const [addresses, subscriptions] = await Promise.all([\n optional(() => ctx.client.list(`/api/v1/customers/${id}/addresses`, undefined, opts)),\n optional(() => ctx.client.list('/api/v1/subscriptions', { customerId: id }, opts)),\n ]);\n return {\n customer,\n addresses: addresses.ok ? addresses.value.data : addresses.unavailable,\n subscriptions: subscriptions.ok ? subscriptions.value.data : subscriptions.unavailable,\n };\n },\n\n // ----------------------------------------------------------- subscriptions\n list_subscriptions: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/subscriptions',\n {\n customerId: args.customerId,\n status: args.status,\n createdAfter: args.createdAfter,\n createdBefore: args.createdBefore,\n ...page(args),\n },\n { applicationId: args.applicationId },\n ),\n\n get_subscription: async (ctx, args) =>\n ctx.client.get(`/api/v1/subscriptions/${String(args.id)}`, undefined, {\n applicationId: args.applicationId,\n }),\n\n // ------------------------------------------------------------------ quotes\n search_quotes: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/quotes',\n {\n status: args.status,\n createdAfter: args.createdAfter,\n createdBefore: args.createdBefore,\n ...page(args),\n },\n { applicationId: args.applicationId },\n ),\n\n get_quote: async (ctx, args) =>\n ctx.client.get(`/api/v1/quotes/${String(args.id)}`, undefined, {\n applicationId: args.applicationId,\n }),\n\n // ---------------------------------------------------------------- invoices\n list_invoices: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/invoices',\n { status: args.status, ...page(args) },\n { applicationId: args.applicationId },\n ),\n\n receivables_aging: async (ctx, args) =>\n ctx.client.get('/api/v1/invoices/aging', undefined, { applicationId: args.applicationId }),\n\n // --------------------------------------------------------------- discounts\n search_discounts: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/discounts',\n {\n q: args.q,\n code: args.code,\n type: args.type,\n isActive: args.isActive,\n createdAfter: args.createdAfter,\n createdBefore: args.createdBefore,\n ...page(args),\n },\n { applicationId: args.applicationId },\n ),\n\n get_discount: async (ctx, args) =>\n ctx.client.get(`/api/v1/discounts/${String(args.id)}`, undefined, {\n applicationId: args.applicationId,\n }),\n\n // ---------------------------------------------------------------- payments\n search_payments: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/payments',\n {\n method: args.method,\n status: args.status,\n // The route only accepts these as snake_case query params -- confirmed\n // by reading its querystring schema directly, not assumed from the\n // platform's usual camelCase convention.\n order_id: args.orderId,\n aging: args.aging,\n due_from: args.dueFrom,\n due_to: args.dueTo,\n amount_min: args.amountMin,\n amount_max: args.amountMax,\n ...page(args),\n },\n { applicationId: args.applicationId },\n ),\n\n get_payment: async (ctx, args) => {\n const id = String(args.id);\n const opts = { applicationId: args.applicationId };\n const payment = await ctx.client.get(`/api/v1/payments/${id}`, undefined, opts);\n const transactions = await optional(() =>\n ctx.client.list(`/api/v1/payments/${id}/transactions`, undefined, opts),\n );\n return {\n payment,\n transactions: transactions.ok ? transactions.value.data : transactions.unavailable,\n };\n },\n\n // ---------------------------------------------------------------- invoices\n get_invoice: async (ctx, args) =>\n ctx.client.get(`/api/v1/invoices/${String(args.id)}`, undefined, {\n applicationId: args.applicationId,\n }),\n\n // ------------------------------------------------------------------ carts\n list_abandoned_carts: async (ctx, args) => {\n const opts = { applicationId: args.applicationId };\n const [carts, summary] = await Promise.all([\n optional(() => ctx.client.list('/api/v1/abandoned-carts', { ...page(args) }, opts)),\n optional(() =>\n ctx.client.get('/api/v1/abandoned-carts/summary', { sinceDays: args.sinceDays }, opts),\n ),\n ]);\n return {\n carts: carts.ok ? carts.value.data : carts.unavailable,\n summary: summary.ok ? summary.value : summary.unavailable,\n };\n },\n\n // --------------------------------------------------------------- debugging\n search_events: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/events',\n {\n type: args.type,\n entityType: args.entityType,\n entityId: args.entityId,\n ...page(args),\n },\n { applicationId: args.applicationId },\n ),\n\n list_webhook_deliveries: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/webhook-deliveries',\n {\n endpointId: args.endpointId,\n status: args.status,\n eventType: args.eventType,\n limit: args.limit,\n },\n { applicationId: args.applicationId },\n ),\n\n get_webhook_delivery: async (ctx, args) =>\n ctx.client.get(`/api/v1/webhook-deliveries/${String(args.id)}`, undefined, {\n applicationId: args.applicationId,\n }),\n\n send_test_webhook: async (ctx, args) =>\n ctx.client.post(`/api/v1/webhook-endpoints/${String(args.id)}/test`, {\n body: { eventType: args.eventType },\n idempotencyKey: `mcp-send-test-webhook-${String(args.id)}-${Date.now()}`,\n }),\n\n replay_webhook_delivery: async (ctx, args) =>\n ctx.client.post(`/api/v1/webhook-deliveries/${String(args.id)}/replay`, {\n idempotencyKey: `mcp-replay-webhook-delivery-${String(args.id)}-${Date.now()}`,\n }),\n\n explain_checkout_failure: async (ctx, args) => {\n const id = String(args.id);\n const opts = { applicationId: args.applicationId };\n const session = await optional(() =>\n ctx.client.get<any>(`/api/v1/checkout-sessions/${id}`, undefined, opts),\n );\n if (!session.ok) {\n return {\n note: `No checkout session ${id} (${session.unavailable}). If this is a cart id, use search_events for its activity (or read /api/v1/carts/${id} with api_get, where that tool is available).`,\n };\n }\n const cartId = (session.value?.cartId as string | undefined) ?? undefined;\n const [cart, sessionEvents, cartEvents, deliveries] = await Promise.all([\n optional(() => ctx.client.get(`/api/v1/checkout-sessions/${id}/cart`, undefined, opts)),\n optional(() => ctx.client.list('/api/v1/events', { entityId: id, limit: 25 }, opts)),\n cartId\n ? optional(() => ctx.client.list('/api/v1/events', { entityId: cartId, limit: 25 }, opts))\n : Promise.resolve({ ok: true as const, value: { data: [], pagination: null } }),\n optional(() => ctx.client.list('/api/v1/webhook-deliveries', { limit: 15 }, opts)),\n ]);\n return {\n session: session.value,\n cart: cart.ok ? cart.value : cart.unavailable,\n events: [\n ...(sessionEvents.ok ? sessionEvents.value.data : []),\n ...(cartEvents.ok ? cartEvents.value.data : []),\n ],\n eventsUnavailable: sessionEvents.ok ? undefined : sessionEvents.unavailable,\n recentWebhookDeliveries: deliveries.ok ? deliveries.value.data : deliveries.unavailable,\n hint: 'Compare the session state against the events: a session that never emitted checkout_started usually means the browser SDK failed before submitting, not a payment decline.',\n };\n },\n\n // ------------------------------------------------------------ sandbox seed\n seed_test_data: async (ctx, args) => {\n // Belt and braces: the server also refuses to register this tool against a\n // production credential, but a guard at the call site means no future\n // registration change can turn it into a live-data generator.\n if (ctx.identity.environment.providerEnvironment === 'production') {\n throw new Error(\n 'seed_test_data refuses to run against a production environment. Use a non-production API key.',\n );\n }\n const stamp = Date.now();\n const customer = await ctx.client.post<any>('/api/v1/customers', {\n body: {\n email: String(args.customerEmail ?? `mcp-seed-${stamp}@example.test`),\n firstName: 'Seed',\n lastName: 'Customer',\n },\n idempotencyKey: `mcp-seed-customer-${stamp}`,\n });\n const cart = await ctx.client.post<any>('/api/v1/carts', {\n // Unlike /api/v1/customers, cart creation requires applicationId\n // explicitly in the body (it's cross-checked against the caller's own\n // authenticated application, not inferred) -- omitting it is a real\n // 400 missing_application_id from the live API, not a hypothetical.\n body: { applicationId: ctx.identity.application?.id, customerId: customer?.id },\n idempotencyKey: `mcp-seed-cart-${stamp}`,\n });\n const requested = Array.isArray(args.lineItems) && args.lineItems.length > 0\n ? (args.lineItems as Record<string, unknown>[])\n : [{ name: 'Seed widget', unitPrice: 2500, quantity: 2 }];\n const items: unknown[] = [];\n for (const [index, item] of requested.entries()) {\n items.push(\n await ctx.client.post(`/api/v1/carts/${cart?.id}/items`, {\n body: item,\n idempotencyKey: `mcp-seed-item-${stamp}-${index}`,\n }),\n );\n }\n const order = await ctx.client.post(`/api/v1/carts/${cart?.id}/finalize`, {\n idempotencyKey: `mcp-seed-finalize-${stamp}`,\n });\n return {\n environment: ctx.identity.environment.slug,\n customer,\n cart,\n lineItems: items,\n order,\n note: 'Seeded a finalized DRAFT order. No payment was captured — that needs a browser-tokenised payment method, which a server-side key cannot produce.',\n };\n },\n\n // ---------------------------------------------------------- inbound writes\n create_customer: async (ctx, args) =>\n ctx.client.post('/api/v1/customers', {\n // `createCustomerBody` is `.strict()`, so only fields it declares may be\n // sent; `undefined` values drop out at JSON.stringify.\n body: {\n email: args.email,\n firstName: args.firstName,\n lastName: args.lastName,\n phone: args.phone,\n company: args.company,\n externalId: args.externalId,\n netN: args.netN,\n acceptsMarketing: args.acceptsMarketing,\n },\n idempotencyKey: `mcp-create-customer-${String(args.email)}-${Date.now()}`,\n }),\n\n update_customer: async (ctx, args) =>\n ctx.client.patch(`/api/v1/customers/${String(args.id)}`, {\n // `id` is the path parameter, not a body field — `updateCustomerBody` is\n // `.strict()` and would reject it. A null `externalId` is meaningful\n // (it clears the value), so only `undefined` is dropped.\n body: {\n email: args.email,\n firstName: args.firstName,\n lastName: args.lastName,\n phone: args.phone,\n company: args.company,\n externalId: args.externalId,\n netN: args.netN,\n acceptsMarketing: args.acceptsMarketing,\n },\n idempotencyKey: `mcp-update-customer-${String(args.id)}-${Date.now()}`,\n }),\n\n create_checkout_link: async (ctx, args) => {\n const lineItems = Array.isArray(args.lineItems)\n ? (args.lineItems as Record<string, unknown>[])\n : [];\n if (lineItems.length === 0) {\n throw new Error('create_checkout_link: lineItems must contain at least one item.');\n }\n const stamp = Date.now();\n // Cart creation cross-checks applicationId against the caller's own\n // authenticated application rather than inferring it, so omitting it is a\n // real 400 missing_application_id — same as seed_test_data.\n const applicationId = ctx.identity.application?.id;\n const cart = await ctx.client.post<any>('/api/v1/carts', {\n body: {\n applicationId,\n customerId: args.customerId,\n customerEmail: args.customerEmail,\n netN: args.netN,\n },\n idempotencyKey: `mcp-checkout-link-cart-${stamp}`,\n });\n for (const [index, item] of lineItems.entries()) {\n await ctx.client.post(`/api/v1/carts/${cart?.id}/items`, {\n body: item,\n idempotencyKey: `mcp-checkout-link-item-${stamp}-${index}`,\n });\n }\n // The session needs a cart that ALREADY holds its items — there is no\n // endpoint that takes line items directly.\n const session = await ctx.client.post<any>('/api/v1/checkout/sessions', {\n body: {\n applicationId,\n cartId: cart?.id,\n returnUrl: args.returnUrl,\n cancelUrl: args.cancelUrl,\n customerEmail: args.customerEmail,\n discountCode: args.discountCode,\n },\n idempotencyKey: `mcp-checkout-link-session-${stamp}`,\n });\n return { cartId: cart?.id, ...session };\n },\n\n // -------------------------------------------------------------- money/mail\n manage_subscription: async (ctx, args) => {\n const id = String(args.id);\n const action = String(args.action);\n if (action !== 'pause' && action !== 'resume') {\n throw new Error(`manage_subscription: action must be \"pause\" or \"resume\", got \"${action}\".`);\n }\n return ctx.client.post(`/api/v1/subscriptions/${id}/${action}`, {\n idempotencyKey: `mcp-manage-subscription-${id}-${action}-${Date.now()}`,\n });\n },\n\n create_quote: async (ctx, args) =>\n // The real route's body shape differs from this tool's flatter,\n // model-facing input: line items are \"items\" (not \"lineItems\"), Net-N\n // terms are nested under paymentTerms.netN with an explicit mode (not a\n // flat \"netN\"), and the buyer-visible note field is \"buyerNote\" (not\n // \"notes\"). Confirmed against packages/platform-api/src/validation/quotes.ts's\n // actual zod schema after a live call 400'd with unrecognized_keys.\n ctx.client.post('/api/v1/quotes', {\n body: {\n customerId: args.customerId,\n items: args.items,\n expiresAt: args.expiresAt,\n paymentTerms:\n args.netN !== undefined ? { mode: 'net_terms', netN: args.netN } : undefined,\n buyerNote: args.notes,\n },\n idempotencyKey: `mcp-create-quote-${String(args.customerId)}-${Date.now()}`,\n }),\n\n get_sales_timeseries: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/orders-timeseries',\n {\n from: args.from,\n to: args.to,\n groupBy: args.groupBy,\n timezone: args.timezone,\n compareTo: args.compareTo,\n },\n { applicationId: args.applicationId },\n ),\n\n get_business_summary: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/business-summary',\n {\n period: args.period,\n from: args.from,\n to: args.to,\n timezone: args.timezone,\n },\n { applicationId: args.applicationId },\n ),\n\n get_attention_digest: async (ctx, args) =>\n ctx.client.get('/api/v1/analytics/attention-digest', undefined, {\n applicationId: args.applicationId,\n }),\n\n get_top_products: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/products',\n {\n from: args.from,\n to: args.to,\n timezone: args.timezone,\n by: args.by,\n limit: args.limit,\n },\n { applicationId: args.applicationId },\n ),\n\n // `.get()`, not `.list()` — the response is a single object (`{ data: {\n // range, signups, ordersByCustomerType, topCustomers, totals } }`), and\n // `.list()` only unwraps arrays: it would silently return an empty list\n // instead of the real payload.\n get_customer_growth: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/customers',\n {\n from: args.from,\n to: args.to,\n groupBy: args.groupBy,\n timezone: args.timezone,\n topBy: args.topBy,\n topLimit: args.topLimit,\n },\n { applicationId: args.applicationId },\n ),\n\n // `.get()`, not `.list()` — the response is a single object (`{ data: {\n // range, dimension, rows, totals, note } }`), not a paginated array.\n get_revenue_breakdown: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/revenue-breakdown',\n {\n dimension: args.dimension,\n from: args.from,\n to: args.to,\n timezone: args.timezone,\n },\n { applicationId: args.applicationId },\n ),\n\n // `.get()`, not `.list()` — the response is a single object (`{ data: {\n // range, stages, conversionRate, dropOff, note } }`), not a paginated array.\n get_funnel_conversion: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/funnel',\n {\n from: args.from,\n to: args.to,\n timezone: args.timezone,\n },\n { applicationId: args.applicationId },\n ),\n\n // `.get()`, not `.list()` — the response is a single object (`{ data: {\n // range, series, totals, note } }`), not a paginated array.\n get_subscription_movement: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/subscriptions',\n {\n from: args.from,\n to: args.to,\n timezone: args.timezone,\n groupBy: args.groupBy,\n },\n { applicationId: args.applicationId },\n ),\n\n // `.get()`, not `.list()` — the response is a single object (`{ data: {\n // range, rows, totals, note } }`), not a paginated array.\n get_discount_performance: async (ctx, args) =>\n ctx.client.get(\n '/api/v1/analytics/discounts',\n {\n from: args.from,\n to: args.to,\n timezone: args.timezone,\n limit: args.limit,\n },\n { applicationId: args.applicationId },\n ),\n\n // ------------------------------------------------------------- extensions\n list_extension_installations: async (ctx, args) =>\n ctx.client.list(\n '/api/v1/installations',\n { status: args.status, ...page(args) },\n { applicationId: args.applicationId },\n ),\n\n // ------------------------------------------------------------- connectors\n get_connector_routing: async (ctx, args) => {\n const opts = { applicationId: args.applicationId };\n const [paymentRouting, routingConnectors, cardDecline, otherDecline] = await Promise.all([\n optional(() => ctx.client.get('/api/v1/payment-routing', undefined, opts)),\n optional(() => ctx.client.get('/api/v1/routing-connectors', undefined, opts)),\n optional(() => ctx.client.get('/api/v1/card-decline', undefined, opts)),\n optional(() => ctx.client.get('/api/v1/other-decline', undefined, opts)),\n ]);\n return {\n paymentRouting: paymentRouting.ok ? paymentRouting.value : paymentRouting.unavailable,\n routingConnectors: routingConnectors.ok ? routingConnectors.value : routingConnectors.unavailable,\n cardDecline: cardDecline.ok ? cardDecline.value : cardDecline.unavailable,\n otherDecline: otherDecline.ok ? otherDecline.value : otherDecline.unavailable,\n };\n },\n\n get_integration_status: async (ctx, args) => {\n const opts = { applicationId: args.applicationId };\n const [connectors, endpoints, coverage] = await Promise.all([\n optional(() => ctx.client.list('/api/v1/connectors', undefined, opts)),\n optional(() => ctx.client.list('/api/v1/webhook-endpoints', undefined, opts)),\n optional(() => ctx.client.get('/api/v1/webhook-endpoints/coverage', undefined, opts)),\n ]);\n // ctx.identity.application is resolved ONCE PER SESSION from the grant's\n // default application, before any per-call override. Echoing it next to\n // data read under an `applicationId` override would mislabel the\n // overridden application's connectors/webhook endpoints as the default\n // application's. Report the id the data actually describes, and only\n // include the cached name/slug object when it truly describes this\n // response (i.e. no override is in play).\n const overridden = Boolean(args.applicationId) && args.applicationId !== ctx.identity.application?.id;\n return {\n environment: ctx.identity.environment,\n workspace: ctx.identity.workspace,\n applicationId: args.applicationId ?? ctx.identity.application?.id ?? null,\n application: overridden ? undefined : ctx.identity.application,\n connectors: connectors.ok ? connectors.value.data : connectors.unavailable,\n webhookEndpoints: endpoints.ok ? endpoints.value.data : endpoints.unavailable,\n unsubscribedEvents: coverage.ok ? coverage.value : coverage.unavailable,\n };\n },\n\n // --------------------------------------------------------------- workspace\n // No applicationId forwarding here: /api/v1/merchants/me is workspace-only\n // (`WHERE workspace_id = ...`, never reads auth.applicationId) — an\n // applicationId field on this tool would be a silent no-op affordance.\n get_workspace_settings: async (ctx) => ctx.client.get('/api/v1/merchants/me'),\n\n // No applicationId forwarding here either: /api/v1/audit-log filters by\n // workspaceId (and optionally environmentId), never applicationId.\n get_audit_log: async (ctx, args) => ctx.client.list('/api/v1/audit-log', { limit: args.limit }),\n\n // --------------------------------------------------------- applications\n // `.get()`, not `.list()` — the legacy /v1/stores route returns a bare\n // array with no `meta.pagination`, and the brief calls for `.get()` here\n // specifically.\n list_applications: async (ctx) => ctx.client.get('/api/v1/stores'),\n};\n","import { z, type ZodTypeAny } from 'zod';\nimport type { ActionField } from '@core/action-catalog';\n\n/**\n * Projects the catalog's portable field descriptors into a zod shape for the MCP\n * SDK. The catalog stays zod-free on purpose (Zapier and Make runtimes never need\n * it), so the derivation lives here — the one place that does.\n */\nexport function fieldsToZodShape(fields: readonly ActionField[]): Record<string, ZodTypeAny> {\n const shape: Record<string, ZodTypeAny> = {};\n for (const field of fields) {\n shape[field.name] = applyModifiers(field, baseType(field));\n }\n return shape;\n}\n\nfunction baseType(field: ActionField): ZodTypeAny {\n if (field.enum && field.enum.length > 0) {\n return z.enum([...field.enum] as [string, ...string[]]);\n }\n switch (field.type) {\n case 'string':\n return z.string();\n case 'number':\n return z.number();\n case 'boolean':\n return z.boolean();\n case 'array':\n return z.array(z.unknown());\n case 'object':\n return z.record(z.unknown());\n }\n}\n\nfunction applyModifiers(field: ActionField, type: ZodTypeAny): ZodTypeAny {\n const described = type.describe(field.description);\n if (field.required) return described;\n return field.default === undefined ? described.optional() : described.default(field.default);\n}\n","/**\n * Output allowlists for OAuth sessions on the hosted server.\n *\n * A tool reached over OAuth (ChatGPT, Claude) returns only the fields named\n * here; everything else is dropped. The REST API's own redaction\n * (`redactShopperPii`) is a list of keys to remove, and a list like that keeps\n * missing the next free-text field — a return `reason`, a quote timeline\n * `message`, a buyer-typed item description. A list of keys to KEEP fails the\n * other way: a field the API adds later is simply absent until someone decides\n * it belongs here. It also drops what the model has no use for (tenant ids,\n * `updatedAt`, processor internals), which is OpenAI's minimization rule.\n *\n * A field name says nothing about what is in it, so every kept string is\n * also classified by who wrote it:\n *\n * - `S` is a value Throttle generates or constrains: ids, statuses and other\n * enums, amounts, currencies, timestamps, country codes. A string here must\n * be a single token (no spaces, no `@`, at most 200 characters) or it comes\n * back null — a field that could hold \"Jane Doe\" or an email address was\n * misclassified, and it fails closed rather than passing the text on.\n * - `T` is text the merchant or Throttle wrote: an application or plan name,\n * a discount code, a carrier, a handler's note. Kept as is.\n * The full list is pinned by a test (`__tests__/projection.test.ts`), so a\n * new one is a reviewed decision.\n * - Text a buyer can type is not kept at all: line-item and quote-item names,\n * SKUs and reference ids (a quote request form takes them from the buyer,\n * and an accepted quote becomes an order), company, street/city/region/\n * postal code, and the merchant's external ids (which can be an email or a\n * name, and no pattern can prove otherwise).\n *\n * Shapes:\n * - `oneOf(values)` keeps a string only if it is one of a fixed set Throttle\n * generates (an order's `displayStatus`, \"Fulfilled · Partially refunded\"),\n * where `S` would null a legitimate value for containing a space.\n * - Webhook endpoint URLs are not kept at all: they routinely carry a secret in\n * the path (`hooks.slack.com/services/…`), and readiness needs only the id.\n * - `S` / `T` keep a primitive (string, number, boolean, null). An object or\n * array in that position is dropped, so a field that turns into a free-form\n * object cannot slip through under a scalar entry.\n * - `{ key: shape }` keeps the named keys of an object.\n * - `[shape]` keeps every element of an array (one-element array: the element shape).\n * - `section(shape)` is a sub-read that may come back instead as one of\n * `optional()`'s fixed strings (\"not readable with this credential\") — any\n * other string is nulled — or as an analytics\n * `{ omitted, grantable, reason }` marker; both are kept.\n * - `PASS` returns the value untouched. Only for tools that read no workspace\n * data at all (the docs and OpenAPI-contract lookups).\n */\nexport type Shape =\n | typeof S\n | typeof T\n | typeof PASS\n | { readonly [key: string]: Shape }\n | readonly Shape[]\n | Section\n | OneOf;\n\ninterface Section {\n readonly __section: Shape;\n}\n\ninterface OneOf {\n readonly __oneOf: ReadonlySet<string>;\n}\n\nexport const S = 'scalar' as const;\nexport const T = 'text' as const;\nexport const PASS = 'pass' as const;\nconst section = (shape: Shape): Section => ({ __section: shape });\nexport const oneOf = (values: Iterable<string>): OneOf => ({ __oneOf: new Set(values) });\n\nfunction isPrimitive(value: unknown): boolean {\n return value === null || ['string', 'number', 'boolean'].includes(typeof value);\n}\n\nconst TOKEN = /^[^\\s@]{0,200}$/;\n\nconst OMITTED = { omitted: S, grantable: T, reason: T } as const;\n/** The only strings a sub-read comes back as: `optional()` in client.ts. */\nconst UNAVAILABLE = /^(not readable with this credential \\(missing scope\\)|not found|unavailable \\([^\\s@]{0,100}\\))$/;\n\nexport function project(value: unknown, shape: Shape): unknown {\n if (value === undefined) return undefined;\n if (shape === PASS) return value;\n if (shape === S) {\n if (!isPrimitive(value)) return undefined;\n return typeof value === 'string' && !TOKEN.test(value) ? null : value;\n }\n if (shape === T) return isPrimitive(value) ? value : undefined;\n if ('__oneOf' in (shape as object)) {\n if (!isPrimitive(value)) return undefined;\n return typeof value === 'string' && !(shape as OneOf).__oneOf.has(value) ? null : value;\n }\n if (Array.isArray(shape)) {\n return Array.isArray(value) ? value.map((item) => project(item, shape[0] as Shape)) : undefined;\n }\n if ('__section' in (shape as object)) {\n if (typeof value === 'string') return UNAVAILABLE.test(value) ? value : null;\n if (value && typeof value === 'object' && (value as { omitted?: unknown }).omitted === true) {\n return project(value, OMITTED);\n }\n return project(value, (shape as Section).__section);\n }\n if (value === null) return null;\n if (typeof value !== 'object' || Array.isArray(value)) return undefined;\n const out: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(shape as Record<string, Shape>)) {\n const projected = project((value as Record<string, unknown>)[key], child);\n if (projected !== undefined) out[key] = projected;\n }\n return out;\n}\n\n// ------------------------------------------------------------------ building blocks\n\nconst PAGINATION = { cursor: S, nextCursor: S, hasMore: S };\nconst page = (row: Shape) => ({ data: [row], pagination: PAGINATION });\n\n/** The country is enough to say where an order went; every other address line is typed by the buyer. */\nconst ADDRESS = { countryCode: S };\nconst CUSTOMER_REF = { id: S };\nconst APPLICATION = { id: S, name: T, slug: S };\n\n/**\n * Every value `orderDisplayStatus` (@commerce/orders status-model) can return:\n * a lifecycle label, alone or with one ` · ` qualifier. A label added there and\n * not here comes back null — pinned by a test that runs the real function.\n */\nconst LIFECYCLE_LABELS = ['Draft', 'Pending', 'Processing', 'Partially fulfilled', 'Fulfilled', 'Cancelled', 'Closed'];\nconst DISPLAY_QUALIFIERS = [\n 'Comped',\n 'Awaiting payment', 'Authorized', 'Partially paid', 'Partially refunded', 'Refunded', 'Payment failed',\n 'Voided', 'Payment processing', 'Disputed', 'Authorization expired',\n 'Returned', 'Partially returned', 'Delivered', 'In transit',\n];\nexport const ORDER_DISPLAY_STATUSES: ReadonlySet<string> = new Set(\n LIFECYCLE_LABELS.flatMap((l) => [l, ...DISPLAY_QUALIFIERS.map((q) => `${l} · ${q}`)]),\n);\nconst DISPLAY_STATUS = oneOf(ORDER_DISPLAY_STATUSES);\nconst RANGE = { from: S, to: S, timezone: S, groupBy: S };\n\n// No name, SKU or reference id: see the header.\nconst LINE_ITEM = {\n id: S, type: S, quantity: S, unitPrice: S, subtotal: S, discountAmount: S, taxAmount: S, total: S,\n recurring: S,\n};\n\nconst ORDER = {\n id: S, orderNumber: S, status: S, displayStatus: DISPLAY_STATUS, paymentStatus: S, type: S,\n source: S, currency: S, subtotal: S, discountTotal: S, shippingTotal: S, taxTotal: S, total: S,\n capturedAmount: S, refundedAmount: S, compAmount: S, onHold: S,\n taxReverseCharge: S, customerId: S, customer: CUSTOMER_REF, subscriptionId: S,\n shippingAddress: ADDRESS, billingAddress: ADDRESS,\n fulfillmentSummary: { itemsFulfilled: S, itemsRemaining: S, itemsTotal: S },\n lineItems: [LINE_ITEM], createdAt: S, completedAt: S, cancelledAt: S, closedAt: S,\n};\n\nconst PAYMENT = {\n id: S, orderId: S, status: S, method: S, processor: S, amount: S, capturedAmount: S, currency: S,\n cardBrand: S, disputed: S, disputeOpenedAt: S, errorCode: S, netN: S, netNSource: S,\n authorizedAt: S, capturedAt: S, voidedAt: S, createdAt: S,\n};\n\nconst RETURN = {\n id: S, orderId: S, status: S, restock: S, refundAmount: S, refundPaymentId: S, createdAt: S,\n items: [{ lineItemId: S, quantity: S }],\n};\n\nconst FULFILLMENT = {\n id: S, orderId: S, type: S, status: S, createdAt: S,\n lineItems: [{ lineItemId: S, quantity: S }],\n detail: { carrier: T, serviceLevel: T, trackingNumber: T, trackingUrl: T, shippedAt: S, estimatedDelivery: S, actualDelivery: S },\n};\n\nconst CUSTOMER = { id: S, netN: S, acceptsMarketing: S, createdAt: S };\n\nconst SUBSCRIPTION = {\n id: S, status: S, planName: T, planReference: T, amount: S, currency: S, interval: S, quantity: S,\n intervalUnit: S, intervalCount: S, totalPayments: S, paymentsMade: S, completedAt: S,\n customerId: S, customer: CUSTOMER_REF, currentPeriodStart: S, currentPeriodEnd: S, billingAnchorAt: S,\n cancelAtPeriodEnd: S, trialEnd: S, pausedAt: S, cancelledAt: S, lastPaymentAt: S, failureCount: S,\n pendingPlanName: T, pendingPlanReference: T, pendingAmount: S, pendingInterval: S, pendingQuantity: S,\n pendingIntervalUnit: S, pendingIntervalCount: S,\n createdAt: S,\n};\n\nconst QUOTE_SUMMARY = {\n id: S, quoteNumber: S, status: S, source: S, currency: S, total: S, customerId: S, orderId: S,\n expiresAt: S, acceptedAt: S, declinedAt: S, createdAt: S,\n};\n\nconst QUOTE = {\n ...QUOTE_SUMMARY,\n revisions: [{\n id: S, revisionNumber: S, state: S, subtotal: S, discountTotal: S, shippingTotal: S, taxTotal: S,\n total: S, depositAmount: S, shippingMode: S, issuedAt: S, expiresAt: S,\n paymentTerms: { mode: S, netN: S, balanceNetN: S, deposit: { type: S, value: S } },\n items: [{\n type: S, quantity: S, unitPrice: S, subtotal: S, discountAmount: S, taxAmount: S, total: S,\n optional: S, optionalSelected: S,\n }],\n }],\n // Who commented and when, never what they wrote.\n comments: [{ authorType: S, visibility: S, createdAt: S }],\n timeline: [{ type: S, actorType: S, createdAt: S }],\n};\n\nconst INVOICE = {\n id: S, number: S, status: S, sourceType: S, sourceId: S, customerId: S, currency: S, subtotal: S,\n discountTotal: S, shippingTotal: S, taxTotal: S, total: S, amountRefunded: S, issuedAt: S, dueAt: S,\n periodStart: S, periodEnd: S, createdAt: S,\n billingSnapshot: {\n planName: T,\n period: { start: S, end: S },\n lineItems: [{ quantity: S, unitPrice: S, discountAmount: S, taxAmount: S, total: S }],\n totals: { currency: S, subtotal: S, discountTotal: S, shippingTotal: S, taxTotal: S, total: S },\n payment: { method: S, brand: S, status: S },\n },\n};\n\nconst DISCOUNT = {\n id: S, code: T, name: T, type: S, value: S, isActive: S, startsAt: S, endsAt: S, usageCount: S,\n usageLimit: S, maxRedemptionsPerCustomer: S, createdAt: S,\n};\n\nconst EVENT = {\n id: S, type: S, entityType: S, entityId: S, createdAt: S,\n data: {\n status: S, previousStatus: S, action: S, amount: S, currency: S, attempt: S, orderId: S, paymentId: S,\n order: { id: S, orderNumber: S, status: S, paymentStatus: S, currency: S, total: S },\n payment: { id: S, orderId: S, status: S, method: S, amount: S, currency: S },\n subscription: { id: S, status: S, planName: T, amount: S, currency: S, interval: S },\n fulfillment: { id: S, orderId: S, type: S, status: S },\n },\n};\n\n/** The payload and the endpoint's error text are left out: both carry whatever the order carried. */\nconst DELIVERY = {\n id: S, endpointId: S, eventId: S, eventType: S, status: S, attemptCount: S, lastStatus: S,\n deliveredAt: S, nextRetryAt: S, createdAt: S, replayOf: S,\n};\n\nconst MONEY_COUNT = { count: S, totalCents: S };\nconst ORDER_PERIOD = { orderCount: S, grossCents: S, netCents: S, refundsCents: S, avgOrderCents: S };\n\n// ------------------------------------------------------------------------ per tool\n\nexport const OAUTH_PROJECTIONS: Readonly<Record<string, Shape>> = {\n whoami: {\n type: S,\n workspace: { name: T, slug: S },\n application: APPLICATION,\n environment: { slug: S, kind: S, providerEnvironment: S },\n note: T,\n },\n search_docs: PASS,\n describe_endpoint: PASS,\n validate_payload: PASS,\n\n search_orders: page(ORDER),\n get_order: {\n order: ORDER,\n payments: section([PAYMENT]),\n returns: section([RETURN]),\n fulfillments: section([FULFILLMENT]),\n },\n\n search_customers: page(CUSTOMER),\n get_customer: {\n customer: CUSTOMER,\n addresses: section([{ id: S, isDefault: S, ...ADDRESS }]),\n subscriptions: section([SUBSCRIPTION]),\n },\n\n list_subscriptions: page(SUBSCRIPTION),\n get_subscription: SUBSCRIPTION,\n\n search_quotes: page(QUOTE_SUMMARY),\n get_quote: QUOTE,\n\n list_invoices: page(INVOICE),\n get_invoice: INVOICE,\n receivables_aging: {\n buckets: [{ key: S, label: T, count: S, total_amount: S }],\n total_outstanding_amount: S,\n total_outstanding_count: S,\n },\n\n search_discounts: page(DISCOUNT),\n get_discount: DISCOUNT,\n\n search_payments: page(PAYMENT),\n get_payment: {\n payment: PAYMENT,\n transactions: section([{ id: S, type: S, status: S, amount: S, currency: S, createdAt: S }]),\n },\n\n list_abandoned_carts: {\n carts: section([{\n id: S, abandonedAt: S, currency: S, itemCount: S, recoveryStatus: S, total: S, customer: { id: S },\n }]),\n summary: section({ abandonedCount: S, abandonedValue: S, recoveryEmailsSent: S, sinceDays: S }),\n },\n\n search_events: page(EVENT),\n list_webhook_deliveries: page(DELIVERY),\n get_webhook_delivery: DELIVERY,\n explain_checkout_failure: {\n note: T,\n hint: T,\n session: {\n id: S, status: S, cartId: S, customerId: S, expiresAt: S, completedAt: S,\n allowedMethods: [S],\n collect: { shippingAddress: S, billingAddress: S, vatNumber: S },\n shippingAddress: ADDRESS,\n billingAddress: ADDRESS,\n recurringTerms: {\n interval: S, intervalUnit: S, intervalCount: S, totalPayments: S, taxApplies: S,\n planChargedToday: S, planName: T, trialDays: S, currency: S, firstChargeAmountMinor: S,\n },\n },\n cart: section({\n id: S, status: S, currency: S, subtotal: S, discountTotal: S, shippingTotal: S, taxTotal: S,\n total: S, itemCount: S, items: [LINE_ITEM], lineItems: [LINE_ITEM],\n }),\n events: [EVENT],\n eventsUnavailable: T,\n recentWebhookDeliveries: section([DELIVERY]),\n },\n\n list_extension_installations: page({\n id: S, extensionId: S, extensionName: T, extensionSlug: S, versionId: S, status: S,\n environmentSlug: S, installedAt: S, uninstalledAt: S,\n }),\n get_connector_routing: {\n paymentRouting: section({\n defaultCascade: [S],\n rules: [{ cascade: [S], conditions: [{ type: S, op: S, currency: S, min: S, max: S, values: [S] }] }],\n }),\n cardDecline: section({ rules: [{ errorCode: S, conditions: [{ type: S, op: S, values: [S] }] }] }),\n otherDecline: section({ rules: [{ errorCode: S, conditions: [{ type: S, op: S, values: [S] }] }] }),\n routingConnectors: section([{ id: S, displayName: T, method: S }]),\n },\n get_integration_status: {\n environment: { slug: S, kind: S, providerEnvironment: S },\n workspace: { name: T, slug: S },\n applicationId: S,\n application: APPLICATION,\n connectors: section([{\n id: S, displayName: T, method: S, type: S, status: S, active: S, position: S,\n acceptedCountries: [S], acceptedCurrencies: [S], threeDSecureEnabled: S, createdAt: S,\n }]),\n webhookEndpoints: section([{ id: S, isActive: S, enabledEvents: [S], createdAt: S }]),\n unsubscribedEvents: section({ windowDays: S, unsubscribed: [{ type: S, count: S, lastEmittedAt: S }] }),\n },\n get_workspace_settings: { name: T, slug: S, brandColor: S, logoUrl: T, onboardingCompletedAt: S },\n // What happened and to which record; not which team member did it.\n get_audit_log: page({ id: S, action: S, resourceType: S, resourceId: S, createdAt: S }),\n list_applications: [{ id: S, name: T, slug: S, currency: S, isActive: S }],\n\n // Analytics: computed aggregates, listed field by field all the same.\n get_business_summary: {\n period: S,\n range: RANGE,\n orders: section({ current: ORDER_PERIOD, previous: ORDER_PERIOD, deltaPct: S }),\n subscriptions: section({\n mrr: { currentCents: S, periodStartCents: S, deltaPct: S },\n newSubscriptions: S, cancelledSubscriptions: S, churnRate: S, note: T,\n }),\n receivables: section({ outstandingCents: S, outstandingCount: S }),\n quotes: section({ sent: MONEY_COUNT, accepted: MONEY_COUNT, declined: MONEY_COUNT, expired: MONEY_COUNT }),\n },\n get_attention_digest: {\n disputes: section({ open: S, totalCents: S }),\n subscriptionsInDunning: section(S),\n overdueInvoices: section(MONEY_COUNT),\n unhealthyWebhooks: section([{ endpointId: S, failureRate: S, attempts7d: S }]),\n },\n get_sales_timeseries: {\n application: APPLICATION, range: RANGE, currency: S, days: S, note: T,\n series: [{ date: S, grossCents: S, orders: S }], totalGrossCents: S, totalOrders: S,\n },\n // get_top_products has no entry, so it is not offered over OAuth: it ranks\n // products by line-item reference id or name, which a buyer can type.\n get_customer_growth: {\n application: APPLICATION, range: RANGE, note: T, topBy: S,\n signups: { total: S, series: [{ date: S, signups: S }] },\n ordersByCustomerType: { newCustomerOrders: S, returningCustomerOrders: S },\n // The ranking, by id: a top customer's name and email stay behind.\n topCustomers: [{ customerId: S, orderCount: S, revenueCents: S }],\n totals: { customerCount: S, orderCount: S, revenueCents: S },\n },\n get_revenue_breakdown: {\n application: APPLICATION, range: RANGE, dimension: S, note: T,\n rows: [{ key: S, orderCount: S, grossCents: S }],\n totals: { orderCount: S, grossCents: S },\n },\n get_funnel_conversion: {\n application: APPLICATION, range: RANGE, note: T, conversionRate: S,\n stages: [{ name: S, count: S }],\n dropOff: [{ from: S, to: S, ratePct: S }],\n },\n get_subscription_movement: {\n application: APPLICATION, range: RANGE, note: T,\n series: [{ date: S, newSubscriptions: S, churnedSubscriptions: S, mrrDeltaCents: S }],\n totals: { newSubscriptions: S, churnedSubscriptions: S, netMrrDeltaCents: S },\n },\n get_discount_performance: {\n application: APPLICATION, range: RANGE, note: T,\n rows: [{ discountId: S, code: T, redemptions: S, discountedRevenueCents: S, discountGivenCents: S }],\n totals: { redemptions: S, discountedRevenueCents: S, discountGivenCents: S },\n },\n};\n","import { readFileSync } from 'node:fs';\nimport type { DocsIndex } from './docs';\nimport type { ContractIndex } from './contract';\n\n/**\n * Indexes are generated into `dist/` at build time and shipped in the tarball. A\n * missing index degrades that one tool instead of preventing boot — the API tools\n * are unaffected and the failure is legible on stderr.\n */\nfunction loadIndex<T extends { generatedAt: string }>(file: string, empty: T, label: string): T {\n try {\n return JSON.parse(readFileSync(new URL(`./${file}`, import.meta.url), 'utf8')) as T;\n } catch {\n process.stderr.write(\n `throttle-mcp: ${label} index missing (${file}); that tool will return no results. Run \"pnpm --filter @usethrottle/mcp build:indexes\".\\n`,\n );\n return empty;\n }\n}\n\nexport function loadDocsIndex(): DocsIndex {\n return loadIndex<DocsIndex>('docs-index.json', { generatedAt: '', entries: [] }, 'docs');\n}\n\nexport function loadContractIndex(): ContractIndex {\n return loadIndex<ContractIndex>('contract-index.json', { generatedAt: '', operations: [] }, 'contract');\n}\n"],"mappings":"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","names":["page"]}
|