Surface API
The /surface entry point defines the contract between an isolated webview contribution and The AI Platform. It does not mount a framework for you.
Mount Contract
Export a mount function that accepts an HTMLElement and TapFederatedSurfaceMountContext, then returns a TapFederatedSurfaceMount cleanup handle.
The context identifies the package, release, installation, contribution,
instance, and host origin. Interactive mounts may also receive userId, the
host-canonical control-plane user identity used by trusted MCP {userId}
storage selectors. It is not the OAuth/OIDC profile subject. Optional
workspace, channel, and conversation IDs describe the immutable instance-policy
scope and appear only when that scope provides them. Read context.owner for
the live host-selected workspace, channel, and conversation. Subscribe to
context.launches for verified context actions routed to this exact surface.
Disposable
activation-preflight mounts omit userId and do not receive an owner.
Make unmount idempotent. Remove event listeners, subscriptions, timers, framework roots, and rendered content, and settle or ignore work that finishes after cleanup.
File Handler Launches
context.userFileLaunchContext is an optional
TapFederatedSurfaceUserFileLaunchContext delivered only with the initial
mount for one host-validated file-handler launch. It contains apiVersion: 1,
an open, import, or export intent, and an opaque owner-bound file handle.
Use the handle through sdk.files; the context never exposes a native path.
Production desktop file associations launch only with the open intent. Start
Import through a user-mediated file picker so the host can apply import and
disclosure consent. Start Export from an owner-authorized surface action and
commit it through the trusted projection boundary. A native file association
does not grant import disclosure, artifact checkpoint, or export authority.
Test Lab can supply all three intent values to test each semantic path.
Successful mount preparation accepts that launch. Later OS launches create a
fresh mount instead of using an event, subscription, query parameter, or
ordinary postMessage byte channel. Clean up all launch-derived work during
unmount. The host also revokes the mount owner's handles when the frame leaves,
even if package cleanup does not run.
Throw TapFederatedSurfaceUserFileLaunchUnsupportedError only when the package
recognizes the handler contract but cannot support the selected document
version. Its reason is the
TapFederatedSurfaceUserFileLaunchUnsupportedReason value
unsupported-version or newer-version, and its stable code is
file_unsupported. This narrow failure lets the host try another eligible
handler. Validation errors, provider failures, and ordinary mount failures must
remain their original errors and must not trigger handler fallback.
Package Events
TapPackageEventPublisher exposes publish and subscribe for the declared package event channel. subscribe returns a cleanup function; call it during unmount. Event access does not confer channel, project, or navigation authority.
Surface Entropy
Use context.entropy.randomUUID() for identifiers owned by the surface instead
of reading an ambient random source. Ordinary mounts use cryptographically
strong browser UUIDs. Test Lab mounts derive a deterministic stream from the
test profile seed and exact frame identity, so the same action sequence is
repeatable while retained remounts remain distinct.
The stream belongs to the current mount context. Do not retain it after unmount, use it as secret material, or assume Test Lab UUIDs are globally random.
Host Authority
TapFederatedSurfaceHostAuthority exposes a boolean snapshot and a subscription. A candidate frame can start without authority, so wait for getSnapshot() to become true before performing host-backed effects.
Authority can be revoked while the surface remains mounted. Disable protected actions promptly and keep cleanup available regardless of the current snapshot.
Selected Owner
TapFederatedSurfaceOwner exposes the host-selected owner of the mounted realm.
Its snapshot is null until the host projects one. A per-workspace or
singleton realm can remain mounted while its selected conversation changes,
so use the subscription instead of treating the immutable mount-context scope
fields as current selection.
Context Action Launches
TapFederatedSurfaceLaunches delivers host-verified action.command
invocations to the exact package release, target, surface contribution, and
logical instance named by the manifest. The host queues the launch before it
opens or focuses the surface. The launch contains an opaque artifact reference,
not copied message, task, issue, or pull-request content.
Delivery is FIFO and at least once. The runtime acknowledges a launch only
after one subscriber resolves to true. If no subscriber handles it because
listeners return false, throw, or are absent, that launch remains pending and
prevents later launches from overtaking it. The SDK sends the acknowledgement
for you and binds it to the exact frame document. Package code cannot
acknowledge a different request or surface.
Use launch.requestId as the idempotency key for any durable effect. A launch
can be delivered again before its acknowledgement reaches the host. The
actionContributionId names the manifest action, invokedAt records the host
invocation time, and optional owner is the immutable workspace, channel, and
conversation selection captured for that invocation. Do not substitute the
live context.owner snapshot when the effect must remain bound to the original
selection.
The artifact reference expires at reference.expiresAt. Finish resolution
promptly, and treat a null artifact as an ordinary unavailable result. See
Artifact context resolution for the
reference and snapshot contract.
Package Assets
resolvePackageAssetUrl joins a canonical relative path to context.packageAssetBaseUrl and returns a URL that remains inside the descriptor-selected target directory.
Absolute paths, traversal segments, encoded separators, credentials, query strings, fragments, control characters, and non-HTTP package bases fail closed. Keep assets in the emitted target graph so integrity and portability checks can cover them.