oui-spec 0.1.0 → 0.3.0

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.
Files changed (61) hide show
  1. package/README.md +161 -104
  2. package/dist/{chunk-CVUUSPF4.js → chunk-BMCL2K74.js} +2 -2
  3. package/dist/chunk-BMCL2K74.js.map +1 -0
  4. package/dist/chunk-DCVVTP3V.cjs +155 -0
  5. package/dist/chunk-DCVVTP3V.cjs.map +1 -0
  6. package/dist/chunk-F3SKRAGU.cjs +98 -0
  7. package/dist/chunk-F3SKRAGU.cjs.map +1 -0
  8. package/dist/chunk-F3WKIRAU.js +153 -0
  9. package/dist/chunk-F3WKIRAU.js.map +1 -0
  10. package/dist/chunk-IIZ6HL2L.js +89 -0
  11. package/dist/chunk-IIZ6HL2L.js.map +1 -0
  12. package/dist/chunk-KNWGQRXL.cjs +567 -0
  13. package/dist/chunk-KNWGQRXL.cjs.map +1 -0
  14. package/dist/chunk-NYCJZQSP.js +92 -0
  15. package/dist/chunk-NYCJZQSP.js.map +1 -0
  16. package/dist/chunk-ROGKEMLL.cjs +91 -0
  17. package/dist/chunk-ROGKEMLL.cjs.map +1 -0
  18. package/dist/chunk-TRNVXAB5.js +563 -0
  19. package/dist/chunk-TRNVXAB5.js.map +1 -0
  20. package/dist/{chunk-3DCIL4FV.cjs → chunk-ZKM4XWAB.cjs} +2 -2
  21. package/dist/chunk-ZKM4XWAB.cjs.map +1 -0
  22. package/dist/core/index.cjs +13 -4
  23. package/dist/core/index.d.cts +123 -102
  24. package/dist/core/index.d.ts +123 -102
  25. package/dist/core/index.js +3 -2
  26. package/dist/index.cjs +31 -10
  27. package/dist/index.d.cts +7 -4
  28. package/dist/index.d.ts +7 -4
  29. package/dist/index.js +5 -4
  30. package/dist/react/index.cjs +15 -3
  31. package/dist/react/index.d.cts +33 -50
  32. package/dist/react/index.d.ts +33 -50
  33. package/dist/react/index.js +1 -1
  34. package/dist/spec/index.cjs +2 -2
  35. package/dist/spec/index.d.cts +35 -7
  36. package/dist/spec/index.d.ts +35 -7
  37. package/dist/spec/index.js +1 -1
  38. package/dist/surface-runtime--2lZGB7Z.d.cts +241 -0
  39. package/dist/surface-runtime-Dj_nhd7r.d.ts +241 -0
  40. package/dist/transport/index.cjs +4 -3
  41. package/dist/transport/index.d.cts +4 -77
  42. package/dist/transport/index.d.ts +4 -77
  43. package/dist/transport/index.js +2 -1
  44. package/dist/websocket-YfWILdZ4.d.cts +96 -0
  45. package/dist/websocket-c5tIUWY5.d.ts +96 -0
  46. package/package.json +8 -3
  47. package/spec/OUI-SPEC-v0.1.md +229 -155
  48. package/dist/chunk-2ON5IEXB.cjs +0 -167
  49. package/dist/chunk-2ON5IEXB.cjs.map +0 -1
  50. package/dist/chunk-3DCIL4FV.cjs.map +0 -1
  51. package/dist/chunk-7EXSMPGR.js +0 -207
  52. package/dist/chunk-7EXSMPGR.js.map +0 -1
  53. package/dist/chunk-CVUUSPF4.js.map +0 -1
  54. package/dist/chunk-JO5LGOB6.js +0 -88
  55. package/dist/chunk-JO5LGOB6.js.map +0 -1
  56. package/dist/chunk-LEXIU2MH.cjs +0 -90
  57. package/dist/chunk-LEXIU2MH.cjs.map +0 -1
  58. package/dist/chunk-UIGRLZOX.js +0 -164
  59. package/dist/chunk-UIGRLZOX.js.map +0 -1
  60. package/dist/chunk-WZXUKJ7E.cjs +0 -210
  61. package/dist/chunk-WZXUKJ7E.cjs.map +0 -1
