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,96 @@
1
+ import { OUIActionRequest, OUIActionResult, OUIObservationUpdate, OUISurface } from './spec/index.cjs';
2
+
3
+ /**
4
+ * OUI Transport — the wire protocol between agent runtime and surfaces.
5
+ *
6
+ * - Dispatch (runtime → client): an `OUIActionRequest`, carrying a `requestId`.
7
+ * - Result (client → runtime): the `OUIActionResult` for that `requestId`.
8
+ * - Observations (client → runtime): state updates pushed as they happen.
9
+ * - Surface lifecycle (client → runtime): registration, for runtimes that keep
10
+ * a server-side registry. A runtime can instead take the client's snapshot.
11
+ *
12
+ * Every dispatch is answered by exactly one result. An earlier version of this
13
+ * transport had no correlation id and no result channel, so an agent could
14
+ * never learn whether its action ran, and was told it succeeded before the
15
+ * client had done anything.
16
+ */
17
+ interface OUITransport {
18
+ /** Send an action request to the client. */
19
+ dispatch(request: OUIActionRequest): void;
20
+ /** Receive action requests (client side). */
21
+ onAction(handler: OUIActionHandler): () => void;
22
+ /** Answer an action request (client side). */
23
+ sendResult(result: OUIActionResult): void;
24
+ /** Receive action results (runtime side). */
25
+ onResult(handler: OUIResultHandler): () => void;
26
+ /** Push an observation update from the surface to the agent runtime */
27
+ pushObservation(update: OUIObservationUpdate): void;
28
+ /** Receive observation updates (runtime/server side) */
29
+ onObservation(handler: OUIObservationHandler): () => void;
30
+ /** Register a surface manifest (client → server) */
31
+ registerSurface(surface: OUISurface): void;
32
+ /** Deregister a surface (client → server) */
33
+ deregisterSurface(surfaceId: string): void;
34
+ /** Receive surface registrations (server side) */
35
+ onSurfaceRegister(handler: (surface: OUISurface) => void): () => void;
36
+ /** Receive surface deregistrations (server side) */
37
+ onSurfaceDeregister(handler: (surfaceId: string) => void): () => void;
38
+ readonly connected: boolean;
39
+ connect(): Promise<void>;
40
+ /** Disconnect the underlying socket. The integrator owns the socket: prefer `dispose`. */
41
+ disconnect(): void;
42
+ onConnectionChange(handler: (connected: boolean) => void): () => void;
43
+ /**
44
+ * Detach every listener this transport attached to its socket, and leave the
45
+ * socket connected. A socket outlives the transports built on it; without
46
+ * this, each one leaked its connection listeners onto the shared socket.
47
+ */
48
+ dispose(): void;
49
+ }
50
+ /** Handler for incoming action requests (client side) */
51
+ type OUIActionHandler = (request: OUIActionRequest) => void;
52
+ /** Handler for incoming action results (runtime side) */
53
+ type OUIResultHandler = (result: OUIActionResult) => void;
54
+ /** Handler for incoming observation updates (server side) */
55
+ type OUIObservationHandler = (update: OUIObservationUpdate) => void;
56
+ /**
57
+ * Transport configuration options.
58
+ */
59
+ interface OUITransportConfig {
60
+ /** Namespace prefix for events (default: 'oui') */
61
+ namespace?: string;
62
+ /** Connection timeout in ms */
63
+ connectTimeoutMs?: number;
64
+ /** Whether to buffer outbound messages while disconnected */
65
+ bufferWhileDisconnected?: boolean;
66
+ /** Max buffer size (messages dropped after this) */
67
+ maxBufferSize?: number;
68
+ }
69
+
70
+ /**
71
+ * WebSocket transport using Socket.IO.
72
+ * Maps OUI protocol events to socket events with a configurable namespace prefix.
73
+ *
74
+ * Events:
75
+ * {ns}:dispatch — action request (runtime → client)
76
+ * {ns}:action:result — action result (client → runtime)
77
+ * {ns}:observation — observation (client → runtime)
78
+ * {ns}:surface:register — registration (client → runtime)
79
+ * {ns}:surface:deregister — deregistration (client → runtime)
80
+ */
81
+ declare function createWebSocketTransport(socket: SocketLike, config?: OUITransportConfig): OUITransport;
82
+ /**
83
+ * Minimal socket interface — compatible with Socket.IO client or server socket.
84
+ * Only the methods OUI actually uses.
85
+ */
86
+ interface SocketLike {
87
+ readonly connected?: boolean;
88
+ emit(event: string, data: unknown): void;
89
+ on(event: string, handler: (...args: any[]) => void): void;
90
+ off(event: string, handler: (...args: any[]) => void): void;
91
+ once(event: string, handler: (...args: any[]) => void): void;
92
+ connect?(): void;
93
+ disconnect?(): void;
94
+ }
95
+
96
+ export { type OUIActionHandler as O, type SocketLike as S, type OUIObservationHandler as a, type OUIResultHandler as b, type OUITransport as c, type OUITransportConfig as d, createWebSocketTransport as e };
@@ -0,0 +1,96 @@
1
+ import { OUIActionRequest, OUIActionResult, OUIObservationUpdate, OUISurface } from './spec/index.js';
2
+
3
+ /**
4
+ * OUI Transport — the wire protocol between agent runtime and surfaces.
5
+ *
6
+ * - Dispatch (runtime → client): an `OUIActionRequest`, carrying a `requestId`.
7
+ * - Result (client → runtime): the `OUIActionResult` for that `requestId`.
8
+ * - Observations (client → runtime): state updates pushed as they happen.
9
+ * - Surface lifecycle (client → runtime): registration, for runtimes that keep
10
+ * a server-side registry. A runtime can instead take the client's snapshot.
11
+ *
12
+ * Every dispatch is answered by exactly one result. An earlier version of this
13
+ * transport had no correlation id and no result channel, so an agent could
14
+ * never learn whether its action ran, and was told it succeeded before the
15
+ * client had done anything.
16
+ */
17
+ interface OUITransport {
18
+ /** Send an action request to the client. */
19
+ dispatch(request: OUIActionRequest): void;
20
+ /** Receive action requests (client side). */
21
+ onAction(handler: OUIActionHandler): () => void;
22
+ /** Answer an action request (client side). */
23
+ sendResult(result: OUIActionResult): void;
24
+ /** Receive action results (runtime side). */
25
+ onResult(handler: OUIResultHandler): () => void;
26
+ /** Push an observation update from the surface to the agent runtime */
27
+ pushObservation(update: OUIObservationUpdate): void;
28
+ /** Receive observation updates (runtime/server side) */
29
+ onObservation(handler: OUIObservationHandler): () => void;
30
+ /** Register a surface manifest (client → server) */
31
+ registerSurface(surface: OUISurface): void;
32
+ /** Deregister a surface (client → server) */
33
+ deregisterSurface(surfaceId: string): void;
34
+ /** Receive surface registrations (server side) */
35
+ onSurfaceRegister(handler: (surface: OUISurface) => void): () => void;
36
+ /** Receive surface deregistrations (server side) */
37
+ onSurfaceDeregister(handler: (surfaceId: string) => void): () => void;
38
+ readonly connected: boolean;
39
+ connect(): Promise<void>;
40
+ /** Disconnect the underlying socket. The integrator owns the socket: prefer `dispose`. */
41
+ disconnect(): void;
42
+ onConnectionChange(handler: (connected: boolean) => void): () => void;
43
+ /**
44
+ * Detach every listener this transport attached to its socket, and leave the
45
+ * socket connected. A socket outlives the transports built on it; without
46
+ * this, each one leaked its connection listeners onto the shared socket.
47
+ */
48
+ dispose(): void;
49
+ }
50
+ /** Handler for incoming action requests (client side) */
51
+ type OUIActionHandler = (request: OUIActionRequest) => void;
52
+ /** Handler for incoming action results (runtime side) */
53
+ type OUIResultHandler = (result: OUIActionResult) => void;
54
+ /** Handler for incoming observation updates (server side) */
55
+ type OUIObservationHandler = (update: OUIObservationUpdate) => void;
56
+ /**
57
+ * Transport configuration options.
58
+ */
59
+ interface OUITransportConfig {
60
+ /** Namespace prefix for events (default: 'oui') */
61
+ namespace?: string;
62
+ /** Connection timeout in ms */
63
+ connectTimeoutMs?: number;
64
+ /** Whether to buffer outbound messages while disconnected */
65
+ bufferWhileDisconnected?: boolean;
66
+ /** Max buffer size (messages dropped after this) */
67
+ maxBufferSize?: number;
68
+ }
69
+
70
+ /**
71
+ * WebSocket transport using Socket.IO.
72
+ * Maps OUI protocol events to socket events with a configurable namespace prefix.
73
+ *
74
+ * Events:
75
+ * {ns}:dispatch — action request (runtime → client)
76
+ * {ns}:action:result — action result (client → runtime)
77
+ * {ns}:observation — observation (client → runtime)
78
+ * {ns}:surface:register — registration (client → runtime)
79
+ * {ns}:surface:deregister — deregistration (client → runtime)
80
+ */
81
+ declare function createWebSocketTransport(socket: SocketLike, config?: OUITransportConfig): OUITransport;
82
+ /**
83
+ * Minimal socket interface — compatible with Socket.IO client or server socket.
84
+ * Only the methods OUI actually uses.
85
+ */
86
+ interface SocketLike {
87
+ readonly connected?: boolean;
88
+ emit(event: string, data: unknown): void;
89
+ on(event: string, handler: (...args: any[]) => void): void;
90
+ off(event: string, handler: (...args: any[]) => void): void;
91
+ once(event: string, handler: (...args: any[]) => void): void;
92
+ connect?(): void;
93
+ disconnect?(): void;
94
+ }
95
+
96
+ export { type OUIActionHandler as O, type SocketLike as S, type OUIObservationHandler as a, type OUIResultHandler as b, type OUITransport as c, type OUITransportConfig as d, createWebSocketTransport as e };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oui-spec",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
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",
@@ -69,12 +69,13 @@
69
69
  ],
