@ggui-ai/protocol 0.1.0-rc.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.
Files changed (222) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +46 -0
  3. package/dist/bridge/invoke-agent.d.ts +65 -0
  4. package/dist/bridge/invoke-agent.d.ts.map +1 -0
  5. package/dist/bridge/invoke-agent.js +113 -0
  6. package/dist/envelope-adapters.d.ts +24 -0
  7. package/dist/envelope-adapters.d.ts.map +1 -0
  8. package/dist/envelope-adapters.js +14 -0
  9. package/dist/envelopes/builders.d.ts +145 -0
  10. package/dist/envelopes/builders.d.ts.map +1 -0
  11. package/dist/envelopes/builders.js +113 -0
  12. package/dist/errors/unknown-permission-name.d.ts +12 -0
  13. package/dist/errors/unknown-permission-name.d.ts.map +1 -0
  14. package/dist/errors/unknown-permission-name.js +29 -0
  15. package/dist/errors/version-mismatch.d.ts +55 -0
  16. package/dist/errors/version-mismatch.d.ts.map +1 -0
  17. package/dist/errors/version-mismatch.js +52 -0
  18. package/dist/gadgets/resolve-contract-gadgets.d.ts +93 -0
  19. package/dist/gadgets/resolve-contract-gadgets.d.ts.map +1 -0
  20. package/dist/gadgets/resolve-contract-gadgets.js +119 -0
  21. package/dist/gadgets/stdlib-gadgets.d.ts +43 -0
  22. package/dist/gadgets/stdlib-gadgets.d.ts.map +1 -0
  23. package/dist/gadgets/stdlib-gadgets.js +161 -0
  24. package/dist/iframe-bridge.d.ts +63 -0
  25. package/dist/iframe-bridge.d.ts.map +1 -0
  26. package/dist/iframe-bridge.js +166 -0
  27. package/dist/index.d.ts +62 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +79 -0
  30. package/dist/integrations/mcp-apps.d.ts +1218 -0
  31. package/dist/integrations/mcp-apps.d.ts.map +1 -0
  32. package/dist/integrations/mcp-apps.js +427 -0
  33. package/dist/navigation/index.d.ts +3 -0
  34. package/dist/navigation/index.d.ts.map +1 -0
  35. package/dist/navigation/index.js +1 -0
  36. package/dist/navigation/stack-navigation.d.ts +55 -0
  37. package/dist/navigation/stack-navigation.d.ts.map +1 -0
  38. package/dist/navigation/stack-navigation.js +80 -0
  39. package/dist/recommended-prompts.d.ts +56 -0
  40. package/dist/recommended-prompts.d.ts.map +1 -0
  41. package/dist/recommended-prompts.js +55 -0
  42. package/dist/registry/blueprint-key.d.ts +9 -0
  43. package/dist/registry/blueprint-key.d.ts.map +1 -0
  44. package/dist/registry/blueprint-key.js +28 -0
  45. package/dist/registry/canonicalize-contract.d.ts +35 -0
  46. package/dist/registry/canonicalize-contract.d.ts.map +1 -0
  47. package/dist/registry/canonicalize-contract.js +166 -0
  48. package/dist/registry/summarize-contract.d.ts +46 -0
  49. package/dist/registry/summarize-contract.d.ts.map +1 -0
  50. package/dist/registry/summarize-contract.js +63 -0
  51. package/dist/schema-learning/derive-contract.d.ts +67 -0
  52. package/dist/schema-learning/derive-contract.d.ts.map +1 -0
  53. package/dist/schema-learning/derive-contract.js +117 -0
  54. package/dist/schema-learning/merge.d.ts +32 -0
  55. package/dist/schema-learning/merge.d.ts.map +1 -0
  56. package/dist/schema-learning/merge.js +146 -0
  57. package/dist/schemas/blueprint.d.ts +32 -0
  58. package/dist/schemas/blueprint.d.ts.map +1 -0
  59. package/dist/schemas/blueprint.js +92 -0
  60. package/dist/schemas/data-contract.d.ts +750 -0
  61. package/dist/schemas/data-contract.d.ts.map +1 -0
  62. package/dist/schemas/data-contract.js +663 -0
  63. package/dist/schemas/gadget-name-grammar.d.ts +29 -0
  64. package/dist/schemas/gadget-name-grammar.d.ts.map +1 -0
  65. package/dist/schemas/gadget-name-grammar.js +28 -0
  66. package/dist/schemas/handshake-suggestion.d.ts +46 -0
  67. package/dist/schemas/handshake-suggestion.d.ts.map +1 -0
  68. package/dist/schemas/handshake-suggestion.js +107 -0
  69. package/dist/schemas/invoke.d.ts +337 -0
  70. package/dist/schemas/invoke.d.ts.map +1 -0
  71. package/dist/schemas/invoke.js +169 -0
  72. package/dist/schemas/mcp.d.ts +301 -0
  73. package/dist/schemas/mcp.d.ts.map +1 -0
  74. package/dist/schemas/mcp.js +373 -0
  75. package/dist/schemas/ops-blueprint.d.ts +176 -0
  76. package/dist/schemas/ops-blueprint.d.ts.map +1 -0
  77. package/dist/schemas/ops-blueprint.js +259 -0
  78. package/dist/schemas/sync-check.d.ts +11 -0
  79. package/dist/schemas/sync-check.d.ts.map +1 -0
  80. package/dist/schemas/sync-check.js +60 -0
  81. package/dist/screen-blueprints/define.d.ts +22 -0
  82. package/dist/screen-blueprints/define.d.ts.map +1 -0
  83. package/dist/screen-blueprints/define.js +3 -0
  84. package/dist/screen-blueprints/index.d.ts +4 -0
  85. package/dist/screen-blueprints/index.d.ts.map +1 -0
  86. package/dist/screen-blueprints/index.js +3 -0
  87. package/dist/screen-blueprints/match.d.ts +35 -0
  88. package/dist/screen-blueprints/match.d.ts.map +1 -0
  89. package/dist/screen-blueprints/match.js +51 -0
  90. package/dist/screen-blueprints/types.d.ts +164 -0
  91. package/dist/screen-blueprints/types.d.ts.map +1 -0
  92. package/dist/screen-blueprints/types.js +1 -0
  93. package/dist/stream/stream-parser.d.ts +62 -0
  94. package/dist/stream/stream-parser.d.ts.map +1 -0
  95. package/dist/stream/stream-parser.js +199 -0
  96. package/dist/transport/websocket.d.ts +178 -0
  97. package/dist/transport/websocket.d.ts.map +1 -0
  98. package/dist/transport/websocket.js +1 -0
  99. package/dist/types/app-config.d.ts +61 -0
  100. package/dist/types/app-config.d.ts.map +1 -0
  101. package/dist/types/app-config.js +1 -0
  102. package/dist/types/auth.d.ts +61 -0
  103. package/dist/types/auth.d.ts.map +1 -0
  104. package/dist/types/auth.js +1 -0
  105. package/dist/types/blueprint.d.ts +206 -0
  106. package/dist/types/blueprint.d.ts.map +1 -0
  107. package/dist/types/blueprint.js +1 -0
  108. package/dist/types/canvas-lifecycle.d.ts +105 -0
  109. package/dist/types/canvas-lifecycle.d.ts.map +1 -0
  110. package/dist/types/canvas-lifecycle.js +38 -0
  111. package/dist/types/capabilities.d.ts +40 -0
  112. package/dist/types/capabilities.d.ts.map +1 -0
  113. package/dist/types/capabilities.js +19 -0
  114. package/dist/types/contract-inference.d.ts +401 -0
  115. package/dist/types/contract-inference.d.ts.map +1 -0
  116. package/dist/types/contract-inference.js +44 -0
  117. package/dist/types/credential.d.ts +41 -0
  118. package/dist/types/credential.d.ts.map +1 -0
  119. package/dist/types/credential.js +32 -0
  120. package/dist/types/data-bindings.d.ts +322 -0
  121. package/dist/types/data-bindings.d.ts.map +1 -0
  122. package/dist/types/data-bindings.js +29 -0
  123. package/dist/types/data-contract.d.ts +1296 -0
  124. package/dist/types/data-contract.d.ts.map +1 -0
  125. package/dist/types/data-contract.js +111 -0
  126. package/dist/types/events.d.ts +182 -0
  127. package/dist/types/events.d.ts.map +1 -0
  128. package/dist/types/events.js +8 -0
  129. package/dist/types/feedback.d.ts +24 -0
  130. package/dist/types/feedback.d.ts.map +1 -0
  131. package/dist/types/feedback.js +7 -0
  132. package/dist/types/gadget.d.ts +121 -0
  133. package/dist/types/gadget.d.ts.map +1 -0
  134. package/dist/types/gadget.js +24 -0
  135. package/dist/types/handshake-suggestion.d.ts +264 -0
  136. package/dist/types/handshake-suggestion.d.ts.map +1 -0
  137. package/dist/types/handshake-suggestion.js +70 -0
  138. package/dist/types/host-context.d.ts +163 -0
  139. package/dist/types/host-context.d.ts.map +1 -0
  140. package/dist/types/host-context.js +142 -0
  141. package/dist/types/interface-context.d.ts +105 -0
  142. package/dist/types/interface-context.d.ts.map +1 -0
  143. package/dist/types/interface-context.js +115 -0
  144. package/dist/types/invoke.d.ts +28 -0
  145. package/dist/types/invoke.d.ts.map +1 -0
  146. package/dist/types/invoke.js +7 -0
  147. package/dist/types/live-channel.d.ts +613 -0
  148. package/dist/types/live-channel.d.ts.map +1 -0
  149. package/dist/types/live-channel.js +1 -0
  150. package/dist/types/llm.d.ts +61 -0
  151. package/dist/types/llm.d.ts.map +1 -0
  152. package/dist/types/llm.js +186 -0
  153. package/dist/types/mcp-proxy.d.ts +67 -0
  154. package/dist/types/mcp-proxy.d.ts.map +1 -0
  155. package/dist/types/mcp-proxy.js +46 -0
  156. package/dist/types/mcp.d.ts +637 -0
  157. package/dist/types/mcp.d.ts.map +1 -0
  158. package/dist/types/mcp.js +30 -0
  159. package/dist/types/openrouter-models.d.ts +22 -0
  160. package/dist/types/openrouter-models.d.ts.map +1 -0
  161. package/dist/types/openrouter-models.js +4843 -0
  162. package/dist/types/region.d.ts +26 -0
  163. package/dist/types/region.d.ts.map +1 -0
  164. package/dist/types/region.js +36 -0
  165. package/dist/types/session.d.ts +419 -0
  166. package/dist/types/session.d.ts.map +1 -0
  167. package/dist/types/session.js +1 -0
  168. package/dist/types/thread.d.ts +207 -0
  169. package/dist/types/thread.d.ts.map +1 -0
  170. package/dist/types/thread.js +57 -0
  171. package/dist/types/ui-generator.d.ts +100 -0
  172. package/dist/types/ui-generator.d.ts.map +1 -0
  173. package/dist/types/ui-generator.js +53 -0
  174. package/dist/validation/ajv-runtime.d.ts +140 -0
  175. package/dist/validation/ajv-runtime.d.ts.map +1 -0
  176. package/dist/validation/ajv-runtime.js +452 -0
  177. package/dist/validation/content-hash.d.ts +3 -0
  178. package/dist/validation/content-hash.d.ts.map +1 -0
  179. package/dist/validation/content-hash.js +21 -0
  180. package/dist/validation/contract-validator.d.ts +244 -0
  181. package/dist/validation/contract-validator.d.ts.map +1 -0
  182. package/dist/validation/contract-validator.js +711 -0
  183. package/dist/validation/cross-references.d.ts +105 -0
  184. package/dist/validation/cross-references.d.ts.map +1 -0
  185. package/dist/validation/cross-references.js +164 -0
  186. package/dist/validation/hygiene-rules.d.ts +250 -0
  187. package/dist/validation/hygiene-rules.d.ts.map +1 -0
  188. package/dist/validation/hygiene-rules.js +564 -0
  189. package/dist/validation/lint-contract.d.ts +130 -0
  190. package/dist/validation/lint-contract.d.ts.map +1 -0
  191. package/dist/validation/lint-contract.js +225 -0
  192. package/dist/validation/name-invariants.d.ts +117 -0
  193. package/dist/validation/name-invariants.d.ts.map +1 -0
  194. package/dist/validation/name-invariants.js +172 -0
  195. package/dist/validation/reserved-channels.d.ts +156 -0
  196. package/dist/validation/reserved-channels.d.ts.map +1 -0
  197. package/dist/validation/reserved-channels.js +356 -0
  198. package/dist/validation/resolve-stream-channel.d.ts +78 -0
  199. package/dist/validation/resolve-stream-channel.d.ts.map +1 -0
  200. package/dist/validation/resolve-stream-channel.js +64 -0
  201. package/dist/validation/sanitize-error.d.ts +46 -0
  202. package/dist/validation/sanitize-error.d.ts.map +1 -0
  203. package/dist/validation/sanitize-error.js +88 -0
  204. package/dist/validation/schema-compat-invariants.d.ts +140 -0
  205. package/dist/validation/schema-compat-invariants.d.ts.map +1 -0
  206. package/dist/validation/schema-compat-invariants.js +220 -0
  207. package/dist/validation/schema-meta-validation.d.ts +60 -0
  208. package/dist/validation/schema-meta-validation.d.ts.map +1 -0
  209. package/dist/validation/schema-meta-validation.js +131 -0
  210. package/dist/validation/schema-subset.d.ts +165 -0
  211. package/dist/validation/schema-subset.d.ts.map +1 -0
  212. package/dist/validation/schema-subset.js +295 -0
  213. package/dist/validation/ui-security.d.ts +54 -0
  214. package/dist/validation/ui-security.d.ts.map +1 -0
  215. package/dist/validation/ui-security.js +138 -0
  216. package/dist/validation/zod-to-json-schema.d.ts +63 -0
  217. package/dist/validation/zod-to-json-schema.d.ts.map +1 -0
  218. package/dist/validation/zod-to-json-schema.js +126 -0
  219. package/dist/version.d.ts +1458 -0
  220. package/dist/version.d.ts.map +1 -0
  221. package/dist/version.js +1459 -0
  222. package/package.json +113 -0