@@ -0,0 +1,241 @@
1
+ import { JSONSchema, OUIActionPolling, OUIActivation, OUISurface, OUISurfaceSnapshot, OUIActionRequest, OUIActionResult } from './spec/index.cjs';
2
+ import { S as SocketLike, d as OUITransportConfig } from './websocket-YfWILdZ4.cjs';
3
+
4
+ /**
5
+ * Nominal branding for values OUI must construct itself.
6
+ *
7
+ * Structural typing means any object with the right shape satisfies an
8
+ * interface. That is how Closure Studio ended up hand-rolling OUI's transport:
9
+ * `SocketLike` was importable, `OUITransport` was a plain interface, so an
10
+ * integrator could satisfy every type without ever calling OUI. The result was
11
+ * a second implementation of the wire — hardcoded namespace, re-declared
12
+ * payload types on the server, and a dead `action:result` mapping alongside the
13
+ * observation channel that already carried results.
14
+ *
15
+ * A unique symbol cannot be produced outside this module. Branding the types
16
+ * OUI owns turns "you should use our constructor" into "you cannot compile
17
+ * without it".
18
+ */
19
+ declare const OUI_BRAND: unique symbol;
20
+ /** Marks a value as constructed by OUI itself. */
21
+ interface OUIBranded<TKind extends string> {
22
+ readonly [OUI_BRAND]: TKind;
23
+ }
24
+
25
+ /**
26
+ * Configuration for defining an OUI surface with handlers.
27
+ * This is the "integration file" an app provides — it declares both
28
+ * the schema (what the agent sees) and the implementation (what executes).
29
+ */
30
+ interface SurfaceDefinition<TContext = unknown> {
31
+ id: string;
32
+ name: string;
33
+ description: string;
34
+ version?: string;
35
+ activation?: OUIActivation;
36
+ actions: ActionDefinition<TContext>[];
37
+ observations?: ObservationDefinition[];
38
+ metadata?: Record<string, unknown>;
39
+ }
40
+ /**
41
+ * Polling config with an optional resolve handler.
42
+ * The spec's OUIActionPolling is the manifest shape (no functions).
43
+ * The core extends it with the resolve implementation for the runtime.
44
+ */
45
+ interface ActionPollingConfig<TContext = unknown> extends OUIActionPolling {
46
+ /**
47
+ * Called on each poll interval. Receives the dispatch result from the handler
48
+ * plus the current context. Return { done: true, data } to stop polling,
49
+ * or { done: false, data } to continue.
50
+ */
51
+ resolve?: (dispatchResult: unknown, context: TContext) => Promise<{
52
+ done: boolean;
53
+ data: unknown;
54
+ }>;
55
+ }
56
+ /**
57
+ * An action definition includes both the schema (for the agent) and
58
+ * the handler (for execution). This is the single source of truth —
59
+ * no separate YAML, no separate listener, no drift possible.
60
+ */
61
+ interface ActionDefinition<TContext = unknown> {
62
+ id: string;
63
+ description: string;
64
+ input: JSONSchema;
65
+ output?: JSONSchema;
66
+ confirm?: boolean;
67
+ async?: boolean;
68
+ /**
69
+ * Polling/subscription config for async actions.
70
+ * After the handler returns, the OUI runtime starts polling or subscribing
71
+ * and pushes observation updates until the operation completes.
72
+ * Extends the spec's OUIActionPolling with an optional resolve handler.
73
+ */
74
+ polling?: ActionPollingConfig<TContext>;
75
+ usage?: string;
76
+ preconditions?: string;
77
+ estimatedDuration?: string;
78
+ tags?: string[];
79
+ /**
80
+ * The handler that executes when the agent invokes this action.
81
+ * Receives typed params and a context object (app-specific state/utilities).
82
+ * Returns a result that the agent sees as the tool output.
83
+ */
84
+ handler: (params: Record<string, unknown>, context: TContext) => Promise<ActionHandlerResult>;
85
+ }
86
+ interface ActionHandlerResult {
87
+ success: boolean;
88
+ data?: unknown;
89
+ error?: {
90
+ code: string;
91
+ message: string;
92
+ details?: unknown;
93
+ };
94
+ /** For async actions: metadata passed to the polling resolver */
95
+ dispatchMeta?: Record<string, unknown>;
96
+ }
97
+ interface ObservationDefinition {
98
+ id: string;
99
+ description: string;
100
+ schema: JSONSchema;
101
+ /** Function that returns the current observation value */
102
+ getValue?: () => unknown;
103
+ }
104
+ /**
105
+ * Define an OUI surface — the single entry point for integrating
106
+ * an application feature with the OUI protocol.
107
+ *
108
+ * This function validates the definition and returns a typed surface
109
+ * object that can be registered with an agent runtime or transport layer.
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const mySurface = defineSurface({
114
+ * id: 'my-feature',
115
+ * name: 'My Feature',
116
+ * description: 'Does something cool',
117
+ * actions: [
118
+ * {
119
+ * id: 'do_thing',
120
+ * description: 'Does the thing',
121
+ * input: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
122
+ * handler: async (params) => {
123
+ * const result = await doTheThing(params.name);
124
+ * return { success: true, data: result };
125
+ * },
126
+ * },
127
+ * ],
128
+ * });
129
+ * ```
130
+ */
131
+ declare function defineSurface<TContext = unknown, const TId extends string = string>(definition: SurfaceDefinition<TContext> & {
132
+ id: TId;
133
+ }): DefinedSurface<TContext> & {
134
+ id: TId;
135
+ };
136
+ /** A fully defined surface with both manifest extraction and execution capabilities */
137
+ /**
138
+ * Branded so it can only come from `defineSurface`.
139
+ *
140
+ * Without the brand a plain object literal satisfies this interface
141
+ * structurally, which is how an integrator can assemble a surface that never
142
+ * ran defineSurface's duplicate-id checks and never produced a real manifest.
143
+ */
144
+ interface DefinedSurface<TContext = unknown> extends SurfaceDefinition<TContext>, OUIBranded<"surface"> {
145
+ toManifest(): OUISurface;
146
+ executeAction(actionId: string, params: Record<string, unknown>, context: TContext): Promise<ActionHandlerResult>;
147
+ getActionIds(): string[];
148
+ /** Get the polling config for an action (if async) */
149
+ getPollingConfig(actionId: string): OUIActionPolling | undefined;
150
+ }
151
+
152
+ /**
153
+ * The client-side surface runtime.
154
+ *
155
+ * Holds the surfaces a client has mounted, answers every action request with a
156
+ * result, and produces the snapshot an agent runtime works from.
157
+ *
158
+ * WHY THIS EXISTS
159
+ *
160
+ * The first integration kept no client-side record of what was mounted. Each
161
+ * surface hook registered itself with a server-side registry and listened for
162
+ * dispatches on its own. Three things followed:
163
+ *
164
+ * - The registry was the only record of what the client could do, and it lost
165
+ * entries: a dead socket's cleanup removed a live tab's registration, and the
166
+ * browser never registered again. The agent then had no UI tools at all.
167
+ * - Nothing answered a dispatch. The agent was told an action succeeded before
168
+ * the client had run it, and never saw the page an action led to.
169
+ * - Every hook listened independently, through two paths, so one dispatch ran
170
+ * twice and nothing de-duplicated it.
171
+ *
172
+ * Here the client is the record. `snapshot()` is what the client can do right
173
+ * now, and every request is run once, waited on until the UI settles, and
174
+ * answered with its result and the snapshot after it.
175
+ */
176
+
177
+ interface SettleOptions {
178
+ /**
179
+ * The UI counts as settled once nothing has mounted, unmounted or changed an
180
+ * observation for this long, and no hold is open. Default 250 ms.
181
+ */
182
+ quietMs?: number;
183
+ /** Give up waiting after this long and answer with `settled: false`. Default 5000 ms. */
184
+ timeoutMs?: number;
185
+ }
186
+ interface SurfaceRuntimeOptions {
187
+ /** The socket to answer requests on. Can be set or replaced later with `attach`. */
188
+ socket?: SocketLike | null;
189
+ /** Wire configuration for the transport the runtime builds on the socket. */
190
+ transport?: OUITransportConfig;
191
+ /**
192
+ * Also announce registrations and observations over the transport, for agent
193
+ * runtimes that keep a server-side registry. Default true.
194
+ *
195
+ * An agent runtime that takes the client's snapshot instead (sent with each
196
+ * turn, and returned on every result) has no use for them: set false.
197
+ */
198
+ announce?: boolean;
199
+ settle?: SettleOptions;
200
+ /** How many answered request ids to remember, for de-duplication. Default 500. */
201
+ dedupeWindow?: number;
202
+ }
203
+ interface MountedSurface {
204
+ readonly surfaceId: string;
205
+ /** Record an observation value. A no-op once unmounted. */
206
+ pushObservation(observationId: string, value: unknown): void;
207
+ /** Remove this mount. Other mounts of the same surface id are unaffected. */
208
+ unmount(): void;
209
+ }
210
+ interface SurfaceRuntime {
211
+ /**
212
+ * Mount a surface. `getContext` is read when an action runs, so handlers see
213
+ * the latest state rather than the state at mount time.
214
+ *
215
+ * Mounting the same surface id twice is allowed (React StrictMode does it on
216
+ * every mount); the most recent mount serves its actions.
217
+ */
218
+ mount<TContext>(surface: DefinedSurface<TContext>, getContext: () => TContext): MountedSurface;
219
+ /** Answer requests arriving on this socket (null detaches). */
220
+ attach(socket: SocketLike | null): void;
221
+ /** What the client can do right now. */
222
+ snapshot(): OUISurfaceSnapshot;
223
+ /**
224
+ * Run a request once and resolve with its result. A request id seen before
225
+ * resolves with the first result instead of running again.
226
+ */
227
+ execute(request: OUIActionRequest): Promise<OUIActionResult>;
228
+ /**
229
+ * Keep the UI unsettled until the returned function is called. For work an
230
+ * action starts that mounting and unmounting cannot show, such as a route's
231
+ * code still loading or a page fetching the data it will display.
232
+ */
233
+ hold(): () => void;
234
+ /** Called whenever the snapshot changes. */
235
+ subscribe(listener: () => void): () => void;
236
+ /** Stop polling, detach from the socket and forget every mount. */
237
+ dispose(): void;
238
+ }
239
+ declare function createSurfaceRuntime(options?: SurfaceRuntimeOptions): SurfaceRuntime;
240
+
241
+ export { type ActionDefinition as A, type DefinedSurface as D, type MountedSurface as M, type OUIBranded as O, type SettleOptions as S, type ActionHandlerResult as a, type ActionPollingConfig as b, type ObservationDefinition as c, type SurfaceDefinition as d, type SurfaceRuntime as e, type SurfaceRuntimeOptions as f, createSurfaceRuntime as g, defineSurface as h };
@@ -0,0 +1,241 @@
1
+ import { JSONSchema, OUIActionPolling, OUIActivation, OUISurface, OUISurfaceSnapshot, OUIActionRequest, OUIActionResult } from './spec/index.js';
2
+ import { S as SocketLike, d as OUITransportConfig } from './websocket-c5tIUWY5.js';
3
+
4
+ /**
5
+ * Nominal branding for values OUI must construct itself.
6
+ *
7
+ * Structural typing means any object with the right shape satisfies an
8
+ * interface. That is how Closure Studio ended up hand-rolling OUI's transport:
9
+ * `SocketLike` was importable, `OUITransport` was a plain interface, so an
10
+ * integrator could satisfy every type without ever calling OUI. The result was
11
+ * a second implementation of the wire — hardcoded namespace, re-declared
12
+ * payload types on the server, and a dead `action:result` mapping alongside the
13
+ * observation channel that already carried results.
14
+ *
15
+ * A unique symbol cannot be produced outside this module. Branding the types
16
+ * OUI owns turns "you should use our constructor" into "you cannot compile
17
+ * without it".
18
+ */
19
+ declare const OUI_BRAND: unique symbol;
20
+ /** Marks a value as constructed by OUI itself. */
21
+ interface OUIBranded<TKind extends string> {
22
+ readonly [OUI_BRAND]: TKind;
23
+ }
24
+
25
+ /**
26
+ * Configuration for defining an OUI surface with handlers.
27
+ * This is the "integration file" an app provides — it declares both
28
+ * the schema (what the agent sees) and the implementation (what executes).
29
+ */
30
+ interface SurfaceDefinition<TContext = unknown> {
31
+ id: string;
32
+ name: string;
33
+ description: string;
34
+ version?: string;
35
+ activation?: OUIActivation;
36
+ actions: ActionDefinition<TContext>[];
37
+ observations?: ObservationDefinition[];
38
+ metadata?: Record<string, unknown>;
39
+ }
40
+ /**
41
+ * Polling config with an optional resolve handler.
42
+ * The spec's OUIActionPolling is the manifest shape (no functions).
43
+ * The core extends it with the resolve implementation for the runtime.
44
+ */
45
+ interface ActionPollingConfig<TContext = unknown> extends OUIActionPolling {
46
+ /**
47
+ * Called on each poll interval. Receives the dispatch result from the handler
48
+ * plus the current context. Return { done: true, data } to stop polling,
49
+ * or { done: false, data } to continue.
50
+ */
51
+ resolve?: (dispatchResult: unknown, context: TContext) => Promise<{
52
+ done: boolean;
53
+ data: unknown;
54
+ }>;
55
+ }
56
+ /**
57
+ * An action definition includes both the schema (for the agent) and
58
+ * the handler (for execution). This is the single source of truth —
59
+ * no separate YAML, no separate listener, no drift possible.
60
+ */
61
+ interface ActionDefinition<TContext = unknown> {
62
+ id: string;
63
+ description: string;
64
+ input: JSONSchema;
65
+ output?: JSONSchema;
66
+ confirm?: boolean;
67
+ async?: boolean;
68
+ /**
69
+ * Polling/subscription config for async actions.
70
+ * After the handler returns, the OUI runtime starts polling or subscribing
71
+ * and pushes observation updates until the operation completes.
72
+ * Extends the spec's OUIActionPolling with an optional resolve handler.
73
+ */
74
+ polling?: ActionPollingConfig<TContext>;
75
+ usage?: string;
76
+ preconditions?: string;
77
+ estimatedDuration?: string;
78
+ tags?: string[];
79
+ /**
80
+ * The handler that executes when the agent invokes this action.
81
+ * Receives typed params and a context object (app-specific state/utilities).
82
+ * Returns a result that the agent sees as the tool output.
83
+ */
84
+ handler: (params: Record<string, unknown>, context: TContext) => Promise<ActionHandlerResult>;
85
+ }
86
+ interface ActionHandlerResult {
87
+ success: boolean;
88
+ data?: unknown;
89
+ error?: {
90
+ code: string;
91
+ message: string;
92
+ details?: unknown;
93
+ };
94
+ /** For async actions: metadata passed to the polling resolver */
95
+ dispatchMeta?: Record<string, unknown>;
96
+ }
97
+ interface ObservationDefinition {
98
+ id: string;
99
+ description: string;
100
+ schema: JSONSchema;
101
+ /** Function that returns the current observation value */
102
+ getValue?: () => unknown;
103
+ }
104
+ /**
105
+ * Define an OUI surface — the single entry point for integrating
106
+ * an application feature with the OUI protocol.
107
+ *
108
+ * This function validates the definition and returns a typed surface
109
+ * object that can be registered with an agent runtime or transport layer.
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const mySurface = defineSurface({
114
+ * id: 'my-feature',
115
+ * name: 'My Feature',
116
+ * description: 'Does something cool',
117
+ * actions: [
118
+ * {
119
+ * id: 'do_thing',
120
+ * description: 'Does the thing',
121
+ * input: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
122
+ * handler: async (params) => {
123
+ * const result = await doTheThing(params.name);
124
+ * return { success: true, data: result };
125
+ * },
126
+ * },
127
+ * ],
128
+ * });
129
+ * ```
130
+ */
131
+ declare function defineSurface<TContext = unknown, const TId extends string = string>(definition: SurfaceDefinition<TContext> & {
132
+ id: TId;
133
+ }): DefinedSurface<TContext> & {
134
+ id: TId;
135
+ };
136
+ /** A fully defined surface with both manifest extraction and execution capabilities */
137
+ /**
138
+ * Branded so it can only come from `defineSurface`.
139
+ *
140
+ * Without the brand a plain object literal satisfies this interface
141
+ * structurally, which is how an integrator can assemble a surface that never
142
+ * ran defineSurface's duplicate-id checks and never produced a real manifest.
143
+ */
144
+ interface DefinedSurface<TContext = unknown> extends SurfaceDefinition<TContext>, OUIBranded<"surface"> {
145
+ toManifest(): OUISurface;
146
+ executeAction(actionId: string, params: Record<string, unknown>, context: TContext): Promise<ActionHandlerResult>;
147
+ getActionIds(): string[];
148
+ /** Get the polling config for an action (if async) */
149
+ getPollingConfig(actionId: string): OUIActionPolling | undefined;
150
+ }
151
+
152
+ /**
153
+ * The client-side surface runtime.
154
+ *
155
+ * Holds the surfaces a client has mounted, answers every action request with a
156
+ * result, and produces the snapshot an agent runtime works from.
157
+ *
158
+ * WHY THIS EXISTS
159
+ *
160
+ * The first integration kept no client-side record of what was mounted. Each
161
+ * surface hook registered itself with a server-side registry and listened for
162
+ * dispatches on its own. Three things followed:
163
+ *
164
+ * - The registry was the only record of what the client could do, and it lost
165
+ * entries: a dead socket's cleanup removed a live tab's registration, and the
166
+ * browser never registered again. The agent then had no UI tools at all.
167
+ * - Nothing answered a dispatch. The agent was told an action succeeded before
168
+ * the client had run it, and never saw the page an action led to.
169
+ * - Every hook listened independently, through two paths, so one dispatch ran
170
+ * twice and nothing de-duplicated it.
171
+ *
172
+ * Here the client is the record. `snapshot()` is what the client can do right
173
+ * now, and every request is run once, waited on until the UI settles, and
174
+ * answered with its result and the snapshot after it.
175
+ */
176
+
177
+ interface SettleOptions {
178
+ /**
179
+ * The UI counts as settled once nothing has mounted, unmounted or changed an
180
+ * observation for this long, and no hold is open. Default 250 ms.
181
+ */
182
+ quietMs?: number;
183
+ /** Give up waiting after this long and answer with `settled: false`. Default 5000 ms. */
184
+ timeoutMs?: number;
185
+ }
186
+ interface SurfaceRuntimeOptions {
187
+ /** The socket to answer requests on. Can be set or replaced later with `attach`. */
188
+ socket?: SocketLike | null;
189
+ /** Wire configuration for the transport the runtime builds on the socket. */
190
+ transport?: OUITransportConfig;
191
+ /**
192
+ * Also announce registrations and observations over the transport, for agent
193
+ * runtimes that keep a server-side registry. Default true.
194
+ *
195
+ * An agent runtime that takes the client's snapshot instead (sent with each
196
+ * turn, and returned on every result) has no use for them: set false.
197
+ */
198
+ announce?: boolean;
199
+ settle?: SettleOptions;
200
+ /** How many answered request ids to remember, for de-duplication. Default 500. */
201
+ dedupeWindow?: number;
202
+ }
203
+ interface MountedSurface {
204
+ readonly surfaceId: string;
205
+ /** Record an observation value. A no-op once unmounted. */
206
+ pushObservation(observationId: string, value: unknown): void;
207
+ /** Remove this mount. Other mounts of the same surface id are unaffected. */
208
+ unmount(): void;
209
+ }
210
+ interface SurfaceRuntime {
211
+ /**
212
+ * Mount a surface. `getContext` is read when an action runs, so handlers see
213
+ * the latest state rather than the state at mount time.
214
+ *
215
+ * Mounting the same surface id twice is allowed (React StrictMode does it on
216
+ * every mount); the most recent mount serves its actions.
217
+ */
218
+ mount<TContext>(surface: DefinedSurface<TContext>, getContext: () => TContext): MountedSurface;
219
+ /** Answer requests arriving on this socket (null detaches). */
220
+ attach(socket: SocketLike | null): void;
221
+ /** What the client can do right now. */
222
+ snapshot(): OUISurfaceSnapshot;
223
+ /**
224
+ * Run a request once and resolve with its result. A request id seen before
225
+ * resolves with the first result instead of running again.
226
+ */
227
+ execute(request: OUIActionRequest): Promise<OUIActionResult>;
228
+ /**
229
+ * Keep the UI unsettled until the returned function is called. For work an
230
+ * action starts that mounting and unmounting cannot show, such as a route's
231
+ * code still loading or a page fetching the data it will display.
232
+ */
233
+ hold(): () => void;
234
+ /** Called whenever the snapshot changes. */
235
+ subscribe(listener: () => void): () => void;
236
+ /** Stop polling, detach from the socket and forget every mount. */
237
+ dispose(): void;
238
+ }
239
+ declare function createSurfaceRuntime(options?: SurfaceRuntimeOptions): SurfaceRuntime;
240
+
241
+ export { type ActionDefinition as A, type DefinedSurface as D, type MountedSurface as M, type OUIBranded as O, type SettleOptions as S, type ActionHandlerResult as a, type ActionPollingConfig as b, type ObservationDefinition as c, type SurfaceDefinition as d, type SurfaceRuntime as e, type SurfaceRuntimeOptions as f, createSurfaceRuntime as g, defineSurface as h };
@@ -1,16 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var chunkWZXUKJ7E_cjs = require('../chunk-WZXUKJ7E.cjs');
3
+ var chunkROGKEMLL_cjs = require('../chunk-ROGKEMLL.cjs');
4
+ var chunkDCVVTP3V_cjs = require('../chunk-DCVVTP3V.cjs');
4
5
 
