nudge-ui 0.2.0 → 0.2.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 (201) hide show
  1. package/bin/nudge-ui.mjs +3 -1
  2. package/dist/cli/agentCommand.d.ts +8 -0
  3. package/dist/cli/agentCommand.js +59 -0
  4. package/dist/client.mjs +872 -12
  5. package/dist/hosts/astro/astroRuntimeConfig.js +1 -1
  6. package/dist/hosts/astro/clientTransport.js +60 -11
  7. package/dist/hosts/next/sidecar.d.ts +4 -0
  8. package/dist/hosts/next/sidecar.js +49 -6
  9. package/dist/hosts/next/wrapper.js +30 -2
  10. package/dist/hosts/projectBridge.d.ts +20 -0
  11. package/dist/hosts/projectBridge.js +97 -0
  12. package/dist/hosts/static/cli.d.ts +1 -1
  13. package/dist/hosts/static/cli.js +6 -1
  14. package/dist/hosts/static/manifest.d.ts +1 -1
  15. package/dist/hosts/static/manifest.js +1 -1
  16. package/dist/hosts/static/server.js +44 -3
  17. package/dist/hosts/vite/vite.d.ts +5 -1
  18. package/dist/hosts/vite/vite.js +78 -14
  19. package/dist/inspector/agent/McpConnectionDialog.d.ts +2 -2
  20. package/dist/inspector/agent/McpConnectionDialog.js +11 -35
  21. package/dist/inspector/agent/client.d.ts +10 -3
  22. package/dist/inspector/agent/client.js +80 -9
  23. package/dist/inspector/agent/connectionStatus.js +3 -3
  24. package/dist/inspector/agent/httpTransport.d.ts +2 -0
  25. package/dist/inspector/agent/httpTransport.js +37 -17
  26. package/dist/inspector/agent/protocol.d.ts +8 -3
  27. package/dist/inspector/agent/protocol.js +1 -1
  28. package/dist/inspector/agent/verification.d.ts +1 -1
  29. package/dist/inspector/agent/verification.js +69 -12
  30. package/dist/inspector/canvas/CanvasCard.d.ts +5 -3
  31. package/dist/inspector/canvas/CanvasCard.js +181 -91
  32. package/dist/inspector/canvas/CanvasElementOverlay.js +246 -52
  33. package/dist/inspector/canvas/CanvasToolbar.d.ts +12 -0
  34. package/dist/inspector/canvas/CanvasToolbar.js +24 -0
  35. package/dist/inspector/canvas/CanvasWorkspace.d.ts +4 -1
  36. package/dist/inspector/canvas/CanvasWorkspace.js +392 -73
  37. package/dist/inspector/canvas/activeCanvasDocument.d.ts +5 -0
  38. package/dist/inspector/canvas/activeCanvasDocument.js +23 -0
  39. package/dist/inspector/canvas/canvasResize.d.ts +30 -0
  40. package/dist/inspector/canvas/canvasResize.js +52 -0
  41. package/dist/inspector/canvas/canvasStore.d.ts +30 -6
  42. package/dist/inspector/canvas/canvasStore.js +128 -61
  43. package/dist/inspector/canvas/frameProtocol.d.ts +69 -5
  44. package/dist/inspector/canvas/frameProtocol.js +56 -2
  45. package/dist/inspector/canvas/keyboardShortcuts.d.ts +3 -0
  46. package/dist/inspector/canvas/keyboardShortcuts.js +14 -0
  47. package/dist/inspector/canvas/projection.d.ts +7 -0
  48. package/dist/inspector/canvas/projection.js +118 -25
  49. package/dist/inspector/canvas/rendererBootstrap.js +29 -29
  50. package/dist/inspector/canvas/rendererElementSelector.js +341 -30
  51. package/dist/inspector/canvas/rendererMessageRouter.d.ts +11 -0
  52. package/dist/inspector/canvas/rendererMessageRouter.js +43 -0
  53. package/dist/inspector/canvas/rendererSelectionProxy.js +6 -2
  54. package/dist/inspector/canvas/sessionStore.d.ts +1 -0
  55. package/dist/inspector/canvas/sessionStore.js +12 -4
  56. package/dist/inspector/canvas/staleChangeDetector.js +16 -14
  57. package/dist/inspector/changes/changesLog.js +31 -1
  58. package/dist/inspector/changes/managedStyleProjection.d.ts +1 -1
  59. package/dist/inspector/changes/managedStyleProjection.js +3 -3
  60. package/dist/inspector/changes/structuralTypes.d.ts +4 -0
  61. package/dist/inspector/clientManifest.d.ts +5 -0
  62. package/dist/inspector/clientManifest.js +11 -0
  63. package/dist/inspector/componentSemantics/adapterRegistry.js +4 -3
  64. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +2 -2
  65. package/dist/inspector/componentSemantics/runtimeBridge.js +16 -3
  66. package/dist/inspector/index.d.ts +2 -0
  67. package/dist/inspector/index.js +74 -24
  68. package/dist/inspector/inline-text/inlineTextDiagnostics.d.ts +10 -0
  69. package/dist/inspector/inline-text/inlineTextDiagnostics.js +65 -0
  70. package/dist/inspector/inline-text/inlineTextEditor.d.ts +3 -5
  71. package/dist/inspector/inline-text/inlineTextEditor.js +74 -206
  72. package/dist/inspector/inline-text/inlineTextFeedback.d.ts +5 -0
  73. package/dist/inspector/inline-text/inlineTextFeedback.js +27 -0
  74. package/dist/inspector/inline-text/inlineTextLifecycle.js +2 -0
  75. package/dist/inspector/inline-text/textEditChange.d.ts +14 -0
  76. package/dist/inspector/inline-text/textEditChange.js +165 -0
  77. package/dist/inspector/inspection/selectionProperty.d.ts +1 -0
  78. package/dist/inspector/inspection/selectionProperty.js +1 -0
  79. package/dist/inspector/overlay/selectedGeometry.js +21 -2
  80. package/dist/inspector/overlay/spacingGestures.d.ts +45 -0
  81. package/dist/inspector/overlay/spacingGestures.js +353 -0
  82. package/dist/inspector/overlay/structuralGestures.d.ts +2 -2
  83. package/dist/inspector/overlay/structuralGestures.js +12 -10
  84. package/dist/inspector/projection/managedStylesheet.js +4 -1
  85. package/dist/inspector/projection/renderedInstance.d.ts +2 -0
  86. package/dist/inspector/projection/renderedInstance.js +5 -1
  87. package/dist/inspector/projection/structuralProjection.d.ts +2 -0
  88. package/dist/inspector/projection/structuralProjection.js +85 -1
  89. package/dist/inspector/projection/structuralProjectionBoundary.js +17 -1
  90. package/dist/inspector/projection/textProjection.d.ts +2 -0
  91. package/dist/inspector/projection/textProjection.js +10 -4
  92. package/dist/inspector/prompt/clipboardHandoff.d.ts +1 -1
  93. package/dist/inspector/prompt/clipboardHandoff.js +3 -3
  94. package/dist/inspector/prompt/generatePrompt.d.ts +2 -1
  95. package/dist/inspector/prompt/generatePrompt.js +19 -2
  96. package/dist/inspector/runtime/editorShell.d.ts +2 -0
  97. package/dist/inspector/runtime/editorShell.js +4 -0
  98. package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
  99. package/dist/inspector/runtime/runtimeConfig.js +4 -0
  100. package/dist/inspector/selection/selectionStore.js +2 -0
  101. package/dist/inspector/settings/SettingsDialog.js +10 -0
  102. package/dist/inspector/shell/AppShell.js +5 -1
  103. package/dist/inspector/shell/ChangesLog.js +8 -4
  104. package/dist/inspector/shell/CopyPromptButton.js +95 -19
  105. package/dist/inspector/shell/EmptyState.js +1 -1
  106. package/dist/inspector/shell/InspectorShell.d.ts +0 -1
  107. package/dist/inspector/shell/InspectorShell.js +37 -38
  108. package/dist/inspector/shell/PeekOriginalButton.d.ts +7 -0
  109. package/dist/inspector/shell/PeekOriginalButton.js +57 -0
  110. package/dist/inspector/shell/PeekOriginalIcon.d.ts +7 -0
  111. package/dist/inspector/shell/PeekOriginalIcon.js +9 -0
  112. package/dist/inspector/shell/originalPreview.d.ts +9 -0
  113. package/dist/inspector/shell/originalPreview.js +61 -0
  114. package/dist/inspector/shell/shortcuts.d.ts +3 -0
  115. package/dist/inspector/shell/shortcuts.js +15 -0
  116. package/dist/inspector/sketch/SketchChanges.d.ts +2 -0
  117. package/dist/inspector/sketch/SketchChanges.js +72 -0
  118. package/dist/inspector/sketch/SketchEditor.d.ts +21 -0
  119. package/dist/inspector/sketch/SketchEditor.js +402 -0
  120. package/dist/inspector/sketch/SketchEntryButton.d.ts +4 -0
  121. package/dist/inspector/sketch/SketchEntryButton.js +11 -0
  122. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +11 -0
  123. package/dist/inspector/sketch/SketchFrameOverlay.js +119 -0
  124. package/dist/inspector/sketch/SketchLayersPanel.d.ts +2 -0
  125. package/dist/inspector/sketch/SketchLayersPanel.js +63 -0
  126. package/dist/inspector/sketch/SketchOverlay.d.ts +19 -0
  127. package/dist/inspector/sketch/SketchOverlay.js +420 -0
  128. package/dist/inspector/sketch/SketchPromptPanel.d.ts +15 -0
  129. package/dist/inspector/sketch/SketchPromptPanel.js +18 -0
  130. package/dist/inspector/sketch/SketchWorkspace.d.ts +13 -0
  131. package/dist/inspector/sketch/SketchWorkspace.js +152 -0
  132. package/dist/inspector/sketch/capture.d.ts +55 -0
  133. package/dist/inspector/sketch/capture.js +350 -0
  134. package/dist/inspector/sketch/freehand.d.ts +13 -0
  135. package/dist/inspector/sketch/freehand.js +64 -0
  136. package/dist/inspector/sketch/geometry.d.ts +17 -0
  137. package/dist/inspector/sketch/geometry.js +98 -0
  138. package/dist/inspector/sketch/handoff.d.ts +21 -0
  139. package/dist/inspector/sketch/handoff.js +72 -0
  140. package/dist/inspector/sketch/interaction.d.ts +21 -0
  141. package/dist/inspector/sketch/interaction.js +98 -0
  142. package/dist/inspector/sketch/model.d.ts +104 -0
  143. package/dist/inspector/sketch/model.js +282 -0
  144. package/dist/inspector/sketch/persistence.d.ts +21 -0
  145. package/dist/inspector/sketch/persistence.js +205 -0
  146. package/dist/inspector/sketch/raster.d.ts +22 -0
  147. package/dist/inspector/sketch/raster.js +203 -0
  148. package/dist/inspector/sketch/sketchNote.d.ts +10 -0
  149. package/dist/inspector/sketch/sketchNote.js +30 -0
  150. package/dist/inspector/sketch/store.d.ts +47 -0
  151. package/dist/inspector/sketch/store.js +409 -0
  152. package/dist/inspector/styleEditors/BorderEditor.js +15 -19
  153. package/dist/inspector/styleEditors/BorderRadiusEditor.js +6 -6
  154. package/dist/inspector/styleEditors/BoxShadowEditor.js +12 -1
  155. package/dist/inspector/styleEditors/ColorPicker.js +11 -36
  156. package/dist/inspector/styleEditors/GapField.d.ts +3 -2
  157. package/dist/inspector/styleEditors/GapField.js +2 -2
  158. package/dist/inspector/styleEditors/GridSection.js +1 -1
  159. package/dist/inspector/styleEditors/LayoutSection.js +11 -8
  160. package/dist/inspector/styleEditors/SpacingBox.js +23 -30
  161. package/dist/inspector/styleEditors/layoutPreviewState.d.ts +5 -0
  162. package/dist/inspector/styleEditors/layoutPreviewState.js +19 -0
  163. package/dist/inspector/styleEditors/layoutValue.js +3 -0
  164. package/dist/inspector/styleEditors/nudgeValue.d.ts +11 -0
  165. package/dist/inspector/styleEditors/nudgeValue.js +91 -5
  166. package/dist/inspector/styleEditors/stylePresence.d.ts +7 -0
  167. package/dist/inspector/styleEditors/stylePresence.js +22 -0
  168. package/dist/inspector/styleEditors/textRelevance.d.ts +3 -0
  169. package/dist/inspector/styleEditors/textRelevance.js +35 -0
  170. package/dist/inspector/styleEditors/useFieldVisibility.d.ts +6 -0
  171. package/dist/inspector/styleEditors/useFieldVisibility.js +26 -0
  172. package/dist/inspector/tokens/TokenField.js +111 -7
  173. package/dist/inspector/tokens/editActions.d.ts +2 -0
  174. package/dist/inspector/tokens/editActions.js +2 -2
  175. package/dist/inspector/tokens/resolution/cssomCollector.d.ts +1 -1
  176. package/dist/inspector/tokens/resolution/cssomCollector.js +9 -5
  177. package/dist/inspector/tokens/resolution/ruleMatching.d.ts +40 -0
  178. package/dist/inspector/tokens/resolution/ruleMatching.js +423 -0
  179. package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +19 -3
  180. package/dist/inspector/tokens/resolution/selectorSemantics.js +378 -4
  181. package/dist/inspector/tokens/resolution.d.ts +3 -26
  182. package/dist/inspector/tokens/resolution.js +44 -735
  183. package/dist/inspector/tokens/tokenAvailability.d.ts +18 -0
  184. package/dist/inspector/tokens/tokenAvailability.js +204 -0
  185. package/dist/inspector/ui/Button.d.ts +1 -1
  186. package/dist/inspector/ui/SideValuesField.js +2 -2
  187. package/dist/inspector/ui/StatusCallout.d.ts +4 -1
  188. package/dist/inspector/ui/StatusCallout.js +2 -2
  189. package/dist/inspector/ui/styles.js +13 -11
  190. package/dist/internal/agent-protocol.d.ts +65 -1
  191. package/dist/internal/agent-protocol.js +183 -3
  192. package/dist/nudge-ui.mjs +261 -57
  193. package/dist/transport/editor.d.ts +28 -0
  194. package/dist/transport/editor.js +132 -0
  195. package/dist/transport/index.d.ts +1 -0
  196. package/dist/transport/index.js +1 -0
  197. package/dist/transport/routes.d.ts +7 -0
  198. package/dist/transport/routes.js +7 -0
  199. package/package.json +3 -1
  200. package/dist/inspector/shell/panelLayout.d.ts +0 -2
  201. package/dist/inspector/shell/panelLayout.js +0 -29
