Reference

API reference

Auto-generated from @vincia/sdk. Every exported symbol has its JSDoc comment and signature reproduced verbatim. Re-run pnpm generate:api-reference from apps/forge-vincia/ after the SDK changes to refresh this file.

@vincia/sdk/runtime

runtime/index.ts

@vincia/sdk/runtime — the vincia.* API exposed to plugin code inside the V8 isolate sandbox.

The 8 namespaces + 17 methods exposed here are part of the frozen v1.0 contract surface — see docs/contributor-platform/04-sdk-types-spec.md Section D. Adding methods is a minor bump; removing or renaming is major.

At runtime, the actual behaviour is injected by @vincia/plugin-runtime (the sidecar — session P1-S2) via globalThis.__vincia_runtime__. This file provides the typed surface + thin delegations.

vincia (const)

The vincia global as it appears to plugin code. Identical in shape to the per-invocation ctx.{outbound,storage,...} view on {@link PluginContext}.

@example import { vincia } from '@vincia/sdk/runtime'; await vincia.log.info('starting'); const res = await vincia.outbound.fetch(url);

export const vincia = {

Defined in packages/sdk/src/runtime/index.ts.

runtime/log.ts

vincia.log — structured logging into the sidecar's observability pipeline.

Logs are tagged with build_id, tenant_id, and trace_id automatically. Plugins should not use console.* — those calls are visible in dev but dropped in production.

info (function)

Emit an info-level log.

@param msg Human-readable message. @param attrs Optional structured attributes (key-value, JSON-serialisable).

export function info(msg: string, attrs?: Record<string, unknown>): void

Defined in packages/sdk/src/runtime/log.ts.

warn (function)

Emit a warning-level log.

@param msg Human-readable message. @param attrs Optional structured attributes.

export function warn(msg: string, attrs?: Record<string, unknown>): void

Defined in packages/sdk/src/runtime/log.ts.

error (function)

Emit an error-level log. Does NOT throw — use throw new Error() for that.

@param msg Human-readable message. @param attrs Optional structured attributes. Pass { error: err.message } or a serialised stack — Error instances do not serialise on their own.

export function error(msg: string, attrs?: Record<string, unknown>): void

Defined in packages/sdk/src/runtime/log.ts.

runtime/metrics.ts

vincia.metrics — counters and timings.

Metrics are sampled by the sidecar and forwarded to the platform's observability backend. Per-plugin metric cardinality is bounded — keep the tag set small (e.g. status code, not free-form strings).

increment (function)

Increment a counter.

@param name Counter name. Use dot.case (e.g. phonepe.intents_created). @param value Amount to increment by. Defaults to 1. @param tags Optional tag map. Sidecar caps cardinality per metric.

export function increment(name: string, value?: number, tags?: Record<string, string>): void

Defined in packages/sdk/src/runtime/metrics.ts.

timing (function)

Record a duration in milliseconds.

@param name Timer name (dot.case). @param ms Duration in milliseconds. Use performance.now() deltas inside the isolate. @param tags Optional tag map.

export function timing(name: string, ms: number, tags?: Record<string, string>): void

Defined in packages/sdk/src/runtime/metrics.ts.

runtime/types.ts

Shared types for the @vincia/sdk/runtime facade.

These are the types every plugin sees on ctx and on the vincia.* namespaces. They are part of the frozen v1.0 contract surface — see docs/contributor-platform/04-sdk-types-spec.md.

Query (interface)

Storage query passed to vincia.storage.list and to the widget useStorage hook. Shape is intentionally minimal at v1.0 (filter + sort + paginate); richer query support is additive and lives behind a minor bump.

export interface Query {
  /**
   * Equality filters keyed by field name. `null` matches `IS NULL`.
   */
  where?: Record<string, string | number | boolean | null>;
  /**
   * Field name to sort by. Prefix with `-` to sort descending.
   * @example "-created_at"
   */
  orderBy?: string;
  /** Max rows to return. Server applies an upper bound regardless. */
  limit?: number;
  /** Cursor token returned by a prior list call. */
  cursor?: string;
}

Defined in packages/sdk/src/runtime/types.ts.

QueueOpts (interface)

Options for vincia.queue.enqueue.

export interface QueueOpts {
  /** Defer execution by this many seconds. Server clamps to its policy. */
  delaySeconds?: number;
  /** Optional idempotency key. Same key within the dedupe window is a no-op. */
  idempotencyKey?: string;
}

Defined in packages/sdk/src/runtime/types.ts.

PluginContext (interface)

The ctx object passed to connector methods, workflow step execute, and other plugin entry points. Implementations are injected by the sidecar; this interface is the contract shape every entry point can rely on.

outbound/storage/secrets/workflow/log/metrics/queue/crypto on ctx are exactly the same callables exported from vincia.* — but scoped to the current invocation (trace id, tenant id, etc).

export interface PluginContext {
  /** Plugin build id (manifest id + version + content hash). */
  build_id: string;
  /** Tenant (build) id the plugin is currently executing inside. */
  tenant_id: string;
  /** Optional end-user id when the invocation is on a user-bound request. */
  user_id?: string;
  /** OpenTelemetry-compatible trace id for log correlation. */
  trace_id: string;

  // Per-invocation views of the `vincia.*` namespaces.
  outbound: VinciaOutbound;
  storage: VinciaStorage;
  secrets: VinciaSecrets;
  workflow: VinciaWorkflow;
  log: VinciaLog;
  metrics: VinciaMetrics;
  queue: VinciaQueue;
  crypto: VinciaCrypto;
  events: VinciaEvents;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaOutbound (interface)

export interface VinciaOutbound {
  fetch(url: string | URL, init?: RequestInit): Promise<Response>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaStorage (interface)

export interface VinciaStorage {
  get<T = unknown>(collection: string, id: string): Promise<T | null>;
  list<T = unknown>(collection: string, query?: Query): Promise<T[]>;
  write<T = unknown>(collection: string, id: string, data: T): Promise<void>;
  delete(collection: string, id: string): Promise<void>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaSecrets (interface)

export interface VinciaSecrets {
  get(key: string): Promise<string>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaWorkflow (interface)

export interface VinciaWorkflow {
  trigger(name: string, payload: unknown): Promise<{ runId: string }>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaLog (interface)

export interface VinciaLog {
  info(msg: string, attrs?: Record<string, unknown>): void;
  warn(msg: string, attrs?: Record<string, unknown>): void;
  error(msg: string, attrs?: Record<string, unknown>): void;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaMetrics (interface)

export interface VinciaMetrics {
  increment(name: string, value?: number, tags?: Record<string, string>): void;
  timing(name: string, ms: number, tags?: Record<string, string>): void;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaQueue (interface)

export interface VinciaQueue {
  enqueue(name: string, payload: unknown, opts?: QueueOpts): Promise<void>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaCrypto (interface)

export interface VinciaCrypto {
  digest(algorithm: 'sha256' | 'sha512', data: ArrayBuffer): Promise<ArrayBuffer>;
  hmac(algorithm: 'sha256', key: ArrayBuffer, data: ArrayBuffer): Promise<ArrayBuffer>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaEvents (interface)

Event-bus binding for plugin-to-plugin events. Requires events:emit scope. See M-02 Part B / G-S39 + @vincia/event-bus.

export interface VinciaEvents {
  /**
   * Emit a plugin-namespaced event. `name` must match
   * `plugin-<your-slug>:<event-name>`; canonical events are emitted by
   * anyapp itself and cannot be impersonated.
   */
  emit(name: string, payload: unknown): Promise<void>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaWebhookEvent (interface)

Payload delivered to a plugin's onWebhook handler by the runtime when an inbound third-party webhook arrives at /__vincia/webhook/<install>/<name> AND HMAC validation succeeded.

headers is the curated safe subset (no cookies / auth headers / proxy hops) so plugins can pivot on Content-Type and User-Agent without inheriting host-side trust.

export interface VinciaWebhookEvent {
  /** Manifest webhook slug that fired (e.g. 'stripe', 'github'). */
  readonly webhook_name: string;
  /** Decoded JSON payload, or `{ _raw: string }` for non-JSON bodies. */
  readonly payload: unknown;
  /** Curated subset of inbound HTTP headers. */
  readonly headers: Readonly<Record<string, string>>;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaBusEvent (interface)

Payload delivered to a plugin's onEvent handler when a canonical or plugin-namespaced event the plugin subscribed to fires.

export interface VinciaBusEvent {
  /** Canonical (`user.signup`) or plugin-namespaced (`plugin-x:bar`). */
  readonly event_name: string;
  /** JSON payload as the emitter passed it. */
  readonly payload: unknown;
  /** When the bus received the event (ISO 8601 UTC). */
  readonly received_at: string;
}

Defined in packages/sdk/src/runtime/types.ts.

VinciaEventAck (interface)

Acknowledgement shape. Plugins return this from onWebhook / onEvent so the dispatcher can record the outcome. Truthy ok skips retry; falsy triggers the retry queue (exponential backoff → dead-letter).

export interface VinciaEventAck {
  readonly ok: boolean;
  /** Optional human-readable note for the events replay UI. */
  readonly note?: string;
}

Defined in packages/sdk/src/runtime/types.ts.

InjectedRuntime (interface)

The shape the sidecar injects on globalThis.__vincia_runtime__. The SDK's runtime files thin-wrap these methods; they do not provide behaviour themselves.

export interface InjectedRuntime {
  outbound: VinciaOutbound;
  storage: VinciaStorage;
  secrets: VinciaSecrets;
  workflow: VinciaWorkflow;
  log: VinciaLog;
  metrics: VinciaMetrics;
  queue: VinciaQueue;
  crypto: VinciaCrypto;
  events: VinciaEvents;
}

Defined in packages/sdk/src/runtime/types.ts.

_getInjectedRuntime (function)

Internal helper used by every runtime/* module. Looks up the injected runtime on globalThis and throws a contributor-friendly error if it's missing (i.e. the SDK is being used outside the sidecar isolate — usually a contributor's local unit test that should be using @vincia/sdk-types/testing instead).

@internal

export function _getInjectedRuntime(): InjectedRuntime

Defined in packages/sdk/src/runtime/types.ts.

@vincia/sdk/connector

connector/auth.ts

OAuth provider capability interface for T1 auth connectors.

A connector with capability: 'auth-provider' implements this interface. The host's OAuth relay calls into these methods at the four standard lifecycle points: authorize URL generation, code exchange, token refresh, and user info retrieval.

OAuthAuthorizeArgs (interface)

Args for getAuthorizeUrl. Standard OAuth 2.0 authorize params.

export interface OAuthAuthorizeArgs {
  /** Where the provider should redirect after consent. */
  redirectUri: string;
  /** Space-separated scopes the host wants. */
  scope: string;
  /** CSRF nonce — opaque to the provider. */
  state: string;
  /** Optional PKCE challenge (recommended for public clients). */
  codeChallenge?: string;
  /** PKCE method when `codeChallenge` is set. */
  codeChallengeMethod?: 'S256' | 'plain';
}

Defined in packages/sdk/src/connector/auth.ts.

OAuthTokens (interface)

Token set returned by exchangeCode and refreshToken.

export interface OAuthTokens {
  /** Short-lived access token. */
  accessToken: string;
  /** Optional refresh token (issued only when the provider supports it). */
  refreshToken?: string;
  /** Seconds until `accessToken` expires. */
  expiresIn: number;
  /** Token type — typically `Bearer`. */
  tokenType: string;
  /** Space-separated effective scopes the provider returned. */
  scope?: string;
  /** Optional OIDC id token (when the scope set requested `openid`). */
  idToken?: string;
}

Defined in packages/sdk/src/connector/auth.ts.

OAuthUserInfo (interface)

User profile returned by getUserInfo. Keep shape minimal — providers vary wildly on optional fields.

export interface OAuthUserInfo {
  /** Provider-side stable user id. NEVER the email. */
  id: string;
  /** Verified email if available. `null` when unverified or absent. */
  email: string | null;
  /** Whether the provider asserts the email is verified. */
  emailVerified: boolean;
  /** Display name. May be `null` when the provider doesn't expose one. */
  name: string | null;
  /** Avatar URL when available. */
  avatarUrl?: string | null;
}

Defined in packages/sdk/src/connector/auth.ts.

OAuthProvider (interface)

Concrete contract every T1 auth-provider connector implements.

Implementations are responsible for vendor quirks (GitHub's separate /user/emails call, LinkedIn's R2 access token, etc); the host treats every provider through this single interface.

export interface OAuthProvider {
  /**
   * Build the authorize URL the host should redirect the user to.
   */
  getAuthorizeUrl(args: OAuthAuthorizeArgs, ctx: PluginContext): Promise<string>;
  /**
   * Exchange an authorization code for tokens. Called on the callback URL.
   */
  exchangeCode(code: string, ctx: PluginContext): Promise<OAuthTokens>;
  /**
   * Refresh an access token using a refresh token. Implementations should
   * throw if the provider has revoked the refresh token.
   */
  refreshToken(refreshToken: string, ctx: PluginContext): Promise<OAuthTokens>;
  /**
   * Fetch the user profile for `accessToken`. Result is used to upsert the
   * host-side user row and to drive auto-link / sign-up flows.
   */
  getUserInfo(accessToken: string, ctx: PluginContext): Promise<OAuthUserInfo>;
}

Defined in packages/sdk/src/connector/auth.ts.

connector/index.ts

@vincia/sdk/connector — T1 Connector capability interfaces and the defineConnector helper.

Every T1 connector exports a defineConnector<I>(...) default, where I is one of the five capability interfaces re-exported below.

ConnectorCapability (type)

The five capability strings T1 connectors may declare. Matches the connector.json manifest schema's capability enum (@vincia/sdk-types).

export type ConnectorCapability =
  | 'payment'
  | 'storage'
  | 'notification'
  | 'auth-provider'
  | 'mailbox';

Defined in packages/sdk/src/connector/index.ts.

ConnectorDef (interface)

A wired T1 connector — manifest metadata + concrete implementation. The sidecar instantiates an isolate per (buildId, connector.id) and dispatches inbound calls to implementation.<method>.

export interface ConnectorDef<I> {
  /** Manifest id (kebab-case, matches `connector.json` `id`). */
  id: string;
  /** Capability this connector advertises. */
  capability: ConnectorCapability;
  /** Connector version (semver, matches `connector.json` `version`). */
  version: string;
  /** The concrete implementation of the capability interface. */
  implementation: I;
}

Defined in packages/sdk/src/connector/index.ts.

defineConnector (function)

Identity-function helper that binds a connector definition to a capability interface. Catches signature mismatches at compile time — implementation must satisfy I exactly.

@example import { defineConnector } from '@vincia/sdk/connector'; import type { PaymentProvider } from '@vincia/sdk/connector';

export default defineConnector<PaymentProvider>({ id: 'phonepe', capability: 'payment', version: '1.0.0', implementation: { async createIntent(args, ctx) { ... }, async capture(id, ctx) { ... }, async refund(id, amount, ctx) { ... }, async verifyWebhook(payload, sig, ctx) { ... }, }, });

export function defineConnector<I>(def: ConnectorDef<I>): ConnectorDef<I>

Defined in packages/sdk/src/connector/index.ts.

connector/mailbox.ts

Mailbox provider capability interface for T1 mailbox connectors.

A connector with capability: 'mailbox' implements this interface. Used by the host's mailbox bundle (inbox + compose widgets) to talk to IMAP, Gmail API, Microsoft Graph, etc.

MailboxCreds (interface)

Credentials passed to connect. The exact shape is provider-defined (OAuth tokens for Gmail, host+port+password for IMAP, etc) — implementations cast to their own typed shape.

export interface MailboxCreds {
  /** Provider-defined credential bag. */
  [key: string]: unknown;
}

Defined in packages/sdk/src/connector/mailbox.ts.

OutgoingMessage (interface)

Outgoing message shape for send.

export interface OutgoingMessage {
  to: string[];
  cc?: string[];
  bcc?: string[];
  subject: string;
  /** Plain-text body. */
  text?: string;
  /** HTML body. At least one of `text`/`html` must be set. */
  html?: string;
  /** Optional in-reply-to message id for threading. */
  inReplyTo?: string;
  /** Optional attachment list. Each attachment carries inline base64 bytes. */
  attachments?: Array<{
    filename: string;
    /** Base64-encoded content. */
    content: string;
    contentType?: string;
  }>;
}

Defined in packages/sdk/src/connector/mailbox.ts.

MailboxProvider (interface)

Concrete contract every T1 mailbox connector implements.

export interface MailboxProvider {
  /**
   * Bind a credential bag to a host-side account id. The returned `accountId`
   * is what the host stores for later sync/send calls.
   */
  connect(creds: MailboxCreds, ctx: PluginContext): Promise<{ accountId: string }>;
  /**
   * Pull new messages for `accountId` and persist them through the host's
   * mailbox writes. Returns the count of newly-ingested messages for log
   * surfacing.
   */
  sync(accountId: string, ctx: PluginContext): Promise<{ newMessages: number }>;
  /**
   * Send an outgoing message via `accountId`'s provider.
   */
  send(message: OutgoingMessage, ctx: PluginContext): Promise<{ messageId: string }>;
}

Defined in packages/sdk/src/connector/mailbox.ts.

connector/notification.ts

Notification channel capability interface for T1 connectors.

A connector with capability: 'notification' implements this interface. The channel sub-type (email / sms / push / etc) is internal config of the connector — the host treats every notification connector through this single interface.

NotificationMessage (interface)

Outgoing message shape. Channel-specific fields (subject for email, "from" for SMS, etc) belong on metadata; the connector reads what it needs.

export interface NotificationMessage {
  /** Recipient address (email, phone, push token, etc — channel-defined). */
  to: string;
  /** Plain-text body. For HTML email, use `metadata.html`. */
  body: string;
  /** Optional subject line (email/push) or template id (transactional channels). */
  subject?: string;
  /** Channel-specific extras. */
  metadata?: Record<string, unknown>;
}

Defined in packages/sdk/src/connector/notification.ts.

DeliveryStatus (interface)

Delivery status reported back to the host. Returned by verifyDelivery.

export interface DeliveryStatus {
  /** `delivered` is terminal-success; `bounced` and `failed` are terminal-fail. */
  state: 'queued' | 'sent' | 'delivered' | 'bounced' | 'failed';
  /** Provider-side reason on failure. */
  reason?: string;
  /** When the provider observed this state. */
  updatedAt: string;
}

Defined in packages/sdk/src/connector/notification.ts.

NotificationChannel (interface)

Concrete contract every T1 notification connector implements.

export interface NotificationChannel {
  /**
   * Send `message`. Returns the provider's message id so the host can
   * later call {@link verifyDelivery} or correlate inbound delivery events.
   */
  send(message: NotificationMessage, ctx: PluginContext): Promise<{ messageId: string }>;
  /**
   * Poll the provider for delivery status. Used when the channel does not
   * push delivery webhooks (or as a fallback).
   */
  verifyDelivery(messageId: string, ctx: PluginContext): Promise<DeliveryStatus>;
}

Defined in packages/sdk/src/connector/notification.ts.

connector/payment.ts

Payment capability interface for T1 connectors.

A connector with capability: 'payment' implements this interface. The sidecar dispatches checkout / capture / refund / webhook flows through these methods.

PaymentIntent (interface)

The intent record returned by createIntent and capture. Mirrors the common shape used by Stripe / Razorpay / PhonePe checkout APIs.

export interface PaymentIntent {
  /** Provider-side intent id. Persisted on the order. */
  id: string;
  /** Hosted-checkout URL to send the buyer to. */
  checkoutUrl: string;
  /** Settlement state. */
  status: 'pending' | 'succeeded' | 'failed';
  /** Amount in minor units (paise / cents). */
  amount: number;
  /** ISO-4217 currency code. */
  currency: string;
}

Defined in packages/sdk/src/connector/payment.ts.

CreatePaymentIntentArgs (interface)

Args for createIntent. order_id lets the host correlate the eventual webhook back to the originating order without trusting metadata.

export interface CreatePaymentIntentArgs {
  /** Amount in minor units (paise / cents). */
  amount: number;
  /** ISO-4217 currency code. */
  currency: string;
  /** Optional buyer email — providers may use for receipts. */
  customer_email?: string;
  /** Host-side order id; round-tripped via webhook metadata. */
  order_id: string;
  /** Free-form provider metadata. Always string-valued (provider constraint). */
  metadata?: Record<string, string>;
}

Defined in packages/sdk/src/connector/payment.ts.

PaymentProvider (interface)

Concrete contract every T1 payment connector implements. The sidecar passes a fresh {@link PluginContext} on every call (per-invocation trace id, tenant id, scoped secrets/outbound/storage views).

export interface PaymentProvider {
  /**
   * Create a payment intent. Called when the buyer clicks "pay".
   * Implementations must declare `outbound:<provider-host>` scope and
   * `secret:<api_key>`-style scope for any credential reads.
   */
  createIntent(args: CreatePaymentIntentArgs, ctx: PluginContext): Promise<PaymentIntent>;
  /**
   * Capture an authorised intent. Idempotent on the same intent id.
   */
  capture(intentId: string, ctx: PluginContext): Promise<void>;
  /**
   * Refund an amount (full or partial) against a captured intent.
   *
   * @param amount Refund amount in minor units; must be ≤ intent amount.
   */
  refund(intentId: string, amount: number, ctx: PluginContext): Promise<void>;
  /**
   * Verify a webhook signature. Sidecar dispatches inbound webhooks through
   * here before persisting the event. Return `false` on signature mismatch —
   * the sidecar will 401 the request.
   */
  verifyWebhook(payload: unknown, signature: string, ctx: PluginContext): Promise<boolean>;
}

Defined in packages/sdk/src/connector/payment.ts.

connector/storage.ts

Storage capability interface for T1 connectors.

A connector with capability: 'storage' implements this interface. The sidecar routes blob put/get/delete/list/presign operations through it.

StorageProvider (interface)

Concrete contract every T1 storage connector implements (S3, R2, GCS, etc).

export interface StorageProvider {
  /**
   * Upload bytes to `key`. The returned URL is provider-resolved (e.g. an
   * `https://bucket.s3...` URL); host code persists it on the row that
   * referenced the upload.
   */
  put(key: string, content: ReadableStream, ctx: PluginContext): Promise<{ url: string }>;
  /**
   * Download bytes for `key`. Stream is returned for large objects; consume
   * via the Web Streams API.
   */
  get(key: string, ctx: PluginContext): Promise<ReadableStream>;
  /**
   * Delete the object at `key`. No-op if absent.
   */
  delete(key: string, ctx: PluginContext): Promise<void>;
  /**
   * List keys under `prefix`. Caps and pagination are provider-specific —
   * implementations should fetch up to a reasonable bound (e.g. 1000).
   */
  list(prefix: string, ctx: PluginContext): Promise<string[]>;
  /**
   * Issue a presigned URL the client can use directly for `key`.
   *
   * @param expiresIn Lifetime in seconds. Implementations should clamp to
   *   the provider's max.
   */
  presignUrl(key: string, expiresIn: number, ctx: PluginContext): Promise<string>;
}

Defined in packages/sdk/src/connector/storage.ts.

@vincia/sdk/workflow

workflow/index.ts

@vincia/sdk/workflow — T2 Workflow Node author surface.

defineStep (function)

Identity-function helper that binds a workflow step definition to its input/output types. Inference flows from inputs.__t and outputs.__t to the execute signature, so contributors get a typed input and a type-checked return value.

@example import { defineStep } from '@vincia/sdk/workflow';

export default defineStep({ id: 'send-receipt', version: '1.0.0', inputs: { type: 'object', required: ['orderId'], properties: { orderId: { type: 'string' } }, }, outputs: { type: 'object', properties: { messageId: { type: 'string' } }, }, async execute(input, ctx) { // input.orderId is typed as string const order = await ctx.storage.get('orders', input.orderId); // ... return { messageId: 'abc' }; }, });

export function defineStep<I, O>(def: WorkflowStepDef<I, O>): WorkflowStepDef<I, O>

Defined in packages/sdk/src/workflow/index.ts.

workflow/types.ts

Types for @vincia/sdk/workflow — T2 Workflow Node step contracts.

SchemaDef (interface)

Light JSON-schema-shaped descriptor of an input or output type. Mirrors the minimal subset of JSON Schema the host validator enforces today. Use the generic T to thread the TS type through to the step's execute signature.

@typeParam T The TypeScript shape the schema describes.

export interface SchemaDef<T> {
  /** Top-level JSON type. */
  type: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
  /** Property descriptors (when `type === 'object'`). */
  properties?: Record<string, SchemaDef<unknown>>;
  /** Required property names (when `type === 'object'`). */
  required?: string[];
  /** Item schema (when `type === 'array'`). */
  items?: SchemaDef<unknown>;
  /** Closed-set enum constraint. */
  enum?: readonly unknown[];
  /** String format hint (`email`, `uri`, etc). Validator-honoured. */
  format?: string;
  /** Free-form description shown to designers wiring the step. */
  description?: string;
  /**
   * Compile-time anchor so `SchemaDef<MyType>` is non-assignable to
   * `SchemaDef<OtherType>`. Never present at runtime.
   * @internal
   */
  readonly __t?: T;
}

Defined in packages/sdk/src/workflow/types.ts.

WorkflowContext (interface)

ctx passed to a workflow step's execute. Mirrors PluginContext plus workflow-only state (variables and event).

export interface WorkflowContext extends PluginContext {
  /** Outbound HTTP (manifest-scoped). */
  outbound: VinciaOutbound;
  /** Collection storage (manifest-scoped). */
  storage: VinciaStorage;
  /** Secret reads (manifest-scoped). */
  secrets: VinciaSecrets;
  /** Structured logging tagged with workflow_run id automatically. */
  log: VinciaLog;
  /** Per-run variable bag — read/write keys carried across steps. */
  variables: WorkflowVariables;
  /** Custom event bus for `event:publish:<name>` scope holders. */
  event: WorkflowEvents;
}

Defined in packages/sdk/src/workflow/types.ts.

WorkflowVariables (interface)

ctx.variables — per-run shared state. Variable names are validated by the host against the workflow's declared variable schema.

export interface WorkflowVariables {
  get<T = unknown>(key: string): Promise<T | null>;
  set(key: string, value: unknown): Promise<void>;
}

Defined in packages/sdk/src/workflow/types.ts.

WorkflowEvents (interface)

ctx.event — publish custom events. Requires event:publish:<name> scope declared in the workflow node manifest.

export interface WorkflowEvents {
  publish(name: string, payload: unknown): Promise<void>;
}

Defined in packages/sdk/src/workflow/types.ts.

WorkflowStepDef (interface)

A wired T2 workflow step — metadata + I/O schemas + execute.

@typeParam Input The validated input shape (matches inputs schema). @typeParam Output The validated output shape (matches outputs schema).

export interface WorkflowStepDef<Input, Output> {
  /** Manifest id (kebab-case, matches `workflow-node.json` `id`). */
  id: string;
  /** Step version (semver). */
  version: string;
  /** JSON-shaped descriptor of the input type. */
  inputs: SchemaDef<Input>;
  /** JSON-shaped descriptor of the output type. */
  outputs: SchemaDef<Output>;
  /**
   * Execute the step. The host guarantees `input` satisfies `inputs` and
   * validates the returned value against `outputs`.
   */
  execute(input: Input, ctx: WorkflowContext): Promise<Output>;
}

Defined in packages/sdk/src/workflow/types.ts.

@vincia/sdk/widget

widget/hooks.ts

Hooks for T3 widget authors. These run inside the widget's iframe; the bridge (./iframe-bridge.ts) forwards every call to the parent tenant-runtime, which enforces manifest scopes before honouring them.

The hooks read their bridge from the iframe-local singleton installed by the widget runner (mountBridge in ./iframe-bridge.ts). Production code goes through mountBridge; unit tests should install a stub via the same function (see test/widget-hooks.test.ts).

UseStorageResult (interface)

Result shape returned by useStorage. Mirrors the SWR / TanStack Query { data, loading, error } contract.

export interface UseStorageResult<T> {
  /** Most-recent successful result, or `[]` before the first reply. */
  data: T[];
  /** True while a fetch is in flight. */
  loading: boolean;
  /** Most-recent error, or `null` once a subsequent fetch succeeds. */
  error: Error | null;
  /** Force-refetch the query with the same args. */
  refetch(): void;
}

Defined in packages/sdk/src/widget/hooks.ts.

WorkflowTrigger (interface)

The handle returned by useWorkflow. Mirrors vincia.workflow.* so widget code reads the same API surface as connector code.

export interface WorkflowTrigger {
  trigger(name: string, payload: unknown): Promise<{ runId: string }>;
}

Defined in packages/sdk/src/widget/hooks.ts.

VinciaHandle (interface)

The handle returned by useVincia. Exposes the subset of vincia. that makes sense inside an iframe — outbound, log, metrics, secrets, workflow, crypto. Storage uses the dedicated useStorage hook to take advantage of built-in subscriptions; raw vincia.storage. is not exposed via this hook.

export interface VinciaHandle {
  ctx: VinciaWidgetContext;
  outbound: { fetch(url: string | URL, init?: RequestInit): Promise<Response> };
  log: {
    info(m: string, a?: Record<string, unknown>): void;
    warn(m: string, a?: Record<string, unknown>): void;
    error(m: string, a?: Record<string, unknown>): void;
  };
  metrics: {
    increment(n: string, v?: number, t?: Record<string, string>): void;
    timing(n: string, ms: number, t?: Record<string, string>): void;
  };
  secrets: VinciaSecrets;
  workflow: VinciaWorkflow;
  crypto: VinciaCrypto;
}

Defined in packages/sdk/src/widget/hooks.ts.

useVincia (function)

Access the per-iframe Vincia handle. Returns a stable handle once the parent's vincia:init handshake has resolved; before that the hook suspends rendering by returning null — widget code should branch on handle === null to render a loading state.

Requires no manifest scope; every iframe receives a handle.

export function useVincia(): VinciaHandle | null

Defined in packages/sdk/src/widget/hooks.ts.

useStorage (function)

Subscribe to a list query against a collection. Re-fetches when collection or query change (compared by JSON-structural equality). Requires read:collection:<slug> scope.

@param collection Collection slug — must match a read:collection:<slug> scope. @param query Optional filter/sort/paginate. Re-runs on change.

export function useStorage<T = unknown>(collection: string, query?: Query): UseStorageResult<T>

Defined in packages/sdk/src/widget/hooks.ts.

useWorkflow (function)

Access the workflow trigger handle. Requires workflow:trigger:<name> scope declared in the widget pack manifest for any name the widget triggers at runtime.

export function useWorkflow(): WorkflowTrigger

Defined in packages/sdk/src/widget/hooks.ts.

useConfig (function)

Access the typed widget config block from the page schema. The shape is whatever the widget's configSchema describes (constrained at type level via the generic Config). The config is delivered alongside vincia:init; before that the hook returns null.

export function useConfig<Config = unknown>(): Config | null

Defined in packages/sdk/src/widget/hooks.ts.

widget/iframe-bridge.ts

postMessage RPC framework for T3 widgets.

T3 widget bundles render inside an iframe sandbox. The useVincia/ useStorage/useWorkflow hooks bridge to the parent tenant-runtime via this protocol — the parent enforces scopes before honouring the call.

Protocol shape (frozen at v1.0): parent → iframe: { type: 'vincia:init', context, config } iframe → parent: { type: 'vincia:call', id, namespace, method, args } parent → iframe: { type: 'vincia:reply', id, ok: true, value } parent → iframe: { type: 'vincia:reply', id, ok: false, error: { message } }

P4-S4 ships the iframe side of this protocol as a working postMessage client. P5-S2 owns the parent side (scope enforcement, dispatch to Anyapp / sidecar). The two halves are coordinated only by the message shapes above — no shared state.

BridgeInitMessage (interface)

Init payload the parent sends once on iframe load. The iframe waits for this before resolving bridge.ready and rendering any hook output.

export interface BridgeInitMessage {
  type: 'vincia:init';
  context: VinciaWidgetContext;
  /** Widget-specific config from the page schema. */
  config: unknown;
}

Defined in packages/sdk/src/widget/iframe-bridge.ts.

BridgeCallMessage (interface)

Hook call from inside the iframe to the parent.

export interface BridgeCallMessage {
  type: 'vincia:call';
  /** Caller-allocated id, echoed back on the reply. */
  id: string;
  /** Namespace under `vincia.*` (e.g. `'storage'`). */
  namespace: string;
  /** Method on that namespace (e.g. `'list'`). */
  method: string;
  /** Method args as a tuple, JSON-serialised. */
  args: unknown[];
}

Defined in packages/sdk/src/widget/iframe-bridge.ts.

BridgeReplyMessage (type)

Reply from the parent to a call. ok: true carries value; ok: false carries error.message. The id matches the originating call.

export type BridgeReplyMessage =
  | { type: 'vincia:reply'; id: string; ok: true; value: unknown }
  | { type: 'vincia:reply'; id: string; ok: false; error: { message: string } };

Defined in packages/sdk/src/widget/iframe-bridge.ts.

BridgeMessage (type)

Union of every message shape that may flow on the bridge. Discrimination is via the literal type field.

export type BridgeMessage = BridgeInitMessage | BridgeCallMessage | BridgeReplyMessage;

/**
 * The widget-side context the parent injects on init. Includes the same
 * trace ids as `PluginContext` plus widget-specific framing.
 */
export interface VinciaWidgetContext {
  build_id: string;

Defined in packages/sdk/src/widget/iframe-bridge.ts.

VinciaWidgetContext (interface)

The widget-side context the parent injects on init. Includes the same trace ids as PluginContext plus widget-specific framing.

export interface VinciaWidgetContext {
  build_id: string;
  tenant_id: string;
  user_id?: string;
  trace_id: string;
  /** The widget id this iframe is rendering. */
  widget_id: string;
  /** Manifest version of the widget bundle. */
  widget_version: string;
}

Defined in packages/sdk/src/widget/iframe-bridge.ts.

BridgeOptions (interface)

Optional configuration for {@link createBridge}. Defaults match the production iframe layout (window.parent is the target; window is the message source).

export interface BridgeOptions {
  /**
   * Where call messages should be posted to. Defaults to `window.parent`.
   * Test code may pass a `MessagePort` mock or a stand-in `Window`.
   */
  target?: BridgeTarget | null;
  /**
   * Event source that receives reply + init messages. Defaults to `window`.
   * Test code may pass a `MessagePort` or `EventTarget`.
   */
  source?: BridgeSource;
  /**
   * Allowed origin for the parent. When set, init/reply messages from a
   * different origin are ignored. Defaults to `'*'` (any origin) — the
   * parent enforces strict origin checks on its side, and the iframe is
   * sandboxed by the host.
   */
  parentOrigin?: string;
  /**
   * Id allocator for outgoing calls. Defaults to a counter prefixed with
   * `'c'`. Pass a deterministic one in tests.
   */
  idFactory?: () => string;
}

Defined in packages/sdk/src/widget/iframe-bridge.ts.

BridgeTarget (interface)

Minimal contract the bridge needs from its outbound target. Window and MessagePort both satisfy this shape; tests may pass a stub.

export interface BridgeTarget {
  postMessage(message: unknown, targetOriginOrOptions?: string | { transfer?: unknown[] }): void;
}

Defined in packages/sdk/src/widget/iframe-bridge.ts.

BridgeSource (interface)

Minimal contract the bridge needs from its inbound source.

export interface BridgeSource {
  addEventListener(type: 'message', listener: (ev: MessageEvent) => void): void;
  removeEventListener(type: 'message', listener: (ev: MessageEvent) => void): void;
}

Defined in packages/sdk/src/widget/iframe-bridge.ts.

Bridge (interface)

Iframe-side bridge handle. Hook implementations close over a singleton instance set up by {@link mountBridge} on widget mount.

export interface Bridge {
  /**
   * Resolves once the parent has sent the `vincia:init` handshake. Reads on
   * `context` / `config` may begin only after this resolves.
   */
  readonly ready: Promise<{ context: VinciaWidgetContext; config: unknown }>;
  /**
   * Synchronously read the init payload, or `null` if the parent hasn't
   * sent it yet. Hooks branch on this to render a loading state on first
   * paint.
   */
  initSnapshot(): { context: VinciaWidgetContext; config: unknown } | null;
  /**
   * Issue an RPC. Resolves with the parent's `value` or rejects with the
   * parent's error message. The id space is private to the bridge.
   */
  call<T = unknown>(namespace: string, method: string, args: unknown[]): Promise<T>;
  /**
   * Tear down the listener + reject every pending call. The bridge cannot
   * be re-used after `dispose`.
   */
  dispose(): void;
}

Defined in packages/sdk/src/widget/iframe-bridge.ts.

createBridge (function)

Create a bridge bound to a target window / source event target. Production code should call {@link mountBridge} once per iframe mount; this lower-level factory exists for tests + advanced embedding scenarios.

export function createBridge(options: BridgeOptions =

Defined in packages/sdk/src/widget/iframe-bridge.ts.

mountBridge (function)

Install bridge as the active iframe bridge. The widget runner calls this once on iframe mount; tests may call it to install a stub.

@internal Reserved for the widget runner; contributors should use the useVincia / useStorage / useWorkflow hooks instead.

export function mountBridge(bridge: Bridge): void

Defined in packages/sdk/src/widget/iframe-bridge.ts.

unmountBridge (function)

Tear down the current bridge installation. Idempotent.

@internal

export function unmountBridge(): void

Defined in packages/sdk/src/widget/iframe-bridge.ts.

getCurrentBridge (function)

Lookup the currently-mounted bridge. Throws a contributor-friendly error when no bridge is installed (i.e. hooks called outside the widget iframe).

@internal

export function getCurrentBridge(): Bridge

Defined in packages/sdk/src/widget/iframe-bridge.ts.

widget/index.ts

@vincia/sdk/widget — T3 Widget Pack author surface.

Widget code runs inside an iframe sandbox. The hooks bridge to the parent tenant-runtime via iframe-bridge.ts; the parent enforces manifest scopes before honouring each call.

NOTE: This module declares ambient JSX.Element so contributor code can import these types without depending on a specific React version. When the widget runner lands (P4-S6), it will provide the concrete React binding and a <react>-backed JSX.Element resolves naturally.

WidgetElement (type)

Widget-side renderable. Intentionally minimal so the SDK does not pin a React version onto every plugin author. Real widgets render React elements; the type is structurally compatible with React.ReactElement.

export type WidgetElement = unknown;

/**
 * Auth gate for a widget. Mirrors the `AuthRule` `$def` in
 * `@vincia/sdk-types/shared-fields.json`.
 */
export type AuthRule = 'public' | 'signed-in' | 'role-based' | 'creator-only';

Defined in packages/sdk/src/widget/index.ts.

AuthRule (type)

Auth gate for a widget. Mirrors the AuthRule $def in @vincia/sdk-types/shared-fields.json.

export type AuthRule = 'public' | 'signed-in' | 'role-based' | 'creator-only';

/**
 * Capability declarations the widget makes. Used by the LLM gate +
 * super-admin reviewer to know what the widget needs at the host level.
 */
export interface WidgetCapabilities {
  /** Widget needs to be wired to forms (renders inside form contexts). */
  formAware?: boolean;

Defined in packages/sdk/src/widget/index.ts.

WidgetCapabilities (interface)

Capability declarations the widget makes. Used by the LLM gate + super-admin reviewer to know what the widget needs at the host level.

export interface WidgetCapabilities {
  /** Widget needs to be wired to forms (renders inside form contexts). */
  formAware?: boolean;
  /** Widget supports SSR-rendered initial markup. */
  ssr?: boolean;
  /** Widget exposes a chrome region (header/footer/aside). */
  chromeRegion?: 'parent-public' | 'parent-private' | 'child-public' | 'child-private' | 'isolated';
}

Defined in packages/sdk/src/widget/index.ts.

WidgetDef (interface)

Manifest-level widget descriptor. Compile-time companion to widget-pack.json — fields here mirror the manifest entries the widget pack declares for each widget.

export interface WidgetDef<Config = unknown> {
  /** Widget kind / id (kebab-case, matches `widget-pack.json` `widgets[].id`). */
  id: string;
  /** Widget version (semver). */
  version: string;
  /** Marketplace category (e.g. `'commerce'`, `'forms'`, `'layout'`). */
  category: string;
  /** Compile-time schema for the widget's config block. */
  configSchema: SchemaDef<Config>;
  /** Auth gate. Defaults to `'public'` when omitted. */
  authRule?: AuthRule;
  /** Capability declarations consumed by the host. */
  capabilities: WidgetCapabilities;
  /** Server-rendered initial markup. Returns a React-compatible element. */
  render(config: Config): WidgetElement;
}

Defined in packages/sdk/src/widget/index.ts.

defineWidget (function)

Identity-function helper that binds a widget definition to its config type. Inference flows from configSchema.__t into the render signature.

@example import { defineWidget } from '@vincia/sdk/widget';

export default defineWidget({ id: 'phonepe-checkout', version: '1.0.0', category: 'commerce', configSchema: { type: 'object', required: ['orderId'], properties: { orderId: { type: 'string' } }, }, capabilities: { ssr: true }, render(config) { // config.orderId typed as string return <CheckoutForm orderId={config.orderId} />; }, });

export function defineWidget<Config>(def: WidgetDef<Config>): WidgetDef<Config>

Defined in packages/sdk/src/widget/index.ts.

@vincia/sdk/blueprint

blueprint/index.ts

@vincia/sdk/blueprint — T0 Blueprint manifest types + the defineBlueprint helper.

Runtime validation against the JSON schema is provided by @vincia/sdk-types (blueprintSchema); this package exposes the TS companion + a type-narrowing identity function.

defineBlueprint (function)

Identity-function helper that narrows a blueprint manifest object to the BlueprintManifest shape at compile time. Inference is shallow; the JSON schema still authoritatively validates at publish time.

@example import { defineBlueprint } from '@vincia/sdk/blueprint';

export default defineBlueprint({ id: 'event-portal', version: '1.0.0', tier: 'T0', name: 'Event Portal', archetype: 'portal', platform_contract_version: '^1.0', monetization: 'free', views: [...], collections: [...], requires_plugins: [], });

export function defineBlueprint<M extends BlueprintManifest>(manifest: M): M

Defined in packages/sdk/src/blueprint/index.ts.

blueprint/types.ts

Types for @vincia/sdk/blueprint — T0 Blueprint manifest authoring.

Mirrors the field shape of blueprint.json in @vincia/sdk-types but exposes a TypeScript-friendly companion. The JSON schema is the source of truth at runtime; this type is the source of truth at compile time.

BlueprintField (interface)

Field on a blueprint-declared collection. Open shape (extensible: true in the JSON schema) so blueprint authors can add storage-engine-specific properties.

export interface BlueprintField {
  name: string;
  type: string;
  /** Whether the field is required on writes. */
  required?: boolean;
  /** Default value (literal). */
  default?: unknown;
  /** Free-form description shown in admin UI. */
  description?: string;
  /** Engine-specific extras (open object — extensible). */
  [extra: string]: unknown;
}

Defined in packages/sdk/src/blueprint/types.ts.

BlueprintCollection (interface)

Collection declared by a blueprint. Auto-created on bootstrap.

export interface BlueprintCollection {
  slug: string;
  fields: BlueprintField[];
  /** Extensible: collection-level engine options. */
  [extra: string]: unknown;
}

Defined in packages/sdk/src/blueprint/types.ts.

BlueprintWidget (interface)

Widget reference inside a BlueprintView. The shape is intentionally open — blueprint authors place full widget config blocks here, and the host passes them through to the rendered page.

export interface BlueprintWidget {
  /** Widget kind / id (matches a registered widget). */
  kind: string;
  /** Optional widget data block — shape depends on the widget. */
  data?: Record<string, unknown>;
  /** Layout slot the widget renders into. */
  slot?: string;
  /** Free-form additional keys. */
  [extra: string]: unknown;
}

Defined in packages/sdk/src/blueprint/types.ts.

BlueprintView (interface)

View (route) declared by a blueprint. The host generates an admin / public route per view at install time.

export interface BlueprintView {
  /** URL path (matches `ViewDef.path` pattern: `^/[a-zA-Z0-9/_:.\[\]-]*$`). */
  path: string;
  /** Widget tree to render. */
  widgets: BlueprintWidget[];
  /** Free-form additional keys (title, gate, layout, etc — extensible). */
  [extra: string]: unknown;
}

Defined in packages/sdk/src/blueprint/types.ts.

PluginRequirement (interface)

Plugin-to-plugin requirement. Carries an id + version range; optional capability lets a blueprint require a capability without naming the concrete connector ("any payment connector ≥ 1.0").

export interface PluginRequirement {
  /** Plugin id (e.g. `'phonepe'`). */
  id: string;
  /** Semver range (e.g. `'^1.0'`). */
  version: string;
  /** Optional capability hint (e.g. `'payment'`, `'auth-provider'`). */
  capability?: string;
  /** When true, the host installs the blueprint even if this plugin is missing. */
  optional?: boolean;
}

Defined in packages/sdk/src/blueprint/types.ts.

ExternalDependency (interface)

External (vendor / contributor / self-contained) dependency the blueprint relies on. Surfaced in the marketplace listing so end-users can confirm they have the credentials available before installing.

export interface ExternalDependency {
  /** Service name (e.g. `'PhonePe'`). */
  service: string;
  /** Vendor host (e.g. `'api.phonepe.com'`). */
  host: string;
  /** Who operates the integration. */
  operator: 'vendor' | 'contributor' | 'self-contained';
  /** Whether the dependency is required at install time. */
  required: boolean;
  /** Free-form description shown to end-users. */
  purpose: string;
}

Defined in packages/sdk/src/blueprint/types.ts.

BlueprintMonetization (type)

Blueprint monetization. T0 supports paid (price_cents + currency required).

export type BlueprintMonetization =
  | { kind: 'free' }
  | { kind: 'paid'; price_cents: number; currency: string };

Defined in packages/sdk/src/blueprint/types.ts.

BlueprintManifest (interface)

The TypeScript companion to blueprint.json. Validated at publish time by the manifest schema from @vincia/sdk-types.

export interface BlueprintManifest {
  id: string;
  version: string;
  tier: 'T0';
  name: string;
  description?: string;
  archetype: 'website' | 'portal';
  signupEnabled?: boolean;
  views: BlueprintView[];
  collections: BlueprintCollection[];
  modules?: string[];
  requires_plugins: PluginRequirement[];
  platform_contract_version: string;
  monetization: 'free' | 'paid';
  price_cents?: number;
  currency?: string;
  externalDependencies?: ExternalDependency[];
}

Defined in packages/sdk/src/blueprint/types.ts.

blueprint/validators.ts

Structural validators for BlueprintManifest.

The authoritative schema is blueprintSchema in @vincia/sdk-types (ajv-validated by the CLI + the LLM gate). This module provides a zero-dep TypeScript validator for plugin self-tests + contributor pre-publish checks — it mirrors the required fields, the closed enums, and the conditional monetization = paid → price_cents + currency rule from the JSON schema. It does NOT cover every shared-fields constraint (pattern matches for PluginId, Semver, Currency); those are enforced by the publish-time ajv pass.

Use this for fast in-code validation; rely on the manifest schema for the contractual gate.

BlueprintValidationResult (type)

Result of a structural validation pass. ok: true guarantees the input has every required key with the right shape; further constraint checks (pattern matches, etc) still happen at publish time.

export type BlueprintValidationResult =
  | { ok: true; manifest: BlueprintManifest }
  | { ok: false; errors: BlueprintValidationError[] };

Defined in packages/sdk/src/blueprint/validators.ts.

BlueprintValidationError (interface)

Single validation failure. path uses JSON-pointer-style segments separated by .. expected describes the invariant violated.

export interface BlueprintValidationError {
  /** Dotted path to the offending property (e.g. `'views[0].path'`). */
  path: string;
  /** Human-readable description of the rule that failed. */
  message: string;
}

Defined in packages/sdk/src/blueprint/validators.ts.

validateBlueprintManifest (function)

Validate the structural shape of a {@link BlueprintManifest}. Use the narrowing form when you need TypeScript to refine the type:

@example const result = validateBlueprintManifest(input); if (result.ok) { // result.manifest is typed as BlueprintManifest } else { for (const err of result.errors) console.error(err.path, err.message); }

export function validateBlueprintManifest(value: unknown): BlueprintValidationResult

Defined in packages/sdk/src/blueprint/validators.ts.

isBlueprintManifest (function)

Boolean type guard form. Use {@link validateBlueprintManifest} when you need diagnostic error messages.

export function isBlueprintManifest(value: unknown): value is BlueprintManifest

Defined in packages/sdk/src/blueprint/validators.ts.