5
6
 
6
7
 
7
8
  Object.defineProperty(exports, "createDirectTransportPair", {
8
9
  enumerable: true,
9
- get: function () { return chunkWZXUKJ7E_cjs.createDirectTransportPair; }
10
+ get: function () { return chunkROGKEMLL_cjs.createDirectTransportPair; }
10
11
  });
11
12
  Object.defineProperty(exports, "createWebSocketTransport", {
12
13
  enumerable: true,
13
- get: function () { return chunkWZXUKJ7E_cjs.createWebSocketTransport; }
14
+ get: function () { return chunkDCVVTP3V_cjs.createWebSocketTransport; }
14
15
  });
15
16
  //# sourceMappingURL=index.cjs.map
16
17
  //# sourceMappingURL=index.cjs.map
@@ -1,79 +1,6 @@
1
- import { OUIObservationUpdate, OUISurface } from '../spec/index.cjs';
2
-
3
- /**
4
- * OUI Transport — the wire protocol between agent runtime and surfaces.
5
- *
6
- * Two one-way channels:
7
- * - Dispatch channel (server → client): sends action instructions
8
- * - Observation channel (client → server): pushes state updates
9
- *
10
- * NO request/response. NO correlation IDs. NO waiting.
11
- * The Lambda dispatches and terminates. The browser processes and pushes state.
12
- */
13
- interface OUITransport {
14
- /** Dispatch an action to a surface (one-way, fire-and-forget) */
15
- dispatch(surfaceId: string, actionId: string, params: Record<string, unknown>): void;
16
- /** Receive dispatched actions (surface/client side) */
17
- onAction(handler: OUIActionHandler): () => void;
18
- /** Push an observation update from the surface to the agent runtime */
19
- pushObservation(update: OUIObservationUpdate): void;
20
- /** Receive observation updates (runtime/server side) */
21
- onObservation(handler: OUIObservationHandler): () => void;
22
- /** Register a surface manifest (client → server) */
23
- registerSurface(surface: OUISurface): void;
24
- /** Deregister a surface (client → server) */
25
- deregisterSurface(surfaceId: string): void;
26
- /** Receive surface registrations (server side) */
27
- onSurfaceRegister(handler: (surface: OUISurface) => void): () => void;
28
- /** Receive surface deregistrations (server side) */
29
- onSurfaceDeregister(handler: (surfaceId: string) => void): () => void;
30
- readonly connected: boolean;
31
- connect(): Promise<void>;
32
- disconnect(): void;
33
- onConnectionChange(handler: (connected: boolean) => void): () => void;
34
- }
35
- /** Handler for incoming action dispatches (client side) */
36
- type OUIActionHandler = (surfaceId: string, actionId: string, params: Record<string, unknown>) => void;
37
- /** Handler for incoming observation updates (server side) */
38
- type OUIObservationHandler = (update: OUIObservationUpdate) => void;
39
- /**
40
- * Transport configuration options.
41
- */
42
- interface OUITransportConfig {
43
- /** Namespace prefix for events (default: 'oui') */
44
- namespace?: string;
45
- /** Connection timeout in ms */
46
- connectTimeoutMs?: number;
47
- /** Whether to buffer dispatches while disconnected */
48
- bufferWhileDisconnected?: boolean;
49
- /** Max buffer size (messages dropped after this) */
50
- maxBufferSize?: number;
51
- }
52
-
53
- /**
54
- * WebSocket transport using Socket.IO.
55
- * Maps OUI protocol events to socket events with a configurable namespace prefix.
56
- *
57
- * Events emitted:
58
- * {ns}:dispatch — action dispatch (server → client)
59
- * {ns}:observation — observation update (client → server)
60
- * {ns}:surface:register — surface registration (client → server)
61
- * {ns}:surface:deregister — surface deregistration (client → server)
62
- */
63
- declare function createWebSocketTransport(socket: SocketLike, config?: OUITransportConfig): OUITransport;
64
- /**
65
- * Minimal socket interface — compatible with Socket.IO client or server socket.
66
- * Only the methods OUI actually uses.
67
- */
68
- interface SocketLike {
69
- readonly connected?: boolean;
70
- emit(event: string, data: unknown): void;
71
- on(event: string, handler: (...args: any[]) => void): void;
72
- off(event: string, handler: (...args: any[]) => void): void;
73
- once(event: string, handler: (...args: any[]) => void): void;
74
- connect?(): void;
75
- disconnect?(): void;
76
- }
1
+ import { c as OUITransport } from '../websocket-YfWILdZ4.cjs';
2
+ export { O as OUIActionHandler, a as OUIObservationHandler, b as OUIResultHandler, d as OUITransportConfig, S as SocketLike, e as createWebSocketTransport } from '../websocket-YfWILdZ4.cjs';
3
+ import '../spec/index.cjs';
77
4
 
