Today Canvas Kit
SDK packages

@todayai-labs/tck

Widget-author SDK. Types, hooks, primitives, patch helpers. Compiled INTO the widget bundle.

The widget-author SDK. Widget source code (the .tck.tsx file) imports from this package; the bundler externalises it. Every TCK widget compiles against @todayai-labs/tck.

The full surface is split into 5 subpaths plus a barrel re-export. Subpath imports keep the bundle's import graph minimal; the barrel is for ergonomics — both resolve to the same physical tck.mjs via the host import map, so module identity is preserved across the boundary (see DEFAULT_GROUPS).

Subpaths

@todayai-labs/tck/manifest

Manifest schema, validators, and the externals whitelist that bundler + host both pull from.

  • Types: WidgetManifest, WidgetSize, WidgetPermission, WidgetSource, JsonValue, JsonObject, JsonArray, GridPosition, WidgetInstanceId, TodayPageDescriptor, TodayPageItem, HostOnlySpec, ParsedSize, TckExternalSpecifier.
  • Constants: TCK_EXTERNAL_SPECIFIERS, ALL_WIDGET_SIZES, HOST_ONLY_SPECS.
  • Predicates / parsers: validateManifest, isWidgetSize, isAutoHeightSize, isHostOnlySpec, isTckExternalSpecifier, isSizeSupported, parseSize, manifestIdToScopeSlug.
  • Errors: InvalidManifestError, InvalidSizeError.

@todayai-labs/tck/patch

RFC-6902 JSON Patch primitives and the envelope wire shape.

  • Operations: applyPatch, applyOp — pure functions; produce new immutable docs.
  • Pointer: parsePointer, formatPointer — JSON Pointer (RFC 6901).
  • Envelope: PatchEnvelope, PatchAck, newPatchId.
  • Errors: PatchError, PointerError.

@todayai-labs/tck/agent

Wire types for the bidirectional a2ui agent protocol.

  • Types: AgentEnvelope, AgentMessage (discriminated union: state.change / patch.send / host.add-widget / host.move-widget / host.remove-widget / agent.suggestion / agent.pin / error), Suggestion.
  • Version: A2UI_PROTOCOL_VERSION.

@todayai-labs/tck/hooks

The widget-facing hooks family. All consume WidgetCtx from @todayai-labs/tck/runtime via React context.

  • Doc state: useFieldState (JSON-pointer sugar), usePersistState (selector + setter).
  • Host context: useWidgetCtx (raw ctx), useCurrentWidgetSize, useVisibility, useTheme.
  • Ambient host services: useFocusTimer (host-owned focus timer snapshot or null), useMediaController (host-owned media controller snapshot or null).
  • Agent channel: useAgent (returns AgentChannel | null — null when the manifest didn't declare agent.read / agent.write), useAgentSubscription (subscribe to inbound envelopes).
  • Errors: MissingWidgetCtxError.

@todayai-labs/tck/runtime

Types for the host-provided context object.

  • Types: WidgetCtx, AgentChannel, Theme, ExpandedProps.
  • Context: WidgetCtxContext — the React context. Singleton across the host/widget boundary by TCK_EXTERNAL_SPECIFIERS resolution. (See Runtime instance semantics for why this matters.)

@todayai-labs/tck (barrel)

Re-export of the common surface above plus three families that don't live under a dedicated subpath:

  • Container offer: ContainerParams, containerParamsToQuery, parseContainerParams, InvalidContainerParamsError. See container contract.
  • Bridge (cross-window / cross-realm transport): BridgeDispatcher, BridgeEnvelope, BridgeRequest, BridgeReply, BridgePush, BridgeNotify, BridgeHandler, BridgeTransport, BridgeReplyError, isBridgeEnvelope, postMessageTransport, TCK_BRIDGE_VERSION.
  • Host control plane: HostControlEnvelope, HostControlRequest, HostControlReply, HostControlPush, HostControlInstanceSnapshot, isHostControlEnvelope.
  • ID minter: widgetInstanceId.

@todayai-labs/tck/specifiers is a special-case subpath that exports only the TCK_EXTERNAL_SPECIFIERS array as plain JS — for build tools (bundler, host import-map plugin, the scripts/build-widgets.ts parity check) that need the constant without paying for the rest of the SDK's TypeScript surface.

Constraints

  • tck-host is NOT importable from a widget. Widgets never import '@todayai-labs/tck-host' — it's host-only and is deliberately absent from the externals whitelist. The bundler rejects bundles that import it.
  • No browser storage APIs. No localStorage, no sessionStorage, no IndexedDB, no document.cookie. Persistence flows through useFieldState / usePersistState — the host's doc-store is the single channel.
  • No prefers-color-scheme reads. Theme is host-injected; see theme-injection contract.
  • No portals to document.body. Use ctx.portalTarget; see Platform ABI § Portals.

Source

On this page