@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,373 @@
1
+ /**
2
+ * MCP Tool Zod Schemas — Single Source of Truth
3
+ *
4
+ * These schemas define the validation rules for MCP tool inputs.
5
+ * TypeScript types in types/mcp.ts are derived from these via z.infer.
6
+ * The server handler imports these for runtime validation.
7
+ */
8
+ import { z } from 'zod';
9
+ import { blueprintDraftSchema, handshakeSuggestionSchema, pushDecisionSchema, } from './handshake-suggestion.js';
10
+ // ── Shared Sub-Schemas ──
11
+ export const viewportSchema = z.object({
12
+ width: z.number(),
13
+ height: z.number(),
14
+ });
15
+ export const interfaceContextSchema = z.object({
16
+ viewport: viewportSchema,
17
+ platform: z.enum(['web', 'mobile', 'desktop']),
18
+ deviceType: z.enum(['phone', 'tablet', 'desktop']),
19
+ orientation: z.enum(['portrait', 'landscape']),
20
+ devicePixelRatio: z.number().optional(),
21
+ touchPrimary: z.boolean().optional(),
22
+ shellType: z.enum(['chat', 'fullscreen', 'spatial']).optional(),
23
+ colorScheme: z.enum(['light', 'dark']).optional(),
24
+ reducedMotion: z.boolean().optional(),
25
+ }).passthrough();
26
+ // ── Other Tool Schemas ──
27
+ // Input schemas: pre-launch posture is `.strict()` — unknown keys reject.
28
+ // Pre-fix all of these had `.passthrough()` as forward-compat shims. Pre-
29
+ // launch No Backward Compatibility (CLAUDE.md) supersedes — typos in agent
30
+ // args (`stackItemid`, `sesssionId`, etc.) surface immediately at the wire
31
+ // boundary instead of silently no-op-ing because the server stripped them.
32
+ export const popInputSchema = z.object({
33
+ sessionId: z.string().describe('Session opaque id from ggui_new_session.'),
34
+ }).strict();
35
+ export const consumeInputSchema = z.object({
36
+ stackItemId: z.string().describe('Stack item opaque id (UUID) — returned by ggui_push.'),
37
+ timeout: z.number().min(0).max(25).optional()
38
+ .describe('Long-poll timeout in seconds (default short; max 25).'),
39
+ }).strict();
40
+ /**
41
+ * Input schema for `ggui_emit` — emit a stamped delivery on a declared
42
+ * `streamSpec[channel]`.
43
+ */
44
+ export const emitInputSchema = z.object({
45
+ sessionId: z.string().describe('Session opaque id from ggui_new_session.'),
46
+ channel: z.string()
47
+ .describe('Channel name declared on the active stack item streamSpec.'),
48
+ payload: z.unknown().describe('Payload — must match streamSpec[channel].schema.'),
49
+ complete: z.boolean().optional()
50
+ .describe('True marks the stream complete; subsequent emits on this channel reject.'),
51
+ stackItemId: z.string().optional()
52
+ .describe('Stack item to scope this emit to; defaults to session top.'),
53
+ }).strict();
54
+ export const getSessionInputSchema = z.object({
55
+ sessionId: z.string().describe('Session opaque id from ggui_new_session.'),
56
+ }).strict();
57
+ export const getStackInputSchema = z.object({
58
+ sessionId: z.string().describe('Session opaque id from ggui_new_session.'),
59
+ }).strict();
60
+ export const closeInputSchema = z.object({
61
+ sessionId: z.string().describe('Session opaque id from ggui_new_session.'),
62
+ }).strict();
63
+ export const listFeaturedBlueprintsInputSchema = z.object({
64
+ level: z.enum(['primitive', 'component', 'composite', 'template']).optional(),
65
+ category: z.string().optional(),
66
+ tags: z.array(z.string()).optional(),
67
+ limit: z.number().optional(),
68
+ }).strict();
69
+ export const searchBlueprintsInputSchema = z.object({
70
+ query: z.string(),
71
+ limit: z.number().optional(),
72
+ }).strict();
73
+ export const renderBlueprintInputSchema = z.object({
74
+ blueprintId: z.string(),
75
+ props: z.record(z.string(), z.unknown()).optional(),
76
+ }).strict();
77
+ export const discoverInputSchema = z.object({}).strict();
78
+ export const requestCredentialInputSchema = z.object({
79
+ serviceId: z.string().describe('OAuth service ID (e.g., "bashdoor", "ubot")'),
80
+ reason: z.string().optional().describe('Why the agent needs this credential (shown to user)'),
81
+ sessionId: z.string().optional().describe('Existing session ID to push consent UI into'),
82
+ }).strict();
83
+ // ── Protocol v1.1 — canonical tool quartet ──
84
+ //
85
+ // `ggui_new_session` + `ggui_handshake` + `ggui_push` + `ggui_update`.
86
+ // The session lifecycle is decoupled from the push lifecycle: agents
87
+ // mint a sessionId via `ggui_new_session` ONCE per chat, then thread
88
+ // it across every subsequent `ggui_handshake`. `ggui_update` mutates
89
+ // stack-item props addressed by the globally-unique `stackItemId` — no
90
+ // sessionId required (server resolves via the SessionStore's stackItemId
91
+ // secondary index, with appId tenancy enforced from `ctx.appId`).
92
+ //
93
+ /**
94
+ * `ggui_new_session` — mint or resolve a chat-scoped session handle.
95
+ *
96
+ * Server-mints, agent-threads. SEP-2567 aligned ("Sessionless MCP",
97
+ * Final 2026-03-11): the MCP spec deliberately removes Mcp-Session-Id
98
+ * because hosts can't agree on what a session means; the recommended
99
+ * pattern is exactly this — server returns explicit handles, agent
100
+ * threads them through subsequent calls.
101
+ *
102
+ * No inputs — every call mints a fresh random sessionId. (A prior
103
+ * optional `seed` for deterministic derivation was retired because
104
+ * LLMs were passing the same seed across user turns and getting back
105
+ * the same sessionId, defeating the "new" in the tool name.)
106
+ */
107
+ export const newSessionInputSchema = z.object({}).strict();
108
+ export const newSessionOutputSchema = z.object({
109
+ sessionId: z.string()
110
+ .describe('Thread this through every subsequent ggui_handshake / ggui_update call in this chat.'),
111
+ appId: z.string(),
112
+ createdAt: z.string()
113
+ .describe('ISO 8601 — creation timestamp of the freshly-minted session.'),
114
+ nextStep: z.object({
115
+ tool: z.literal('ggui_handshake'),
116
+ description: z.string(),
117
+ example: z.string(),
118
+ }).describe('Wire-shape recovery hint — a worked literal example of the next call.'),
119
+ });
120
+ //
121
+ // `ggui_handshake` + `ggui_push` + `ggui_update` follow.
122
+ //
123
+ /**
124
+ * `ggui_handshake` — three-step suggestion protocol.
125
+ *
126
+ * Step 1 (this input): the agent posts a draft — its idea: contract +
127
+ * optional variance + optional generator hint.
128
+ *
129
+ * Step 2 (server-side, see `handshakeOutputSchema`): the server runs
130
+ * `BlueprintSearch` and contract-validation in parallel and returns a
131
+ * `HandshakeSuggestion` routed by `origin: cache | agent | synth`.
132
+ *
133
+ * Step 3 (paired `ggui_push`): the agent accepts (reuses the
134
+ * provisional `blueprintId` minted in step-2) OR overrides (mints a
135
+ * fresh `blueprintId` against a NEW draft).
136
+ *
137
+ * Locked decisions:
138
+ *
139
+ * - `blueprintDraft` is the single-field input wrapping contract +
140
+ * variance + generator hint.
141
+ * - The agent is the contract authority; synth amends only when
142
+ * validation fails.
143
+ */
144
+ export const handshakeInputSchema = z.object({
145
+ /**
146
+ * Required. Mint via `ggui_new_session` once per chat, then thread
147
+ * through every subsequent handshake. Server validates existence +
148
+ * tenant ownership; unknown / cross-tenant ids surface as
149
+ * session_not_found.
150
+ */
151
+ sessionId: z.string()
152
+ .min(1)
153
+ .describe('Session handle minted by ggui_new_session. Required — call ggui_new_session({seed?}) first to obtain one. Reuse the same sessionId across multiple handshake/push pairs in the same chat to grow the session stack.'),
154
+ /**
155
+ * Concise semantic identity of the UI. Same intent across calls =
156
+ * same component reused. Required — drives blueprint-search keying
157
+ * (intent tokens contribute to the intent axis).
158
+ * @example "Gmail inbox for email triage"
159
+ * @example "Current weather conditions"
160
+ */
161
+ intent: z.string().min(1).describe('Concise purpose — same intent = same component reused. e.g. "Gmail inbox for email triage"'),
162
+ /**
163
+ * Agent's draft — contract (required) + variance + generator hint.
164
+ * The contract drives the blueprint-search embed/structural axes
165
+ * and the contract validators; variance feeds the variance axis
166
+ * and rides through to the suggestion's `blueprintMeta`.
167
+ */
168
+ blueprintDraft: blueprintDraftSchema
169
+ .describe('Agent\'s draft: contract (required) + optional variance + optional generator slug hint. The server combines this with cached blueprints + validator outcomes to produce a three-mode suggestion (cache / agent / synth).'),
170
+ /**
171
+ * Skip blueprint-search on step-2 and route straight to validation
172
+ * + (if validation passes) agent-mode suggestion against the draft.
173
+ * Used after a prior handshake returned an unwanted cache suggestion
174
+ * and the agent wants to force a fresh-gen path on the paired push.
175
+ */
176
+ forceCreate: z.boolean().optional(),
177
+ }).strict();
178
+ /**
179
+ * Three-step handshake output. Single `suggestion` carries
180
+ * `origin: cache | agent | synth`, `blueprintMeta` (always present),
181
+ * and optional `amendments` (synth-only) / `validationFindings`
182
+ * (soft on cache).
183
+ *
184
+ * The agent reads `suggestion.origin` to branch the paired push:
185
+ *
186
+ * - `cache` → push `{decision: {kind: 'accept'}}` for cache delivery.
187
+ * - `agent` → push `{decision: {kind: 'accept'}}` to gen against the draft.
188
+ * - `synth` → push `{decision: {kind: 'accept'}}` to gen against the amended contract.
189
+ *
190
+ * Any origin → push `{decision: {kind: 'override', blueprintDraft: {...}}}` to
191
+ * discard the suggestion and gen against a fresh draft (mints a new
192
+ * `blueprintId` server-side).
193
+ *
194
+ * Wire-output is intentionally lean. The handler carries `reason`,
195
+ * `target`, `alternatives`, `contractHash`, `serverCapabilities` on
196
+ * its internal `HandshakeOutput` TS shape for telemetry / post-classify
197
+ * tracing — zod strips them before structuredContent serialization.
198
+ *
199
+ * `serverCapabilities` reaches the iframe via `_meta.ggui.bootstrap`
200
+ * (see `bootstrap-meta-derivation.ts`), not via this response.
201
+ */
202
+ export const handshakeOutputSchema = z.object({
203
+ handshakeId: z.string().describe('Stable id — pass to ggui_push / ggui_update'),
204
+ action: z.enum(['create', 'reuse', 'update', 'replace', 'compose', 'declined']),
205
+ /**
206
+ * The handshake suggestion — see `handshakeSuggestionSchema`. The
207
+ * routing discriminator is `suggestion.origin`; `blueprintMeta` is
208
+ * ALWAYS present; `amendments` / `validationFindings` are
209
+ * conditional on the routing outcome.
210
+ */
211
+ suggestion: handshakeSuggestionSchema
212
+ .describe('Server\'s suggestion — origin-routed (cache | agent | synth). Always carries a provisional `blueprintMeta` the agent reuses by sending `decision: \'accept\'` on push.'),
213
+ /**
214
+ * Truncated human-readable rationale for the `action` value. Helps
215
+ * the agent and the operator narrate why the server chose to reuse a cached
216
+ * blueprint vs synth a fresh one vs decline. Internal-only
217
+ * `target`, `alternatives`, `contractHash`, `serverCapabilities`
218
+ * stay off the wire — they're telemetry, not agent-actionable.
219
+ */
220
+ reason: z
221
+ .string()
222
+ .max(280)
223
+ .optional()
224
+ .describe('Short rationale (≤280 chars) for the `action` value. Surfaced for agent + operator visibility; truncated to keep the structuredContent payload predictable.'),
225
+ nextStep: z.object({
226
+ tool: z.literal('ggui_push'),
227
+ description: z.string(),
228
+ example: z.string(),
229
+ }).optional().describe('Wire-shape recovery hint. A worked literal example of the next ggui_push call the agent should emit — the example string can be copied verbatim and tweaked (e.g. fill in `props` placeholders). Top-level field so a skimming agent finds it immediately.'),
230
+ });
231
+ /**
232
+ * `ggui_push` — materialises a UI emission. Step 3 of the three-step
233
+ * handshake protocol.
234
+ *
235
+ * The agent commits its decision relative to the prior handshake's
236
+ * suggestion: ACCEPT (use the provisional `blueprintMeta` from
237
+ * step-2 verbatim) or OVERRIDE (mint a fresh blueprintId with a NEW
238
+ * `blueprintDraft`).
239
+ *
240
+ * Locked decisions:
241
+ *
242
+ * - `decision` discriminator: `{kind: 'accept'} |
243
+ * {kind: 'override', blueprintDraft: {...}}`.
244
+ * - `accept` reuses `handshake.suggestion.blueprintMeta.blueprintId`
245
+ * exactly; `override` discards the provisional id and mints fresh.
246
+ *
247
+ * There is no separate `ggui_commit` — push absorbs that responsibility.
248
+ */
249
+ export const pushInputSchema = z.object({
250
+ handshakeId: z
251
+ .string({
252
+ message: 'ggui_push: handshakeId is REQUIRED. Call ggui_handshake({sessionId, intent, blueprintDraft}) first to negotiate — handshake returns a handshakeId + suggestion. Then push with {handshakeId, decision: {kind: \'accept\'}} (accept the suggestion) or {handshakeId, decision: {kind: \'override\', blueprintDraft: {...}}} (override with a fresh draft). Direct-push without a handshakeId is not supported.',
253
+ })
254
+ .min(1, 'ggui_push: handshakeId must be a non-empty string from a prior ggui_handshake call.'),
255
+ /**
256
+ * Runtime prop values for THIS render. Validated against the
257
+ * effective contract's `propsSpec` — required-field checks + type
258
+ * checks per spec entry. Validation failures fail the push with a
259
+ * recoverable `ContractViolationError`.
260
+ */
261
+ props: z.record(z.string(), z.unknown()).optional(),
262
+ /**
263
+ * Decision discriminator (REQUIRED).
264
+ *
265
+ * - `{kind: 'accept'}` — use the handshake's
266
+ * `suggestion.blueprintMeta` verbatim. Cache delivery (origin
267
+ * === 'cache') or gen-against-suggestion (origin === 'agent' /
268
+ * 'synth'). Reuses the provisional `blueprintId`.
269
+ * - `{kind: 'override', blueprintDraft: {...}}` — mint a fresh
270
+ * `blueprintId` and gen against the agent's NEW draft. The
271
+ * provisional id from the handshake is discarded. Telemetry
272
+ * threads via `handshakeId`.
273
+ */
274
+ decision: pushDecisionSchema
275
+ .describe('Accept the handshake suggestion (use provisional blueprintId verbatim) or override with a fresh draft (mint new blueprintId).'),
276
+ }).strict();
277
+ /**
278
+ * Wire-output shape — intentionally lean: `{stackItemId, nextStep?,
279
+ * url, action}`. The handler carries `sessionId`, `shortCode`,
280
+ * `codeReady`, `handshakeId`, `decision`, `contract`, `contractHash`,
281
+ * `cache`, `codeUrl`, `codeHash` on its internal `PushOutput` TS shape
282
+ * for telemetry / post-classify tracing — zod strips them before
283
+ * structuredContent serialization.
284
+ *
285
+ * The iframe receives bootstrap credentials (`wsUrl`, `token`,
286
+ * `expiresAt`) via `_meta.ggui.bootstrap`, not via this response.
287
+ */
288
+ export const pushOutputSchema = z.object({
289
+ stackItemId: z.string(),
290
+ url: z.string().url(),
291
+ action: z.enum(['create', 'reuse', 'update', 'replace', 'compose', 'declined']),
292
+ /**
293
+ * Wire-shape recovery hint for the next call. Emitted ONLY when the
294
+ * pushed contract has a non-empty `actionSpec` — i.e. the agent will
295
+ * receive user-action events on this stack item. Pure-display pushes
296
+ * (props only) get no `nextStep` because there is nothing to consume.
297
+ *
298
+ * Mirrors the chain at `new_session.nextStep` (→ handshake) and
299
+ * `handshake.nextStep` (→ push). Closes the loop with consume.
300
+ *
301
+ * `args.stackItemId` is the literal value the agent passes to
302
+ * `ggui_consume` — copy-paste shape.
303
+ */
304
+ nextStep: z.object({
305
+ tool: z.literal('ggui_consume'),
306
+ description: z.string(),
307
+ example: z.string(),
308
+ args: z.object({
309
+ stackItemId: z.string(),
310
+ }),
311
+ }).optional().describe('Recovery hint — when the pushed contract has actions, points the agent at ggui_consume({stackItemId}) for the inbound action loop. Absent for pure-display pushes.'),
312
+ });
313
+ /**
314
+ * `ggui_update` — refresh the rendered UI with new state.
315
+ *
316
+ * Discriminated on `kind`:
317
+ *
318
+ * - `kind: 'replace'` + `props` — full props replacement. The new
319
+ * map IS the new state. Use when most props change OR when you
320
+ * want deterministic state restoration (no merge ambiguity).
321
+ *
322
+ * - `kind: 'merge'` + `patch` — RFC 7396 JSON Merge Patch semantics.
323
+ * Top-level keys merge shallow; nested objects merge recursively;
324
+ * a `null` value DELETES the key; arrays fully replace (NOT element-
325
+ * wise). Use when most props stay the same and the agent only
326
+ * needs to send a small delta — common after a single domain-tool
327
+ * mutation. RFC 7396 chosen because it has a published spec and
328
+ * wide library support (GitHub API, Kubernetes strategic-merge).
329
+ *
330
+ * Anti-patterns (the discriminated union rejects these structurally,
331
+ * but they're a common author mistake when copy-pasting):
332
+ *
333
+ * - Do NOT send `props` on `kind: 'merge'` — use `patch`.
334
+ * - Do NOT send `patch` on `kind: 'replace'` — use `props`.
335
+ *
336
+ * Both modes validate the FINAL props state (post-merge for `merge`)
337
+ * against the stack item's `propsSpec` and reject on violation —
338
+ * partial patches that would break required fields, type-mismatch
339
+ * values, etc. all reject pre-persist.
340
+ *
341
+ * `stackItemId` is globally unique; the server resolves the owning
342
+ * session via its secondary index and tenancy-checks via `ctx.appId`.
343
+ * NO `sessionId` on the wire.
344
+ */
345
+ export const updateInputSchema = z.discriminatedUnion('kind', [
346
+ z.object({
347
+ stackItemId: z.string().describe('Stack item opaque id (UUID) — returned by ggui_push.'),
348
+ kind: z.literal('replace'),
349
+ props: z.record(z.string(), z.unknown())
350
+ .describe('Full replacement props map. New map IS the new state.'),
351
+ }).strict(),
352
+ z.object({
353
+ stackItemId: z.string().describe('Stack item opaque id (UUID) — returned by ggui_push.'),
354
+ kind: z.literal('merge'),
355
+ patch: z.record(z.string(), z.unknown())
356
+ .describe('RFC 7396 JSON Merge Patch — null deletes a key; arrays fully replace.'),
357
+ }).strict(),
358
+ ]);
359
+ /**
360
+ * Wire-output shape — minimal acknowledgement. The handler carries
361
+ * `sessionId`, `decision`, `contract`, `contractHash` on its internal
362
+ * `UpdateOutput` TS shape — zod strips them before structuredContent
363
+ * serialization.
364
+ *
365
+ * Post-update the iframe receives the new props via the live-channel
366
+ * `props_update` WS frame; the cross-host fallback path receives them
367
+ * via `_meta.ggui.bootstrap.propsJson` (see `update.resultMeta`). The
368
+ * wire response itself is just acknowledgement.
369
+ */
370
+ export const updateOutputSchema = z.object({
371
+ stackItemId: z.string(),
372
+ updated: z.boolean(),
373
+ });
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Zod input + output schemas for the operator-class blueprint tools.
3
+ * Four tools, all `audience: 'ops'`, all served on `/ops`:
4
+ *
5
+ * - `ggui_ops_generate_blueprint` — author a new blueprint by
6
+ * dispatching through the registry's selected generator and
7
+ * persisting the result. Optionally pins as the operator default
8
+ * for its `(appId, contractHash)` group.
9
+ * - `ggui_ops_list_blueprints` — enumerate blueprint metadata
10
+ * (no code body) under tenancy + optional filters. Sorted by
11
+ * `createdAt desc`.
12
+ * - `ggui_ops_update_blueprint` — toggle the operator-default flag
13
+ * and/or patch variance tags. Immutable fields (contractHash,
14
+ * appId, codeS3Url, codeHash, generator, createdAt, createdBy)
15
+ * never mutate; the tool MUST refuse them on input.
16
+ * - `ggui_ops_delete_blueprint` — idempotent removal. Second delete
17
+ * for the same id returns `{deleted: true}` — never throws.
18
+ *
19
+ * The schemas live in `@ggui-ai/protocol` (not the handler package)
20
+ * for the same reason all wire-shape schemas do: the protocol package
21
+ * is the source of truth for every MCP wire surface, and consumers
22
+ * (cloud pod handlers, console UI, fixture authors) can import from
23
+ * one place. Handler package wraps these into `SharedHandler`
24
+ * factories.
25
+ */
26
+ import { z } from 'zod';
27
+ /**
28
+ * `ggui_ops_generate_blueprint` input. Operator picks the contract +
29
+ * optional generator override + variance tags. `setAsOperatorDefault`
30
+ * pins the newly-minted blueprint as the default for its
31
+ * `(appId, contractHash)` group (the store clears any prior default
32
+ * in the same group, mirroring `BlueprintStore.setOperatorDefault`).
33
+ *
34
+ * `persona` is a top-level convenience field — handlers fold it into
35
+ * the `variance.persona` slot after normalization (lowercase + trim
36
+ * + Levenshtein near-dup warning).
37
+ *
38
+ * `appId` is NOT on the input shape — the handler reads it off
39
+ * `ctx.appId` resolved by the upstream auth adapter. Cross-tenant
40
+ * authorship would be a security-boundary violation.
41
+ */
42
+ export declare const opsGenerateBlueprintInputSchema: z.ZodObject<{
43
+ contract: z.ZodType<import("../index.js").DataContract, unknown, z.core.$ZodTypeInternals<import("../index.js").DataContract, unknown>>;
44
+ generator: z.ZodOptional<z.ZodString>;
45
+ persona: z.ZodOptional<z.ZodString>;
46
+ aesthetic: z.ZodOptional<z.ZodString>;
47
+ context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<import("../index.js").JsonValue, unknown, z.core.$ZodTypeInternals<import("../index.js").JsonValue, unknown>>>>;
48
+ seedPrompt: z.ZodOptional<z.ZodString>;
49
+ setAsOperatorDefault: z.ZodOptional<z.ZodBoolean>;
50
+ }, z.core.$strict>;
51
+ /**
52
+ * `ggui_ops_generate_blueprint` output. Metadata-only — the code body
53
+ * lives in S3 (cloud) or the in-memory code map (OSS) and is fetched
54
+ * via the existing push fast-path on cache hit.
55
+ */
56
+ export declare const opsGenerateBlueprintOutputSchema: z.ZodObject<{
57
+ blueprintId: z.ZodString;
58
+ codeHash: z.ZodOptional<z.ZodString>;
59
+ validatorScore: z.ZodOptional<z.ZodNumber>;
60
+ generator: z.ZodString;
61
+ }, z.core.$strict>;
62
+ /**
63
+ * `ggui_ops_register_blueprint` input. Sibling of `*_generate_*` — no
64
+ * LLM dispatch, no generator. The operator supplies the COMPONENT
65
+ * CODE BYTES directly and the handler persists them under the same
66
+ * `(appId, contractHash)` slot. Use cases:
67
+ *
68
+ * - Seeding pre-vetted blueprints at deploy time (fixture corpus,
69
+ * migration imports).
70
+ * - Round-tripping export+reimport — operator exports a blueprint
71
+ * from one tenant and re-registers it in another.
72
+ * - Reapplying a fixed version of a blueprint after live edits
73
+ * (manual recovery from a bad generate run).
74
+ *
75
+ * Same tenancy + variance + default-pin semantics as
76
+ * `*_generate_*`; the only difference is the LLM/generator dispatch
77
+ * is replaced with a verbatim accept of the operator's
78
+ * `componentCode` string.
79
+ *
80
+ * `generator` is OPTIONAL here too — when omitted, the handler stamps
81
+ * the registry default's slug onto the persisted Blueprint so
82
+ * downstream `*_list_blueprints` consumers see a stable provenance
83
+ * field. `validatorScore` is never populated (no validator ran);
84
+ * operators wanting validator metadata should round-trip through
85
+ * `*_generate_*` instead.
86
+ */
87
+ export declare const opsRegisterBlueprintInputSchema: z.ZodObject<{
88
+ contract: z.ZodType<import("../index.js").DataContract, unknown, z.core.$ZodTypeInternals<import("../index.js").DataContract, unknown>>;
89
+ componentCode: z.ZodString;
90
+ generator: z.ZodOptional<z.ZodString>;
91
+ persona: z.ZodOptional<z.ZodString>;
92
+ aesthetic: z.ZodOptional<z.ZodString>;
93
+ context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<import("../index.js").JsonValue, unknown, z.core.$ZodTypeInternals<import("../index.js").JsonValue, unknown>>>>;
94
+ seedPrompt: z.ZodOptional<z.ZodString>;
95
+ setAsOperatorDefault: z.ZodOptional<z.ZodBoolean>;
96
+ }, z.core.$strict>;
97
+ /**
98
+ * `ggui_ops_register_blueprint` output. Same shape as
99
+ * `*_generate_*` minus `validatorScore` (no validator runs on the
100
+ * register path).
101
+ */
102
+ export declare const opsRegisterBlueprintOutputSchema: z.ZodObject<{
103
+ blueprintId: z.ZodString;
104
+ codeHash: z.ZodString;
105
+ generator: z.ZodString;
106
+ }, z.core.$strict>;
107
+ /**
108
+ * `ggui_ops_list_blueprints` input. `appId` is NOT carried on the
109
+ * wire — handlers scope from `ctx.appId`. The filters below are AND-
110
+ * composed against the matching `(appId, *)` view of the store.
111
+ *
112
+ * Behavior split:
113
+ * - When `contractHash` is the ONLY filter (no semantic keywords
114
+ * or persona), handlers dispatch through
115
+ * `BlueprintStore.list(appId, contractHash)` for the indexed
116
+ * fast path.
117
+ * - When `intentKeywords` or `persona` carry semantic intent,
118
+ * handlers dispatch through `BlueprintSearch.search()` and
119
+ * return the matching rows (sorted by score desc, then
120
+ * `createdAt desc`).
121
+ * - When no filter is supplied, handlers enumerate every blueprint
122
+ * under `appId` via the search seam (which scopes by appId
123
+ * internally), sorted `createdAt desc`.
124
+ */
125
+ export declare const opsListBlueprintsInputSchema: z.ZodObject<{
126
+ contractHash: z.ZodOptional<z.ZodString>;
127
+ generator: z.ZodOptional<z.ZodString>;
128
+ persona: z.ZodOptional<z.ZodString>;
129
+ intentKeywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
130
+ }, z.core.$strict>;
131
+ export declare const opsListBlueprintsOutputSchema: z.ZodObject<{
132
+ blueprints: z.ZodArray<z.ZodType<import("../index.js").Blueprint, unknown, z.core.$ZodTypeInternals<import("../index.js").Blueprint, unknown>>>;
133
+ }, z.core.$strict>;
134
+ /**
135
+ * `ggui_ops_update_blueprint` input. Only mutable fields are present
136
+ * here — `contractHash`, `appId`, `codeS3Url`, `codeHash`,
137
+ * `generator`, `createdAt`, `createdBy` are immutable invariants
138
+ * and the schema does NOT accept them. Operators who want to
139
+ * "replace" a row delete + re-generate.
140
+ */
141
+ export declare const opsUpdateBlueprintInputSchema: z.ZodObject<{
142
+ blueprintId: z.ZodString;
143
+ isOperatorDefault: z.ZodOptional<z.ZodLiteral<true>>;
144
+ variance: z.ZodOptional<z.ZodType<import("../index.js").BlueprintVariance, unknown, z.core.$ZodTypeInternals<import("../index.js").BlueprintVariance, unknown>>>;
145
+ }, z.core.$strict>;
146
+ export declare const opsUpdateBlueprintOutputSchema: z.ZodObject<{
147
+ blueprintId: z.ZodString;
148
+ updatedAt: z.ZodString;
149
+ }, z.core.$strict>;
150
+ /**
151
+ * `ggui_ops_delete_blueprint` input + output. Idempotent: the handler
152
+ * returns `{deleted: true}` regardless of whether the row existed,
153
+ * matching `BlueprintStore.delete`'s no-throw contract.
154
+ */
155
+ export declare const opsDeleteBlueprintInputSchema: z.ZodObject<{
156
+ blueprintId: z.ZodString;
157
+ }, z.core.$strict>;
158
+ export declare const opsDeleteBlueprintOutputSchema: z.ZodObject<{
159
+ deleted: z.ZodLiteral<true>;
160
+ }, z.core.$strict>;
161
+ /**
162
+ * Inferred TS types — exposed so handler factories and tests share
163
+ * one source of truth with the wire shape. Pre-launch posture: no
164
+ * `@deprecated` aliases — these are the canonical names.
165
+ */
166
+ export type OpsGenerateBlueprintInput = z.infer<typeof opsGenerateBlueprintInputSchema>;
167
+ export type OpsGenerateBlueprintOutput = z.infer<typeof opsGenerateBlueprintOutputSchema>;
168
+ export type OpsRegisterBlueprintInput = z.infer<typeof opsRegisterBlueprintInputSchema>;
169
+ export type OpsRegisterBlueprintOutput = z.infer<typeof opsRegisterBlueprintOutputSchema>;
170
+ export type OpsListBlueprintsInput = z.infer<typeof opsListBlueprintsInputSchema>;
171
+ export type OpsListBlueprintsOutput = z.infer<typeof opsListBlueprintsOutputSchema>;
172
+ export type OpsUpdateBlueprintInput = z.infer<typeof opsUpdateBlueprintInputSchema>;
173
+ export type OpsUpdateBlueprintOutput = z.infer<typeof opsUpdateBlueprintOutputSchema>;
174
+ export type OpsDeleteBlueprintInput = z.infer<typeof opsDeleteBlueprintInputSchema>;
175
+ export type OpsDeleteBlueprintOutput = z.infer<typeof opsDeleteBlueprintOutputSchema>;
176
+ //# sourceMappingURL=ops-blueprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops-blueprint.d.ts","sourceRoot":"","sources":["../../src/schemas/ops-blueprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;kBAyCjC,CAAC;AAEZ;;;;GAIG;AACH,eAAO,MAAM,gCAAgC;;;;;kBAsBlC,CAAC;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;kBA+CjC,CAAC;AAEZ;;;;GAIG;AACH,eAAO,MAAM,gCAAgC;;;;kBAgBlC,CAAC;AAEZ;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,4BAA4B;;;;;kBA6B9B,CAAC;AAEZ,eAAO,MAAM,6BAA6B;;kBAI/B,CAAC;AAEZ;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B;;;;kBAe/B,CAAC;AAEZ,eAAO,MAAM,8BAA8B;;;kBAKhC,CAAC;AAEZ;;;;GAIG;AACH,eAAO,MAAM,6BAA6B;;kBAI/B,CAAC;AAEZ,eAAO,MAAM,8BAA8B;;kBAIhC,CAAC;AAEZ;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,+BAA+B,CACvC,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAC9C,OAAO,gCAAgC,CACxC,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,+BAA+B,CACvC,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAC9C,OAAO,gCAAgC,CACxC,CAAC;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAC1C,OAAO,4BAA4B,CACpC,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,8BAA8B,CACtC,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,8BAA8B,CACtC,CAAC"}