78
5
  /**
79
6
  * Direct transport — for same-process communication.
@@ -88,4 +15,4 @@ declare function createDirectTransportPair(): {
88
15
  client: OUITransport;
89
16
  };
90
17
 
91
- export { type OUIActionHandler, type OUIObservationHandler, type OUITransport, type OUITransportConfig, type SocketLike, createDirectTransportPair, createWebSocketTransport };
18
+ export { OUITransport, createDirectTransportPair };
@@ -1,79 +1,6 @@
1
- import { OUIObservationUpdate, OUISurface } from '../spec/index.js';
2
-
3
- /**
4
- * OUI Transport — the wire protocol between agent runtime and surfaces.
5
- *
6
- * Two one-way channels:
7
- * - Dispatch channel (server → client): sends action instructions
8
- * - Observation channel (client → server): pushes state updates
9
- *
10
- * NO request/response. NO correlation IDs. NO waiting.
11
- * The Lambda dispatches and terminates. The browser processes and pushes state.
12
- */
13
- interface OUITransport {
14
- /** Dispatch an action to a surface (one-way, fire-and-forget) */
15
- dispatch(surfaceId: string, actionId: string, params: Record<string, unknown>): void;
16
- /** Receive dispatched actions (surface/client side) */
17
- onAction(handler: OUIActionHandler): () => void;
18
- /** Push an observation update from the surface to the agent runtime */
19
- pushObservation(update: OUIObservationUpdate): void;
20
- /** Receive observation updates (runtime/server side) */
21
- onObservation(handler: OUIObservationHandler): () => void;
22
- /** Register a surface manifest (client → server) */
23
- registerSurface(surface: OUISurface): void;
24
- /** Deregister a surface (client → server) */
25
- deregisterSurface(surfaceId: string): void;
26
- /** Receive surface registrations (server side) */
27
- onSurfaceRegister(handler: (surface: OUISurface) => void): () => void;
28
- /** Receive surface deregistrations (server side) */
29
- onSurfaceDeregister(handler: (surfaceId: string) => void): () => void;
30
- readonly connected: boolean;
31
- connect(): Promise<void>;
32
- disconnect(): void;
33
- onConnectionChange(handler: (connected: boolean) => void): () => void;
34
- }
35
- /** Handler for incoming action dispatches (client side) */
36
- type OUIActionHandler = (surfaceId: string, actionId: string, params: Record<string, unknown>) => void;
37
- /** Handler for incoming observation updates (server side) */
38
- type OUIObservationHandler = (update: OUIObservationUpdate) => void;
39
- /**
40
- * Transport configuration options.
41
- */
42
- interface OUITransportConfig {
43
- /** Namespace prefix for events (default: 'oui') */
44
- namespace?: string;
45
- /** Connection timeout in ms */
46
- connectTimeoutMs?: number;
47
- /** Whether to buffer dispatches while disconnected */
48
- bufferWhileDisconnected?: boolean;
49
- /** Max buffer size (messages dropped after this) */
50
- maxBufferSize?: number;
51
- }
52
-
53
- /**
54
- * WebSocket transport using Socket.IO.
55
- * Maps OUI protocol events to socket events with a configurable namespace prefix.
56
- *
57
- * Events emitted:
58
- * {ns}:dispatch — action dispatch (server → client)
59
- * {ns}:observation — observation update (client → server)
60
- * {ns}:surface:register — surface registration (client → server)
61
- * {ns}:surface:deregister — surface deregistration (client → server)
62
- */
63
- declare function createWebSocketTransport(socket: SocketLike, config?: OUITransportConfig): OUITransport;
64
- /**
65
- * Minimal socket interface — compatible with Socket.IO client or server socket.
66
- * Only the methods OUI actually uses.
67
- */
68
- interface SocketLike {
69
- readonly connected?: boolean;
70
- emit(event: string, data: unknown): void;
71
- on(event: string, handler: (...args: any[]) => void): void;
72
- off(event: string, handler: (...args: any[]) => void): void;
73
- once(event: string, handler: (...args: any[]) => void): void;
74
- connect?(): void;
75
- disconnect?(): void;
76
- }
1
+ import { c as OUITransport } from '../websocket-c5tIUWY5.js';
2
+ export { O as OUIActionHandler, a as OUIObservationHandler, b as OUIResultHandler, d as OUITransportConfig, S as SocketLike, e as createWebSocketTransport } from '../websocket-c5tIUWY5.js';
3
+ import '../spec/index.js';
77
4
 
78
5
  /**
79
6
  * Direct transport — for same-process communication.
@@ -88,4 +15,4 @@ declare function createDirectTransportPair(): {
88
15
  client: OUITransport;
89
16
  };
90
17
 
91
- export { type OUIActionHandler, type OUIObservationHandler, type OUITransport, type OUITransportConfig, type SocketLike, createDirectTransportPair, createWebSocketTransport };
18
+ export { OUITransport, createDirectTransportPair };
@@ -1,3 +1,4 @@
1
- export { createDirectTransportPair, createWebSocketTransport } from '../chunk-7EXSMPGR.js';
1
+ export { createDirectTransportPair } from '../chunk-IIZ6HL2L.js';
2
+ export { createWebSocketTransport } from '../chunk-F3WKIRAU.js';
2
3
  //# sourceMappingURL=index.js.map
3
4
  //# sourceMappingURL=index.js.map