@@ -0,0 +1,113 @@
1
+ import { PROTOCOL_SCHEMA_VERSION } from '../version.js';
2
+ /**
3
+ * Resolve the stamp decision for the three semantic paths. Returns
4
+ * `undefined` when the field should be omitted entirely; returns a
5
+ * string when it should be stamped.
6
+ */
7
+ function resolveSchemaVersion(parts) {
8
+ if ('schemaVersion' in parts) {
9
+ // Caller wrote the key — trust their decision (string OR explicit
10
+ // undefined-to-omit).
11
+ return parts.schemaVersion;
12
+ }
13
+ // Key absent — default stamp.
14
+ return PROTOCOL_SCHEMA_VERSION;
15
+ }
16
+ /**
17
+ * Build an {@link ActionEnvelope} with `schemaVersion` stamped to
18
+ * {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
19
+ *
20
+ * Filters `undefined` optional fields so the serialized wire message
21
+ * omits them (matches the producer convention that "absent field =
22
+ * default").
23
+ */
24
+ export function makeActionEnvelope(parts) {
25
+ const envelope = {
26
+ sessionId: parts.sessionId,
27
+ type: parts.type,
28
+ };
29
+ if (parts.payload !== undefined)
30
+ envelope.payload = parts.payload;
31
+ if (parts.stackIndex !== undefined)
32
+ envelope.stackIndex = parts.stackIndex;
33
+ if (parts.stackItemId !== undefined)
34
+ envelope.stackItemId = parts.stackItemId;
35
+ if (parts.clientSeq !== undefined)
36
+ envelope.clientSeq = parts.clientSeq;
37
+ const stamp = resolveSchemaVersion(parts);
38
+ if (stamp !== undefined)
39
+ envelope.schemaVersion = stamp;
40
+ return envelope;
41
+ }
42
+ /**
43
+ * Build a {@link StreamEnvelope} with `schemaVersion` stamped to
44
+ * {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
45
+ *
46
+ * Filters `undefined` optional fields (`complete`, `seq`) so the
47
+ * serialized wire message omits them. `seq` is server-assigned in
48
+ * practice — callers pass the value the buffer hands them.
49
+ */
50
+ export function makeStreamEnvelope(parts) {
51
+ const envelope = {
52
+ sessionId: parts.sessionId,
53
+ channel: parts.channel,
54
+ mode: parts.mode,
55
+ payload: parts.payload,
56
+ };
57
+ if (parts.complete !== undefined)
58
+ envelope.complete = parts.complete;
59
+ if (parts.seq !== undefined)
60
+ envelope.seq = parts.seq;
61
+ const stamp = resolveSchemaVersion(parts);
62
+ if (stamp !== undefined)
63
+ envelope.schemaVersion = stamp;
64
+ return envelope;
65
+ }
66
+ /**
67
+ * Build an {@link ErrorPayload} for the `{type: 'error'}` wire frame.
68
+ *
69
+ * Does NOT stamp `schemaVersion` — `ErrorPayload` is the wire-level
70
+ * error envelope (free-form `code: string`), not an envelope that
71
+ * opts into the forward-compat stamp (see {@link ActionEnvelope} /
72
+ * {@link StreamEnvelope} / {@link ContractErrorPayload}). Keeping
73
+ * `ErrorPayload` stamp-free preserves byte-equivalence with every
74
+ * existing server-side error emission that pre-dates the central
75
+ * builders.
76
+ *
77
+ * The builder exists so first-party subscribe / handshake paths emit
78
+ * canonical codes (e.g. `UPGRADE_REQUIRED`) via a single helper
79
+ * instead of spreading `{code, message}` object literals. `details`
80
+ * is filtered when `undefined` so the serialized frame matches the
81
+ * pre-builder `{code, message}` shape byte-for-byte.
82
+ */
83
+ export function makeErrorPayload(parts) {
84
+ const payload = {
85
+ code: parts.code,
86
+ message: parts.message,
87
+ };
88
+ if (parts.details !== undefined)
89
+ payload.details = parts.details;
90
+ return payload;
91
+ }
92
+ /**
93
+ * Build a {@link ContractErrorPayload} with `schemaVersion` stamped
94
+ * to {@link PROTOCOL_SCHEMA_VERSION} unless the caller overrides.
95
+ *
96
+ * Filters `undefined` optional fields so the emitted payload keeps
97
+ * byte-equivalence with the pre-refactor session-channel router
98
+ * code.
99
+ */
100
+ export function makeContractErrorPayload(parts) {
101
+ const stamp = resolveSchemaVersion(parts);
102
+ const payload = {
103
+ toolName: parts.toolName,
104
+ error: parts.error,
105
+ timestamp: parts.timestamp,
106
+ ...(parts.actionName !== undefined ? { actionName: parts.actionName } : {}),
107
+ ...(parts.sourceAction !== undefined
108
+ ? { sourceAction: parts.sourceAction }
109
+ : {}),
110
+ ...(stamp !== undefined ? { schemaVersion: stamp } : {}),
111
+ };
112
+ return payload;
113
+ }
@@ -0,0 +1,12 @@
1
+ export interface UnknownPermissionNameErrorOptions {
2
+ /** The name the SDK caller passed to `requestPermission`. */
3
+ readonly observedName: string;
4
+ }
5
+ export declare class UnknownPermissionNameError extends Error {
6
+ /** The name the SDK caller passed. */
7
+ readonly observedName: string;
8
+ /** Accepted permission-name enum (Web Permissions API + MCP Apps mirror). */
9
+ readonly acceptedNames: readonly string[];
10
+ constructor(opts: UnknownPermissionNameErrorOptions);
11
+ }
12
+ //# sourceMappingURL=unknown-permission-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unknown-permission-name.d.ts","sourceRoot":"","sources":["../../src/errors/unknown-permission-name.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,iCAAiC;IAChD,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,sCAAsC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAA0B;gBAEvD,IAAI,EAAE,iCAAiC;CAUpD"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Typed error surface for SDK `requestPermission(name)` calls that pass
3
+ * a permission name outside the Web Permissions API enum
4
+ * (`KNOWN_PERMISSION_NAMES`).
5
+ *
6
+ * Background: the grant model lives on
7
+ * `clientCapabilities.gadgets[*].permission`. Without a validation
8
+ * gate, SDK callers (and LLM-generated component code) could request
9
+ * arbitrary permission strings, including typos like `'geolocaiton'`
10
+ * or unsupported names. This error is that gate.
11
+ *
12
+ * The class pins `.name === 'UnknownPermissionNameError'` so consumers
13
+ * can pattern-match without sniffing the message string. Carries the
14
+ * observed name + the accepted enum so operators can diagnose without
15
+ * additional context.
16
+ */
17
+ import { KNOWN_PERMISSION_NAMES } from '../validation/hygiene-rules.js';
18
+ export class UnknownPermissionNameError extends Error {
19
+ /** The name the SDK caller passed. */
20
+ observedName;
21
+ /** Accepted permission-name enum (Web Permissions API + MCP Apps mirror). */
22
+ acceptedNames = KNOWN_PERMISSION_NAMES;
23
+ constructor(opts) {
24
+ super(`Unknown permission name '${opts.observedName}'. ` +
25
+ `Pick a name from the Web Permissions API enum: [${KNOWN_PERMISSION_NAMES.join(', ')}].`);
26
+ this.name = 'UnknownPermissionNameError';
27
+ this.observedName = opts.observedName;
28
+ }
29
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Typed error surface for the protocol-version handshake.
3
+ *
4
+ * Raised by first-party clients + servers when the handshake observes
5
+ * a version mismatch:
6
+ *
7
+ * - Server side: `SubscribePayload.supportedVersions` is present AND
8
+ * does not contain the server's `PROTOCOL_SCHEMA_VERSION`. The
9
+ * server emits an `{type: 'error'}` frame with `code:
10
+ * UPGRADE_REQUIRED`; first-party servers also surface this class
11
+ * to their own observability path so operators see the
12
+ * unsatisfied subscribe locally.
13
+ * - Client side: on ack receipt, `AckPayload.serverVersion` is
14
+ * present AND NOT in `CLIENT_SUPPORTED_VERSIONS`. The client
15
+ * instantiates this class and surfaces it to the caller via the
16
+ * session's `onError` hook.
17
+ *
18
+ * The class pins `.name === 'UpgradeRequiredError'` and `.code ===
19
+ * UPGRADE_REQUIRED` so consumers can pattern-match without
20
+ * string-sniffing the message — `UPGRADE_REQUIRED` is reachable via
21
+ * a typed protocol-error surface, not just via raw string compares.
22
+ *
23
+ * Wire-shape coupling: the class carries the observed version(s) +
24
+ * the receiver's known-accepted set so operators can diagnose without
25
+ * additional context. The `code` property matches the wire value
26
+ * emitted in `ErrorPayload.code` — symmetric by design.
27
+ */
28
+ import { UPGRADE_REQUIRED } from '../version.js';
29
+ export interface UpgradeRequiredErrorOptions {
30
+ /**
31
+ * The version the peer declared on the wire. Server-side: the
32
+ * client's `supportedVersions` entry or the full list. Client-side:
33
+ * `AckPayload.serverVersion`.
34
+ */
35
+ readonly observedVersion?: string | readonly string[];
36
+ /**
37
+ * The receiver's accepted-versions set. Server-side: a singleton
38
+ * `[PROTOCOL_SCHEMA_VERSION]`. Client-side: `CLIENT_SUPPORTED_VERSIONS`.
39
+ */
40
+ readonly acceptedVersions: readonly string[];
41
+ /**
42
+ * Which side observed the mismatch. Server-side emission sets
43
+ * `'server'`; client-side surface sets `'client'`.
44
+ */
45
+ readonly observedBy: 'server' | 'client';
46
+ }
47
+ export declare class UpgradeRequiredError extends Error {
48
+ /** Canonical `ErrorPayload.code` value. Symmetric with wire shape. */
49
+ readonly code: typeof UPGRADE_REQUIRED;
50
+ readonly observedVersion?: string | readonly string[];
51
+ readonly acceptedVersions: readonly string[];
52
+ readonly observedBy: 'server' | 'client';
53
+ constructor(opts: UpgradeRequiredErrorOptions);
54
+ }
55
+ //# sourceMappingURL=version-mismatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-mismatch.d.ts","sourceRoot":"","sources":["../../src/errors/version-mismatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC1C;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,OAAO,gBAAgB,CAAoB;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACtD,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,CAAC;gBAE7B,IAAI,EAAE,2BAA2B;CAoB9C"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Typed error surface for the protocol-version handshake.
3
+ *
4
+ * Raised by first-party clients + servers when the handshake observes
5
+ * a version mismatch:
6
+ *
7
+ * - Server side: `SubscribePayload.supportedVersions` is present AND
8
+ * does not contain the server's `PROTOCOL_SCHEMA_VERSION`. The
9
+ * server emits an `{type: 'error'}` frame with `code:
10
+ * UPGRADE_REQUIRED`; first-party servers also surface this class
11
+ * to their own observability path so operators see the
12
+ * unsatisfied subscribe locally.
13
+ * - Client side: on ack receipt, `AckPayload.serverVersion` is
14
+ * present AND NOT in `CLIENT_SUPPORTED_VERSIONS`. The client
15
+ * instantiates this class and surfaces it to the caller via the
16
+ * session's `onError` hook.
17
+ *
18
+ * The class pins `.name === 'UpgradeRequiredError'` and `.code ===
19
+ * UPGRADE_REQUIRED` so consumers can pattern-match without
20
+ * string-sniffing the message — `UPGRADE_REQUIRED` is reachable via
21
+ * a typed protocol-error surface, not just via raw string compares.
22
+ *
23
+ * Wire-shape coupling: the class carries the observed version(s) +
24
+ * the receiver's known-accepted set so operators can diagnose without
25
+ * additional context. The `code` property matches the wire value
26
+ * emitted in `ErrorPayload.code` — symmetric by design.
27
+ */
28
+ import { UPGRADE_REQUIRED } from '../version.js';
29
+ export class UpgradeRequiredError extends Error {
30
+ /** Canonical `ErrorPayload.code` value. Symmetric with wire shape. */
31
+ code = UPGRADE_REQUIRED;
32
+ observedVersion;
33
+ acceptedVersions;
34
+ observedBy;
35
+ constructor(opts) {
36
+ const observed = opts.observedVersion === undefined
37
+ ? 'unknown'
38
+ : Array.isArray(opts.observedVersion)
39
+ ? opts.observedVersion.join(', ')
40
+ : String(opts.observedVersion);
41
+ const accepted = opts.acceptedVersions.join(', ');
42
+ super(`UPGRADE_REQUIRED: ${opts.observedBy === 'server' ? 'client' : 'server'} ` +
43
+ `speaks version '${observed}' which is not in the ${opts.observedBy === 'server' ? 'server' : 'client'}'s ` +
44
+ `accepted set [${accepted}].`);
45
+ this.name = 'UpgradeRequiredError';
46
+ if (opts.observedVersion !== undefined) {
47
+ this.observedVersion = opts.observedVersion;
48
+ }
49
+ this.acceptedVersions = opts.acceptedVersions;
50
+ this.observedBy = opts.observedBy;
51
+ }
52
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Contract → descriptor resolution helpers.
3
+ *
4
+ * The wire side (`contract.clientCapabilities.gadgets`) is
5
+ * PACKAGE-KEYED two-level: `Record<package, Record<exportName, …>>`.
6
+ * It carries identity only — `(package, export name)` — never
7
+ * `version` or transport metadata. The operator's `App.gadgets`
8
+ * catalog owns those; `filterDescriptorsToContract` snapshots the
9
+ * referenced subset onto `SessionStackEntry.gadgetDescriptors` as a
10
+ * sidecar.
11
+ */
12
+ import type { DataContract, GadgetDescriptor, GadgetExport, GadgetUse } from '../types/data-contract.js';
13
+ /**
14
+ * The export name a {@link GadgetExport} carries — the `hook` field
15
+ * for a hook export, the `component` field for a component export.
16
+ * Discrimination is by field presence; there is no `kind` field. The
17
+ * single accessor so callers never re-spell the field-presence check.
18
+ *
19
+ * Total over the union: it checks BOTH fields explicitly and throws
20
+ * on a malformed member rather than assuming `component` in the else
21
+ * branch (which silently returned `undefined` for a both-fields-
22
+ * absent object). The `GadgetHookExport.component?: never` /
23
+ * `GadgetComponentExport.hook?: never` exclusivity markers (F1) make
24
+ * `hook` / `component` OPTIONAL keys of the opposite member, so `'k' in
25
+ * x` no longer narrows — discrimination is by VALUE presence
26
+ * (`!== undefined`). A future third union member that carries neither
27
+ * field falls through to the throw rather than silently mistyping.
28
+ *
29
+ * Wire-side use records ({@link GadgetUse}) carry the export name as a
30
+ * plain `name` field — no accessor needed there.
31
+ */
32
+ export declare function gadgetExportName(x: GadgetExport): string;
33
+ /**
34
+ * Canonical string key for a gadget EXPORT's identity —
35
+ * `(name, package)`. Every site that decides "does this wire ref
36
+ * resolve to that registered export?" MUST key through this helper so
37
+ * the resolver and the push-time gates (`assertGadgetsRegistered`,
38
+ * `assertPublicEnvSatisfied`) agree byte-for-byte on what "the same
39
+ * gadget export" means.
40
+ *
41
+ * `version` is NOT part of the key — it is not on the wire. An App's
42
+ * `App.gadgets` catalog registers at most one descriptor per package
43
+ * (enforced by the catalog lint), so `(name, package)` resolves to
44
+ * exactly one registered export.
45
+ *
46
+ * The export name is itself kind-disambiguating: `use`-prefixed hook
47
+ * names (`HOOK_NAME_RE`) and PascalCase component names
48
+ * (`COMPONENT_NAME_RE`) are grammar-disjoint, so a hook and a
49
+ * component can never collide on name.
50
+ *
51
+ * Separator `\t`: the hook / component name grammars and
52
+ * `NPM_PACKAGE_NAME_RE` all exclude tab, so no field value can smuggle
53
+ * a separator.
54
+ */
55
+ export declare function gadgetIdentityKey(use: {
56
+ name: string;
57
+ package: string;
58
+ }): string;
59
+ /**
60
+ * Flatten the package-keyed `contract.clientCapabilities.gadgets` into
61
+ * a list of `(package, name)` use records — one per export the
62
+ * contract references. The single accessor every consumer (push
63
+ * gates, descriptor resolver, code-gen) iterates, so the nested wire
64
+ * shape is walked in exactly one place.
65
+ *
66
+ * Returns an empty array when the contract declares no
67
+ * `clientCapabilities.gadgets`. Pure function. No I/O.
68
+ */
69
+ export declare function listContractGadgets(contract: DataContract): readonly GadgetUse[];
70
+ /**
71
+ * Given a wire-side {@link DataContract} and the operator's
72
+ * `App.gadgets` catalog, return the subset of package descriptors the
73
+ * contract references via `clientCapabilities.gadgets`.
74
+ *
75
+ * Matching key is the npm PACKAGE name — the wire map's own key. A
76
+ * descriptor IS a package, and `App.gadgets` registers at most one
77
+ * descriptor per package, so a package key resolves to exactly one
78
+ * descriptor. The filtered list lands as a sidecar on
79
+ * `SessionStackEntry.gadgetDescriptors`.
80
+ *
81
+ * Ordering: descriptors appear in the order their package key first
82
+ * appears on `clientCapabilities.gadgets`. A package absent from
83
+ * `appGadgets` is dropped — the push-time `assertGadgetsRegistered`
84
+ * gate rejects the push with a precise registration-mismatch code
85
+ * BEFORE this helper runs, so silent drop here is safe in the happy
86
+ * path.
87
+ *
88
+ * Pure function. No I/O. Returns an empty array when the contract has
89
+ * no `clientCapabilities.gadgets`, `appGadgets` is empty, or no
90
+ * package resolves to a registered descriptor.
91
+ */
92
+ export declare function filterDescriptorsToContract(contract: DataContract, appGadgets: readonly GadgetDescriptor[]): readonly GadgetDescriptor[];
93
+ //# sourceMappingURL=resolve-contract-gadgets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-contract-gadgets.d.ts","sourceRoot":"","sources":["../../src/gadgets/resolve-contract-gadgets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACV,MAAM,2BAA2B,CAAC;AAEnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAMxD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAET;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,GACrB,SAAS,SAAS,EAAE,CAiBtB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,SAAS,gBAAgB,EAAE,GACtC,SAAS,gBAAgB,EAAE,CAiB7B"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * The export name a {@link GadgetExport} carries — the `hook` field
3
+ * for a hook export, the `component` field for a component export.
4
+ * Discrimination is by field presence; there is no `kind` field. The
5
+ * single accessor so callers never re-spell the field-presence check.
6
+ *
7
+ * Total over the union: it checks BOTH fields explicitly and throws
8
+ * on a malformed member rather than assuming `component` in the else
9
+ * branch (which silently returned `undefined` for a both-fields-
10
+ * absent object). The `GadgetHookExport.component?: never` /
11
+ * `GadgetComponentExport.hook?: never` exclusivity markers (F1) make
12
+ * `hook` / `component` OPTIONAL keys of the opposite member, so `'k' in
13
+ * x` no longer narrows — discrimination is by VALUE presence
14
+ * (`!== undefined`). A future third union member that carries neither
15
+ * field falls through to the throw rather than silently mistyping.
16
+ *
17
+ * Wire-side use records ({@link GadgetUse}) carry the export name as a
18
+ * plain `name` field — no accessor needed there.
19
+ */
20
+ export function gadgetExportName(x) {
21
+ if (x.hook !== undefined)
22
+ return x.hook;
23
+ if (x.component !== undefined)
24
+ return x.component;
25
+ throw new Error('gadgetExportName: malformed GadgetExport — neither hook nor component field present');
26
+ }
27
+ /**
28
+ * Canonical string key for a gadget EXPORT's identity —
29
+ * `(name, package)`. Every site that decides "does this wire ref
30
+ * resolve to that registered export?" MUST key through this helper so
31
+ * the resolver and the push-time gates (`assertGadgetsRegistered`,
32
+ * `assertPublicEnvSatisfied`) agree byte-for-byte on what "the same
33
+ * gadget export" means.
34
+ *
35
+ * `version` is NOT part of the key — it is not on the wire. An App's
36
+ * `App.gadgets` catalog registers at most one descriptor per package
37
+ * (enforced by the catalog lint), so `(name, package)` resolves to
38
+ * exactly one registered export.
39
+ *
40
+ * The export name is itself kind-disambiguating: `use`-prefixed hook
41
+ * names (`HOOK_NAME_RE`) and PascalCase component names
42
+ * (`COMPONENT_NAME_RE`) are grammar-disjoint, so a hook and a
43
+ * component can never collide on name.
44
+ *
45
+ * Separator `\t`: the hook / component name grammars and
46
+ * `NPM_PACKAGE_NAME_RE` all exclude tab, so no field value can smuggle
47
+ * a separator.
48
+ */
49
+ export function gadgetIdentityKey(use) {
50
+ return `${use.name}\t${use.package}`;
51
+ }
52
+ /**
53
+ * Flatten the package-keyed `contract.clientCapabilities.gadgets` into
54
+ * a list of `(package, name)` use records — one per export the
55
+ * contract references. The single accessor every consumer (push
56
+ * gates, descriptor resolver, code-gen) iterates, so the nested wire
57
+ * shape is walked in exactly one place.
58
+ *
59
+ * Returns an empty array when the contract declares no
60
+ * `clientCapabilities.gadgets`. Pure function. No I/O.
61
+ */
62
+ export function listContractGadgets(contract) {
63
+ const declared = contract.clientCapabilities?.gadgets;
64
+ if (!declared)
65
+ return [];
66
+ const out = [];
67
+ for (const [pkg, exports] of Object.entries(declared)) {
68
+ for (const [name, meta] of Object.entries(exports)) {
69
+ out.push({
70
+ package: pkg,
71
+ name,
72
+ ...(meta.description !== undefined
73
+ ? { description: meta.description }
74
+ : {}),
75
+ ...(meta.usage !== undefined ? { usage: meta.usage } : {}),
76
+ });
77
+ }
78
+ }
79
+ return out;
80
+ }
81
+ /**
82
+ * Given a wire-side {@link DataContract} and the operator's
83
+ * `App.gadgets` catalog, return the subset of package descriptors the
84
+ * contract references via `clientCapabilities.gadgets`.
85
+ *
86
+ * Matching key is the npm PACKAGE name — the wire map's own key. A
87
+ * descriptor IS a package, and `App.gadgets` registers at most one
88
+ * descriptor per package, so a package key resolves to exactly one
89
+ * descriptor. The filtered list lands as a sidecar on
90
+ * `SessionStackEntry.gadgetDescriptors`.
91
+ *
92
+ * Ordering: descriptors appear in the order their package key first
93
+ * appears on `clientCapabilities.gadgets`. A package absent from
94
+ * `appGadgets` is dropped — the push-time `assertGadgetsRegistered`
95
+ * gate rejects the push with a precise registration-mismatch code
96
+ * BEFORE this helper runs, so silent drop here is safe in the happy
97
+ * path.
98
+ *
99
+ * Pure function. No I/O. Returns an empty array when the contract has
100
+ * no `clientCapabilities.gadgets`, `appGadgets` is empty, or no
101
+ * package resolves to a registered descriptor.
102
+ */
103
+ export function filterDescriptorsToContract(contract, appGadgets) {
104
+ const declared = contract.clientCapabilities?.gadgets;
105
+ if (!declared || appGadgets.length === 0) {
106
+ return [];
107
+ }
108
+ const byPackage = new Map();
109
+ for (const descriptor of appGadgets) {
110
+ byPackage.set(descriptor.package, descriptor);
111
+ }
112
+ const out = [];
113
+ for (const pkg of Object.keys(declared)) {
114
+ const descriptor = byPackage.get(pkg);
115
+ if (descriptor)
116
+ out.push(descriptor);
117
+ }
118
+ return out;
119
+ }
@@ -0,0 +1,43 @@
1
+ import type { GadgetDescriptor } from '../types/data-contract';
2
+ /**
3
+ * The first-party `@ggui-ai/gadgets` package name. Used as
4
+ * the default `package` for every entry in {@link STDLIB_GADGETS}
5
+ * and as the `DEFAULT_GADGET_PACKAGE` literal in the hygiene linter.
6
+ */
7
+ export declare const STDLIB_GADGETS_PACKAGE = "@ggui-ai/gadgets";
8
+ /**
9
+ * Pinned semver of the stdlib gadgets every descriptor declares on
10
+ * its `version` field. Mirrors
11
+ * `packages/gadgets/package.json#version`; a cross-package parity test
12
+ * in `@ggui-ai/gadgets` asserts the two stay in sync, so a release-time
13
+ * bump to the runtime package without updating this constant fails CI.
14
+ */
15
+ export declare const STDLIB_GADGETS_VERSION = "0.1.0-rc.1";
16
+ /**
17
+ * v1 catalog of stdlib gadget descriptors. Every entry's
18
+ * `package` defaults to {@link STDLIB_GADGETS_PACKAGE}; the
19
+ * `permission` field, where present, mirrors the Web Permissions API
20
+ * name and lines up with the hygiene linter's
21
+ * `KNOWN_PERMISSION_HOOKS` table.
22
+ *
23
+ * **Ordering:** alphabetical by hook name. Stable so consumers can
24
+ * diff the list across protocol minor bumps without false positives
25
+ * from re-ordering.
26
+ *
27
+ * **Shape note:** entries are typed `Readonly<GadgetDescriptor>` so
28
+ * downstream consumers (App.gadgets default-on-read, the LLM
29
+ * generator's catalog, the `ggui_list_gadgets` handler)
30
+ * can structurally clone without mutating the source. Callers that
31
+ * need a mutable copy should `structuredClone` explicitly.
32
+ */
33
+ export declare const STDLIB_GADGETS: readonly Readonly<GadgetDescriptor>[];
34
+ /**
35
+ * Hook-name index over {@link STDLIB_GADGETS}. Lazily
36
+ * constructed for callers that need O(1) "is hook X part of the
37
+ * stdlib?" checks (the hygiene linter, the per-app gadget validator,
38
+ * the `ggui_list_gadgets` handler).
39
+ *
40
+ * Frozen so accidental mutation is loud, not silent.
41
+ */
42
+ export declare const STDLIB_GADGET_HOOKS: ReadonlySet<string>;
43
+ //# sourceMappingURL=stdlib-gadgets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdlib-gadgets.d.ts","sourceRoot":"","sources":["../../src/gadgets/stdlib-gadgets.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,QAAQ,CAAC,gBAAgB,CAAC,EA+F/D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAUnD,CAAC"}