70
70
  "scripts": {
71
71
  "build": "tsup",
72
- "typecheck": "tsc --noEmit",
72
+ "typecheck": "tsc --noEmit && npm run typecheck:contract",
73
73
  "lint": "eslint src",
74
74
  "test": "vitest run",
75
75
  "test:watch": "vitest",
76
76
  "prepare": "husky",
77
- "prepublishOnly": "npm run build"
77
+ "prepublishOnly": "npm run build",
78
+ "typecheck:contract": "tsc --noEmit --strict --target ES2022 --module ESNext --moduleResolution bundler __tests__/create-oui.compile.test-d.ts"
78
79
  },
79
80
  "peerDependencies": {
80
81
  "react": ">=18.0.0"
@@ -85,14 +86,18 @@
85
86
  }
86
87
  },
87
88
  "devDependencies": {
89
+ "@testing-library/react": "^16.3.3",
88
90
  "@types/react": "^19.0.0",
91
+ "@types/react-dom": "^19.3.0",
89
92
  "@typescript-eslint/eslint-plugin": "^8.0.0",
90
93
  "@typescript-eslint/parser": "^8.0.0",
91
94
  "eslint": "^9.0.0",
92
95
  "husky": "^9.1.7",
96
+ "jsdom": "^26.1.0",
93
97
  "lint-staged": "^16.4.0",
94
98
  "prettier": "^3.9.6",
95
99
  "react": "^19.0.0",
100
+ "react-dom": "^19.3.0",
96
101
  "tsup": "^8.4.0",
97
102
  "typescript": "^5.8.0",
98
103
  "vitest": "^3.0.0"