@ekanos/integration-schema. There are no subpath entrypoints.
Integration Definition Contract
IntegrationDefinitionSchema
The canonical, strict zod schema for an integration definition — the same schema @ekanos/sdk’s defineIntegration() and the Ekanos host validate against.
- Requires
slug(kebab-case),name,description, and a semverversion - Rejects unknown keys on the definition and its declaration objects (
.strict()) - Requires unique widget ids, tool names, webhook ids, and schedule ids within a definition
- Checks tool names are lowercase snake_case, and widget, webhook, schedule, and action ids are kebab-case
- Checks storage keys against the scope’s allowed data types
- Requires
egressentries to behttps://origins (optionallyhttps://*.wildcards), and OAuth endpoints to behttps://URLs
Prefer
parseIntegrationDefinition() or collectDefinitionFindings() over
calling safeParse directly: they also run the plain-data pre-check (below)
and return friendlier messages.parseIntegrationDefinition(input)
defineIntegration() and the host. It rejects non-plain containers, parses against the schema, and returns the sanitized, deep-frozen result.data — never the caller’s object. On failure it throws an Error whose message lists every issue.
collectDefinitionFindings(input, options?)
parseIntegrationDefinition(). Returns an array of findings; an empty array means the definition is valid. Synchronous.
check: 'definition.plain-data' for a failed plain-data pre-check, and check: 'definition.schema' for each schema issue, with the zod path at the start of message (e.g. components.widgets.0.id: …).
validateIntegrationDefinitions(definitions, firstParty?)
firstParty is given, against first-party identifiers. Returns nothing on success; throws one Error listing every collision.
collectCollisionFindings(definitions, firstParty?)
validateIntegrationDefinitions(). Every finding is severity: 'error', with check one of collision.slug, collision.widget-id, collision.tool-name, collision.reserved-slug, collision.reserved-widget-id, or collision.reserved-tool-name.
getDiscoveredToolName(slug, rawName)
slug.replace(/-/g, '*')), unless the name already starts with that prefix. Collision checks compare effective names.
assertPlainDeclaration(value, path?, ancestors?)
Throws if a declaration contains a cycle, a getter/setter, or a class/exotic instance where a plain object or array is expected. Functions and zod schemas are allowed as leaves. parseIntegrationDefinition() and collectDefinitionFindings() run this for you.
deepFreezeDefinition(value)
parseIntegrationDefinition() already returns a frozen result.
Integration Definition Types
These TypeScript types are re-exported by@ekanos/sdk. The generic Schemas parameter types ctx.storage from your storage declaration.
IntegrationDefinition<Schemas>
IntegrationComponentDeclarations
PartnerWidgetDeclaration
Inferred from the widget schema:
IntegrationCapabilityDeclaration and IntegrationPermissionDeclaration
PartnerToolModule<Schemas>
A tool exposed to the assistant.
PartnerActionDeclaration<TInput, TOutput, Schemas>
A widget-invoked server handler, keyed by kebab-case action name in actions.
IntegrationProposals and ToolClassificationProposal
Values a partner proposes; the host decides.
proposes.tools must match a declared tool name.
OnActivateHandler<Schemas>
Capability-Context Types
The canonical home of the context types;@ekanos/sdk re-exports them. The value half (error classes, the egress matcher) lives in @ekanos/sdk/context.
IntegrationContext<Schemas>
The one object handlers receive (tools, actions, webhooks, schedules, onTokens, onActivate).
IntegrationActor
IntegrationStorage<Schemas> and ScopedStore
set validates against the key’s schema before writing, and a read whose stored data no longer matches the schema throws StorageValidationError.
StorageSchemas, StorageSchemaMap, and key declarations
"<dataType>" or "<dataType>/<subtype>" in lowercase [a-z0-9_-]. clientReadable: true opts a key in to the browser-readable storage route; omitted, a key is server-only. StorageScopeSchemas and StorageKeySchema are helper types that resolve a scope’s map and a key’s zod schema.
IntegrationSecrets
set writes only to the account-tier store; writing a name that resolves only from source or global tiers throws SecretAccessError.
IntegrationFetch
egress allowlist on the resolved URL’s origin, redirect targets included. A denied call throws EgressDeniedError before any network I/O.
IntegrationLogger
Event Surfaces
PartnerWebhookDeclaration<Schemas>
scheme (a keyed format needs a digestKey, {timestamp} needs a source, a timestamp source needs {timestamp} in signedPayload, and so on) are enforced at parse time; see Webhooks. A handler that cannot process a valid event should throw, which the transport maps to a retryable failure.
PartnerScheduleDeclaration<Schemas>
cron is present; defineIntegration() validates the syntax.
PartnerOAuthDeclaration<Schemas>
onTokens persists tokens via ctx.secrets. defineIntegration() rejects the declaration unless both endpoint origins are covered by egress.
Workspace Targets
WorkspaceTargetSlugSchema
A trimmed string, 1–100 characters, lowercase alphanumeric with single hyphens between segments.
WorkspaceTargetLayoutSchema
createWorkspaceTargetSchema(options?) and WorkspaceTargetSchema
WorkspaceTargetSchema is the default instance with no icon-name check (icons are still validated as non-empty strings up to 100 characters).
inheritsWidgets and includedWidgetIds, and includedWidgetIds must not be empty.
WorkspaceTargetDefinition and ResolvedWorkspaceTarget
WorkspaceTargetDefinition is the input type; ResolvedWorkspaceTarget is the parsed output, where layout defaults to 'masonry'.
createWorkspaceTargetListSchema(options?) and WorkspaceTargetListSchema
The schema for a whole declaration set: at most 20 targets, unique slugs, and exactly one target without includedWidgetIds that sets inheritsWidgets: true (a single target may omit it). IntegrationDefinitionSchema validates workspaceTargets with WorkspaceTargetListSchema.
normalizeWorkspaceTargets(declared, options?)
inheritsWidgets: true for a lone target that omitted it.
Storage Data Types
ThedataType segment of every storage key must come from its scope’s list.
secret is never addressable through ctx.storage; use ctx.secrets instead.
Product ID Derivation
Deterministic slug → UUID derivation, so the same slug yields the same id everywhere.deriveProductId(slug)
uuidv5(slug, EKANOS_INTEGRATION_NAMESPACE). Throws if slug is not kebab-case.
derivePlanId(slug, planName)
uuidv5('plan:<slug>:<planName>', EKANOS_INTEGRATION_NAMESPACE), with planName trimmed and lowercased first. Throws on a non-kebab-case slug or an empty plan name.
uuidv5(name, namespace)
EKANOS_INTEGRATION_NAMESPACE and DNS_NAMESPACE
EKANOS_INTEGRATION_NAMESPACE is '269944fc-4736-5497-b751-381be92fb8df' — itself uuidv5('ekanos.dev', DNS_NAMESPACE). DNS_NAMESPACE is the standard RFC 4122 DNS namespace, '6ba7b810-9dad-11d1-80b4-00c04fd430c8'.
Component References
ComponentReference
A dependency-pure stand-in for a React component:
React.lazy returns), or a React exotic object such as memo or forwardRef. Pass the component itself, not an element or a module path.
isComponentReference(value)
$$typeof property.
Utility Types
JsonValue
JsonValue (for example outputExample), Infinity, -Infinity, and NaN are rejected.
DefinitionCollisionInput and FirstPartyInventory
IntegrationDefinition is assignable to DefinitionCollisionInput.
Findings
Finding
line is usually absent — zod reports a path, which appears in message. ekanos validate adds line when it can locate the path in your source.