@@ -6,7 +6,7 @@
6
6
  * imports. Hosts can use the same validation and message shapes without
7
7
  * pulling the companion into a browser bundle.
8
8
  */
9
- export declare const AGENT_PROTOCOL_VERSION: 1;
9
+ export declare const AGENT_PROTOCOL_VERSION: 2;
10
10
  export declare const AGENT_PROTOCOL_LIMITS: {
11
11
  readonly projectId: 256;
12
12
  readonly workspaceRoot: 4096;
@@ -14,7 +14,21 @@ export declare const AGENT_PROTOCOL_LIMITS: {
14
14
  readonly sessionToken: 256;
15
15
  readonly requestId: 256;
16
16
  readonly commandId: 256;
17
+ readonly clientDispatchId: 256;
17
18
  readonly prompt: 32000;
19
+ readonly sketchId: 256;
20
+ readonly sketchRevision: 2147483647;
21
+ readonly sketchFilename: 256;
22
+ readonly sketchDescription: 2000;
23
+ readonly sketchCount: 4;
24
+ readonly sketchImageBytes: number;
25
+ readonly sketchTotalBytes: number;
26
+ readonly sketchEncodedBytes: number;
27
+ readonly sketchAnnotationCount: 50;
28
+ readonly sketchUrl: 2048;
29
+ readonly sketchTitle: 512;
30
+ readonly sketchFramework: 128;
31
+ readonly sketchHost: 128;
18
32
  readonly groupId: 256;
19
33
  readonly label: 160;
20
34
  readonly routeUrl: 2048;
@@ -108,6 +122,47 @@ export interface AgentPromptRequest {
108
122
  readonly prompt: string;
109
123
  /** The browser's canonical change revision captured at dispatch time. */
110
124
  readonly changeRevision?: number;
125
+ /** Correlates the durable browser handoff batch across a lost response. */
126
+ readonly clientDispatchId?: string;
127
+ /** Metadata for the exact sketch revisions included in this request. */
128
+ readonly sketches?: readonly AgentSketchMetadata[];
129
+ }
130
+ export interface AgentSketchCaptureMetadata {
131
+ readonly url: string;
132
+ readonly title: string;
133
+ readonly timestamp: number;
134
+ readonly viewportWidth: number;
135
+ readonly viewportHeight: number;
136
+ readonly scrollX: number;
137
+ readonly scrollY: number;
138
+ readonly devicePixelRatio: number;
139
+ readonly host: string;
140
+ readonly framework: string;
141
+ }
142
+ export interface AgentSketchAnnotation {
143
+ readonly number: number;
144
+ readonly description: string;
145
+ }
146
+ /** Metadata retained in statuses and acknowledgements without image bytes. */
147
+ export interface AgentSketchMetadata {
148
+ readonly id: string;
149
+ readonly revision: number;
150
+ readonly filename: string;
151
+ readonly mimeType: "image/png";
152
+ readonly width: number;
153
+ readonly height: number;
154
+ readonly byteSize: number;
155
+ readonly capture: AgentSketchCaptureMetadata;
156
+ readonly description?: string;
157
+ readonly annotations?: readonly AgentSketchAnnotation[];
158
+ }
159
+ /** The only protocol shape that carries screenshot bytes. */
160
+ export interface AgentSketchAttachment extends AgentSketchMetadata {
161
+ readonly data: string;
162
+ }
163
+ /** Internal companion delivery shape; attachment bytes are never status data. */
164
+ export interface AgentDeliveredPrompt extends AgentPromptRequest {
165
+ readonly attachments?: readonly AgentSketchAttachment[];
111
166
  }
112
167
  export type AgentRequestStatus = "working" | "completed" | "failed" | "interrupted";
113
168
  export interface AgentRequestOutcome {
@@ -166,6 +221,8 @@ export interface CanvasCommandAcknowledgement {
166
221
  export interface PairingRequest {
167
222
  readonly projectId: string;
168
223
  readonly origin: string;
224
+ /** Reuses an existing pairing across a same-browser reload. */
225
+ readonly sessionToken?: string;
169
226
  /** The active page is retained only while this process is alive. */
170
227
  readonly pageUrl?: string;
171
228
  }
@@ -182,6 +239,8 @@ export interface PromptDispatchRequest {
182
239
  readonly sessionToken: string;
183
240
  readonly prompt: string;
184
241
  readonly changeRevision?: number;
242
+ readonly clientDispatchId?: string;
243
+ readonly attachments?: readonly AgentSketchAttachment[];
185
244
  }
186
245
  export interface PromptDispatchResponse {
187
246
  readonly request: AgentPromptRequest;
@@ -223,6 +282,11 @@ export declare function validateRoutes(value: unknown, origin: string): AgentRou
223
282
  /** Validates the fields shared by every companion message. */
224
283
  export declare function isProtocolVersion(value: unknown): value is AgentProtocolVersion;
225
284
  export declare function isProjectIdentity(value: unknown): value is AgentProjectIdentity;
285
+ export declare function isAgentSketchCaptureMetadata(value: unknown): value is AgentSketchCaptureMetadata;
286
+ export declare function isAgentSketchAnnotation(value: unknown): value is AgentSketchAnnotation;
287
+ export declare function isAgentSketchMetadata(value: unknown): value is AgentSketchMetadata;
288
+ export declare function isAgentSketchAttachment(value: unknown): value is AgentSketchAttachment;
289
+ export declare function validateSketchAttachments(value: unknown): AgentSketchAttachment[];
226
290
  export declare function isAgentPromptRequest(value: unknown): value is AgentPromptRequest;
227
291
  export declare function isAgentStatusUpdate(value: unknown): value is AgentStatusUpdate;
228
292
  export declare function isCanvasState(value: unknown): value is CanvasState;
@@ -6,7 +6,7 @@
6
6
  * imports. Hosts can use the same validation and message shapes without
7
7
  * pulling the companion into a browser bundle.
8
8
  */
9
- export const AGENT_PROTOCOL_VERSION = 1;
9
+ export const AGENT_PROTOCOL_VERSION = 2;
10
10
  export const AGENT_PROTOCOL_LIMITS = {
11
11
  projectId: 256,
12
12
  workspaceRoot: 4096,
@@ -14,7 +14,21 @@ export const AGENT_PROTOCOL_LIMITS = {
14
14
  sessionToken: 256,
15
15
  requestId: 256,
16
16
  commandId: 256,
17
+ clientDispatchId: 256,
17
18
  prompt: 32_000,
19
+ sketchId: 256,
20
+ sketchRevision: 2_147_483_647,
21
+ sketchFilename: 256,
22
+ sketchDescription: 2_000,
23
+ sketchCount: 4,
24
+ sketchImageBytes: 2 * 1024 * 1024,
25
+ sketchTotalBytes: 8 * 1024 * 1024,
26
+ sketchEncodedBytes: 12 * 1024 * 1024,
27
+ sketchAnnotationCount: 50,
28
+ sketchUrl: 2_048,
29
+ sketchTitle: 512,
30
+ sketchFramework: 128,
31
+ sketchHost: 128,
18
32
  groupId: 256,
19
33
  label: 160,
20
34
  routeUrl: 2048,
@@ -64,6 +78,25 @@ function optionalString(value, maximum) {
64
78
  function optionalRevision(value) {
65
79
  return value === undefined || (typeof value === "number" && Number.isSafeInteger(value) && value >= 0);
66
80
  }
81
+ function boundedNumber(value, maximum) {
82
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= maximum;
83
+ }
84
+ function boundedFiniteNumber(value, maximum) {
85
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= maximum;
86
+ }
87
+ function boundedString(value, maximum) {
88
+ return typeof value === "string" && value.length <= maximum;
89
+ }
90
+ function validBase64(value, maximum) {
91
+ return typeof value === "string"
92
+ && value.length > 0
93
+ && value.length <= maximum
94
+ && /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value);
95
+ }
96
+ function encodedByteLength(value) {
97
+ const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
98
+ return Math.max(0, Math.floor(value.length * 3 / 4) - padding);
99
+ }
67
100
  /**
68
101
  * Returns a canonical origin or null. Credentials, paths, and fragments are
69
102
  * rejected so the browser cannot broaden the pairing boundary accidentally.
@@ -157,13 +190,160 @@ export function isProjectIdentity(value) {
157
190
  && (value.origin === undefined || isCanonicalOrigin(value.origin))
158
191
  && optionalString(value.workspaceRoot, AGENT_PROTOCOL_LIMITS.workspaceRoot);
159
192
  }
193
+ export function isAgentSketchCaptureMetadata(value) {
194
+ if (!isRecord(value) || !hasOnlyKeys(value, [
195
+ "url",
196
+ "title",
197
+ "timestamp",
198
+ "viewportWidth",
199
+ "viewportHeight",
200
+ "scrollX",
201
+ "scrollY",
202
+ "devicePixelRatio",
203
+ "host",
204
+ "framework",
205
+ ]))
206
+ return false;
207
+ if (!nonEmptyString(value.url, AGENT_PROTOCOL_LIMITS.sketchUrl)
208
+ || !boundedString(value.title, AGENT_PROTOCOL_LIMITS.sketchTitle)
209
+ || !boundedNumber(value.timestamp, Number.MAX_SAFE_INTEGER)
210
+ || !boundedNumber(value.viewportWidth, 100_000)
211
+ || !boundedNumber(value.viewportHeight, 100_000)
212
+ || !boundedFiniteNumber(value.scrollX, Number.MAX_SAFE_INTEGER)
213
+ || !boundedFiniteNumber(value.scrollY, Number.MAX_SAFE_INTEGER)
214
+ || !boundedFiniteNumber(value.devicePixelRatio, 100)
215
+ || value.devicePixelRatio <= 0
216
+ || !nonEmptyString(value.host, AGENT_PROTOCOL_LIMITS.sketchHost)
217
+ || !nonEmptyString(value.framework, AGENT_PROTOCOL_LIMITS.sketchFramework)) {
218
+ return false;
219
+ }
220
+ try {
221
+ const url = new URL(value.url);
222
+ if (url.protocol !== "http:" && url.protocol !== "https:")
223
+ return false;
224
+ }
225
+ catch {
226
+ return false;
227
+ }
228
+ return true;
229
+ }
230
+ export function isAgentSketchAnnotation(value) {
231
+ if (!isRecord(value) || !hasOnlyKeys(value, ["number", "description"]))
232
+ return false;
233
+ return boundedNumber(value.number, AGENT_PROTOCOL_LIMITS.sketchAnnotationCount)
234
+ && value.number >= 1
235
+ && nonEmptyString(value.description, AGENT_PROTOCOL_LIMITS.sketchDescription);
236
+ }
237
+ function validSketchAnnotationList(value) {
238
+ if (!Array.isArray(value)
239
+ || value.length > AGENT_PROTOCOL_LIMITS.sketchAnnotationCount
240
+ || !value.every(isAgentSketchAnnotation))
241
+ return false;
242
+ return new Set(value.map((annotation) => annotation.number)).size === value.length;
243
+ }
244
+ export function isAgentSketchMetadata(value) {
245
+ if (!isRecord(value) || !hasOnlyKeys(value, [
246
+ "id",
247
+ "revision",
248
+ "filename",
249
+ "mimeType",
250
+ "width",
251
+ "height",
252
+ "byteSize",
253
+ "capture",
254
+ "description",
255
+ "annotations",
256
+ ]))
257
+ return false;
258
+ return nonEmptyString(value.id, AGENT_PROTOCOL_LIMITS.sketchId)
259
+ && boundedNumber(value.revision, AGENT_PROTOCOL_LIMITS.sketchRevision)
260
+ && value.revision > 0
261
+ && nonEmptyString(value.filename, AGENT_PROTOCOL_LIMITS.sketchFilename)
262
+ && value.mimeType === "image/png"
263
+ && boundedNumber(value.width, 2_048)
264
+ && value.width > 0
265
+ && boundedNumber(value.height, 2_048)
266
+ && value.height > 0
267
+ && boundedNumber(value.byteSize, AGENT_PROTOCOL_LIMITS.sketchImageBytes)
268
+ && value.byteSize > 0
269
+ && isAgentSketchCaptureMetadata(value.capture)
270
+ && (value.description === undefined
271
+ || boundedString(value.description, AGENT_PROTOCOL_LIMITS.sketchDescription))
272
+ && (value.annotations === undefined || validSketchAnnotationList(value.annotations));
273
+ }
274
+ export function isAgentSketchAttachment(value) {
275
+ if (!isRecord(value) || !hasOnlyKeys(value, [
276
+ "id",
277
+ "revision",
278
+ "filename",
279
+ "mimeType",
280
+ "width",
281
+ "height",
282
+ "byteSize",
283
+ "capture",
284
+ "description",
285
+ "annotations",
286
+ "data",
287
+ ]) || !isAgentSketchMetadata({
288
+ id: value.id,
289
+ revision: value.revision,
290
+ filename: value.filename,
291
+ mimeType: value.mimeType,
292
+ width: value.width,
293
+ height: value.height,
294
+ byteSize: value.byteSize,
295
+ capture: value.capture,
296
+ ...(value.description === undefined ? {} : { description: value.description }),
297
+ ...(value.annotations === undefined ? {} : { annotations: value.annotations }),
298
+ }))
299
+ return false;
300
+ return validBase64(value.data, AGENT_PROTOCOL_LIMITS.sketchEncodedBytes)
301
+ && encodedByteLength(value.data) === value.byteSize;
302
+ }
303
+ export function validateSketchAttachments(value) {
304
+ if (value === undefined)
305
+ return [];
306
+ if (!Array.isArray(value) || value.length > AGENT_PROTOCOL_LIMITS.sketchCount) {
307
+ throw new TypeError(`attachments must contain at most ${AGENT_PROTOCOL_LIMITS.sketchCount} items`);
308
+ }
309
+ const attachments = value.map((candidate, index) => {
310
+ if (!isAgentSketchAttachment(candidate)) {
311
+ throw new TypeError(`attachments[${index}] is not a valid PNG attachment`);
312
+ }
313
+ return { ...candidate, capture: { ...candidate.capture } };
314
+ });
315
+ if (new Set(attachments.map((attachment) => `${attachment.id}\u0000${attachment.revision}`)).size
316
+ !== attachments.length) {
317
+ throw new TypeError("attachments must not contain duplicate sketch revisions");
318
+ }
319
+ const totalBytes = attachments.reduce((total, attachment) => total + attachment.byteSize, 0);
320
+ if (totalBytes > AGENT_PROTOCOL_LIMITS.sketchTotalBytes) {
321
+ throw new TypeError(`attachments must contain at most ${AGENT_PROTOCOL_LIMITS.sketchTotalBytes} decoded bytes`);
322
+ }
323
+ return attachments;
324
+ }
325
+ function validSketchMetadataList(value) {
326
+ if (!Array.isArray(value) || value.length > AGENT_PROTOCOL_LIMITS.sketchCount
327
+ || !value.every(isAgentSketchMetadata))
328
+ return false;
329
+ return new Set(value.map((sketch) => `${sketch.id}\u0000${sketch.revision}`)).size === value.length;
330
+ }
160
331
  export function isAgentPromptRequest(value) {
161
- if (!isRecord(value) || !hasOnlyKeys(value, ["requestId", "projectId", "prompt", "changeRevision"]))
332
+ if (!isRecord(value) || !hasOnlyKeys(value, [
333
+ "requestId",
334
+ "projectId",
335
+ "prompt",
336
+ "changeRevision",
337
+ "clientDispatchId",
338
+ "sketches",
339
+ ]))
162
340
  return false;
163
341
  return nonEmptyString(value.requestId, AGENT_PROTOCOL_LIMITS.requestId)
164
342
  && nonEmptyString(value.projectId, AGENT_PROTOCOL_LIMITS.projectId)
165
343
  && nonEmptyString(value.prompt, AGENT_PROTOCOL_LIMITS.prompt)
166
- && optionalRevision(value.changeRevision);
344
+ && optionalRevision(value.changeRevision)
345
+ && (value.clientDispatchId === undefined || nonEmptyString(value.clientDispatchId, AGENT_PROTOCOL_LIMITS.clientDispatchId))
346
+ && (value.sketches === undefined || validSketchMetadataList(value.sketches));
167
347
  }
168
348
  export function isAgentStatusUpdate(value) {
169
349
  if (!isRecord(value) || !hasOnlyKeys(value, ["requestId", "status", "summary", "error"]))