oui-spec 0.4.0 → 0.4.1

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.
@@ -169,6 +169,7 @@ function createSurfaceRuntime(options = {}) {
169
169
  let nextHold = 1;
170
170
  const results = /* @__PURE__ */ new Map();
171
171
  const pollers = /* @__PURE__ */ new Map();
172
+ const abandon = /* @__PURE__ */ new Map();
172
173
  const listeners = /* @__PURE__ */ new Set();
173
174
  const acks = /* @__PURE__ */ new Map();
174
175
  function ackFor(requestId) {
@@ -262,6 +263,11 @@ function createSurfaceRuntime(options = {}) {
262
263
  if (key.startsWith(`${surfaceId}\0`)) {
263
264
  clearInterval(timer);
264
265
  pollers.delete(key);
266
+ abandon.get(key)?.({
267
+ code: "SURFACE_NOT_MOUNTED",
268
+ message: `Surface "${surfaceId}" left the page before its action finished, so it is no longer being followed. Check what the page shows before trying again.`
269
+ });
270
+ abandon.delete(key);
265
271
  }
266
272
  }
267
273
  }
@@ -302,7 +308,15 @@ function createSurfaceRuntime(options = {}) {
302
308
  return;
303
309
  }
304
310
  const existing = pollers.get(pollerKey);
305
- if (existing) clearInterval(existing);
311
+ if (existing) {
312
+ clearInterval(existing);
313
+ pollers.delete(pollerKey);
314
+ abandon.get(pollerKey)?.({
315
+ code: "SUPERSEDED",
316
+ message: `"${actionId}" was started again before this run finished, so only the newer run is being followed.`
317
+ });
318
+ abandon.delete(pollerKey);
319
+ }
306
320
  setObservation(
307
321
  surfaceId,
308
322
  observationId,
@@ -318,6 +332,7 @@ function createSurfaceRuntime(options = {}) {
318
332
  if (attempts > maxAttempts || Date.now() - startedAt > maxDuration) {
319
333
  clearInterval(timer);
320
334
  pollers.delete(pollerKey);
335
+ abandon.delete(pollerKey);
321
336
  setObservation(
322
337
  surfaceId,
323
338
  observationId,
@@ -331,17 +346,22 @@ function createSurfaceRuntime(options = {}) {
331
346
  return;
332
347
  }
333
348
  const entry = activeFor(surfaceId);
334
- const action = entry?.surface.actions.find((a) => a.id === actionId);
335
- if (!entry || !action?.polling?.resolve) {
349
+ if (!entry) {
336
350
  clearInterval(timer);
337
351
  pollers.delete(pollerKey);
352
+ const gone = abandon.get(pollerKey);
353
+ abandon.delete(pollerKey);
354
+ gone?.({
355
+ code: "SURFACE_NOT_MOUNTED",
356
+ message: `Surface "${surfaceId}" left the page before "${actionId}" finished, so it is no longer being followed. Check what the page shows before trying again.`
357
+ });
338
358
  return;
339
359
  }
360
+ const action = entry.surface.actions.find((a) => a.id === actionId);
361
+ const resolve = action?.polling?.resolve ?? polling.resolve;
362
+ if (!resolve) return;
340
363
  try {
341
- const r = await action.polling.resolve(
342
- dispatchResult,
343
- entry.getContext()
344
- );
364
+ const r = await resolve(dispatchResult, entry.getContext());
345
365
  setObservation(
346
366
  surfaceId,
347
367
  observationId,
@@ -354,6 +374,7 @@ function createSurfaceRuntime(options = {}) {
354
374
  if (r.done) {
355
375
  clearInterval(timer);
356
376
  pollers.delete(pollerKey);
377
+ abandon.delete(pollerKey);
357
378
  void finish(true, r.data);
358
379
  }
359
380
  } catch (err) {
@@ -366,6 +387,7 @@ function createSurfaceRuntime(options = {}) {
366
387
  }
367
388
  }, polling.intervalMs);
368
389
  pollers.set(pollerKey, timer);
390
+ abandon.set(pollerKey, (error) => void finish(false, void 0, error));
369
391
  }
370
392
  async function waitUntilSettled(since) {
371
393
  const deadline = since + settleTimeoutMs;
@@ -544,6 +566,7 @@ function createSurfaceRuntime(options = {}) {
544
566
  dispose() {
545
567
  for (const timer of pollers.values()) clearInterval(timer);
546
568
  pollers.clear();
569
+ abandon.clear();
547
570
  attach(null);
548
571
  entries.length = 0;
549
572
  observations.clear();
@@ -569,5 +592,5 @@ function toJsonSafe(value) {
569
592
  exports.createOUI = createOUI;
570
593
  exports.createSurfaceRuntime = createSurfaceRuntime;
571
594
  exports.defineSurface = defineSurface;
572
- //# sourceMappingURL=chunk-DGMKSJTY.cjs.map
573
- //# sourceMappingURL=chunk-DGMKSJTY.cjs.map
595
+ //# sourceMappingURL=chunk-GDB56ZQZ.cjs.map
596
+ //# sourceMappingURL=chunk-GDB56ZQZ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/brand.ts","../src/core/define-surface.ts","../src/core/create-oui.ts","../src/core/surface-runtime.ts"],"names":["createWebSocketTransport"],"mappings":"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","file":"chunk-GDB56ZQZ.cjs","sourcesContent":["/**\n * Nominal branding for values OUI must construct itself.\n *\n * Structural typing means any object with the right shape satisfies an\n * interface. That is how Closure Studio ended up hand-rolling OUI's transport:\n * `SocketLike` was importable, `OUITransport` was a plain interface, so an\n * integrator could satisfy every type without ever calling OUI. The result was\n * a second implementation of the wire — hardcoded namespace, re-declared\n * payload types on the server, and a dead `action:result` mapping alongside the\n * observation channel that already carried results.\n *\n * A unique symbol cannot be produced outside this module. Branding the types\n * OUI owns turns \"you should use our constructor\" into \"you cannot compile\n * without it\".\n */\n\ndeclare const OUI_BRAND: unique symbol;\n\n/** Marks a value as constructed by OUI itself. */\nexport interface OUIBranded<TKind extends string> {\n readonly [OUI_BRAND]: TKind;\n}\n\n/**\n * Attach the brand at runtime. The property does not exist at runtime — the\n * symbol is declare-only — so this is a type-level assertion with no cost.\n */\nexport function brand<TKind extends string, T>(\n value: T,\n): T & OUIBranded<TKind> {\n return value as T & OUIBranded<TKind>;\n}\n","import type {\n OUISurface,\n OUIAction,\n OUIObservation,\n OUIActivation,\n OUIActionPolling,\n JSONSchema,\n} from \"../spec/index.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\n\n/**\n * Configuration for defining an OUI surface with handlers.\n * This is the \"integration file\" an app provides — it declares both\n * the schema (what the agent sees) and the implementation (what executes).\n */\nexport interface SurfaceDefinition<TContext = unknown> {\n id: string;\n name: string;\n description: string;\n version?: string;\n activation?: OUIActivation;\n actions: ActionDefinition<TContext>[];\n observations?: ObservationDefinition[];\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Polling config with an optional resolve handler.\n * The spec's OUIActionPolling is the manifest shape (no functions).\n * The core extends it with the resolve implementation for the runtime.\n */\nexport interface ActionPollingConfig<\n TContext = unknown,\n> extends OUIActionPolling {\n /**\n * Called on each poll interval. Receives the dispatch result from the handler\n * plus the current context. Return { done: true, data } to stop polling,\n * or { done: false, data } to continue.\n */\n resolve?: (\n dispatchResult: unknown,\n context: TContext,\n ) => Promise<{ done: boolean; data: unknown }>;\n}\n\n/**\n * An action definition includes both the schema (for the agent) and\n * the handler (for execution). This is the single source of truth —\n * no separate YAML, no separate listener, no drift possible.\n */\nexport interface ActionDefinition<TContext = unknown> {\n id: string;\n description: string;\n input: JSONSchema;\n output?: JSONSchema;\n confirm?: boolean;\n async?: boolean;\n\n /**\n * Polling/subscription config for async actions.\n * After the handler returns, the OUI runtime starts polling or subscribing\n * and pushes observation updates until the operation completes.\n * Extends the spec's OUIActionPolling with an optional resolve handler.\n */\n polling?: ActionPollingConfig<TContext>;\n\n usage?: string;\n preconditions?: string;\n estimatedDuration?: string;\n tags?: string[];\n\n /**\n * The handler that executes when the agent invokes this action.\n * Receives typed params and a context object (app-specific state/utilities).\n * Returns a result that the agent sees as the tool output.\n */\n handler: (\n params: Record<string, unknown>,\n context: TContext,\n ) => Promise<ActionHandlerResult>;\n}\n\nexport interface ActionHandlerResult {\n success: boolean;\n data?: unknown;\n error?: { code: string; message: string; details?: unknown };\n /** For async actions: metadata passed to the polling resolver */\n dispatchMeta?: Record<string, unknown>;\n}\n\nexport interface ObservationDefinition {\n id: string;\n description: string;\n schema: JSONSchema;\n /** Function that returns the current observation value */\n getValue?: () => unknown;\n}\n\n/**\n * Define an OUI surface — the single entry point for integrating\n * an application feature with the OUI protocol.\n *\n * This function validates the definition and returns a typed surface\n * object that can be registered with an agent runtime or transport layer.\n *\n * @example\n * ```typescript\n * const mySurface = defineSurface({\n * id: 'my-feature',\n * name: 'My Feature',\n * description: 'Does something cool',\n * actions: [\n * {\n * id: 'do_thing',\n * description: 'Does the thing',\n * input: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },\n * handler: async (params) => {\n * const result = await doTheThing(params.name);\n * return { success: true, data: result };\n * },\n * },\n * ],\n * });\n * ```\n */\nexport function defineSurface<\n TContext = unknown,\n const TId extends string = string,\n>(\n definition: SurfaceDefinition<TContext> & { id: TId },\n): DefinedSurface<TContext> & { id: TId } {\n // Validate: no duplicate action IDs\n const actionIds = new Set<string>();\n for (const action of definition.actions) {\n if (actionIds.has(action.id)) {\n throw new Error(\n `[OUI] Duplicate action ID \"${action.id}\" in surface \"${definition.id}\"`,\n );\n }\n actionIds.add(action.id);\n }\n\n // Validate: no duplicate observation IDs\n if (definition.observations) {\n const obsIds = new Set<string>();\n for (const obs of definition.observations) {\n if (obsIds.has(obs.id)) {\n throw new Error(\n `[OUI] Duplicate observation ID \"${obs.id}\" in surface \"${definition.id}\"`,\n );\n }\n obsIds.add(obs.id);\n }\n }\n\n return brand<\"surface\", unknown>({\n ...definition,\n\n /** Extract the manifest (schema only, no handlers) for transmission to the agent runtime */\n toManifest(): OUISurface {\n return {\n id: definition.id,\n name: definition.name,\n description: definition.description,\n version: definition.version,\n activation: definition.activation,\n actions: definition.actions.map(actionToManifest),\n observations: definition.observations?.map(obsToManifest),\n metadata: definition.metadata,\n };\n },\n\n /** Execute an action by ID with the given params and context */\n async executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult> {\n const action = definition.actions.find((a) => a.id === actionId);\n if (!action) {\n return {\n success: false,\n error: {\n code: \"ACTION_NOT_FOUND\",\n message: `Action \"${actionId}\" not found on surface \"${definition.id}\"`,\n },\n };\n }\n try {\n return await action.handler(params, context);\n } catch (err) {\n return {\n success: false,\n error: {\n code: \"ACTION_EXECUTION_ERROR\",\n message: err instanceof Error ? err.message : String(err),\n },\n };\n }\n },\n\n /** Get all action IDs */\n getActionIds(): string[] {\n return definition.actions.map((a) => a.id);\n },\n\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined {\n const action = definition.actions.find((a) => a.id === actionId);\n return action?.polling;\n },\n }) as DefinedSurface<TContext> & { id: TId };\n}\n\n/** A fully defined surface with both manifest extraction and execution capabilities */\n/**\n * Branded so it can only come from `defineSurface`.\n *\n * Without the brand a plain object literal satisfies this interface\n * structurally, which is how an integrator can assemble a surface that never\n * ran defineSurface's duplicate-id checks and never produced a real manifest.\n */\nexport interface DefinedSurface<TContext = unknown>\n extends SurfaceDefinition<TContext>, OUIBranded<\"surface\"> {\n toManifest(): OUISurface;\n executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult>;\n getActionIds(): string[];\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined;\n}\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\nfunction actionToManifest<T>(action: ActionDefinition<T>): OUIAction {\n return {\n id: action.id,\n description: action.description,\n input: action.input,\n output: action.output,\n confirm: action.confirm,\n async: action.async,\n polling: action.polling,\n usage: action.usage,\n preconditions: action.preconditions,\n estimatedDuration: action.estimatedDuration,\n tags: action.tags,\n };\n}\n\nfunction obsToManifest(obs: ObservationDefinition): OUIObservation {\n return {\n id: obs.id,\n description: obs.description,\n schema: obs.schema,\n };\n}\n","/**\n * createOUI — a fixed set of surfaces announced over one socket.\n *\n * For a client whose surfaces come and go (a React app, where a page's\n * surfaces mount with the page), use `createSurfaceRuntime` instead: it keeps\n * the client's own record of what is mounted and answers every request.\n *\n * WHY THIS EXISTS\n *\n * OUI shipped a correct protocol and a correct transport, and its first\n * integrator used neither. studio-ui imported only the `SocketLike` TYPE from\n * oui-spec and rebuilt the wire by hand: a literal map of protocol types to\n * socket names, `oui:` hardcoded so the configurable namespace was unreachable,\n * payload interfaces re-declared on the server, and an `action:result` channel\n * mapped but never sent — duplicating the observation channel that already\n * carries results.\n *\n * Nothing was wrong with the spec. Nothing enforced it. Structural typing meant\n * every hand-rolled piece type-checked, and both ends agreed only by the\n * coincidence of matching string literals. Rename one and the other keeps\n * compiling and silently stops receiving.\n *\n * So the requirements are gated here:\n *\n * OUI owns the wire. The integrator provides a socket; it cannot provide a\n * transport, because `OUITransport` values are branded and only this module\n * brands them.\n *\n * OUI owns the result path. Every dispatch carries a requestId and is\n * answered on OUI's result channel. An integrator cannot add a parallel\n * channel because it cannot construct a transport to add one to.\n *\n * The integrator owns content. Surfaces, action schemas, observation schemas\n * and handlers all arrive through `defineSurface`, whose output is branded —\n * so a plain object shaped like a surface will not compile.\n *\n * Violations fail at compile time with a message naming the offending id.\n */\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport type { SocketLike } from \"../transport/websocket.js\";\nimport { createWebSocketTransport } from \"../transport/websocket.js\";\nimport type { DefinedSurface } from \"./define-surface.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\nimport type { OUIConfigError, ValidateSurfaceIds } from \"./validate.js\";\nimport type { OUISurface } from \"../spec/index.js\";\n\n/** A transport OUI constructed. Integrators cannot produce one. */\nexport type OwnedTransport = OUITransport & OUIBranded<\"transport\">;\n\n/** Surface ids as literal types, for the duplicate check. */\ntype SurfaceIds<T extends readonly DefinedSurface<never>[]> = {\n [K in keyof T]: T[K][\"id\"];\n};\n\nexport interface OUIConfig<TSurfaces extends readonly DefinedSurface<never>[]> {\n /**\n * The socket OUI will speak over. The integrator owns the connection —\n * auth, reconnection, lifecycle — and OUI owns what travels on it.\n */\n socket: SocketLike;\n\n /**\n * Surfaces produced by `defineSurface`. A plain object with the same shape\n * will not compile: DefinedSurface is branded.\n */\n surfaces: TSurfaces;\n\n /**\n * Wire configuration. `namespace` defaults to 'oui' and is the supported way\n * to change the event prefix — hardcoding it at the call site is what made\n * this option unreachable in the first integration.\n */\n transport?: Omit<OUITransportConfig, \"namespace\"> & { namespace?: string };\n}\n\n/** A live OUI instance. */\nexport interface OUIInstance {\n /** The transport OUI owns. Exposed for wiring, not for reimplementation. */\n readonly transport: OwnedTransport;\n\n /** Manifests for every registered surface, as the agent sees them. */\n readonly manifests: readonly OUISurface[];\n\n /** Register every surface and connect. */\n start(): Promise<void>;\n\n /**\n * Deregister every surface and detach OUI from the socket. The socket stays\n * connected: the integrator owns it, and other code may share it.\n */\n stop(): void;\n\n /** Look up a registered surface by id. */\n getSurface(id: string): DefinedSurface<never> | undefined;\n}\n\n/**\n * Instantiate OUI.\n *\n * `const` on the type parameter captures surface ids as literal types, which is\n * what allows duplicate detection to name the offending id rather than failing\n * with an unassignable-to-never error.\n */\nexport function createOUI<\n const TSurfaces extends readonly DefinedSurface<never>[],\n>(\n config: OUIConfig<TSurfaces> & ValidateSurfaceIds<SurfaceIds<TSurfaces>>,\n): OUIInstance {\n const {\n socket,\n surfaces,\n transport: transportConfig,\n } = config as OUIConfig<TSurfaces>;\n\n // Defensive, not decorative: the compile-time checks only bind when a caller\n // passes literals. A surface list assembled at runtime, or JS with no types\n // at all, reaches here unchecked.\n if (!socket) {\n throw new Error(\n \"[OUI] createOUI requires a socket. OUI owns the wire; the integrator owns the connection.\",\n );\n }\n if (!Array.isArray(surfaces) || surfaces.length === 0) {\n throw new Error(\"[OUI] createOUI requires at least one surface.\");\n }\n\n const seen = new Set<string>();\n for (const surface of surfaces) {\n if (seen.has(surface.id)) {\n throw new Error(\n `[OUI] Duplicate surface id \"${surface.id}\". Registration is keyed by id, so the second would replace the first.`,\n );\n }\n seen.add(surface.id);\n }\n\n const transport = brand<\"transport\", OUITransport>(\n createWebSocketTransport(socket, transportConfig),\n );\n\n const byId = new Map(surfaces.map((s) => [s.id, s] as const));\n\n return {\n transport,\n manifests: surfaces.map((s) => s.toManifest()),\n\n async start() {\n await transport.connect();\n for (const surface of surfaces) {\n transport.registerSurface(surface.toManifest());\n }\n },\n\n stop() {\n for (const surface of surfaces) {\n transport.deregisterSurface(surface.id);\n }\n transport.dispose();\n },\n\n getSurface(id) {\n return byId.get(id);\n },\n };\n}\n\n/** Re-exported so integrators can name the error type in tests. */\nexport type { OUIConfigError };\n","/**\n * The client-side surface runtime.\n *\n * Holds the surfaces a client has mounted, answers every action request with a\n * result, and produces the snapshot an agent runtime works from.\n *\n * WHY THIS EXISTS\n *\n * The first integration kept no client-side record of what was mounted. Each\n * surface hook registered itself with a server-side registry and listened for\n * dispatches on its own. Three things followed:\n *\n * - The registry was the only record of what the client could do, and it lost\n * entries: a dead socket's cleanup removed a live tab's registration, and the\n * browser never registered again. The agent then had no UI tools at all.\n * - Nothing answered a dispatch. The agent was told an action succeeded before\n * the client had run it, and never saw the page an action led to.\n * - Every hook listened independently, through two paths, so one dispatch ran\n * twice and nothing de-duplicated it.\n *\n * Here the client is the record. `snapshot()` is what the client can do right\n * now, and every request is run once, waited on until the UI settles, and\n * answered with its result and the snapshot after it.\n */\nimport type {\n OUIActionRequest,\n OUIActionResult,\n OUISurface,\n OUISurfaceSnapshot,\n OUIObservationSnapshot,\n} from \"../spec/index.js\";\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport {\n createWebSocketTransport,\n type SocketLike,\n} from \"../transport/websocket.js\";\nimport type {\n ActionHandlerResult,\n ActionPollingConfig,\n DefinedSurface,\n} from \"./define-surface.js\";\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\nexport interface SettleOptions {\n /**\n * The UI counts as settled once nothing has mounted, unmounted or changed an\n * observation for this long, and no hold is open. Default 250 ms.\n */\n quietMs?: number;\n /** Give up waiting after this long and answer with `settled: false`. Default 5000 ms. */\n timeoutMs?: number;\n}\n\nexport interface SurfaceRuntimeOptions {\n /** The socket to answer requests on. Can be set or replaced later with `attach`. */\n socket?: SocketLike | null;\n\n /** Wire configuration for the transport the runtime builds on the socket. */\n transport?: OUITransportConfig;\n\n /**\n * Also announce registrations and observations over the transport, for agent\n * runtimes that keep a server-side registry. Default true.\n *\n * An agent runtime that takes the client's snapshot instead (sent with each\n * turn, and returned on every result) has no use for them: set false.\n */\n announce?: boolean;\n\n settle?: SettleOptions;\n\n /** How many answered request ids to remember, for de-duplication. Default 500. */\n dedupeWindow?: number;\n\n /**\n * Decides whether a request that arrived on the socket may run at all. A\n * refused request is neither run nor answered, and is logged.\n *\n * The server should be the only sender of action requests, but a client can\n * also check that a request is one it expects: for example, only while its\n * agent has a turn in progress. Requests passed to `execute` directly are\n * not checked; they come from the application itself.\n */\n accept?: (request: OUIActionRequest) => boolean;\n}\n\n// ─── Public types ────────────────────────────────────────────────────────────\n\nexport interface MountedSurface {\n readonly surfaceId: string;\n /** Record an observation value. A no-op once unmounted. */\n pushObservation(observationId: string, value: unknown): void;\n /** Remove this mount. Other mounts of the same surface id are unaffected. */\n unmount(): void;\n}\n\nexport interface SurfaceRuntime {\n /**\n * Mount a surface. `getContext` is read when an action runs, so handlers see\n * the latest state rather than the state at mount time.\n *\n * Mounting the same surface id twice is allowed (React StrictMode does it on\n * every mount); the most recent mount serves its actions.\n */\n mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface;\n\n /** Answer requests arriving on this socket (null detaches). */\n attach(socket: SocketLike | null): void;\n\n /** What the client can do right now. */\n snapshot(): OUISurfaceSnapshot;\n\n /**\n * Run a request once and resolve with its result. A request id seen before\n * resolves with the first result instead of running again.\n */\n execute(request: OUIActionRequest): Promise<OUIActionResult>;\n\n /**\n * Keep the UI unsettled until the returned function is called. For work an\n * action starts that mounting and unmounting cannot show, such as a route's\n * code still loading or a page fetching the data it will display.\n */\n hold(): () => void;\n\n /** Called whenever the snapshot changes. */\n subscribe(listener: () => void): () => void;\n\n /** Stop polling, detach from the socket and forget every mount. */\n dispose(): void;\n}\n\n// ─── Implementation ──────────────────────────────────────────────────────────\n\ninterface Entry {\n key: number;\n surface: DefinedSurface<unknown>;\n getContext: () => unknown;\n}\n\nconst DEFAULT_QUIET_MS = 250;\nconst DEFAULT_SETTLE_TIMEOUT_MS = 5000;\nconst DEFAULT_DEDUPE_WINDOW = 500;\nconst SETTLE_TICK_MS = 50;\n\nexport function createSurfaceRuntime(\n options: SurfaceRuntimeOptions = {},\n): SurfaceRuntime {\n const announce = options.announce ?? true;\n const quietMs = options.settle?.quietMs ?? DEFAULT_QUIET_MS;\n const settleTimeoutMs =\n options.settle?.timeoutMs ?? DEFAULT_SETTLE_TIMEOUT_MS;\n const dedupeWindow = options.dedupeWindow ?? DEFAULT_DEDUPE_WINDOW;\n\n let nextKey = 1;\n const entries: Entry[] = [];\n const observations = new Map<string, Map<string, unknown>>();\n const serializedObservations = new Map<string, string>();\n const holds = new Set<number>();\n let nextHold = 1;\n const results = new Map<string, Promise<OUIActionResult>>();\n const pollers = new Map<string, ReturnType<typeof setInterval>>();\n // How each running poll answers its request if it has to stop early.\n const abandon = new Map<\n string,\n (error: { code: string; message: string }) => void\n >();\n const listeners = new Set<() => void>();\n // Resolves once a request's first result has been handed to the transport.\n const acks = new Map<\n string,\n { promise: Promise<void>; resolve: () => void }\n >();\n function ackFor(requestId: string) {\n let ack = acks.get(requestId);\n if (!ack) {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => (resolve = r));\n ack = { promise, resolve };\n acks.set(requestId, ack);\n }\n return ack;\n }\n function acknowledged(requestId: string): Promise<void> {\n return ackFor(requestId).promise;\n }\n let lastChangeAt = Date.now();\n\n let socket: SocketLike | null = null;\n let transport: OUITransport | null = null;\n let detachTransport: Array<() => void> = [];\n\n /**\n * `settles: false` for changes that are not the UI reacting to an action,\n * such as an async job's progress: those notify listeners but do not keep\n * an action's result waiting.\n */\n function changed(settles = true) {\n if (settles) lastChangeAt = Date.now();\n for (const l of [...listeners]) l();\n }\n\n function activeFor(surfaceId: string): Entry | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].surface.id === surfaceId) return entries[i];\n }\n return undefined;\n }\n\n /** Active entries, one per surface id, in the order each id was first mounted. */\n function activeEntries(): Entry[] {\n const seen = new Set<string>();\n const out: Entry[] = [];\n for (const e of entries) {\n if (seen.has(e.surface.id)) continue;\n seen.add(e.surface.id);\n out.push(activeFor(e.surface.id)!);\n }\n return out;\n }\n\n function announceSurface(entry: Entry) {\n if (!announce || !transport) return;\n transport.registerSurface(entry.surface.toManifest());\n const obs = observations.get(entry.surface.id);\n if (obs) {\n for (const [observationId, value] of obs) {\n transport.pushObservation({\n surfaceId: entry.surface.id,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n }\n }\n\n function announceAll() {\n for (const e of activeEntries()) announceSurface(e);\n }\n\n function setObservation(\n surfaceId: string,\n observationId: string,\n value: unknown,\n settles = true,\n ) {\n const key = `${surfaceId}\\u0000${observationId}`;\n let serialized: string;\n try {\n serialized = JSON.stringify(value) ?? \"undefined\";\n } catch {\n serialized = String(value);\n }\n if (serializedObservations.get(key) === serialized) return;\n serializedObservations.set(key, serialized);\n\n let obs = observations.get(surfaceId);\n if (!obs) {\n obs = new Map();\n observations.set(surfaceId, obs);\n }\n obs.set(observationId, toJsonSafe(value));\n\n if (announce && transport) {\n transport.pushObservation({\n surfaceId,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n changed(settles);\n }\n\n function forgetSurface(surfaceId: string) {\n observations.delete(surfaceId);\n for (const key of [...serializedObservations.keys()]) {\n if (key.startsWith(`${surfaceId}\\u0000`))\n serializedObservations.delete(key);\n }\n for (const [key, timer] of pollers) {\n if (key.startsWith(`${surfaceId}\\u0000`)) {\n clearInterval(timer);\n pollers.delete(key);\n // The request still gets its final answer: a poll that stops\n // without one leaves the agent waiting forever.\n abandon.get(key)?.({\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${surfaceId}\" left the page before its action finished, ` +\n \"so it is no longer being followed. Check what the page shows \" +\n \"before trying again.\",\n });\n abandon.delete(key);\n }\n }\n }\n\n // ─── Polling (async actions) ──────────────────────────────────────────────\n\n /**\n * Polls an async action to completion, publishing progress as an observation\n * and, when it ends, the request's final result (OUI spec §7.3: an async\n * action is acknowledged, then answered once more when it finishes).\n */\n function startPolling(\n requestId: string,\n surfaceId: string,\n actionId: string,\n polling: ActionPollingConfig<unknown>,\n dispatchResult: unknown,\n ) {\n const finish = async (\n success: boolean,\n data: unknown,\n error?: { code: string; message: string },\n ) => {\n // The acknowledgment goes first: a job can finish before the UI settles.\n await acknowledged(requestId);\n const snap = snapshot();\n transport?.sendResult({\n requestId,\n success,\n ...(data !== undefined ? { data: toJsonSafe(data) } : {}),\n ...(error ? { error } : {}),\n interim: false,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n });\n acks.delete(requestId);\n };\n\n // The observation id is the one surfaces have always published under.\n const observationId = `${surfaceId}:${actionId}:status`;\n const pollerKey = `${surfaceId}\\u0000${actionId}`;\n\n if (polling.subscribe) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: true },\n false,\n );\n return;\n }\n if (!polling.resolve) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: false },\n false,\n );\n return;\n }\n\n const existing = pollers.get(pollerKey);\n if (existing) {\n clearInterval(existing);\n pollers.delete(pollerKey);\n abandon.get(pollerKey)?.({\n code: \"SUPERSEDED\",\n message:\n `\"${actionId}\" was started again before this run finished, ` +\n \"so only the newer run is being followed.\",\n });\n abandon.delete(pollerKey);\n }\n\n setObservation(\n surfaceId,\n observationId,\n { status: \"polling\", dispatchResult, interim: true },\n false,\n );\n\n const maxAttempts = polling.maxAttempts ?? Infinity;\n const maxDuration = polling.maxDurationMs ?? Infinity;\n const startedAt = Date.now();\n let attempts = 0;\n\n const timer = setInterval(async () => {\n attempts++;\n if (attempts > maxAttempts || Date.now() - startedAt > maxDuration) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n abandon.delete(pollerKey);\n setObservation(\n surfaceId,\n observationId,\n { status: \"timeout\", dispatchResult, interim: false },\n false,\n );\n void finish(false, undefined, {\n code: \"TIMEOUT\",\n message: `\"${actionId}\" did not finish within its polling limits.`,\n });\n return;\n }\n const entry = activeFor(surfaceId);\n if (!entry) {\n // forgetSurface normally gets here first; answer anyway.\n clearInterval(timer);\n pollers.delete(pollerKey);\n const gone = abandon.get(pollerKey);\n abandon.delete(pollerKey);\n gone?.({\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${surfaceId}\" left the page before \"${actionId}\" ` +\n \"finished, so it is no longer being followed. Check what the \" +\n \"page shows before trying again.\",\n });\n return;\n }\n // The surface may have remounted without this action (a control that is\n // disabled while its job runs, say). The job is still running, so keep\n // following it with the polling it started with.\n const action = entry.surface.actions.find((a) => a.id === actionId);\n const resolve = action?.polling?.resolve ?? polling.resolve;\n if (!resolve) return;\n try {\n const r = await resolve(dispatchResult, entry.getContext());\n setObservation(\n surfaceId,\n observationId,\n {\n ...(r.data as Record<string, unknown>),\n interim: !r.done,\n },\n false,\n );\n if (r.done) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n abandon.delete(pollerKey);\n void finish(true, r.data);\n }\n } catch (err) {\n // A transient failure is reported, not fatal: keep polling.\n setObservation(\n surfaceId,\n observationId,\n { status: \"poll_error\", error: String(err), interim: true },\n false,\n );\n }\n }, polling.intervalMs);\n\n pollers.set(pollerKey, timer);\n abandon.set(pollerKey, (error) => void finish(false, undefined, error));\n }\n\n // ─── Settling ─────────────────────────────────────────────────────────────\n\n async function waitUntilSettled(since: number): Promise<boolean> {\n const deadline = since + settleTimeoutMs;\n for (;;) {\n const now = Date.now();\n const quietFor = now - Math.max(since, lastChangeAt);\n if (holds.size === 0 && quietFor >= quietMs) return true;\n if (now >= deadline) return false;\n await sleep(Math.min(SETTLE_TICK_MS, deadline - now));\n }\n }\n\n // ─── Execution ────────────────────────────────────────────────────────────\n\n async function run(request: OUIActionRequest): Promise<OUIActionResult> {\n const startedAt = Date.now();\n const entry = activeFor(request.surfaceId);\n\n let result: ActionHandlerResult;\n let interim = false;\n if (!entry) {\n const mounted = activeEntries().map((e) => e.surface.id);\n result = {\n success: false,\n error: {\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${request.surfaceId}\" is not on screen. ` +\n `Mounted surfaces: ${mounted.length ? mounted.join(\", \") : \"none\"}.`,\n },\n };\n } else {\n // executeAction turns a thrown handler into ACTION_EXECUTION_ERROR.\n result = await entry.surface.executeAction(\n request.actionId,\n request.params ?? {},\n entry.getContext(),\n );\n if (result.success) {\n const action = entry.surface.actions.find(\n (a) => a.id === request.actionId,\n );\n if (action?.polling) {\n interim = true;\n startPolling(\n request.requestId,\n entry.surface.id,\n action.id,\n action.polling,\n result.data ?? result.dispatchMeta,\n );\n }\n }\n }\n\n const settled = await waitUntilSettled(startedAt);\n const snap = snapshot();\n\n return {\n requestId: request.requestId,\n success: result.success,\n ...(result.data !== undefined ? { data: toJsonSafe(result.data) } : {}),\n ...(result.error\n ? { error: toJsonSafe(result.error) as OUIActionResult[\"error\"] }\n : {}),\n ...(interim ? { interim: true } : {}),\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n settled,\n };\n }\n\n function execute(request: OUIActionRequest): Promise<OUIActionResult> {\n const seen = results.get(request.requestId);\n if (seen) return seen;\n\n const pending = run(request);\n results.set(request.requestId, pending);\n while (results.size > dedupeWindow) {\n const oldest = results.keys().next().value as string;\n results.delete(oldest);\n }\n return pending;\n }\n\n // ─── Snapshot ─────────────────────────────────────────────────────────────\n\n function snapshot(): OUISurfaceSnapshot {\n const surfaces: OUISurface[] = [];\n const obs: OUIObservationSnapshot = {};\n for (const e of activeEntries()) {\n surfaces.push(e.surface.toManifest());\n const values = observations.get(e.surface.id);\n if (values && values.size > 0)\n obs[e.surface.id] = Object.fromEntries(values);\n }\n return { surfaces, observations: obs };\n }\n\n // ─── Transport ────────────────────────────────────────────────────────────\n\n function attach(next: SocketLike | null) {\n if (next === socket) return;\n for (const off of detachTransport) off();\n detachTransport = [];\n transport?.dispose();\n transport = null;\n socket = next;\n if (!next) return;\n\n const t = createWebSocketTransport(next, options.transport);\n transport = t;\n\n detachTransport.push(\n t.onAction((request) => {\n if (options.accept && !options.accept(request)) {\n console.warn(\n `[OUI] Refused a request the client does not accept: ${request.surfaceId}.${request.actionId} (${request.requestId})`,\n );\n return;\n }\n void execute(request).then((result) => {\n // Answer on whichever transport is live when the result is ready: a\n // reconnect in between keeps the same socket, so this still reaches\n // the runtime that asked.\n transport?.sendResult(result);\n const ack = ackFor(request.requestId);\n ack.resolve();\n // Keep the gate only while a final result may still follow.\n if (!result.interim) acks.delete(request.requestId);\n });\n }),\n );\n\n if (announce) {\n // A server-side registry forgets a socket's surfaces when it drops, so\n // every (re)connection announces them again.\n detachTransport.push(\n t.onConnectionChange((connected) => {\n if (connected) announceAll();\n }),\n );\n if (t.connected) announceAll();\n }\n }\n\n if (options.socket) attach(options.socket);\n\n // ─── Mounting ─────────────────────────────────────────────────────────────\n\n function mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface {\n const entry: Entry = {\n key: nextKey++,\n surface: surface as unknown as DefinedSurface<unknown>,\n getContext: getContext as () => unknown,\n };\n entries.push(entry);\n announceSurface(entry);\n changed();\n\n let mounted = true;\n return {\n surfaceId: surface.id,\n pushObservation(observationId, value) {\n // Only the mount serving the surface speaks for it.\n if (!mounted || activeFor(surface.id) !== entry) return;\n setObservation(surface.id, observationId, value);\n },\n unmount() {\n if (!mounted) return;\n mounted = false;\n const i = entries.indexOf(entry);\n if (i >= 0) entries.splice(i, 1);\n const replacement = activeFor(surface.id);\n if (replacement) {\n announceSurface(replacement);\n } else {\n forgetSurface(surface.id);\n if (announce && transport) transport.deregisterSurface(surface.id);\n }\n changed();\n },\n };\n }\n\n return {\n mount,\n attach,\n snapshot,\n execute,\n hold() {\n const id = nextHold++;\n holds.add(id);\n changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n holds.delete(id);\n changed();\n };\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n dispose() {\n for (const timer of pollers.values()) clearInterval(timer);\n pollers.clear();\n abandon.clear();\n attach(null);\n entries.length = 0;\n observations.clear();\n serializedObservations.clear();\n holds.clear();\n listeners.clear();\n acks.clear();\n },\n };\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Results and observations cross a wire as JSON. A handler returning something\n * that is not (a DOM node, a class instance with cycles) must not take the\n * result down with it.\n */\nfunction toJsonSafe(value: unknown): unknown {\n if (value === undefined) return undefined;\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n return String(value);\n }\n}\n"]}
@@ -167,6 +167,7 @@ function createSurfaceRuntime(options = {}) {
167
167
  let nextHold = 1;
168
168
  const results = /* @__PURE__ */ new Map();
169
169
  const pollers = /* @__PURE__ */ new Map();
170
+ const abandon = /* @__PURE__ */ new Map();
170
171
  const listeners = /* @__PURE__ */ new Set();
171
172
  const acks = /* @__PURE__ */ new Map();
172
173
  function ackFor(requestId) {
@@ -260,6 +261,11 @@ function createSurfaceRuntime(options = {}) {
260
261
  if (key.startsWith(`${surfaceId}\0`)) {
261
262
  clearInterval(timer);
262
263
  pollers.delete(key);
264
+ abandon.get(key)?.({
265
+ code: "SURFACE_NOT_MOUNTED",
266
+ message: `Surface "${surfaceId}" left the page before its action finished, so it is no longer being followed. Check what the page shows before trying again.`
267
+ });
268
+ abandon.delete(key);
263
269
  }
264
270
  }
265
271
  }
@@ -300,7 +306,15 @@ function createSurfaceRuntime(options = {}) {
300
306
  return;
301
307
  }
302
308
  const existing = pollers.get(pollerKey);
303
- if (existing) clearInterval(existing);
309
+ if (existing) {
310
+ clearInterval(existing);
311
+ pollers.delete(pollerKey);
312
+ abandon.get(pollerKey)?.({
313
+ code: "SUPERSEDED",
314
+ message: `"${actionId}" was started again before this run finished, so only the newer run is being followed.`
315
+ });
316
+ abandon.delete(pollerKey);
317
+ }
304
318
  setObservation(
305
319
  surfaceId,
306
320
  observationId,
@@ -316,6 +330,7 @@ function createSurfaceRuntime(options = {}) {
316
330
  if (attempts > maxAttempts || Date.now() - startedAt > maxDuration) {
317
331
  clearInterval(timer);
318
332
  pollers.delete(pollerKey);
333
+ abandon.delete(pollerKey);
319
334
  setObservation(
320
335
  surfaceId,
321
336
  observationId,
@@ -329,17 +344,22 @@ function createSurfaceRuntime(options = {}) {
329
344
  return;
330
345
  }
331
346
  const entry = activeFor(surfaceId);
332
- const action = entry?.surface.actions.find((a) => a.id === actionId);
333
- if (!entry || !action?.polling?.resolve) {
347
+ if (!entry) {
334
348
  clearInterval(timer);
335
349
  pollers.delete(pollerKey);
350
+ const gone = abandon.get(pollerKey);
351
+ abandon.delete(pollerKey);
352
+ gone?.({
353
+ code: "SURFACE_NOT_MOUNTED",
354
+ message: `Surface "${surfaceId}" left the page before "${actionId}" finished, so it is no longer being followed. Check what the page shows before trying again.`
355
+ });
336
356
  return;
337
357
  }
358
+ const action = entry.surface.actions.find((a) => a.id === actionId);
359
+ const resolve = action?.polling?.resolve ?? polling.resolve;
360
+ if (!resolve) return;
338
361
  try {
339
- const r = await action.polling.resolve(
340
- dispatchResult,
341
- entry.getContext()
342
- );
362
+ const r = await resolve(dispatchResult, entry.getContext());
343
363
  setObservation(
344
364
  surfaceId,
345
365
  observationId,
@@ -352,6 +372,7 @@ function createSurfaceRuntime(options = {}) {
352
372
  if (r.done) {
353
373
  clearInterval(timer);
354
374
  pollers.delete(pollerKey);
375
+ abandon.delete(pollerKey);
355
376
  void finish(true, r.data);
356
377
  }
357
378
  } catch (err) {
@@ -364,6 +385,7 @@ function createSurfaceRuntime(options = {}) {
364
385
  }
365
386
  }, polling.intervalMs);
366
387
  pollers.set(pollerKey, timer);
388
+ abandon.set(pollerKey, (error) => void finish(false, void 0, error));
367
389
  }
368
390
  async function waitUntilSettled(since) {
369
391
  const deadline = since + settleTimeoutMs;
@@ -542,6 +564,7 @@ function createSurfaceRuntime(options = {}) {
542
564
  dispose() {
543
565
  for (const timer of pollers.values()) clearInterval(timer);
544
566
  pollers.clear();
567
+ abandon.clear();
545
568
  attach(null);
546
569
  entries.length = 0;
547
570
  observations.clear();
@@ -565,5 +588,5 @@ function toJsonSafe(value) {
565
588
  }
566
589
 
567
590
  export { createOUI, createSurfaceRuntime, defineSurface };
568
- //# sourceMappingURL=chunk-GXTNZ44I.js.map
569
- //# sourceMappingURL=chunk-GXTNZ44I.js.map
591
+ //# sourceMappingURL=chunk-UQLG55ST.js.map
592
+ //# sourceMappingURL=chunk-UQLG55ST.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/brand.ts","../src/core/define-surface.ts","../src/core/create-oui.ts","../src/core/surface-runtime.ts"],"names":[],"mappings":"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","file":"chunk-UQLG55ST.js","sourcesContent":["/**\n * Nominal branding for values OUI must construct itself.\n *\n * Structural typing means any object with the right shape satisfies an\n * interface. That is how Closure Studio ended up hand-rolling OUI's transport:\n * `SocketLike` was importable, `OUITransport` was a plain interface, so an\n * integrator could satisfy every type without ever calling OUI. The result was\n * a second implementation of the wire — hardcoded namespace, re-declared\n * payload types on the server, and a dead `action:result` mapping alongside the\n * observation channel that already carried results.\n *\n * A unique symbol cannot be produced outside this module. Branding the types\n * OUI owns turns \"you should use our constructor\" into \"you cannot compile\n * without it\".\n */\n\ndeclare const OUI_BRAND: unique symbol;\n\n/** Marks a value as constructed by OUI itself. */\nexport interface OUIBranded<TKind extends string> {\n readonly [OUI_BRAND]: TKind;\n}\n\n/**\n * Attach the brand at runtime. The property does not exist at runtime — the\n * symbol is declare-only — so this is a type-level assertion with no cost.\n */\nexport function brand<TKind extends string, T>(\n value: T,\n): T & OUIBranded<TKind> {\n return value as T & OUIBranded<TKind>;\n}\n","import type {\n OUISurface,\n OUIAction,\n OUIObservation,\n OUIActivation,\n OUIActionPolling,\n JSONSchema,\n} from \"../spec/index.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\n\n/**\n * Configuration for defining an OUI surface with handlers.\n * This is the \"integration file\" an app provides — it declares both\n * the schema (what the agent sees) and the implementation (what executes).\n */\nexport interface SurfaceDefinition<TContext = unknown> {\n id: string;\n name: string;\n description: string;\n version?: string;\n activation?: OUIActivation;\n actions: ActionDefinition<TContext>[];\n observations?: ObservationDefinition[];\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Polling config with an optional resolve handler.\n * The spec's OUIActionPolling is the manifest shape (no functions).\n * The core extends it with the resolve implementation for the runtime.\n */\nexport interface ActionPollingConfig<\n TContext = unknown,\n> extends OUIActionPolling {\n /**\n * Called on each poll interval. Receives the dispatch result from the handler\n * plus the current context. Return { done: true, data } to stop polling,\n * or { done: false, data } to continue.\n */\n resolve?: (\n dispatchResult: unknown,\n context: TContext,\n ) => Promise<{ done: boolean; data: unknown }>;\n}\n\n/**\n * An action definition includes both the schema (for the agent) and\n * the handler (for execution). This is the single source of truth —\n * no separate YAML, no separate listener, no drift possible.\n */\nexport interface ActionDefinition<TContext = unknown> {\n id: string;\n description: string;\n input: JSONSchema;\n output?: JSONSchema;\n confirm?: boolean;\n async?: boolean;\n\n /**\n * Polling/subscription config for async actions.\n * After the handler returns, the OUI runtime starts polling or subscribing\n * and pushes observation updates until the operation completes.\n * Extends the spec's OUIActionPolling with an optional resolve handler.\n */\n polling?: ActionPollingConfig<TContext>;\n\n usage?: string;\n preconditions?: string;\n estimatedDuration?: string;\n tags?: string[];\n\n /**\n * The handler that executes when the agent invokes this action.\n * Receives typed params and a context object (app-specific state/utilities).\n * Returns a result that the agent sees as the tool output.\n */\n handler: (\n params: Record<string, unknown>,\n context: TContext,\n ) => Promise<ActionHandlerResult>;\n}\n\nexport interface ActionHandlerResult {\n success: boolean;\n data?: unknown;\n error?: { code: string; message: string; details?: unknown };\n /** For async actions: metadata passed to the polling resolver */\n dispatchMeta?: Record<string, unknown>;\n}\n\nexport interface ObservationDefinition {\n id: string;\n description: string;\n schema: JSONSchema;\n /** Function that returns the current observation value */\n getValue?: () => unknown;\n}\n\n/**\n * Define an OUI surface — the single entry point for integrating\n * an application feature with the OUI protocol.\n *\n * This function validates the definition and returns a typed surface\n * object that can be registered with an agent runtime or transport layer.\n *\n * @example\n * ```typescript\n * const mySurface = defineSurface({\n * id: 'my-feature',\n * name: 'My Feature',\n * description: 'Does something cool',\n * actions: [\n * {\n * id: 'do_thing',\n * description: 'Does the thing',\n * input: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },\n * handler: async (params) => {\n * const result = await doTheThing(params.name);\n * return { success: true, data: result };\n * },\n * },\n * ],\n * });\n * ```\n */\nexport function defineSurface<\n TContext = unknown,\n const TId extends string = string,\n>(\n definition: SurfaceDefinition<TContext> & { id: TId },\n): DefinedSurface<TContext> & { id: TId } {\n // Validate: no duplicate action IDs\n const actionIds = new Set<string>();\n for (const action of definition.actions) {\n if (actionIds.has(action.id)) {\n throw new Error(\n `[OUI] Duplicate action ID \"${action.id}\" in surface \"${definition.id}\"`,\n );\n }\n actionIds.add(action.id);\n }\n\n // Validate: no duplicate observation IDs\n if (definition.observations) {\n const obsIds = new Set<string>();\n for (const obs of definition.observations) {\n if (obsIds.has(obs.id)) {\n throw new Error(\n `[OUI] Duplicate observation ID \"${obs.id}\" in surface \"${definition.id}\"`,\n );\n }\n obsIds.add(obs.id);\n }\n }\n\n return brand<\"surface\", unknown>({\n ...definition,\n\n /** Extract the manifest (schema only, no handlers) for transmission to the agent runtime */\n toManifest(): OUISurface {\n return {\n id: definition.id,\n name: definition.name,\n description: definition.description,\n version: definition.version,\n activation: definition.activation,\n actions: definition.actions.map(actionToManifest),\n observations: definition.observations?.map(obsToManifest),\n metadata: definition.metadata,\n };\n },\n\n /** Execute an action by ID with the given params and context */\n async executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult> {\n const action = definition.actions.find((a) => a.id === actionId);\n if (!action) {\n return {\n success: false,\n error: {\n code: \"ACTION_NOT_FOUND\",\n message: `Action \"${actionId}\" not found on surface \"${definition.id}\"`,\n },\n };\n }\n try {\n return await action.handler(params, context);\n } catch (err) {\n return {\n success: false,\n error: {\n code: \"ACTION_EXECUTION_ERROR\",\n message: err instanceof Error ? err.message : String(err),\n },\n };\n }\n },\n\n /** Get all action IDs */\n getActionIds(): string[] {\n return definition.actions.map((a) => a.id);\n },\n\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined {\n const action = definition.actions.find((a) => a.id === actionId);\n return action?.polling;\n },\n }) as DefinedSurface<TContext> & { id: TId };\n}\n\n/** A fully defined surface with both manifest extraction and execution capabilities */\n/**\n * Branded so it can only come from `defineSurface`.\n *\n * Without the brand a plain object literal satisfies this interface\n * structurally, which is how an integrator can assemble a surface that never\n * ran defineSurface's duplicate-id checks and never produced a real manifest.\n */\nexport interface DefinedSurface<TContext = unknown>\n extends SurfaceDefinition<TContext>, OUIBranded<\"surface\"> {\n toManifest(): OUISurface;\n executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult>;\n getActionIds(): string[];\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined;\n}\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\nfunction actionToManifest<T>(action: ActionDefinition<T>): OUIAction {\n return {\n id: action.id,\n description: action.description,\n input: action.input,\n output: action.output,\n confirm: action.confirm,\n async: action.async,\n polling: action.polling,\n usage: action.usage,\n preconditions: action.preconditions,\n estimatedDuration: action.estimatedDuration,\n tags: action.tags,\n };\n}\n\nfunction obsToManifest(obs: ObservationDefinition): OUIObservation {\n return {\n id: obs.id,\n description: obs.description,\n schema: obs.schema,\n };\n}\n","/**\n * createOUI — a fixed set of surfaces announced over one socket.\n *\n * For a client whose surfaces come and go (a React app, where a page's\n * surfaces mount with the page), use `createSurfaceRuntime` instead: it keeps\n * the client's own record of what is mounted and answers every request.\n *\n * WHY THIS EXISTS\n *\n * OUI shipped a correct protocol and a correct transport, and its first\n * integrator used neither. studio-ui imported only the `SocketLike` TYPE from\n * oui-spec and rebuilt the wire by hand: a literal map of protocol types to\n * socket names, `oui:` hardcoded so the configurable namespace was unreachable,\n * payload interfaces re-declared on the server, and an `action:result` channel\n * mapped but never sent — duplicating the observation channel that already\n * carries results.\n *\n * Nothing was wrong with the spec. Nothing enforced it. Structural typing meant\n * every hand-rolled piece type-checked, and both ends agreed only by the\n * coincidence of matching string literals. Rename one and the other keeps\n * compiling and silently stops receiving.\n *\n * So the requirements are gated here:\n *\n * OUI owns the wire. The integrator provides a socket; it cannot provide a\n * transport, because `OUITransport` values are branded and only this module\n * brands them.\n *\n * OUI owns the result path. Every dispatch carries a requestId and is\n * answered on OUI's result channel. An integrator cannot add a parallel\n * channel because it cannot construct a transport to add one to.\n *\n * The integrator owns content. Surfaces, action schemas, observation schemas\n * and handlers all arrive through `defineSurface`, whose output is branded —\n * so a plain object shaped like a surface will not compile.\n *\n * Violations fail at compile time with a message naming the offending id.\n */\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport type { SocketLike } from \"../transport/websocket.js\";\nimport { createWebSocketTransport } from \"../transport/websocket.js\";\nimport type { DefinedSurface } from \"./define-surface.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\nimport type { OUIConfigError, ValidateSurfaceIds } from \"./validate.js\";\nimport type { OUISurface } from \"../spec/index.js\";\n\n/** A transport OUI constructed. Integrators cannot produce one. */\nexport type OwnedTransport = OUITransport & OUIBranded<\"transport\">;\n\n/** Surface ids as literal types, for the duplicate check. */\ntype SurfaceIds<T extends readonly DefinedSurface<never>[]> = {\n [K in keyof T]: T[K][\"id\"];\n};\n\nexport interface OUIConfig<TSurfaces extends readonly DefinedSurface<never>[]> {\n /**\n * The socket OUI will speak over. The integrator owns the connection —\n * auth, reconnection, lifecycle — and OUI owns what travels on it.\n */\n socket: SocketLike;\n\n /**\n * Surfaces produced by `defineSurface`. A plain object with the same shape\n * will not compile: DefinedSurface is branded.\n */\n surfaces: TSurfaces;\n\n /**\n * Wire configuration. `namespace` defaults to 'oui' and is the supported way\n * to change the event prefix — hardcoding it at the call site is what made\n * this option unreachable in the first integration.\n */\n transport?: Omit<OUITransportConfig, \"namespace\"> & { namespace?: string };\n}\n\n/** A live OUI instance. */\nexport interface OUIInstance {\n /** The transport OUI owns. Exposed for wiring, not for reimplementation. */\n readonly transport: OwnedTransport;\n\n /** Manifests for every registered surface, as the agent sees them. */\n readonly manifests: readonly OUISurface[];\n\n /** Register every surface and connect. */\n start(): Promise<void>;\n\n /**\n * Deregister every surface and detach OUI from the socket. The socket stays\n * connected: the integrator owns it, and other code may share it.\n */\n stop(): void;\n\n /** Look up a registered surface by id. */\n getSurface(id: string): DefinedSurface<never> | undefined;\n}\n\n/**\n * Instantiate OUI.\n *\n * `const` on the type parameter captures surface ids as literal types, which is\n * what allows duplicate detection to name the offending id rather than failing\n * with an unassignable-to-never error.\n */\nexport function createOUI<\n const TSurfaces extends readonly DefinedSurface<never>[],\n>(\n config: OUIConfig<TSurfaces> & ValidateSurfaceIds<SurfaceIds<TSurfaces>>,\n): OUIInstance {\n const {\n socket,\n surfaces,\n transport: transportConfig,\n } = config as OUIConfig<TSurfaces>;\n\n // Defensive, not decorative: the compile-time checks only bind when a caller\n // passes literals. A surface list assembled at runtime, or JS with no types\n // at all, reaches here unchecked.\n if (!socket) {\n throw new Error(\n \"[OUI] createOUI requires a socket. OUI owns the wire; the integrator owns the connection.\",\n );\n }\n if (!Array.isArray(surfaces) || surfaces.length === 0) {\n throw new Error(\"[OUI] createOUI requires at least one surface.\");\n }\n\n const seen = new Set<string>();\n for (const surface of surfaces) {\n if (seen.has(surface.id)) {\n throw new Error(\n `[OUI] Duplicate surface id \"${surface.id}\". Registration is keyed by id, so the second would replace the first.`,\n );\n }\n seen.add(surface.id);\n }\n\n const transport = brand<\"transport\", OUITransport>(\n createWebSocketTransport(socket, transportConfig),\n );\n\n const byId = new Map(surfaces.map((s) => [s.id, s] as const));\n\n return {\n transport,\n manifests: surfaces.map((s) => s.toManifest()),\n\n async start() {\n await transport.connect();\n for (const surface of surfaces) {\n transport.registerSurface(surface.toManifest());\n }\n },\n\n stop() {\n for (const surface of surfaces) {\n transport.deregisterSurface(surface.id);\n }\n transport.dispose();\n },\n\n getSurface(id) {\n return byId.get(id);\n },\n };\n}\n\n/** Re-exported so integrators can name the error type in tests. */\nexport type { OUIConfigError };\n","/**\n * The client-side surface runtime.\n *\n * Holds the surfaces a client has mounted, answers every action request with a\n * result, and produces the snapshot an agent runtime works from.\n *\n * WHY THIS EXISTS\n *\n * The first integration kept no client-side record of what was mounted. Each\n * surface hook registered itself with a server-side registry and listened for\n * dispatches on its own. Three things followed:\n *\n * - The registry was the only record of what the client could do, and it lost\n * entries: a dead socket's cleanup removed a live tab's registration, and the\n * browser never registered again. The agent then had no UI tools at all.\n * - Nothing answered a dispatch. The agent was told an action succeeded before\n * the client had run it, and never saw the page an action led to.\n * - Every hook listened independently, through two paths, so one dispatch ran\n * twice and nothing de-duplicated it.\n *\n * Here the client is the record. `snapshot()` is what the client can do right\n * now, and every request is run once, waited on until the UI settles, and\n * answered with its result and the snapshot after it.\n */\nimport type {\n OUIActionRequest,\n OUIActionResult,\n OUISurface,\n OUISurfaceSnapshot,\n OUIObservationSnapshot,\n} from \"../spec/index.js\";\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport {\n createWebSocketTransport,\n type SocketLike,\n} from \"../transport/websocket.js\";\nimport type {\n ActionHandlerResult,\n ActionPollingConfig,\n DefinedSurface,\n} from \"./define-surface.js\";\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\nexport interface SettleOptions {\n /**\n * The UI counts as settled once nothing has mounted, unmounted or changed an\n * observation for this long, and no hold is open. Default 250 ms.\n */\n quietMs?: number;\n /** Give up waiting after this long and answer with `settled: false`. Default 5000 ms. */\n timeoutMs?: number;\n}\n\nexport interface SurfaceRuntimeOptions {\n /** The socket to answer requests on. Can be set or replaced later with `attach`. */\n socket?: SocketLike | null;\n\n /** Wire configuration for the transport the runtime builds on the socket. */\n transport?: OUITransportConfig;\n\n /**\n * Also announce registrations and observations over the transport, for agent\n * runtimes that keep a server-side registry. Default true.\n *\n * An agent runtime that takes the client's snapshot instead (sent with each\n * turn, and returned on every result) has no use for them: set false.\n */\n announce?: boolean;\n\n settle?: SettleOptions;\n\n /** How many answered request ids to remember, for de-duplication. Default 500. */\n dedupeWindow?: number;\n\n /**\n * Decides whether a request that arrived on the socket may run at all. A\n * refused request is neither run nor answered, and is logged.\n *\n * The server should be the only sender of action requests, but a client can\n * also check that a request is one it expects: for example, only while its\n * agent has a turn in progress. Requests passed to `execute` directly are\n * not checked; they come from the application itself.\n */\n accept?: (request: OUIActionRequest) => boolean;\n}\n\n// ─── Public types ────────────────────────────────────────────────────────────\n\nexport interface MountedSurface {\n readonly surfaceId: string;\n /** Record an observation value. A no-op once unmounted. */\n pushObservation(observationId: string, value: unknown): void;\n /** Remove this mount. Other mounts of the same surface id are unaffected. */\n unmount(): void;\n}\n\nexport interface SurfaceRuntime {\n /**\n * Mount a surface. `getContext` is read when an action runs, so handlers see\n * the latest state rather than the state at mount time.\n *\n * Mounting the same surface id twice is allowed (React StrictMode does it on\n * every mount); the most recent mount serves its actions.\n */\n mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface;\n\n /** Answer requests arriving on this socket (null detaches). */\n attach(socket: SocketLike | null): void;\n\n /** What the client can do right now. */\n snapshot(): OUISurfaceSnapshot;\n\n /**\n * Run a request once and resolve with its result. A request id seen before\n * resolves with the first result instead of running again.\n */\n execute(request: OUIActionRequest): Promise<OUIActionResult>;\n\n /**\n * Keep the UI unsettled until the returned function is called. For work an\n * action starts that mounting and unmounting cannot show, such as a route's\n * code still loading or a page fetching the data it will display.\n */\n hold(): () => void;\n\n /** Called whenever the snapshot changes. */\n subscribe(listener: () => void): () => void;\n\n /** Stop polling, detach from the socket and forget every mount. */\n dispose(): void;\n}\n\n// ─── Implementation ──────────────────────────────────────────────────────────\n\ninterface Entry {\n key: number;\n surface: DefinedSurface<unknown>;\n getContext: () => unknown;\n}\n\nconst DEFAULT_QUIET_MS = 250;\nconst DEFAULT_SETTLE_TIMEOUT_MS = 5000;\nconst DEFAULT_DEDUPE_WINDOW = 500;\nconst SETTLE_TICK_MS = 50;\n\nexport function createSurfaceRuntime(\n options: SurfaceRuntimeOptions = {},\n): SurfaceRuntime {\n const announce = options.announce ?? true;\n const quietMs = options.settle?.quietMs ?? DEFAULT_QUIET_MS;\n const settleTimeoutMs =\n options.settle?.timeoutMs ?? DEFAULT_SETTLE_TIMEOUT_MS;\n const dedupeWindow = options.dedupeWindow ?? DEFAULT_DEDUPE_WINDOW;\n\n let nextKey = 1;\n const entries: Entry[] = [];\n const observations = new Map<string, Map<string, unknown>>();\n const serializedObservations = new Map<string, string>();\n const holds = new Set<number>();\n let nextHold = 1;\n const results = new Map<string, Promise<OUIActionResult>>();\n const pollers = new Map<string, ReturnType<typeof setInterval>>();\n // How each running poll answers its request if it has to stop early.\n const abandon = new Map<\n string,\n (error: { code: string; message: string }) => void\n >();\n const listeners = new Set<() => void>();\n // Resolves once a request's first result has been handed to the transport.\n const acks = new Map<\n string,\n { promise: Promise<void>; resolve: () => void }\n >();\n function ackFor(requestId: string) {\n let ack = acks.get(requestId);\n if (!ack) {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => (resolve = r));\n ack = { promise, resolve };\n acks.set(requestId, ack);\n }\n return ack;\n }\n function acknowledged(requestId: string): Promise<void> {\n return ackFor(requestId).promise;\n }\n let lastChangeAt = Date.now();\n\n let socket: SocketLike | null = null;\n let transport: OUITransport | null = null;\n let detachTransport: Array<() => void> = [];\n\n /**\n * `settles: false` for changes that are not the UI reacting to an action,\n * such as an async job's progress: those notify listeners but do not keep\n * an action's result waiting.\n */\n function changed(settles = true) {\n if (settles) lastChangeAt = Date.now();\n for (const l of [...listeners]) l();\n }\n\n function activeFor(surfaceId: string): Entry | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].surface.id === surfaceId) return entries[i];\n }\n return undefined;\n }\n\n /** Active entries, one per surface id, in the order each id was first mounted. */\n function activeEntries(): Entry[] {\n const seen = new Set<string>();\n const out: Entry[] = [];\n for (const e of entries) {\n if (seen.has(e.surface.id)) continue;\n seen.add(e.surface.id);\n out.push(activeFor(e.surface.id)!);\n }\n return out;\n }\n\n function announceSurface(entry: Entry) {\n if (!announce || !transport) return;\n transport.registerSurface(entry.surface.toManifest());\n const obs = observations.get(entry.surface.id);\n if (obs) {\n for (const [observationId, value] of obs) {\n transport.pushObservation({\n surfaceId: entry.surface.id,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n }\n }\n\n function announceAll() {\n for (const e of activeEntries()) announceSurface(e);\n }\n\n function setObservation(\n surfaceId: string,\n observationId: string,\n value: unknown,\n settles = true,\n ) {\n const key = `${surfaceId}\\u0000${observationId}`;\n let serialized: string;\n try {\n serialized = JSON.stringify(value) ?? \"undefined\";\n } catch {\n serialized = String(value);\n }\n if (serializedObservations.get(key) === serialized) return;\n serializedObservations.set(key, serialized);\n\n let obs = observations.get(surfaceId);\n if (!obs) {\n obs = new Map();\n observations.set(surfaceId, obs);\n }\n obs.set(observationId, toJsonSafe(value));\n\n if (announce && transport) {\n transport.pushObservation({\n surfaceId,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n changed(settles);\n }\n\n function forgetSurface(surfaceId: string) {\n observations.delete(surfaceId);\n for (const key of [...serializedObservations.keys()]) {\n if (key.startsWith(`${surfaceId}\\u0000`))\n serializedObservations.delete(key);\n }\n for (const [key, timer] of pollers) {\n if (key.startsWith(`${surfaceId}\\u0000`)) {\n clearInterval(timer);\n pollers.delete(key);\n // The request still gets its final answer: a poll that stops\n // without one leaves the agent waiting forever.\n abandon.get(key)?.({\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${surfaceId}\" left the page before its action finished, ` +\n \"so it is no longer being followed. Check what the page shows \" +\n \"before trying again.\",\n });\n abandon.delete(key);\n }\n }\n }\n\n // ─── Polling (async actions) ──────────────────────────────────────────────\n\n /**\n * Polls an async action to completion, publishing progress as an observation\n * and, when it ends, the request's final result (OUI spec §7.3: an async\n * action is acknowledged, then answered once more when it finishes).\n */\n function startPolling(\n requestId: string,\n surfaceId: string,\n actionId: string,\n polling: ActionPollingConfig<unknown>,\n dispatchResult: unknown,\n ) {\n const finish = async (\n success: boolean,\n data: unknown,\n error?: { code: string; message: string },\n ) => {\n // The acknowledgment goes first: a job can finish before the UI settles.\n await acknowledged(requestId);\n const snap = snapshot();\n transport?.sendResult({\n requestId,\n success,\n ...(data !== undefined ? { data: toJsonSafe(data) } : {}),\n ...(error ? { error } : {}),\n interim: false,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n });\n acks.delete(requestId);\n };\n\n // The observation id is the one surfaces have always published under.\n const observationId = `${surfaceId}:${actionId}:status`;\n const pollerKey = `${surfaceId}\\u0000${actionId}`;\n\n if (polling.subscribe) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: true },\n false,\n );\n return;\n }\n if (!polling.resolve) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: false },\n false,\n );\n return;\n }\n\n const existing = pollers.get(pollerKey);\n if (existing) {\n clearInterval(existing);\n pollers.delete(pollerKey);\n abandon.get(pollerKey)?.({\n code: \"SUPERSEDED\",\n message:\n `\"${actionId}\" was started again before this run finished, ` +\n \"so only the newer run is being followed.\",\n });\n abandon.delete(pollerKey);\n }\n\n setObservation(\n surfaceId,\n observationId,\n { status: \"polling\", dispatchResult, interim: true },\n false,\n );\n\n const maxAttempts = polling.maxAttempts ?? Infinity;\n const maxDuration = polling.maxDurationMs ?? Infinity;\n const startedAt = Date.now();\n let attempts = 0;\n\n const timer = setInterval(async () => {\n attempts++;\n if (attempts > maxAttempts || Date.now() - startedAt > maxDuration) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n abandon.delete(pollerKey);\n setObservation(\n surfaceId,\n observationId,\n { status: \"timeout\", dispatchResult, interim: false },\n false,\n );\n void finish(false, undefined, {\n code: \"TIMEOUT\",\n message: `\"${actionId}\" did not finish within its polling limits.`,\n });\n return;\n }\n const entry = activeFor(surfaceId);\n if (!entry) {\n // forgetSurface normally gets here first; answer anyway.\n clearInterval(timer);\n pollers.delete(pollerKey);\n const gone = abandon.get(pollerKey);\n abandon.delete(pollerKey);\n gone?.({\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${surfaceId}\" left the page before \"${actionId}\" ` +\n \"finished, so it is no longer being followed. Check what the \" +\n \"page shows before trying again.\",\n });\n return;\n }\n // The surface may have remounted without this action (a control that is\n // disabled while its job runs, say). The job is still running, so keep\n // following it with the polling it started with.\n const action = entry.surface.actions.find((a) => a.id === actionId);\n const resolve = action?.polling?.resolve ?? polling.resolve;\n if (!resolve) return;\n try {\n const r = await resolve(dispatchResult, entry.getContext());\n setObservation(\n surfaceId,\n observationId,\n {\n ...(r.data as Record<string, unknown>),\n interim: !r.done,\n },\n false,\n );\n if (r.done) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n abandon.delete(pollerKey);\n void finish(true, r.data);\n }\n } catch (err) {\n // A transient failure is reported, not fatal: keep polling.\n setObservation(\n surfaceId,\n observationId,\n { status: \"poll_error\", error: String(err), interim: true },\n false,\n );\n }\n }, polling.intervalMs);\n\n pollers.set(pollerKey, timer);\n abandon.set(pollerKey, (error) => void finish(false, undefined, error));\n }\n\n // ─── Settling ─────────────────────────────────────────────────────────────\n\n async function waitUntilSettled(since: number): Promise<boolean> {\n const deadline = since + settleTimeoutMs;\n for (;;) {\n const now = Date.now();\n const quietFor = now - Math.max(since, lastChangeAt);\n if (holds.size === 0 && quietFor >= quietMs) return true;\n if (now >= deadline) return false;\n await sleep(Math.min(SETTLE_TICK_MS, deadline - now));\n }\n }\n\n // ─── Execution ────────────────────────────────────────────────────────────\n\n async function run(request: OUIActionRequest): Promise<OUIActionResult> {\n const startedAt = Date.now();\n const entry = activeFor(request.surfaceId);\n\n let result: ActionHandlerResult;\n let interim = false;\n if (!entry) {\n const mounted = activeEntries().map((e) => e.surface.id);\n result = {\n success: false,\n error: {\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${request.surfaceId}\" is not on screen. ` +\n `Mounted surfaces: ${mounted.length ? mounted.join(\", \") : \"none\"}.`,\n },\n };\n } else {\n // executeAction turns a thrown handler into ACTION_EXECUTION_ERROR.\n result = await entry.surface.executeAction(\n request.actionId,\n request.params ?? {},\n entry.getContext(),\n );\n if (result.success) {\n const action = entry.surface.actions.find(\n (a) => a.id === request.actionId,\n );\n if (action?.polling) {\n interim = true;\n startPolling(\n request.requestId,\n entry.surface.id,\n action.id,\n action.polling,\n result.data ?? result.dispatchMeta,\n );\n }\n }\n }\n\n const settled = await waitUntilSettled(startedAt);\n const snap = snapshot();\n\n return {\n requestId: request.requestId,\n success: result.success,\n ...(result.data !== undefined ? { data: toJsonSafe(result.data) } : {}),\n ...(result.error\n ? { error: toJsonSafe(result.error) as OUIActionResult[\"error\"] }\n : {}),\n ...(interim ? { interim: true } : {}),\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n settled,\n };\n }\n\n function execute(request: OUIActionRequest): Promise<OUIActionResult> {\n const seen = results.get(request.requestId);\n if (seen) return seen;\n\n const pending = run(request);\n results.set(request.requestId, pending);\n while (results.size > dedupeWindow) {\n const oldest = results.keys().next().value as string;\n results.delete(oldest);\n }\n return pending;\n }\n\n // ─── Snapshot ─────────────────────────────────────────────────────────────\n\n function snapshot(): OUISurfaceSnapshot {\n const surfaces: OUISurface[] = [];\n const obs: OUIObservationSnapshot = {};\n for (const e of activeEntries()) {\n surfaces.push(e.surface.toManifest());\n const values = observations.get(e.surface.id);\n if (values && values.size > 0)\n obs[e.surface.id] = Object.fromEntries(values);\n }\n return { surfaces, observations: obs };\n }\n\n // ─── Transport ────────────────────────────────────────────────────────────\n\n function attach(next: SocketLike | null) {\n if (next === socket) return;\n for (const off of detachTransport) off();\n detachTransport = [];\n transport?.dispose();\n transport = null;\n socket = next;\n if (!next) return;\n\n const t = createWebSocketTransport(next, options.transport);\n transport = t;\n\n detachTransport.push(\n t.onAction((request) => {\n if (options.accept && !options.accept(request)) {\n console.warn(\n `[OUI] Refused a request the client does not accept: ${request.surfaceId}.${request.actionId} (${request.requestId})`,\n );\n return;\n }\n void execute(request).then((result) => {\n // Answer on whichever transport is live when the result is ready: a\n // reconnect in between keeps the same socket, so this still reaches\n // the runtime that asked.\n transport?.sendResult(result);\n const ack = ackFor(request.requestId);\n ack.resolve();\n // Keep the gate only while a final result may still follow.\n if (!result.interim) acks.delete(request.requestId);\n });\n }),\n );\n\n if (announce) {\n // A server-side registry forgets a socket's surfaces when it drops, so\n // every (re)connection announces them again.\n detachTransport.push(\n t.onConnectionChange((connected) => {\n if (connected) announceAll();\n }),\n );\n if (t.connected) announceAll();\n }\n }\n\n if (options.socket) attach(options.socket);\n\n // ─── Mounting ─────────────────────────────────────────────────────────────\n\n function mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface {\n const entry: Entry = {\n key: nextKey++,\n surface: surface as unknown as DefinedSurface<unknown>,\n getContext: getContext as () => unknown,\n };\n entries.push(entry);\n announceSurface(entry);\n changed();\n\n let mounted = true;\n return {\n surfaceId: surface.id,\n pushObservation(observationId, value) {\n // Only the mount serving the surface speaks for it.\n if (!mounted || activeFor(surface.id) !== entry) return;\n setObservation(surface.id, observationId, value);\n },\n unmount() {\n if (!mounted) return;\n mounted = false;\n const i = entries.indexOf(entry);\n if (i >= 0) entries.splice(i, 1);\n const replacement = activeFor(surface.id);\n if (replacement) {\n announceSurface(replacement);\n } else {\n forgetSurface(surface.id);\n if (announce && transport) transport.deregisterSurface(surface.id);\n }\n changed();\n },\n };\n }\n\n return {\n mount,\n attach,\n snapshot,\n execute,\n hold() {\n const id = nextHold++;\n holds.add(id);\n changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n holds.delete(id);\n changed();\n };\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n dispose() {\n for (const timer of pollers.values()) clearInterval(timer);\n pollers.clear();\n abandon.clear();\n attach(null);\n entries.length = 0;\n observations.clear();\n serializedObservations.clear();\n holds.clear();\n listeners.clear();\n acks.clear();\n },\n };\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Results and observations cross a wire as JSON. A handler returning something\n * that is not (a DOM node, a class instance with cycles) must not take the\n * result down with it.\n */\nfunction toJsonSafe(value: unknown): unknown {\n if (value === undefined) return undefined;\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n return String(value);\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkDGMKSJTY_cjs = require('../chunk-DGMKSJTY.cjs');
3
+ var chunkGDB56ZQZ_cjs = require('../chunk-GDB56ZQZ.cjs');
4
4
  var chunkZKM4XWAB_cjs = require('../chunk-ZKM4XWAB.cjs');
5
5
  require('../chunk-DCVVTP3V.cjs');
6
6
 
@@ -8,15 +8,15 @@ require('../chunk-DCVVTP3V.cjs');
8
8
 
9
9
  Object.defineProperty(exports, "createOUI", {
10
10
  enumerable: true,
11
- get: function () { return chunkDGMKSJTY_cjs.createOUI; }
11
+ get: function () { return chunkGDB56ZQZ_cjs.createOUI; }
12
12
  });
13
13
  Object.defineProperty(exports, "createSurfaceRuntime", {
14
14
  enumerable: true,
15
- get: function () { return chunkDGMKSJTY_cjs.createSurfaceRuntime; }
15
+ get: function () { return chunkGDB56ZQZ_cjs.createSurfaceRuntime; }
16
16
  });
17
17
  Object.defineProperty(exports, "defineSurface", {
18
18
  enumerable: true,
19
- get: function () { return chunkDGMKSJTY_cjs.defineSurface; }
19
+ get: function () { return chunkGDB56ZQZ_cjs.defineSurface; }
20
20
  });
21
21
  Object.defineProperty(exports, "OUI_PROTOCOL_EVENTS", {
22
22
  enumerable: true,
@@ -1,4 +1,4 @@
1
- export { createOUI, createSurfaceRuntime, defineSurface } from '../chunk-GXTNZ44I.js';
1
+ export { createOUI, createSurfaceRuntime, defineSurface } from '../chunk-UQLG55ST.js';
2
2
  export { OUI_PROTOCOL_EVENTS } from '../chunk-BMCL2K74.js';
3
3
  import '../chunk-F3WKIRAU.js';
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkDGMKSJTY_cjs = require('./chunk-DGMKSJTY.cjs');
3
+ var chunkGDB56ZQZ_cjs = require('./chunk-GDB56ZQZ.cjs');
4
4
  var chunkZKM4XWAB_cjs = require('./chunk-ZKM4XWAB.cjs');
5
5
  var chunkF3SKRAGU_cjs = require('./chunk-F3SKRAGU.cjs');
6
6
  var chunkROGKEMLL_cjs = require('./chunk-ROGKEMLL.cjs');
@@ -10,15 +10,15 @@ var chunkDCVVTP3V_cjs = require('./chunk-DCVVTP3V.cjs');
10
10
 
11
11
  Object.defineProperty(exports, "createOUI", {
12
12
  enumerable: true,
13
- get: function () { return chunkDGMKSJTY_cjs.createOUI; }
13
+ get: function () { return chunkGDB56ZQZ_cjs.createOUI; }
14
14
  });
15
15
  Object.defineProperty(exports, "createSurfaceRuntime", {
16
16
  enumerable: true,
17
- get: function () { return chunkDGMKSJTY_cjs.createSurfaceRuntime; }
17
+ get: function () { return chunkGDB56ZQZ_cjs.createSurfaceRuntime; }
18
18
  });
19
19
  Object.defineProperty(exports, "defineSurface", {
20
20
  enumerable: true,
21
- get: function () { return chunkDGMKSJTY_cjs.defineSurface; }
21
+ get: function () { return chunkGDB56ZQZ_cjs.defineSurface; }
22
22
  });
23
23
  Object.defineProperty(exports, "OUI_PROTOCOL_EVENTS", {
24
24
  enumerable: true,
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { createOUI, createSurfaceRuntime, defineSurface } from './chunk-GXTNZ44I.js';
1
+ export { createOUI, createSurfaceRuntime, defineSurface } from './chunk-UQLG55ST.js';
2
2
  export { OUI_PROTOCOL_EVENTS } from './chunk-BMCL2K74.js';
3
3
  export { SurfaceRuntimeProvider, useObservation, useSurface, useSurfaceHold, useSurfaceRuntime } from './chunk-NYCJZQSP.js';
4
4
  export { createDirectTransportPair } from './chunk-IIZ6HL2L.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oui-spec",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "OUI — The OpenUI Specification. A machine-readable contract for agent-controllable user interfaces.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/brand.ts","../src/core/define-surface.ts","../src/core/create-oui.ts","../src/core/surface-runtime.ts"],"names":["createWebSocketTransport"],"mappings":";;;;;AA2BO,SAAS,MACd,KAAA,EACuB;AACvB,EAAA,OAAO,KAAA;AACT;;;AC8FO,SAAS,cAId,UAAA,EACwC;AAExC,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,KAAA,MAAW,MAAA,IAAU,WAAW,OAAA,EAAS;AACvC,IAAA,IAAI,SAAA,CAAU,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,2BAAA,EAA8B,MAAA,CAAO,EAAE,CAAA,cAAA,EAAiB,WAAW,EAAE,CAAA,CAAA;AAAA,OACvE;AAAA,IACF;AACA,IAAA,SAAA,CAAU,GAAA,CAAI,OAAO,EAAE,CAAA;AAAA,EACzB;AAGA,EAAA,IAAI,WAAW,YAAA,EAAc;AAC3B,IAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,IAAA,KAAA,MAAW,GAAA,IAAO,WAAW,YAAA,EAAc;AACzC,MAAA,IAAI,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG;AACtB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,gCAAA,EAAmC,GAAA,CAAI,EAAE,CAAA,cAAA,EAAiB,WAAW,EAAE,CAAA,CAAA;AAAA,SACzE;AAAA,MACF;AACA,MAAA,MAAA,CAAO,GAAA,CAAI,IAAI,EAAE,CAAA;AAAA,IACnB;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAA0B;AAAA,IAC/B,GAAG,UAAA;AAAA;AAAA,IAGH,UAAA,GAAyB;AACvB,MAAA,OAAO;AAAA,QACL,IAAI,UAAA,CAAW,EAAA;AAAA,QACf,MAAM,UAAA,CAAW,IAAA;AAAA,QACjB,aAAa,UAAA,CAAW,WAAA;AAAA,QACxB,SAAS,UAAA,CAAW,OAAA;AAAA,QACpB,YAAY,UAAA,CAAW,UAAA;AAAA,QACvB,OAAA,EAAS,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA;AAAA,QAChD,YAAA,EAAc,UAAA,CAAW,YAAA,EAAc,GAAA,CAAI,aAAa,CAAA;AAAA,QACxD,UAAU,UAAA,CAAW;AAAA,OACvB;AAAA,IACF,CAAA;AAAA;AAAA,IAGA,MAAM,aAAA,CACJ,QAAA,EACA,MAAA,EACA,OAAA,EAC8B;AAC9B,MAAA,MAAM,MAAA,GAAS,WAAW,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,QAAQ,CAAA;AAC/D,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,kBAAA;AAAA,YACN,OAAA,EAAS,CAAA,QAAA,EAAW,QAAQ,CAAA,wBAAA,EAA2B,WAAW,EAAE,CAAA,CAAA;AAAA;AACtE,SACF;AAAA,MACF;AACA,MAAA,IAAI;AACF,QAAA,OAAO,MAAM,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,OAAO,CAAA;AAAA,MAC7C,SAAS,GAAA,EAAK;AACZ,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,wBAAA;AAAA,YACN,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA;AAC1D,SACF;AAAA,MACF;AAAA,IACF,CAAA;AAAA;AAAA,IAGA,YAAA,GAAyB;AACvB,MAAA,OAAO,WAAW,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,IAC3C,CAAA;AAAA;AAAA,IAGA,iBAAiB,QAAA,EAAgD;AAC/D,MAAA,MAAM,MAAA,GAAS,WAAW,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,QAAQ,CAAA;AAC/D,MAAA,OAAO,MAAA,EAAQ,OAAA;AAAA,IACjB;AAAA,GACD,CAAA;AACH;AAyBA,SAAS,iBAAoB,MAAA,EAAwC;AACnE,EAAA,OAAO;AAAA,IACL,IAAI,MAAA,CAAO,EAAA;AAAA,IACX,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,eAAe,MAAA,CAAO,aAAA;AAAA,IACtB,mBAAmB,MAAA,CAAO,iBAAA;AAAA,IAC1B,MAAM,MAAA,CAAO;AAAA,GACf;AACF;AAEA,SAAS,cAAc,GAAA,EAA4C;AACjE,EAAA,OAAO;AAAA,IACL,IAAI,GAAA,CAAI,EAAA;AAAA,IACR,aAAa,GAAA,CAAI,WAAA;AAAA,IACjB,QAAQ,GAAA,CAAI;AAAA,GACd;AACF;;;AC5JO,SAAS,UAGd,MAAA,EACa;AACb,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA,EAAW;AAAA,GACb,GAAI,MAAA;AAKJ,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,IAAK,QAAA,CAAS,WAAW,CAAA,EAAG;AACrD,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AAEA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA,EAAG;AACxB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,4BAAA,EAA+B,QAAQ,EAAE,CAAA,sEAAA;AAAA,OAC3C;AAAA,IACF;AACA,IAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,EAAE,CAAA;AAAA,EACrB;AAEA,EAAA,MAAM,SAAA,GAAY,KAAA;AAAA,IAChBA,0CAAA,CAAyB,QAAQ,eAAe;AAAA,GAClD;AAEA,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,CAAC,CAAU,CAAC,CAAA;AAE5D,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,WAAW,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA;AAAA,IAE7C,MAAM,KAAA,GAAQ;AACZ,MAAA,MAAM,UAAU,OAAA,EAAQ;AACxB,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,SAAA,CAAU,eAAA,CAAgB,OAAA,CAAQ,UAAA,EAAY,CAAA;AAAA,MAChD;AAAA,IACF,CAAA;AAAA,IAEA,IAAA,GAAO;AACL,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,SAAA,CAAU,iBAAA,CAAkB,QAAQ,EAAE,CAAA;AAAA,MACxC;AACA,MAAA,SAAA,CAAU,OAAA,EAAQ;AAAA,IACpB,CAAA;AAAA,IAEA,WAAW,EAAA,EAAI;AACb,MAAA,OAAO,IAAA,CAAK,IAAI,EAAE,CAAA;AAAA,IACpB;AAAA,GACF;AACF;;;ACpBA,IAAM,gBAAA,GAAmB,GAAA;AACzB,IAAM,yBAAA,GAA4B,GAAA;AAClC,IAAM,qBAAA,GAAwB,GAAA;AAC9B,IAAM,cAAA,GAAiB,EAAA;AAEhB,SAAS,oBAAA,CACd,OAAA,GAAiC,EAAC,EAClB;AAChB,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,IAAA;AACrC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,EAAQ,OAAA,IAAW,gBAAA;AAC3C,EAAA,MAAM,eAAA,GACJ,OAAA,CAAQ,MAAA,EAAQ,SAAA,IAAa,yBAAA;AAC/B,EAAA,MAAM,YAAA,GAAe,QAAQ,YAAA,IAAgB,qBAAA;AAE7C,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,MAAM,UAAmB,EAAC;AAC1B,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAkC;AAC3D,EAAA,MAAM,sBAAA,uBAA6B,GAAA,EAAoB;AACvD,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAsC;AAC1D,EAAA,MAAM,OAAA,uBAAc,GAAA,EAA4C;AAChE,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAgB;AAEtC,EAAA,MAAM,IAAA,uBAAW,GAAA,EAGf;AACF,EAAA,SAAS,OAAO,SAAA,EAAmB;AACjC,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAC5B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,IAAI,OAAA;AACJ,MAAA,MAAM,UAAU,IAAI,OAAA,CAAc,CAAC,CAAA,KAAO,UAAU,CAAE,CAAA;AACtD,MAAA,GAAA,GAAM,EAAE,SAAS,OAAA,EAAQ;AACzB,MAAA,IAAA,CAAK,GAAA,CAAI,WAAW,GAAG,CAAA;AAAA,IACzB;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,SAAS,aAAa,SAAA,EAAkC;AACtD,IAAA,OAAO,MAAA,CAAO,SAAS,CAAA,CAAE,OAAA;AAAA,EAC3B;AACA,EAAA,IAAI,YAAA,GAAe,KAAK,GAAA,EAAI;AAE5B,EAAA,IAAI,MAAA,GAA4B,IAAA;AAChC,EAAA,IAAI,SAAA,GAAiC,IAAA;AACrC,EAAA,IAAI,kBAAqC,EAAC;AAO1C,EAAA,SAAS,OAAA,CAAQ,UAAU,IAAA,EAAM;AAC/B,IAAA,IAAI,OAAA,EAAS,YAAA,GAAe,IAAA,CAAK,GAAA,EAAI;AACrC,IAAA,KAAA,MAAW,CAAA,IAAK,CAAC,GAAG,SAAS,GAAG,CAAA,EAAE;AAAA,EACpC;AAEA,EAAA,SAAS,UAAU,SAAA,EAAsC;AACvD,IAAA,KAAA,IAAS,IAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC5C,MAAA,IAAI,OAAA,CAAQ,CAAC,CAAA,CAAE,OAAA,CAAQ,OAAO,SAAA,EAAW,OAAO,QAAQ,CAAC,CAAA;AAAA,IAC3D;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,SAAS,aAAA,GAAyB;AAChC,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,IAAA,MAAM,MAAe,EAAC;AACtB,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA,EAAG;AAC5B,MAAA,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA;AACrB,MAAA,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAE,CAAA;AAAA,IACnC;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,SAAS,gBAAgB,KAAA,EAAc;AACrC,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,SAAA,EAAW;AAC7B,IAAA,SAAA,CAAU,eAAA,CAAgB,KAAA,CAAM,OAAA,CAAQ,UAAA,EAAY,CAAA;AACpD,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,QAAQ,EAAE,CAAA;AAC7C,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,KAAA,MAAW,CAAC,aAAA,EAAe,KAAK,CAAA,IAAK,GAAA,EAAK;AACxC,QAAA,SAAA,CAAU,eAAA,CAAgB;AAAA,UACxB,SAAA,EAAW,MAAM,OAAA,CAAQ,EAAA;AAAA,UACzB,aAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA,EAAW,KAAK,GAAA;AAAI,SACrB,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,SAAS,WAAA,GAAc;AACrB,IAAA,KAAA,MAAW,CAAA,IAAK,aAAA,EAAc,EAAG,eAAA,CAAgB,CAAC,CAAA;AAAA,EACpD;AAEA,EAAA,SAAS,cAAA,CACP,SAAA,EACA,aAAA,EACA,KAAA,EACA,UAAU,IAAA,EACV;AACA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,SAAS,CAAA,EAAA,EAAS,aAAa,CAAA,CAAA;AAC9C,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI;AACF,MAAA,UAAA,GAAa,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,IAAK,WAAA;AAAA,IACxC,CAAA,CAAA,MAAQ;AACN,MAAA,UAAA,GAAa,OAAO,KAAK,CAAA;AAAA,IAC3B;AACA,IAAA,IAAI,sBAAA,CAAuB,GAAA,CAAI,GAAG,CAAA,KAAM,UAAA,EAAY;AACpD,IAAA,sBAAA,CAAuB,GAAA,CAAI,KAAK,UAAU,CAAA;AAE1C,IAAA,IAAI,GAAA,GAAM,YAAA,CAAa,GAAA,CAAI,SAAS,CAAA;AACpC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,GAAA,uBAAU,GAAA,EAAI;AACd,MAAA,YAAA,CAAa,GAAA,CAAI,WAAW,GAAG,CAAA;AAAA,IACjC;AACA,IAAA,GAAA,CAAI,GAAA,CAAI,aAAA,EAAe,UAAA,CAAW,KAAK,CAAC,CAAA;AAExC,IAAA,IAAI,YAAY,SAAA,EAAW;AACzB,MAAA,SAAA,CAAU,eAAA,CAAgB;AAAA,QACxB,SAAA;AAAA,QACA,aAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA,EAAW,KAAK,GAAA;AAAI,OACrB,CAAA;AAAA,IACH;AACA,IAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,EACjB;AAEA,EAAA,SAAS,cAAc,SAAA,EAAmB;AACxC,IAAA,YAAA,CAAa,OAAO,SAAS,CAAA;AAC7B,IAAA,KAAA,MAAW,OAAO,CAAC,GAAG,sBAAA,CAAuB,IAAA,EAAM,CAAA,EAAG;AACpD,MAAA,IAAI,GAAA,CAAI,UAAA,CAAW,CAAA,EAAG,SAAS,CAAA,EAAA,CAAQ,CAAA;AACrC,QAAA,sBAAA,CAAuB,OAAO,GAAG,CAAA;AAAA,IACrC;AACA,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,OAAA,EAAS;AAClC,MAAA,IAAI,GAAA,CAAI,UAAA,CAAW,CAAA,EAAG,SAAS,IAAQ,CAAA,EAAG;AACxC,QAAA,aAAA,CAAc,KAAK,CAAA;AACnB,QAAA,OAAA,CAAQ,OAAO,GAAG,CAAA;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AASA,EAAA,SAAS,YAAA,CACP,SAAA,EACA,SAAA,EACA,QAAA,EACA,SACA,cAAA,EACA;AACA,IAAA,MAAM,MAAA,GAAS,OACb,OAAA,EACA,IAAA,EACA,KAAA,KACG;AAEH,MAAA,MAAM,aAAa,SAAS,CAAA;AAC5B,MAAA,MAAM,OAAO,QAAA,EAAS;AACtB,MAAA,SAAA,EAAW,UAAA,CAAW;AAAA,QACpB,SAAA;AAAA,QACA,OAAA;AAAA,QACA,GAAI,SAAS,MAAA,GAAY,EAAE,MAAM,UAAA,CAAW,IAAI,CAAA,EAAE,GAAI,EAAC;AAAA,QACvD,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU,EAAC;AAAA,QACzB,OAAA,EAAS,KAAA;AAAA,QACT,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,QACpB,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,cAAc,IAAA,CAAK;AAAA,OACpB,CAAA;AACD,MAAA,IAAA,CAAK,OAAO,SAAS,CAAA;AAAA,IACvB,CAAA;AAGA,IAAA,MAAM,aAAA,GAAgB,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,QAAQ,CAAA,OAAA,CAAA;AAC9C,IAAA,MAAM,SAAA,GAAY,CAAA,EAAG,SAAS,CAAA,EAAA,EAAS,QAAQ,CAAA,CAAA;AAE/C,IAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,MAAA,cAAA;AAAA,QACE,SAAA;AAAA,QACA,aAAA;AAAA,QACA,EAAE,MAAA,EAAQ,YAAA,EAAc,cAAA,EAAgB,SAAS,IAAA,EAAK;AAAA,QACtD;AAAA,OACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AACpB,MAAA,cAAA;AAAA,QACE,SAAA;AAAA,QACA,aAAA;AAAA,QACA,EAAE,MAAA,EAAQ,YAAA,EAAc,cAAA,EAAgB,SAAS,KAAA,EAAM;AAAA,QACvD;AAAA,OACF;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AACtC,IAAA,IAAI,QAAA,gBAAwB,QAAQ,CAAA;AAEpC,IAAA,cAAA;AAAA,MACE,SAAA;AAAA,MACA,aAAA;AAAA,MACA,EAAE,MAAA,EAAQ,SAAA,EAAW,cAAA,EAAgB,SAAS,IAAA,EAAK;AAAA,MACnD;AAAA,KACF;AAEA,IAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,IAAe,QAAA;AAC3C,IAAA,MAAM,WAAA,GAAc,QAAQ,aAAA,IAAiB,QAAA;AAC7C,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,IAAA,IAAI,QAAA,GAAW,CAAA;AAEf,IAAA,MAAM,KAAA,GAAQ,YAAY,YAAY;AACpC,MAAA,QAAA,EAAA;AACA,MAAA,IAAI,WAAW,WAAA,IAAe,IAAA,CAAK,GAAA,EAAI,GAAI,YAAY,WAAA,EAAa;AAClE,QAAA,aAAA,CAAc,KAAK,CAAA;AACnB,QAAA,OAAA,CAAQ,OAAO,SAAS,CAAA;AACxB,QAAA,cAAA;AAAA,UACE,SAAA;AAAA,UACA,aAAA;AAAA,UACA,EAAE,MAAA,EAAQ,SAAA,EAAW,cAAA,EAAgB,SAAS,KAAA,EAAM;AAAA,UACpD;AAAA,SACF;AACA,QAAA,KAAK,MAAA,CAAO,OAAO,MAAA,EAAW;AAAA,UAC5B,IAAA,EAAM,SAAA;AAAA,UACN,OAAA,EAAS,IAAI,QAAQ,CAAA,2CAAA;AAAA,SACtB,CAAA;AACD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAA,GAAQ,UAAU,SAAS,CAAA;AACjC,MAAA,MAAM,MAAA,GAAS,OAAO,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,QAAQ,CAAA;AACnE,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,MAAA,EAAQ,SAAS,OAAA,EAAS;AACvC,QAAA,aAAA,CAAc,KAAK,CAAA;AACnB,QAAA,OAAA,CAAQ,OAAO,SAAS,CAAA;AACxB,QAAA;AAAA,MACF;AACA,MAAA,IAAI;AACF,QAAA,MAAM,CAAA,GAAI,MAAM,MAAA,CAAO,OAAA,CAAQ,OAAA;AAAA,UAC7B,cAAA;AAAA,UACA,MAAM,UAAA;AAAW,SACnB;AACA,QAAA,cAAA;AAAA,UACE,SAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,YACE,GAAI,CAAA,CAAE,IAAA;AAAA,YACN,OAAA,EAAS,CAAC,CAAA,CAAE;AAAA,WACd;AAAA,UACA;AAAA,SACF;AACA,QAAA,IAAI,EAAE,IAAA,EAAM;AACV,UAAA,aAAA,CAAc,KAAK,CAAA;AACnB,UAAA,OAAA,CAAQ,OAAO,SAAS,CAAA;AACxB,UAAA,KAAK,MAAA,CAAO,IAAA,EAAM,CAAA,CAAE,IAAI,CAAA;AAAA,QAC1B;AAAA,MACF,SAAS,GAAA,EAAK;AAEZ,QAAA,cAAA;AAAA,UACE,SAAA;AAAA,UACA,aAAA;AAAA,UACA,EAAE,QAAQ,YAAA,EAAc,KAAA,EAAO,OAAO,GAAG,CAAA,EAAG,SAAS,IAAA,EAAK;AAAA,UAC1D;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,EAAG,QAAQ,UAAU,CAAA;AAErB,IAAA,OAAA,CAAQ,GAAA,CAAI,WAAW,KAAK,CAAA;AAAA,EAC9B;AAIA,EAAA,eAAe,iBAAiB,KAAA,EAAiC;AAC/D,IAAA,MAAM,WAAW,KAAA,GAAQ,eAAA;AACzB,IAAA,WAAS;AACP,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,MAAM,QAAA,GAAW,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,OAAO,YAAY,CAAA;AACnD,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,CAAA,IAAK,QAAA,IAAY,SAAS,OAAO,IAAA;AACpD,MAAA,IAAI,GAAA,IAAO,UAAU,OAAO,KAAA;AAC5B,MAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,cAAA,EAAgB,QAAA,GAAW,GAAG,CAAC,CAAA;AAAA,IACtD;AAAA,EACF;AAIA,EAAA,eAAe,IAAI,OAAA,EAAqD;AACtE,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,OAAA,CAAQ,SAAS,CAAA;AAEzC,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,OAAA,GAAU,eAAc,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,EAAE,CAAA;AACvD,MAAA,MAAA,GAAS;AAAA,QACP,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,qBAAA;AAAA,UACN,OAAA,EACE,CAAA,SAAA,EAAY,OAAA,CAAQ,SAAS,CAAA,sCAAA,EACR,OAAA,CAAQ,MAAA,GAAS,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,GAAI,MAAM,CAAA,CAAA;AAAA;AACrE,OACF;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,MAAA,GAAS,MAAM,MAAM,OAAA,CAAQ,aAAA;AAAA,QAC3B,OAAA,CAAQ,QAAA;AAAA,QACR,OAAA,CAAQ,UAAU,EAAC;AAAA,QACnB,MAAM,UAAA;AAAW,OACnB;AACA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA;AAAA,UACnC,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,OAAA,CAAQ;AAAA,SAC1B;AACA,QAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,UAAA,OAAA,GAAU,IAAA;AACV,UAAA,YAAA;AAAA,YACE,OAAA,CAAQ,SAAA;AAAA,YACR,MAAM,OAAA,CAAQ,EAAA;AAAA,YACd,MAAA,CAAO,EAAA;AAAA,YACP,MAAA,CAAO,OAAA;AAAA,YACP,MAAA,CAAO,QAAQ,MAAA,CAAO;AAAA,WACxB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,MAAM,gBAAA,CAAiB,SAAS,CAAA;AAChD,IAAA,MAAM,OAAO,QAAA,EAAS;AAEtB,IAAA,OAAO;AAAA,MACL,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,GAAI,MAAA,CAAO,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,UAAA,CAAW,MAAA,CAAO,IAAI,CAAA,EAAE,GAAI,EAAC;AAAA,MACrE,GAAI,MAAA,CAAO,KAAA,GACP,EAAE,KAAA,EAAO,WAAW,MAAA,CAAO,KAAK,CAAA,EAA8B,GAC9D,EAAC;AAAA,MACL,GAAI,OAAA,GAAU,EAAE,OAAA,EAAS,IAAA,KAAS,EAAC;AAAA,MACnC,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,MACzB,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB;AAAA,KACF;AAAA,EACF;AAEA,EAAA,SAAS,QAAQ,OAAA,EAAqD;AACpE,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,SAAS,CAAA;AAC1C,IAAA,IAAI,MAAM,OAAO,IAAA;AAEjB,IAAA,MAAM,OAAA,GAAU,IAAI,OAAO,CAAA;AAC3B,IAAA,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,SAAA,EAAW,OAAO,CAAA;AACtC,IAAA,OAAO,OAAA,CAAQ,OAAO,YAAA,EAAc;AAClC,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AACrC,MAAA,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,IACvB;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAIA,EAAA,SAAS,QAAA,GAA+B;AACtC,IAAA,MAAM,WAAyB,EAAC;AAChC,IAAA,MAAM,MAA8B,EAAC;AACrC,IAAA,KAAA,MAAW,CAAA,IAAK,eAAc,EAAG;AAC/B,MAAA,QAAA,CAAS,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,UAAA,EAAY,CAAA;AACpC,MAAA,MAAM,MAAA,GAAS,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,QAAQ,EAAE,CAAA;AAC5C,MAAA,IAAI,MAAA,IAAU,OAAO,IAAA,GAAO,CAAA;AAC1B,QAAA,GAAA,CAAI,EAAE,OAAA,CAAQ,EAAE,CAAA,GAAI,MAAA,CAAO,YAAY,MAAM,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,EAAE,QAAA,EAAU,YAAA,EAAc,GAAA,EAAI;AAAA,EACvC;AAIA,EAAA,SAAS,OAAO,IAAA,EAAyB;AACvC,IAAA,IAAI,SAAS,MAAA,EAAQ;AACrB,IAAA,KAAA,MAAW,GAAA,IAAO,iBAAiB,GAAA,EAAI;AACvC,IAAA,eAAA,GAAkB,EAAC;AACnB,IAAA,SAAA,EAAW,OAAA,EAAQ;AACnB,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,MAAA,GAAS,IAAA;AACT,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,MAAM,CAAA,GAAIA,0CAAA,CAAyB,IAAA,EAAM,OAAA,CAAQ,SAAS,CAAA;AAC1D,IAAA,SAAA,GAAY,CAAA;AAEZ,IAAA,eAAA,CAAgB,IAAA;AAAA,MACd,CAAA,CAAE,QAAA,CAAS,CAAC,OAAA,KAAY;AACtB,QAAA,IAAI,QAAQ,MAAA,IAAU,CAAC,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,EAAG;AAC9C,UAAA,OAAA,CAAQ,IAAA;AAAA,YACN,CAAA,oDAAA,EAAuD,QAAQ,SAAS,CAAA,CAAA,EAAI,QAAQ,QAAQ,CAAA,EAAA,EAAK,QAAQ,SAAS,CAAA,CAAA;AAAA,WACpH;AACA,UAAA;AAAA,QACF;AACA,QAAA,KAAK,OAAA,CAAQ,OAAO,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW;AAIrC,UAAA,SAAA,EAAW,WAAW,MAAM,CAAA;AAC5B,UAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA;AACpC,UAAA,GAAA,CAAI,OAAA,EAAQ;AAEZ,UAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,QAAQ,SAAS,CAAA;AAAA,QACpD,CAAC,CAAA;AAAA,MACH,CAAC;AAAA,KACH;AAEA,IAAA,IAAI,QAAA,EAAU;AAGZ,MAAA,eAAA,CAAgB,IAAA;AAAA,QACd,CAAA,CAAE,kBAAA,CAAmB,CAAC,SAAA,KAAc;AAClC,UAAA,IAAI,WAAW,WAAA,EAAY;AAAA,QAC7B,CAAC;AAAA,OACH;AACA,MAAA,IAAI,CAAA,CAAE,WAAW,WAAA,EAAY;AAAA,IAC/B;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,MAAA,EAAQ,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA;AAIzC,EAAA,SAAS,KAAA,CACP,SACA,UAAA,EACgB;AAChB,IAAA,MAAM,KAAA,GAAe;AAAA,MACnB,GAAA,EAAK,OAAA,EAAA;AAAA,MACL,OAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAClB,IAAA,eAAA,CAAgB,KAAK,CAAA;AACrB,IAAA,OAAA,EAAQ;AAER,IAAA,IAAI,OAAA,GAAU,IAAA;AACd,IAAA,OAAO;AAAA,MACL,WAAW,OAAA,CAAQ,EAAA;AAAA,MACnB,eAAA,CAAgB,eAAe,KAAA,EAAO;AAEpC,QAAA,IAAI,CAAC,OAAA,IAAW,SAAA,CAAU,OAAA,CAAQ,EAAE,MAAM,KAAA,EAAO;AACjD,QAAA,cAAA,CAAe,OAAA,CAAQ,EAAA,EAAI,aAAA,EAAe,KAAK,CAAA;AAAA,MACjD,CAAA;AAAA,MACA,OAAA,GAAU;AACR,QAAA,IAAI,CAAC,OAAA,EAAS;AACd,QAAA,OAAA,GAAU,KAAA;AACV,QAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA;AAC/B,QAAA,IAAI,CAAA,IAAK,CAAA,EAAG,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAC,CAAA;AAC/B,QAAA,MAAM,WAAA,GAAc,SAAA,CAAU,OAAA,CAAQ,EAAE,CAAA;AACxC,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,eAAA,CAAgB,WAAW,CAAA;AAAA,QAC7B,CAAA,MAAO;AACL,UAAA,aAAA,CAAc,QAAQ,EAAE,CAAA;AACxB,UAAA,IAAI,QAAA,IAAY,SAAA,EAAW,SAAA,CAAU,iBAAA,CAAkB,QAAQ,EAAE,CAAA;AAAA,QACnE;AACA,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA,GAAO;AACL,MAAA,MAAM,EAAA,GAAK,QAAA,EAAA;AACX,MAAA,KAAA,CAAM,IAAI,EAAE,CAAA;AACZ,MAAA,OAAA,EAAQ;AACR,MAAA,IAAI,QAAA,GAAW,KAAA;AACf,MAAA,OAAO,MAAM;AACX,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,QAAA,GAAW,IAAA;AACX,QAAA,KAAA,CAAM,OAAO,EAAE,CAAA;AACf,QAAA,OAAA,EAAQ;AAAA,MACV,CAAA;AAAA,IACF,CAAA;AAAA,IACA,UAAU,QAAA,EAAU;AAClB,MAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,MAAA,OAAO,MAAM;AACX,QAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,MAC3B,CAAA;AAAA,IACF,CAAA;AAAA,IACA,OAAA,GAAU;AACR,MAAA,KAAA,MAAW,KAAA,IAAS,OAAA,CAAQ,MAAA,EAAO,gBAAiB,KAAK,CAAA;AACzD,MAAA,OAAA,CAAQ,KAAA,EAAM;AACd,MAAA,MAAA,CAAO,IAAI,CAAA;AACX,MAAA,OAAA,CAAQ,MAAA,GAAS,CAAA;AACjB,MAAA,YAAA,CAAa,KAAA,EAAM;AACnB,MAAA,sBAAA,CAAuB,KAAA,EAAM;AAC7B,MAAA,KAAA,CAAM,KAAA,EAAM;AACZ,MAAA,SAAA,CAAU,KAAA,EAAM;AAChB,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb;AAAA,GACF;AACF;AAIA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAOA,SAAS,WAAW,KAAA,EAAyB;AAC3C,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,MAAA;AAChC,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EACzC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB;AACF","file":"chunk-DGMKSJTY.cjs","sourcesContent":["/**\n * Nominal branding for values OUI must construct itself.\n *\n * Structural typing means any object with the right shape satisfies an\n * interface. That is how Closure Studio ended up hand-rolling OUI's transport:\n * `SocketLike` was importable, `OUITransport` was a plain interface, so an\n * integrator could satisfy every type without ever calling OUI. The result was\n * a second implementation of the wire — hardcoded namespace, re-declared\n * payload types on the server, and a dead `action:result` mapping alongside the\n * observation channel that already carried results.\n *\n * A unique symbol cannot be produced outside this module. Branding the types\n * OUI owns turns \"you should use our constructor\" into \"you cannot compile\n * without it\".\n */\n\ndeclare const OUI_BRAND: unique symbol;\n\n/** Marks a value as constructed by OUI itself. */\nexport interface OUIBranded<TKind extends string> {\n readonly [OUI_BRAND]: TKind;\n}\n\n/**\n * Attach the brand at runtime. The property does not exist at runtime — the\n * symbol is declare-only — so this is a type-level assertion with no cost.\n */\nexport function brand<TKind extends string, T>(\n value: T,\n): T & OUIBranded<TKind> {\n return value as T & OUIBranded<TKind>;\n}\n","import type {\n OUISurface,\n OUIAction,\n OUIObservation,\n OUIActivation,\n OUIActionPolling,\n JSONSchema,\n} from \"../spec/index.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\n\n/**\n * Configuration for defining an OUI surface with handlers.\n * This is the \"integration file\" an app provides — it declares both\n * the schema (what the agent sees) and the implementation (what executes).\n */\nexport interface SurfaceDefinition<TContext = unknown> {\n id: string;\n name: string;\n description: string;\n version?: string;\n activation?: OUIActivation;\n actions: ActionDefinition<TContext>[];\n observations?: ObservationDefinition[];\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Polling config with an optional resolve handler.\n * The spec's OUIActionPolling is the manifest shape (no functions).\n * The core extends it with the resolve implementation for the runtime.\n */\nexport interface ActionPollingConfig<\n TContext = unknown,\n> extends OUIActionPolling {\n /**\n * Called on each poll interval. Receives the dispatch result from the handler\n * plus the current context. Return { done: true, data } to stop polling,\n * or { done: false, data } to continue.\n */\n resolve?: (\n dispatchResult: unknown,\n context: TContext,\n ) => Promise<{ done: boolean; data: unknown }>;\n}\n\n/**\n * An action definition includes both the schema (for the agent) and\n * the handler (for execution). This is the single source of truth —\n * no separate YAML, no separate listener, no drift possible.\n */\nexport interface ActionDefinition<TContext = unknown> {\n id: string;\n description: string;\n input: JSONSchema;\n output?: JSONSchema;\n confirm?: boolean;\n async?: boolean;\n\n /**\n * Polling/subscription config for async actions.\n * After the handler returns, the OUI runtime starts polling or subscribing\n * and pushes observation updates until the operation completes.\n * Extends the spec's OUIActionPolling with an optional resolve handler.\n */\n polling?: ActionPollingConfig<TContext>;\n\n usage?: string;\n preconditions?: string;\n estimatedDuration?: string;\n tags?: string[];\n\n /**\n * The handler that executes when the agent invokes this action.\n * Receives typed params and a context object (app-specific state/utilities).\n * Returns a result that the agent sees as the tool output.\n */\n handler: (\n params: Record<string, unknown>,\n context: TContext,\n ) => Promise<ActionHandlerResult>;\n}\n\nexport interface ActionHandlerResult {\n success: boolean;\n data?: unknown;\n error?: { code: string; message: string; details?: unknown };\n /** For async actions: metadata passed to the polling resolver */\n dispatchMeta?: Record<string, unknown>;\n}\n\nexport interface ObservationDefinition {\n id: string;\n description: string;\n schema: JSONSchema;\n /** Function that returns the current observation value */\n getValue?: () => unknown;\n}\n\n/**\n * Define an OUI surface — the single entry point for integrating\n * an application feature with the OUI protocol.\n *\n * This function validates the definition and returns a typed surface\n * object that can be registered with an agent runtime or transport layer.\n *\n * @example\n * ```typescript\n * const mySurface = defineSurface({\n * id: 'my-feature',\n * name: 'My Feature',\n * description: 'Does something cool',\n * actions: [\n * {\n * id: 'do_thing',\n * description: 'Does the thing',\n * input: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },\n * handler: async (params) => {\n * const result = await doTheThing(params.name);\n * return { success: true, data: result };\n * },\n * },\n * ],\n * });\n * ```\n */\nexport function defineSurface<\n TContext = unknown,\n const TId extends string = string,\n>(\n definition: SurfaceDefinition<TContext> & { id: TId },\n): DefinedSurface<TContext> & { id: TId } {\n // Validate: no duplicate action IDs\n const actionIds = new Set<string>();\n for (const action of definition.actions) {\n if (actionIds.has(action.id)) {\n throw new Error(\n `[OUI] Duplicate action ID \"${action.id}\" in surface \"${definition.id}\"`,\n );\n }\n actionIds.add(action.id);\n }\n\n // Validate: no duplicate observation IDs\n if (definition.observations) {\n const obsIds = new Set<string>();\n for (const obs of definition.observations) {\n if (obsIds.has(obs.id)) {\n throw new Error(\n `[OUI] Duplicate observation ID \"${obs.id}\" in surface \"${definition.id}\"`,\n );\n }\n obsIds.add(obs.id);\n }\n }\n\n return brand<\"surface\", unknown>({\n ...definition,\n\n /** Extract the manifest (schema only, no handlers) for transmission to the agent runtime */\n toManifest(): OUISurface {\n return {\n id: definition.id,\n name: definition.name,\n description: definition.description,\n version: definition.version,\n activation: definition.activation,\n actions: definition.actions.map(actionToManifest),\n observations: definition.observations?.map(obsToManifest),\n metadata: definition.metadata,\n };\n },\n\n /** Execute an action by ID with the given params and context */\n async executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult> {\n const action = definition.actions.find((a) => a.id === actionId);\n if (!action) {\n return {\n success: false,\n error: {\n code: \"ACTION_NOT_FOUND\",\n message: `Action \"${actionId}\" not found on surface \"${definition.id}\"`,\n },\n };\n }\n try {\n return await action.handler(params, context);\n } catch (err) {\n return {\n success: false,\n error: {\n code: \"ACTION_EXECUTION_ERROR\",\n message: err instanceof Error ? err.message : String(err),\n },\n };\n }\n },\n\n /** Get all action IDs */\n getActionIds(): string[] {\n return definition.actions.map((a) => a.id);\n },\n\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined {\n const action = definition.actions.find((a) => a.id === actionId);\n return action?.polling;\n },\n }) as DefinedSurface<TContext> & { id: TId };\n}\n\n/** A fully defined surface with both manifest extraction and execution capabilities */\n/**\n * Branded so it can only come from `defineSurface`.\n *\n * Without the brand a plain object literal satisfies this interface\n * structurally, which is how an integrator can assemble a surface that never\n * ran defineSurface's duplicate-id checks and never produced a real manifest.\n */\nexport interface DefinedSurface<TContext = unknown>\n extends SurfaceDefinition<TContext>, OUIBranded<\"surface\"> {\n toManifest(): OUISurface;\n executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult>;\n getActionIds(): string[];\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined;\n}\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\nfunction actionToManifest<T>(action: ActionDefinition<T>): OUIAction {\n return {\n id: action.id,\n description: action.description,\n input: action.input,\n output: action.output,\n confirm: action.confirm,\n async: action.async,\n polling: action.polling,\n usage: action.usage,\n preconditions: action.preconditions,\n estimatedDuration: action.estimatedDuration,\n tags: action.tags,\n };\n}\n\nfunction obsToManifest(obs: ObservationDefinition): OUIObservation {\n return {\n id: obs.id,\n description: obs.description,\n schema: obs.schema,\n };\n}\n","/**\n * createOUI — a fixed set of surfaces announced over one socket.\n *\n * For a client whose surfaces come and go (a React app, where a page's\n * surfaces mount with the page), use `createSurfaceRuntime` instead: it keeps\n * the client's own record of what is mounted and answers every request.\n *\n * WHY THIS EXISTS\n *\n * OUI shipped a correct protocol and a correct transport, and its first\n * integrator used neither. studio-ui imported only the `SocketLike` TYPE from\n * oui-spec and rebuilt the wire by hand: a literal map of protocol types to\n * socket names, `oui:` hardcoded so the configurable namespace was unreachable,\n * payload interfaces re-declared on the server, and an `action:result` channel\n * mapped but never sent — duplicating the observation channel that already\n * carries results.\n *\n * Nothing was wrong with the spec. Nothing enforced it. Structural typing meant\n * every hand-rolled piece type-checked, and both ends agreed only by the\n * coincidence of matching string literals. Rename one and the other keeps\n * compiling and silently stops receiving.\n *\n * So the requirements are gated here:\n *\n * OUI owns the wire. The integrator provides a socket; it cannot provide a\n * transport, because `OUITransport` values are branded and only this module\n * brands them.\n *\n * OUI owns the result path. Every dispatch carries a requestId and is\n * answered on OUI's result channel. An integrator cannot add a parallel\n * channel because it cannot construct a transport to add one to.\n *\n * The integrator owns content. Surfaces, action schemas, observation schemas\n * and handlers all arrive through `defineSurface`, whose output is branded —\n * so a plain object shaped like a surface will not compile.\n *\n * Violations fail at compile time with a message naming the offending id.\n */\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport type { SocketLike } from \"../transport/websocket.js\";\nimport { createWebSocketTransport } from \"../transport/websocket.js\";\nimport type { DefinedSurface } from \"./define-surface.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\nimport type { OUIConfigError, ValidateSurfaceIds } from \"./validate.js\";\nimport type { OUISurface } from \"../spec/index.js\";\n\n/** A transport OUI constructed. Integrators cannot produce one. */\nexport type OwnedTransport = OUITransport & OUIBranded<\"transport\">;\n\n/** Surface ids as literal types, for the duplicate check. */\ntype SurfaceIds<T extends readonly DefinedSurface<never>[]> = {\n [K in keyof T]: T[K][\"id\"];\n};\n\nexport interface OUIConfig<TSurfaces extends readonly DefinedSurface<never>[]> {\n /**\n * The socket OUI will speak over. The integrator owns the connection —\n * auth, reconnection, lifecycle — and OUI owns what travels on it.\n */\n socket: SocketLike;\n\n /**\n * Surfaces produced by `defineSurface`. A plain object with the same shape\n * will not compile: DefinedSurface is branded.\n */\n surfaces: TSurfaces;\n\n /**\n * Wire configuration. `namespace` defaults to 'oui' and is the supported way\n * to change the event prefix — hardcoding it at the call site is what made\n * this option unreachable in the first integration.\n */\n transport?: Omit<OUITransportConfig, \"namespace\"> & { namespace?: string };\n}\n\n/** A live OUI instance. */\nexport interface OUIInstance {\n /** The transport OUI owns. Exposed for wiring, not for reimplementation. */\n readonly transport: OwnedTransport;\n\n /** Manifests for every registered surface, as the agent sees them. */\n readonly manifests: readonly OUISurface[];\n\n /** Register every surface and connect. */\n start(): Promise<void>;\n\n /**\n * Deregister every surface and detach OUI from the socket. The socket stays\n * connected: the integrator owns it, and other code may share it.\n */\n stop(): void;\n\n /** Look up a registered surface by id. */\n getSurface(id: string): DefinedSurface<never> | undefined;\n}\n\n/**\n * Instantiate OUI.\n *\n * `const` on the type parameter captures surface ids as literal types, which is\n * what allows duplicate detection to name the offending id rather than failing\n * with an unassignable-to-never error.\n */\nexport function createOUI<\n const TSurfaces extends readonly DefinedSurface<never>[],\n>(\n config: OUIConfig<TSurfaces> & ValidateSurfaceIds<SurfaceIds<TSurfaces>>,\n): OUIInstance {\n const {\n socket,\n surfaces,\n transport: transportConfig,\n } = config as OUIConfig<TSurfaces>;\n\n // Defensive, not decorative: the compile-time checks only bind when a caller\n // passes literals. A surface list assembled at runtime, or JS with no types\n // at all, reaches here unchecked.\n if (!socket) {\n throw new Error(\n \"[OUI] createOUI requires a socket. OUI owns the wire; the integrator owns the connection.\",\n );\n }\n if (!Array.isArray(surfaces) || surfaces.length === 0) {\n throw new Error(\"[OUI] createOUI requires at least one surface.\");\n }\n\n const seen = new Set<string>();\n for (const surface of surfaces) {\n if (seen.has(surface.id)) {\n throw new Error(\n `[OUI] Duplicate surface id \"${surface.id}\". Registration is keyed by id, so the second would replace the first.`,\n );\n }\n seen.add(surface.id);\n }\n\n const transport = brand<\"transport\", OUITransport>(\n createWebSocketTransport(socket, transportConfig),\n );\n\n const byId = new Map(surfaces.map((s) => [s.id, s] as const));\n\n return {\n transport,\n manifests: surfaces.map((s) => s.toManifest()),\n\n async start() {\n await transport.connect();\n for (const surface of surfaces) {\n transport.registerSurface(surface.toManifest());\n }\n },\n\n stop() {\n for (const surface of surfaces) {\n transport.deregisterSurface(surface.id);\n }\n transport.dispose();\n },\n\n getSurface(id) {\n return byId.get(id);\n },\n };\n}\n\n/** Re-exported so integrators can name the error type in tests. */\nexport type { OUIConfigError };\n","/**\n * The client-side surface runtime.\n *\n * Holds the surfaces a client has mounted, answers every action request with a\n * result, and produces the snapshot an agent runtime works from.\n *\n * WHY THIS EXISTS\n *\n * The first integration kept no client-side record of what was mounted. Each\n * surface hook registered itself with a server-side registry and listened for\n * dispatches on its own. Three things followed:\n *\n * - The registry was the only record of what the client could do, and it lost\n * entries: a dead socket's cleanup removed a live tab's registration, and the\n * browser never registered again. The agent then had no UI tools at all.\n * - Nothing answered a dispatch. The agent was told an action succeeded before\n * the client had run it, and never saw the page an action led to.\n * - Every hook listened independently, through two paths, so one dispatch ran\n * twice and nothing de-duplicated it.\n *\n * Here the client is the record. `snapshot()` is what the client can do right\n * now, and every request is run once, waited on until the UI settles, and\n * answered with its result and the snapshot after it.\n */\nimport type {\n OUIActionRequest,\n OUIActionResult,\n OUISurface,\n OUISurfaceSnapshot,\n OUIObservationSnapshot,\n} from \"../spec/index.js\";\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport {\n createWebSocketTransport,\n type SocketLike,\n} from \"../transport/websocket.js\";\nimport type {\n ActionHandlerResult,\n ActionPollingConfig,\n DefinedSurface,\n} from \"./define-surface.js\";\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\nexport interface SettleOptions {\n /**\n * The UI counts as settled once nothing has mounted, unmounted or changed an\n * observation for this long, and no hold is open. Default 250 ms.\n */\n quietMs?: number;\n /** Give up waiting after this long and answer with `settled: false`. Default 5000 ms. */\n timeoutMs?: number;\n}\n\nexport interface SurfaceRuntimeOptions {\n /** The socket to answer requests on. Can be set or replaced later with `attach`. */\n socket?: SocketLike | null;\n\n /** Wire configuration for the transport the runtime builds on the socket. */\n transport?: OUITransportConfig;\n\n /**\n * Also announce registrations and observations over the transport, for agent\n * runtimes that keep a server-side registry. Default true.\n *\n * An agent runtime that takes the client's snapshot instead (sent with each\n * turn, and returned on every result) has no use for them: set false.\n */\n announce?: boolean;\n\n settle?: SettleOptions;\n\n /** How many answered request ids to remember, for de-duplication. Default 500. */\n dedupeWindow?: number;\n\n /**\n * Decides whether a request that arrived on the socket may run at all. A\n * refused request is neither run nor answered, and is logged.\n *\n * The server should be the only sender of action requests, but a client can\n * also check that a request is one it expects: for example, only while its\n * agent has a turn in progress. Requests passed to `execute` directly are\n * not checked; they come from the application itself.\n */\n accept?: (request: OUIActionRequest) => boolean;\n}\n\n// ─── Public types ────────────────────────────────────────────────────────────\n\nexport interface MountedSurface {\n readonly surfaceId: string;\n /** Record an observation value. A no-op once unmounted. */\n pushObservation(observationId: string, value: unknown): void;\n /** Remove this mount. Other mounts of the same surface id are unaffected. */\n unmount(): void;\n}\n\nexport interface SurfaceRuntime {\n /**\n * Mount a surface. `getContext` is read when an action runs, so handlers see\n * the latest state rather than the state at mount time.\n *\n * Mounting the same surface id twice is allowed (React StrictMode does it on\n * every mount); the most recent mount serves its actions.\n */\n mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface;\n\n /** Answer requests arriving on this socket (null detaches). */\n attach(socket: SocketLike | null): void;\n\n /** What the client can do right now. */\n snapshot(): OUISurfaceSnapshot;\n\n /**\n * Run a request once and resolve with its result. A request id seen before\n * resolves with the first result instead of running again.\n */\n execute(request: OUIActionRequest): Promise<OUIActionResult>;\n\n /**\n * Keep the UI unsettled until the returned function is called. For work an\n * action starts that mounting and unmounting cannot show, such as a route's\n * code still loading or a page fetching the data it will display.\n */\n hold(): () => void;\n\n /** Called whenever the snapshot changes. */\n subscribe(listener: () => void): () => void;\n\n /** Stop polling, detach from the socket and forget every mount. */\n dispose(): void;\n}\n\n// ─── Implementation ──────────────────────────────────────────────────────────\n\ninterface Entry {\n key: number;\n surface: DefinedSurface<unknown>;\n getContext: () => unknown;\n}\n\nconst DEFAULT_QUIET_MS = 250;\nconst DEFAULT_SETTLE_TIMEOUT_MS = 5000;\nconst DEFAULT_DEDUPE_WINDOW = 500;\nconst SETTLE_TICK_MS = 50;\n\nexport function createSurfaceRuntime(\n options: SurfaceRuntimeOptions = {},\n): SurfaceRuntime {\n const announce = options.announce ?? true;\n const quietMs = options.settle?.quietMs ?? DEFAULT_QUIET_MS;\n const settleTimeoutMs =\n options.settle?.timeoutMs ?? DEFAULT_SETTLE_TIMEOUT_MS;\n const dedupeWindow = options.dedupeWindow ?? DEFAULT_DEDUPE_WINDOW;\n\n let nextKey = 1;\n const entries: Entry[] = [];\n const observations = new Map<string, Map<string, unknown>>();\n const serializedObservations = new Map<string, string>();\n const holds = new Set<number>();\n let nextHold = 1;\n const results = new Map<string, Promise<OUIActionResult>>();\n const pollers = new Map<string, ReturnType<typeof setInterval>>();\n const listeners = new Set<() => void>();\n // Resolves once a request's first result has been handed to the transport.\n const acks = new Map<\n string,\n { promise: Promise<void>; resolve: () => void }\n >();\n function ackFor(requestId: string) {\n let ack = acks.get(requestId);\n if (!ack) {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => (resolve = r));\n ack = { promise, resolve };\n acks.set(requestId, ack);\n }\n return ack;\n }\n function acknowledged(requestId: string): Promise<void> {\n return ackFor(requestId).promise;\n }\n let lastChangeAt = Date.now();\n\n let socket: SocketLike | null = null;\n let transport: OUITransport | null = null;\n let detachTransport: Array<() => void> = [];\n\n /**\n * `settles: false` for changes that are not the UI reacting to an action,\n * such as an async job's progress: those notify listeners but do not keep\n * an action's result waiting.\n */\n function changed(settles = true) {\n if (settles) lastChangeAt = Date.now();\n for (const l of [...listeners]) l();\n }\n\n function activeFor(surfaceId: string): Entry | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].surface.id === surfaceId) return entries[i];\n }\n return undefined;\n }\n\n /** Active entries, one per surface id, in the order each id was first mounted. */\n function activeEntries(): Entry[] {\n const seen = new Set<string>();\n const out: Entry[] = [];\n for (const e of entries) {\n if (seen.has(e.surface.id)) continue;\n seen.add(e.surface.id);\n out.push(activeFor(e.surface.id)!);\n }\n return out;\n }\n\n function announceSurface(entry: Entry) {\n if (!announce || !transport) return;\n transport.registerSurface(entry.surface.toManifest());\n const obs = observations.get(entry.surface.id);\n if (obs) {\n for (const [observationId, value] of obs) {\n transport.pushObservation({\n surfaceId: entry.surface.id,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n }\n }\n\n function announceAll() {\n for (const e of activeEntries()) announceSurface(e);\n }\n\n function setObservation(\n surfaceId: string,\n observationId: string,\n value: unknown,\n settles = true,\n ) {\n const key = `${surfaceId}\\u0000${observationId}`;\n let serialized: string;\n try {\n serialized = JSON.stringify(value) ?? \"undefined\";\n } catch {\n serialized = String(value);\n }\n if (serializedObservations.get(key) === serialized) return;\n serializedObservations.set(key, serialized);\n\n let obs = observations.get(surfaceId);\n if (!obs) {\n obs = new Map();\n observations.set(surfaceId, obs);\n }\n obs.set(observationId, toJsonSafe(value));\n\n if (announce && transport) {\n transport.pushObservation({\n surfaceId,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n changed(settles);\n }\n\n function forgetSurface(surfaceId: string) {\n observations.delete(surfaceId);\n for (const key of [...serializedObservations.keys()]) {\n if (key.startsWith(`${surfaceId}\\u0000`))\n serializedObservations.delete(key);\n }\n for (const [key, timer] of pollers) {\n if (key.startsWith(`${surfaceId}\\u0000`)) {\n clearInterval(timer);\n pollers.delete(key);\n }\n }\n }\n\n // ─── Polling (async actions) ──────────────────────────────────────────────\n\n /**\n * Polls an async action to completion, publishing progress as an observation\n * and, when it ends, the request's final result (OUI spec §7.3: an async\n * action is acknowledged, then answered once more when it finishes).\n */\n function startPolling(\n requestId: string,\n surfaceId: string,\n actionId: string,\n polling: ActionPollingConfig<unknown>,\n dispatchResult: unknown,\n ) {\n const finish = async (\n success: boolean,\n data: unknown,\n error?: { code: string; message: string },\n ) => {\n // The acknowledgment goes first: a job can finish before the UI settles.\n await acknowledged(requestId);\n const snap = snapshot();\n transport?.sendResult({\n requestId,\n success,\n ...(data !== undefined ? { data: toJsonSafe(data) } : {}),\n ...(error ? { error } : {}),\n interim: false,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n });\n acks.delete(requestId);\n };\n\n // The observation id is the one surfaces have always published under.\n const observationId = `${surfaceId}:${actionId}:status`;\n const pollerKey = `${surfaceId}\\u0000${actionId}`;\n\n if (polling.subscribe) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: true },\n false,\n );\n return;\n }\n if (!polling.resolve) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: false },\n false,\n );\n return;\n }\n\n const existing = pollers.get(pollerKey);\n if (existing) clearInterval(existing);\n\n setObservation(\n surfaceId,\n observationId,\n { status: \"polling\", dispatchResult, interim: true },\n false,\n );\n\n const maxAttempts = polling.maxAttempts ?? Infinity;\n const maxDuration = polling.maxDurationMs ?? Infinity;\n const startedAt = Date.now();\n let attempts = 0;\n\n const timer = setInterval(async () => {\n attempts++;\n if (attempts > maxAttempts || Date.now() - startedAt > maxDuration) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n setObservation(\n surfaceId,\n observationId,\n { status: \"timeout\", dispatchResult, interim: false },\n false,\n );\n void finish(false, undefined, {\n code: \"TIMEOUT\",\n message: `\"${actionId}\" did not finish within its polling limits.`,\n });\n return;\n }\n const entry = activeFor(surfaceId);\n const action = entry?.surface.actions.find((a) => a.id === actionId);\n if (!entry || !action?.polling?.resolve) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n return;\n }\n try {\n const r = await action.polling.resolve(\n dispatchResult,\n entry.getContext(),\n );\n setObservation(\n surfaceId,\n observationId,\n {\n ...(r.data as Record<string, unknown>),\n interim: !r.done,\n },\n false,\n );\n if (r.done) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n void finish(true, r.data);\n }\n } catch (err) {\n // A transient failure is reported, not fatal: keep polling.\n setObservation(\n surfaceId,\n observationId,\n { status: \"poll_error\", error: String(err), interim: true },\n false,\n );\n }\n }, polling.intervalMs);\n\n pollers.set(pollerKey, timer);\n }\n\n // ─── Settling ─────────────────────────────────────────────────────────────\n\n async function waitUntilSettled(since: number): Promise<boolean> {\n const deadline = since + settleTimeoutMs;\n for (;;) {\n const now = Date.now();\n const quietFor = now - Math.max(since, lastChangeAt);\n if (holds.size === 0 && quietFor >= quietMs) return true;\n if (now >= deadline) return false;\n await sleep(Math.min(SETTLE_TICK_MS, deadline - now));\n }\n }\n\n // ─── Execution ────────────────────────────────────────────────────────────\n\n async function run(request: OUIActionRequest): Promise<OUIActionResult> {\n const startedAt = Date.now();\n const entry = activeFor(request.surfaceId);\n\n let result: ActionHandlerResult;\n let interim = false;\n if (!entry) {\n const mounted = activeEntries().map((e) => e.surface.id);\n result = {\n success: false,\n error: {\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${request.surfaceId}\" is not on screen. ` +\n `Mounted surfaces: ${mounted.length ? mounted.join(\", \") : \"none\"}.`,\n },\n };\n } else {\n // executeAction turns a thrown handler into ACTION_EXECUTION_ERROR.\n result = await entry.surface.executeAction(\n request.actionId,\n request.params ?? {},\n entry.getContext(),\n );\n if (result.success) {\n const action = entry.surface.actions.find(\n (a) => a.id === request.actionId,\n );\n if (action?.polling) {\n interim = true;\n startPolling(\n request.requestId,\n entry.surface.id,\n action.id,\n action.polling,\n result.data ?? result.dispatchMeta,\n );\n }\n }\n }\n\n const settled = await waitUntilSettled(startedAt);\n const snap = snapshot();\n\n return {\n requestId: request.requestId,\n success: result.success,\n ...(result.data !== undefined ? { data: toJsonSafe(result.data) } : {}),\n ...(result.error\n ? { error: toJsonSafe(result.error) as OUIActionResult[\"error\"] }\n : {}),\n ...(interim ? { interim: true } : {}),\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n settled,\n };\n }\n\n function execute(request: OUIActionRequest): Promise<OUIActionResult> {\n const seen = results.get(request.requestId);\n if (seen) return seen;\n\n const pending = run(request);\n results.set(request.requestId, pending);\n while (results.size > dedupeWindow) {\n const oldest = results.keys().next().value as string;\n results.delete(oldest);\n }\n return pending;\n }\n\n // ─── Snapshot ─────────────────────────────────────────────────────────────\n\n function snapshot(): OUISurfaceSnapshot {\n const surfaces: OUISurface[] = [];\n const obs: OUIObservationSnapshot = {};\n for (const e of activeEntries()) {\n surfaces.push(e.surface.toManifest());\n const values = observations.get(e.surface.id);\n if (values && values.size > 0)\n obs[e.surface.id] = Object.fromEntries(values);\n }\n return { surfaces, observations: obs };\n }\n\n // ─── Transport ────────────────────────────────────────────────────────────\n\n function attach(next: SocketLike | null) {\n if (next === socket) return;\n for (const off of detachTransport) off();\n detachTransport = [];\n transport?.dispose();\n transport = null;\n socket = next;\n if (!next) return;\n\n const t = createWebSocketTransport(next, options.transport);\n transport = t;\n\n detachTransport.push(\n t.onAction((request) => {\n if (options.accept && !options.accept(request)) {\n console.warn(\n `[OUI] Refused a request the client does not accept: ${request.surfaceId}.${request.actionId} (${request.requestId})`,\n );\n return;\n }\n void execute(request).then((result) => {\n // Answer on whichever transport is live when the result is ready: a\n // reconnect in between keeps the same socket, so this still reaches\n // the runtime that asked.\n transport?.sendResult(result);\n const ack = ackFor(request.requestId);\n ack.resolve();\n // Keep the gate only while a final result may still follow.\n if (!result.interim) acks.delete(request.requestId);\n });\n }),\n );\n\n if (announce) {\n // A server-side registry forgets a socket's surfaces when it drops, so\n // every (re)connection announces them again.\n detachTransport.push(\n t.onConnectionChange((connected) => {\n if (connected) announceAll();\n }),\n );\n if (t.connected) announceAll();\n }\n }\n\n if (options.socket) attach(options.socket);\n\n // ─── Mounting ─────────────────────────────────────────────────────────────\n\n function mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface {\n const entry: Entry = {\n key: nextKey++,\n surface: surface as unknown as DefinedSurface<unknown>,\n getContext: getContext as () => unknown,\n };\n entries.push(entry);\n announceSurface(entry);\n changed();\n\n let mounted = true;\n return {\n surfaceId: surface.id,\n pushObservation(observationId, value) {\n // Only the mount serving the surface speaks for it.\n if (!mounted || activeFor(surface.id) !== entry) return;\n setObservation(surface.id, observationId, value);\n },\n unmount() {\n if (!mounted) return;\n mounted = false;\n const i = entries.indexOf(entry);\n if (i >= 0) entries.splice(i, 1);\n const replacement = activeFor(surface.id);\n if (replacement) {\n announceSurface(replacement);\n } else {\n forgetSurface(surface.id);\n if (announce && transport) transport.deregisterSurface(surface.id);\n }\n changed();\n },\n };\n }\n\n return {\n mount,\n attach,\n snapshot,\n execute,\n hold() {\n const id = nextHold++;\n holds.add(id);\n changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n holds.delete(id);\n changed();\n };\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n dispose() {\n for (const timer of pollers.values()) clearInterval(timer);\n pollers.clear();\n attach(null);\n entries.length = 0;\n observations.clear();\n serializedObservations.clear();\n holds.clear();\n listeners.clear();\n acks.clear();\n },\n };\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Results and observations cross a wire as JSON. A handler returning something\n * that is not (a DOM node, a class instance with cycles) must not take the\n * result down with it.\n */\nfunction toJsonSafe(value: unknown): unknown {\n if (value === undefined) return undefined;\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n return String(value);\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/brand.ts","../src/core/define-surface.ts","../src/core/create-oui.ts","../src/core/surface-runtime.ts"],"names":[],"mappings":"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","file":"chunk-GXTNZ44I.js","sourcesContent":["/**\n * Nominal branding for values OUI must construct itself.\n *\n * Structural typing means any object with the right shape satisfies an\n * interface. That is how Closure Studio ended up hand-rolling OUI's transport:\n * `SocketLike` was importable, `OUITransport` was a plain interface, so an\n * integrator could satisfy every type without ever calling OUI. The result was\n * a second implementation of the wire — hardcoded namespace, re-declared\n * payload types on the server, and a dead `action:result` mapping alongside the\n * observation channel that already carried results.\n *\n * A unique symbol cannot be produced outside this module. Branding the types\n * OUI owns turns \"you should use our constructor\" into \"you cannot compile\n * without it\".\n */\n\ndeclare const OUI_BRAND: unique symbol;\n\n/** Marks a value as constructed by OUI itself. */\nexport interface OUIBranded<TKind extends string> {\n readonly [OUI_BRAND]: TKind;\n}\n\n/**\n * Attach the brand at runtime. The property does not exist at runtime — the\n * symbol is declare-only — so this is a type-level assertion with no cost.\n */\nexport function brand<TKind extends string, T>(\n value: T,\n): T & OUIBranded<TKind> {\n return value as T & OUIBranded<TKind>;\n}\n","import type {\n OUISurface,\n OUIAction,\n OUIObservation,\n OUIActivation,\n OUIActionPolling,\n JSONSchema,\n} from \"../spec/index.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\n\n/**\n * Configuration for defining an OUI surface with handlers.\n * This is the \"integration file\" an app provides — it declares both\n * the schema (what the agent sees) and the implementation (what executes).\n */\nexport interface SurfaceDefinition<TContext = unknown> {\n id: string;\n name: string;\n description: string;\n version?: string;\n activation?: OUIActivation;\n actions: ActionDefinition<TContext>[];\n observations?: ObservationDefinition[];\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Polling config with an optional resolve handler.\n * The spec's OUIActionPolling is the manifest shape (no functions).\n * The core extends it with the resolve implementation for the runtime.\n */\nexport interface ActionPollingConfig<\n TContext = unknown,\n> extends OUIActionPolling {\n /**\n * Called on each poll interval. Receives the dispatch result from the handler\n * plus the current context. Return { done: true, data } to stop polling,\n * or { done: false, data } to continue.\n */\n resolve?: (\n dispatchResult: unknown,\n context: TContext,\n ) => Promise<{ done: boolean; data: unknown }>;\n}\n\n/**\n * An action definition includes both the schema (for the agent) and\n * the handler (for execution). This is the single source of truth —\n * no separate YAML, no separate listener, no drift possible.\n */\nexport interface ActionDefinition<TContext = unknown> {\n id: string;\n description: string;\n input: JSONSchema;\n output?: JSONSchema;\n confirm?: boolean;\n async?: boolean;\n\n /**\n * Polling/subscription config for async actions.\n * After the handler returns, the OUI runtime starts polling or subscribing\n * and pushes observation updates until the operation completes.\n * Extends the spec's OUIActionPolling with an optional resolve handler.\n */\n polling?: ActionPollingConfig<TContext>;\n\n usage?: string;\n preconditions?: string;\n estimatedDuration?: string;\n tags?: string[];\n\n /**\n * The handler that executes when the agent invokes this action.\n * Receives typed params and a context object (app-specific state/utilities).\n * Returns a result that the agent sees as the tool output.\n */\n handler: (\n params: Record<string, unknown>,\n context: TContext,\n ) => Promise<ActionHandlerResult>;\n}\n\nexport interface ActionHandlerResult {\n success: boolean;\n data?: unknown;\n error?: { code: string; message: string; details?: unknown };\n /** For async actions: metadata passed to the polling resolver */\n dispatchMeta?: Record<string, unknown>;\n}\n\nexport interface ObservationDefinition {\n id: string;\n description: string;\n schema: JSONSchema;\n /** Function that returns the current observation value */\n getValue?: () => unknown;\n}\n\n/**\n * Define an OUI surface — the single entry point for integrating\n * an application feature with the OUI protocol.\n *\n * This function validates the definition and returns a typed surface\n * object that can be registered with an agent runtime or transport layer.\n *\n * @example\n * ```typescript\n * const mySurface = defineSurface({\n * id: 'my-feature',\n * name: 'My Feature',\n * description: 'Does something cool',\n * actions: [\n * {\n * id: 'do_thing',\n * description: 'Does the thing',\n * input: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },\n * handler: async (params) => {\n * const result = await doTheThing(params.name);\n * return { success: true, data: result };\n * },\n * },\n * ],\n * });\n * ```\n */\nexport function defineSurface<\n TContext = unknown,\n const TId extends string = string,\n>(\n definition: SurfaceDefinition<TContext> & { id: TId },\n): DefinedSurface<TContext> & { id: TId } {\n // Validate: no duplicate action IDs\n const actionIds = new Set<string>();\n for (const action of definition.actions) {\n if (actionIds.has(action.id)) {\n throw new Error(\n `[OUI] Duplicate action ID \"${action.id}\" in surface \"${definition.id}\"`,\n );\n }\n actionIds.add(action.id);\n }\n\n // Validate: no duplicate observation IDs\n if (definition.observations) {\n const obsIds = new Set<string>();\n for (const obs of definition.observations) {\n if (obsIds.has(obs.id)) {\n throw new Error(\n `[OUI] Duplicate observation ID \"${obs.id}\" in surface \"${definition.id}\"`,\n );\n }\n obsIds.add(obs.id);\n }\n }\n\n return brand<\"surface\", unknown>({\n ...definition,\n\n /** Extract the manifest (schema only, no handlers) for transmission to the agent runtime */\n toManifest(): OUISurface {\n return {\n id: definition.id,\n name: definition.name,\n description: definition.description,\n version: definition.version,\n activation: definition.activation,\n actions: definition.actions.map(actionToManifest),\n observations: definition.observations?.map(obsToManifest),\n metadata: definition.metadata,\n };\n },\n\n /** Execute an action by ID with the given params and context */\n async executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult> {\n const action = definition.actions.find((a) => a.id === actionId);\n if (!action) {\n return {\n success: false,\n error: {\n code: \"ACTION_NOT_FOUND\",\n message: `Action \"${actionId}\" not found on surface \"${definition.id}\"`,\n },\n };\n }\n try {\n return await action.handler(params, context);\n } catch (err) {\n return {\n success: false,\n error: {\n code: \"ACTION_EXECUTION_ERROR\",\n message: err instanceof Error ? err.message : String(err),\n },\n };\n }\n },\n\n /** Get all action IDs */\n getActionIds(): string[] {\n return definition.actions.map((a) => a.id);\n },\n\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined {\n const action = definition.actions.find((a) => a.id === actionId);\n return action?.polling;\n },\n }) as DefinedSurface<TContext> & { id: TId };\n}\n\n/** A fully defined surface with both manifest extraction and execution capabilities */\n/**\n * Branded so it can only come from `defineSurface`.\n *\n * Without the brand a plain object literal satisfies this interface\n * structurally, which is how an integrator can assemble a surface that never\n * ran defineSurface's duplicate-id checks and never produced a real manifest.\n */\nexport interface DefinedSurface<TContext = unknown>\n extends SurfaceDefinition<TContext>, OUIBranded<\"surface\"> {\n toManifest(): OUISurface;\n executeAction(\n actionId: string,\n params: Record<string, unknown>,\n context: TContext,\n ): Promise<ActionHandlerResult>;\n getActionIds(): string[];\n /** Get the polling config for an action (if async) */\n getPollingConfig(actionId: string): OUIActionPolling | undefined;\n}\n\n// ─── Internal helpers ────────────────────────────────────────────────────────\n\nfunction actionToManifest<T>(action: ActionDefinition<T>): OUIAction {\n return {\n id: action.id,\n description: action.description,\n input: action.input,\n output: action.output,\n confirm: action.confirm,\n async: action.async,\n polling: action.polling,\n usage: action.usage,\n preconditions: action.preconditions,\n estimatedDuration: action.estimatedDuration,\n tags: action.tags,\n };\n}\n\nfunction obsToManifest(obs: ObservationDefinition): OUIObservation {\n return {\n id: obs.id,\n description: obs.description,\n schema: obs.schema,\n };\n}\n","/**\n * createOUI — a fixed set of surfaces announced over one socket.\n *\n * For a client whose surfaces come and go (a React app, where a page's\n * surfaces mount with the page), use `createSurfaceRuntime` instead: it keeps\n * the client's own record of what is mounted and answers every request.\n *\n * WHY THIS EXISTS\n *\n * OUI shipped a correct protocol and a correct transport, and its first\n * integrator used neither. studio-ui imported only the `SocketLike` TYPE from\n * oui-spec and rebuilt the wire by hand: a literal map of protocol types to\n * socket names, `oui:` hardcoded so the configurable namespace was unreachable,\n * payload interfaces re-declared on the server, and an `action:result` channel\n * mapped but never sent — duplicating the observation channel that already\n * carries results.\n *\n * Nothing was wrong with the spec. Nothing enforced it. Structural typing meant\n * every hand-rolled piece type-checked, and both ends agreed only by the\n * coincidence of matching string literals. Rename one and the other keeps\n * compiling and silently stops receiving.\n *\n * So the requirements are gated here:\n *\n * OUI owns the wire. The integrator provides a socket; it cannot provide a\n * transport, because `OUITransport` values are branded and only this module\n * brands them.\n *\n * OUI owns the result path. Every dispatch carries a requestId and is\n * answered on OUI's result channel. An integrator cannot add a parallel\n * channel because it cannot construct a transport to add one to.\n *\n * The integrator owns content. Surfaces, action schemas, observation schemas\n * and handlers all arrive through `defineSurface`, whose output is branded —\n * so a plain object shaped like a surface will not compile.\n *\n * Violations fail at compile time with a message naming the offending id.\n */\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport type { SocketLike } from \"../transport/websocket.js\";\nimport { createWebSocketTransport } from \"../transport/websocket.js\";\nimport type { DefinedSurface } from \"./define-surface.js\";\nimport { brand, type OUIBranded } from \"./brand.js\";\nimport type { OUIConfigError, ValidateSurfaceIds } from \"./validate.js\";\nimport type { OUISurface } from \"../spec/index.js\";\n\n/** A transport OUI constructed. Integrators cannot produce one. */\nexport type OwnedTransport = OUITransport & OUIBranded<\"transport\">;\n\n/** Surface ids as literal types, for the duplicate check. */\ntype SurfaceIds<T extends readonly DefinedSurface<never>[]> = {\n [K in keyof T]: T[K][\"id\"];\n};\n\nexport interface OUIConfig<TSurfaces extends readonly DefinedSurface<never>[]> {\n /**\n * The socket OUI will speak over. The integrator owns the connection —\n * auth, reconnection, lifecycle — and OUI owns what travels on it.\n */\n socket: SocketLike;\n\n /**\n * Surfaces produced by `defineSurface`. A plain object with the same shape\n * will not compile: DefinedSurface is branded.\n */\n surfaces: TSurfaces;\n\n /**\n * Wire configuration. `namespace` defaults to 'oui' and is the supported way\n * to change the event prefix — hardcoding it at the call site is what made\n * this option unreachable in the first integration.\n */\n transport?: Omit<OUITransportConfig, \"namespace\"> & { namespace?: string };\n}\n\n/** A live OUI instance. */\nexport interface OUIInstance {\n /** The transport OUI owns. Exposed for wiring, not for reimplementation. */\n readonly transport: OwnedTransport;\n\n /** Manifests for every registered surface, as the agent sees them. */\n readonly manifests: readonly OUISurface[];\n\n /** Register every surface and connect. */\n start(): Promise<void>;\n\n /**\n * Deregister every surface and detach OUI from the socket. The socket stays\n * connected: the integrator owns it, and other code may share it.\n */\n stop(): void;\n\n /** Look up a registered surface by id. */\n getSurface(id: string): DefinedSurface<never> | undefined;\n}\n\n/**\n * Instantiate OUI.\n *\n * `const` on the type parameter captures surface ids as literal types, which is\n * what allows duplicate detection to name the offending id rather than failing\n * with an unassignable-to-never error.\n */\nexport function createOUI<\n const TSurfaces extends readonly DefinedSurface<never>[],\n>(\n config: OUIConfig<TSurfaces> & ValidateSurfaceIds<SurfaceIds<TSurfaces>>,\n): OUIInstance {\n const {\n socket,\n surfaces,\n transport: transportConfig,\n } = config as OUIConfig<TSurfaces>;\n\n // Defensive, not decorative: the compile-time checks only bind when a caller\n // passes literals. A surface list assembled at runtime, or JS with no types\n // at all, reaches here unchecked.\n if (!socket) {\n throw new Error(\n \"[OUI] createOUI requires a socket. OUI owns the wire; the integrator owns the connection.\",\n );\n }\n if (!Array.isArray(surfaces) || surfaces.length === 0) {\n throw new Error(\"[OUI] createOUI requires at least one surface.\");\n }\n\n const seen = new Set<string>();\n for (const surface of surfaces) {\n if (seen.has(surface.id)) {\n throw new Error(\n `[OUI] Duplicate surface id \"${surface.id}\". Registration is keyed by id, so the second would replace the first.`,\n );\n }\n seen.add(surface.id);\n }\n\n const transport = brand<\"transport\", OUITransport>(\n createWebSocketTransport(socket, transportConfig),\n );\n\n const byId = new Map(surfaces.map((s) => [s.id, s] as const));\n\n return {\n transport,\n manifests: surfaces.map((s) => s.toManifest()),\n\n async start() {\n await transport.connect();\n for (const surface of surfaces) {\n transport.registerSurface(surface.toManifest());\n }\n },\n\n stop() {\n for (const surface of surfaces) {\n transport.deregisterSurface(surface.id);\n }\n transport.dispose();\n },\n\n getSurface(id) {\n return byId.get(id);\n },\n };\n}\n\n/** Re-exported so integrators can name the error type in tests. */\nexport type { OUIConfigError };\n","/**\n * The client-side surface runtime.\n *\n * Holds the surfaces a client has mounted, answers every action request with a\n * result, and produces the snapshot an agent runtime works from.\n *\n * WHY THIS EXISTS\n *\n * The first integration kept no client-side record of what was mounted. Each\n * surface hook registered itself with a server-side registry and listened for\n * dispatches on its own. Three things followed:\n *\n * - The registry was the only record of what the client could do, and it lost\n * entries: a dead socket's cleanup removed a live tab's registration, and the\n * browser never registered again. The agent then had no UI tools at all.\n * - Nothing answered a dispatch. The agent was told an action succeeded before\n * the client had run it, and never saw the page an action led to.\n * - Every hook listened independently, through two paths, so one dispatch ran\n * twice and nothing de-duplicated it.\n *\n * Here the client is the record. `snapshot()` is what the client can do right\n * now, and every request is run once, waited on until the UI settles, and\n * answered with its result and the snapshot after it.\n */\nimport type {\n OUIActionRequest,\n OUIActionResult,\n OUISurface,\n OUISurfaceSnapshot,\n OUIObservationSnapshot,\n} from \"../spec/index.js\";\nimport type { OUITransport, OUITransportConfig } from \"../transport/types.js\";\nimport {\n createWebSocketTransport,\n type SocketLike,\n} from \"../transport/websocket.js\";\nimport type {\n ActionHandlerResult,\n ActionPollingConfig,\n DefinedSurface,\n} from \"./define-surface.js\";\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\nexport interface SettleOptions {\n /**\n * The UI counts as settled once nothing has mounted, unmounted or changed an\n * observation for this long, and no hold is open. Default 250 ms.\n */\n quietMs?: number;\n /** Give up waiting after this long and answer with `settled: false`. Default 5000 ms. */\n timeoutMs?: number;\n}\n\nexport interface SurfaceRuntimeOptions {\n /** The socket to answer requests on. Can be set or replaced later with `attach`. */\n socket?: SocketLike | null;\n\n /** Wire configuration for the transport the runtime builds on the socket. */\n transport?: OUITransportConfig;\n\n /**\n * Also announce registrations and observations over the transport, for agent\n * runtimes that keep a server-side registry. Default true.\n *\n * An agent runtime that takes the client's snapshot instead (sent with each\n * turn, and returned on every result) has no use for them: set false.\n */\n announce?: boolean;\n\n settle?: SettleOptions;\n\n /** How many answered request ids to remember, for de-duplication. Default 500. */\n dedupeWindow?: number;\n\n /**\n * Decides whether a request that arrived on the socket may run at all. A\n * refused request is neither run nor answered, and is logged.\n *\n * The server should be the only sender of action requests, but a client can\n * also check that a request is one it expects: for example, only while its\n * agent has a turn in progress. Requests passed to `execute` directly are\n * not checked; they come from the application itself.\n */\n accept?: (request: OUIActionRequest) => boolean;\n}\n\n// ─── Public types ────────────────────────────────────────────────────────────\n\nexport interface MountedSurface {\n readonly surfaceId: string;\n /** Record an observation value. A no-op once unmounted. */\n pushObservation(observationId: string, value: unknown): void;\n /** Remove this mount. Other mounts of the same surface id are unaffected. */\n unmount(): void;\n}\n\nexport interface SurfaceRuntime {\n /**\n * Mount a surface. `getContext` is read when an action runs, so handlers see\n * the latest state rather than the state at mount time.\n *\n * Mounting the same surface id twice is allowed (React StrictMode does it on\n * every mount); the most recent mount serves its actions.\n */\n mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface;\n\n /** Answer requests arriving on this socket (null detaches). */\n attach(socket: SocketLike | null): void;\n\n /** What the client can do right now. */\n snapshot(): OUISurfaceSnapshot;\n\n /**\n * Run a request once and resolve with its result. A request id seen before\n * resolves with the first result instead of running again.\n */\n execute(request: OUIActionRequest): Promise<OUIActionResult>;\n\n /**\n * Keep the UI unsettled until the returned function is called. For work an\n * action starts that mounting and unmounting cannot show, such as a route's\n * code still loading or a page fetching the data it will display.\n */\n hold(): () => void;\n\n /** Called whenever the snapshot changes. */\n subscribe(listener: () => void): () => void;\n\n /** Stop polling, detach from the socket and forget every mount. */\n dispose(): void;\n}\n\n// ─── Implementation ──────────────────────────────────────────────────────────\n\ninterface Entry {\n key: number;\n surface: DefinedSurface<unknown>;\n getContext: () => unknown;\n}\n\nconst DEFAULT_QUIET_MS = 250;\nconst DEFAULT_SETTLE_TIMEOUT_MS = 5000;\nconst DEFAULT_DEDUPE_WINDOW = 500;\nconst SETTLE_TICK_MS = 50;\n\nexport function createSurfaceRuntime(\n options: SurfaceRuntimeOptions = {},\n): SurfaceRuntime {\n const announce = options.announce ?? true;\n const quietMs = options.settle?.quietMs ?? DEFAULT_QUIET_MS;\n const settleTimeoutMs =\n options.settle?.timeoutMs ?? DEFAULT_SETTLE_TIMEOUT_MS;\n const dedupeWindow = options.dedupeWindow ?? DEFAULT_DEDUPE_WINDOW;\n\n let nextKey = 1;\n const entries: Entry[] = [];\n const observations = new Map<string, Map<string, unknown>>();\n const serializedObservations = new Map<string, string>();\n const holds = new Set<number>();\n let nextHold = 1;\n const results = new Map<string, Promise<OUIActionResult>>();\n const pollers = new Map<string, ReturnType<typeof setInterval>>();\n const listeners = new Set<() => void>();\n // Resolves once a request's first result has been handed to the transport.\n const acks = new Map<\n string,\n { promise: Promise<void>; resolve: () => void }\n >();\n function ackFor(requestId: string) {\n let ack = acks.get(requestId);\n if (!ack) {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => (resolve = r));\n ack = { promise, resolve };\n acks.set(requestId, ack);\n }\n return ack;\n }\n function acknowledged(requestId: string): Promise<void> {\n return ackFor(requestId).promise;\n }\n let lastChangeAt = Date.now();\n\n let socket: SocketLike | null = null;\n let transport: OUITransport | null = null;\n let detachTransport: Array<() => void> = [];\n\n /**\n * `settles: false` for changes that are not the UI reacting to an action,\n * such as an async job's progress: those notify listeners but do not keep\n * an action's result waiting.\n */\n function changed(settles = true) {\n if (settles) lastChangeAt = Date.now();\n for (const l of [...listeners]) l();\n }\n\n function activeFor(surfaceId: string): Entry | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].surface.id === surfaceId) return entries[i];\n }\n return undefined;\n }\n\n /** Active entries, one per surface id, in the order each id was first mounted. */\n function activeEntries(): Entry[] {\n const seen = new Set<string>();\n const out: Entry[] = [];\n for (const e of entries) {\n if (seen.has(e.surface.id)) continue;\n seen.add(e.surface.id);\n out.push(activeFor(e.surface.id)!);\n }\n return out;\n }\n\n function announceSurface(entry: Entry) {\n if (!announce || !transport) return;\n transport.registerSurface(entry.surface.toManifest());\n const obs = observations.get(entry.surface.id);\n if (obs) {\n for (const [observationId, value] of obs) {\n transport.pushObservation({\n surfaceId: entry.surface.id,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n }\n }\n\n function announceAll() {\n for (const e of activeEntries()) announceSurface(e);\n }\n\n function setObservation(\n surfaceId: string,\n observationId: string,\n value: unknown,\n settles = true,\n ) {\n const key = `${surfaceId}\\u0000${observationId}`;\n let serialized: string;\n try {\n serialized = JSON.stringify(value) ?? \"undefined\";\n } catch {\n serialized = String(value);\n }\n if (serializedObservations.get(key) === serialized) return;\n serializedObservations.set(key, serialized);\n\n let obs = observations.get(surfaceId);\n if (!obs) {\n obs = new Map();\n observations.set(surfaceId, obs);\n }\n obs.set(observationId, toJsonSafe(value));\n\n if (announce && transport) {\n transport.pushObservation({\n surfaceId,\n observationId,\n value,\n timestamp: Date.now(),\n });\n }\n changed(settles);\n }\n\n function forgetSurface(surfaceId: string) {\n observations.delete(surfaceId);\n for (const key of [...serializedObservations.keys()]) {\n if (key.startsWith(`${surfaceId}\\u0000`))\n serializedObservations.delete(key);\n }\n for (const [key, timer] of pollers) {\n if (key.startsWith(`${surfaceId}\\u0000`)) {\n clearInterval(timer);\n pollers.delete(key);\n }\n }\n }\n\n // ─── Polling (async actions) ──────────────────────────────────────────────\n\n /**\n * Polls an async action to completion, publishing progress as an observation\n * and, when it ends, the request's final result (OUI spec §7.3: an async\n * action is acknowledged, then answered once more when it finishes).\n */\n function startPolling(\n requestId: string,\n surfaceId: string,\n actionId: string,\n polling: ActionPollingConfig<unknown>,\n dispatchResult: unknown,\n ) {\n const finish = async (\n success: boolean,\n data: unknown,\n error?: { code: string; message: string },\n ) => {\n // The acknowledgment goes first: a job can finish before the UI settles.\n await acknowledged(requestId);\n const snap = snapshot();\n transport?.sendResult({\n requestId,\n success,\n ...(data !== undefined ? { data: toJsonSafe(data) } : {}),\n ...(error ? { error } : {}),\n interim: false,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n });\n acks.delete(requestId);\n };\n\n // The observation id is the one surfaces have always published under.\n const observationId = `${surfaceId}:${actionId}:status`;\n const pollerKey = `${surfaceId}\\u0000${actionId}`;\n\n if (polling.subscribe) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: true },\n false,\n );\n return;\n }\n if (!polling.resolve) {\n setObservation(\n surfaceId,\n observationId,\n { status: \"dispatched\", dispatchResult, interim: false },\n false,\n );\n return;\n }\n\n const existing = pollers.get(pollerKey);\n if (existing) clearInterval(existing);\n\n setObservation(\n surfaceId,\n observationId,\n { status: \"polling\", dispatchResult, interim: true },\n false,\n );\n\n const maxAttempts = polling.maxAttempts ?? Infinity;\n const maxDuration = polling.maxDurationMs ?? Infinity;\n const startedAt = Date.now();\n let attempts = 0;\n\n const timer = setInterval(async () => {\n attempts++;\n if (attempts > maxAttempts || Date.now() - startedAt > maxDuration) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n setObservation(\n surfaceId,\n observationId,\n { status: \"timeout\", dispatchResult, interim: false },\n false,\n );\n void finish(false, undefined, {\n code: \"TIMEOUT\",\n message: `\"${actionId}\" did not finish within its polling limits.`,\n });\n return;\n }\n const entry = activeFor(surfaceId);\n const action = entry?.surface.actions.find((a) => a.id === actionId);\n if (!entry || !action?.polling?.resolve) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n return;\n }\n try {\n const r = await action.polling.resolve(\n dispatchResult,\n entry.getContext(),\n );\n setObservation(\n surfaceId,\n observationId,\n {\n ...(r.data as Record<string, unknown>),\n interim: !r.done,\n },\n false,\n );\n if (r.done) {\n clearInterval(timer);\n pollers.delete(pollerKey);\n void finish(true, r.data);\n }\n } catch (err) {\n // A transient failure is reported, not fatal: keep polling.\n setObservation(\n surfaceId,\n observationId,\n { status: \"poll_error\", error: String(err), interim: true },\n false,\n );\n }\n }, polling.intervalMs);\n\n pollers.set(pollerKey, timer);\n }\n\n // ─── Settling ─────────────────────────────────────────────────────────────\n\n async function waitUntilSettled(since: number): Promise<boolean> {\n const deadline = since + settleTimeoutMs;\n for (;;) {\n const now = Date.now();\n const quietFor = now - Math.max(since, lastChangeAt);\n if (holds.size === 0 && quietFor >= quietMs) return true;\n if (now >= deadline) return false;\n await sleep(Math.min(SETTLE_TICK_MS, deadline - now));\n }\n }\n\n // ─── Execution ────────────────────────────────────────────────────────────\n\n async function run(request: OUIActionRequest): Promise<OUIActionResult> {\n const startedAt = Date.now();\n const entry = activeFor(request.surfaceId);\n\n let result: ActionHandlerResult;\n let interim = false;\n if (!entry) {\n const mounted = activeEntries().map((e) => e.surface.id);\n result = {\n success: false,\n error: {\n code: \"SURFACE_NOT_MOUNTED\",\n message:\n `Surface \"${request.surfaceId}\" is not on screen. ` +\n `Mounted surfaces: ${mounted.length ? mounted.join(\", \") : \"none\"}.`,\n },\n };\n } else {\n // executeAction turns a thrown handler into ACTION_EXECUTION_ERROR.\n result = await entry.surface.executeAction(\n request.actionId,\n request.params ?? {},\n entry.getContext(),\n );\n if (result.success) {\n const action = entry.surface.actions.find(\n (a) => a.id === request.actionId,\n );\n if (action?.polling) {\n interim = true;\n startPolling(\n request.requestId,\n entry.surface.id,\n action.id,\n action.polling,\n result.data ?? result.dispatchMeta,\n );\n }\n }\n }\n\n const settled = await waitUntilSettled(startedAt);\n const snap = snapshot();\n\n return {\n requestId: request.requestId,\n success: result.success,\n ...(result.data !== undefined ? { data: toJsonSafe(result.data) } : {}),\n ...(result.error\n ? { error: toJsonSafe(result.error) as OUIActionResult[\"error\"] }\n : {}),\n ...(interim ? { interim: true } : {}),\n durationMs: Date.now() - startedAt,\n timestamp: Date.now(),\n surfaces: snap.surfaces,\n observations: snap.observations,\n settled,\n };\n }\n\n function execute(request: OUIActionRequest): Promise<OUIActionResult> {\n const seen = results.get(request.requestId);\n if (seen) return seen;\n\n const pending = run(request);\n results.set(request.requestId, pending);\n while (results.size > dedupeWindow) {\n const oldest = results.keys().next().value as string;\n results.delete(oldest);\n }\n return pending;\n }\n\n // ─── Snapshot ─────────────────────────────────────────────────────────────\n\n function snapshot(): OUISurfaceSnapshot {\n const surfaces: OUISurface[] = [];\n const obs: OUIObservationSnapshot = {};\n for (const e of activeEntries()) {\n surfaces.push(e.surface.toManifest());\n const values = observations.get(e.surface.id);\n if (values && values.size > 0)\n obs[e.surface.id] = Object.fromEntries(values);\n }\n return { surfaces, observations: obs };\n }\n\n // ─── Transport ────────────────────────────────────────────────────────────\n\n function attach(next: SocketLike | null) {\n if (next === socket) return;\n for (const off of detachTransport) off();\n detachTransport = [];\n transport?.dispose();\n transport = null;\n socket = next;\n if (!next) return;\n\n const t = createWebSocketTransport(next, options.transport);\n transport = t;\n\n detachTransport.push(\n t.onAction((request) => {\n if (options.accept && !options.accept(request)) {\n console.warn(\n `[OUI] Refused a request the client does not accept: ${request.surfaceId}.${request.actionId} (${request.requestId})`,\n );\n return;\n }\n void execute(request).then((result) => {\n // Answer on whichever transport is live when the result is ready: a\n // reconnect in between keeps the same socket, so this still reaches\n // the runtime that asked.\n transport?.sendResult(result);\n const ack = ackFor(request.requestId);\n ack.resolve();\n // Keep the gate only while a final result may still follow.\n if (!result.interim) acks.delete(request.requestId);\n });\n }),\n );\n\n if (announce) {\n // A server-side registry forgets a socket's surfaces when it drops, so\n // every (re)connection announces them again.\n detachTransport.push(\n t.onConnectionChange((connected) => {\n if (connected) announceAll();\n }),\n );\n if (t.connected) announceAll();\n }\n }\n\n if (options.socket) attach(options.socket);\n\n // ─── Mounting ─────────────────────────────────────────────────────────────\n\n function mount<TContext>(\n surface: DefinedSurface<TContext>,\n getContext: () => TContext,\n ): MountedSurface {\n const entry: Entry = {\n key: nextKey++,\n surface: surface as unknown as DefinedSurface<unknown>,\n getContext: getContext as () => unknown,\n };\n entries.push(entry);\n announceSurface(entry);\n changed();\n\n let mounted = true;\n return {\n surfaceId: surface.id,\n pushObservation(observationId, value) {\n // Only the mount serving the surface speaks for it.\n if (!mounted || activeFor(surface.id) !== entry) return;\n setObservation(surface.id, observationId, value);\n },\n unmount() {\n if (!mounted) return;\n mounted = false;\n const i = entries.indexOf(entry);\n if (i >= 0) entries.splice(i, 1);\n const replacement = activeFor(surface.id);\n if (replacement) {\n announceSurface(replacement);\n } else {\n forgetSurface(surface.id);\n if (announce && transport) transport.deregisterSurface(surface.id);\n }\n changed();\n },\n };\n }\n\n return {\n mount,\n attach,\n snapshot,\n execute,\n hold() {\n const id = nextHold++;\n holds.add(id);\n changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n holds.delete(id);\n changed();\n };\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n dispose() {\n for (const timer of pollers.values()) clearInterval(timer);\n pollers.clear();\n attach(null);\n entries.length = 0;\n observations.clear();\n serializedObservations.clear();\n holds.clear();\n listeners.clear();\n acks.clear();\n },\n };\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Results and observations cross a wire as JSON. A handler returning something\n * that is not (a DOM node, a class instance with cycles) must not take the\n * result down with it.\n */\nfunction toJsonSafe(value: unknown): unknown {\n if (value === undefined) return undefined;\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n return String(value);\n }\n}\n"]}