@kubb/studio 5.2.5 → 5.2.6

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.
@@ -1,2 +1,584 @@
1
- import { A as commandTypes, C as StudioConnectMessage, D as StudioPingMessage, E as StudioGenerateMessage, F as isStudioReadyMessage, M as isDataMessage, N as isDisconnectMessage, O as StudioReadyMessage, P as isStudioPingMessage, S as PluginView, T as StudioErrorMessage, _ as DataMessagePayload, a as AgentPermissions, b as KubbHooks, c as ClientInfo, d as ConfigEditOutcome, f as ConfigFileView, g as DataMessage, h as ConnectMessagePayload, i as AgentMessage, j as isCommandMessage, k as StudioSaveMessage, l as CommandMessage, m as ConfigView, n as AgentConnectResponse, o as AgentPingMessage, p as ConfigRef, r as AgentDisconnectMessage, s as AgentSaveMessage, t as AgentConnectMessage, u as ConfigEdit, v as JSONKubbConfig, w as StudioDisconnectMessage, x as OptionValue, y as KubbHook } from "./index-Dq2uq38g.js";
2
- export { AgentConnectMessage, AgentConnectResponse, AgentDisconnectMessage, AgentMessage, AgentPermissions, AgentPingMessage, AgentSaveMessage, ClientInfo, CommandMessage, ConfigEdit, ConfigEditOutcome, ConfigFileView, ConfigRef, ConfigView, ConnectMessagePayload, DataMessage, DataMessagePayload, JSONKubbConfig, KubbHook, KubbHooks, OptionValue, PluginView, StudioConnectMessage, StudioDisconnectMessage, StudioErrorMessage, StudioGenerateMessage, StudioPingMessage, StudioReadyMessage, StudioSaveMessage, commandTypes, isCommandMessage, isDataMessage, isDisconnectMessage, isStudioPingMessage, isStudioReadyMessage };
1
+ import { t as __name } from "./rolldown-runtime-CRm0XQPb.js";
2
+ import { Config } from "@kubb/core";
3
+ //#region src/protocol/index.d.ts
4
+ /**
5
+ * JSON-serializable Kubb config exchanged over the WebSocket. A live `kubb/kit` config holds
6
+ * functions and class instances that cannot survive JSON, so both sides pass this flattened shape
7
+ * and rebuild the real config from it.
8
+ */
9
+ export type JSONKubbConfig = {
10
+ /**
11
+ * Plugins with their serialized options. `name` is the package name (e.g. `@kubb/plugin-ts`)
12
+ * and `options` is an opaque blob the agent forwards unchanged to the plugin factory. An entry
13
+ * with `disabled: true` is dropped even when the disk config's `plugins` array still lists it.
14
+ */
15
+ plugins?: Array<{
16
+ name: string;
17
+ options?: object;
18
+ disabled?: boolean;
19
+ }>;
20
+ /**
21
+ * Raw OpenAPI / Swagger spec content (YAML or JSON string).
22
+ * Always honored for a 'sandbox' agent. For a non-sandbox agent it is honored only when the
23
+ * agent opts in with `KUBB_AGENT_ALLOW_INPUT`; otherwise the spec is read from disk and this is ignored.
24
+ */
25
+ input?: string;
26
+ /**
27
+ * Adapter option overrides sent from Studio UI. Merged into the disk config's adapter options
28
+ * and re-applied through the same adapter factory, since an adapter instance's functions
29
+ * (`parse`, `getImports`, ...) can't survive JSON serialization over the WebSocket.
30
+ */
31
+ adapter?: object;
32
+ };
33
+ /**
34
+ * Which `defineConfig(...)` entry an edit targets, for a config file that exports an array.
35
+ *
36
+ * A number selects by position, a string matches the entry's `name`. Omitted targets the only
37
+ * entry, or the first one when the file exports an array.
38
+ */
39
+ export type ConfigRef = string | number;
40
+ /**
41
+ * A value the agent can read out of a plugin option in `kubb.config.ts` and round-trip through JSON.
42
+ */
43
+ export type OptionValue = string | number | boolean | null | Array<OptionValue> | {
44
+ [key: string]: OptionValue;
45
+ };
46
+ /**
47
+ * One change to a plugin's options in the user's `kubb.config.ts`.
48
+ *
49
+ * `plugin` is the package name (`@kubb/plugin-ts`), the same identity used in {@link JSONKubbConfig}.
50
+ * The agent applies these to the file with an AST patch, so only the targeted values are rewritten.
51
+ *
52
+ * Declared here rather than in `configFile.ts` because this is the wire contract, and the patcher
53
+ * imports it from here. Type-only, so nothing pulls `magicast` into this entry point.
54
+ */
55
+ export type ConfigEdit =
56
+ /**
57
+ * Write a literal option value. `path` walks nested objects, so `['enum', 'type']` targets
58
+ * `pluginTs({ enum: { type } })`.
59
+ */
60
+ {
61
+ operation: 'set';
62
+ config?: ConfigRef;
63
+ plugin: string;
64
+ path: Array<string>;
65
+ value: unknown;
66
+ } |
67
+ /**
68
+ * Drop an option so the plugin falls back to its default.
69
+ */
70
+ {
71
+ operation: 'remove';
72
+ config?: ConfigRef;
73
+ plugin: string;
74
+ path: Array<string>;
75
+ } |
76
+ /**
77
+ * Add a plugin factory call and its import to the `plugins` array.
78
+ */
79
+ {
80
+ operation: 'add-plugin';
81
+ config?: ConfigRef;
82
+ plugin: string;
83
+ importName?: string;
84
+ options?: Record<string, unknown>;
85
+ } |
86
+ /**
87
+ * Comment the plugin call out, keeping its options in the file so enabling it again restores them.
88
+ */
89
+ {
90
+ operation: 'disable-plugin';
91
+ config?: ConfigRef;
92
+ plugin: string;
93
+ } |
94
+ /**
95
+ * Uncomment a plugin call a previous `disable-plugin` commented out.
96
+ */
97
+ {
98
+ operation: 'enable-plugin';
99
+ config?: ConfigRef;
100
+ plugin: string;
101
+ };
102
+ /**
103
+ * A plugin factory call the agent found in the `plugins` array of a `defineConfig(...)`.
104
+ */
105
+ export type PluginView = {
106
+ /**
107
+ * Local identifier of the factory in the file, e.g. `pluginTs`. This is the alias when the plugin
108
+ * was imported under one.
109
+ */
110
+ importName: string;
111
+ /**
112
+ * Module the factory is imported from, e.g. `@kubb/plugin-ts`.
113
+ */
114
+ packageName: string;
115
+ /**
116
+ * Top-level option keys, each flagged with whether the agent may write it and, when it can, the
117
+ * value found in the file. An option marked `literal: false` holds a function or a reference the
118
+ * agent will not overwrite, so Studio shows the control disabled rather than hiding it, and
119
+ * `value` is absent since there is nothing safe to display as the current value.
120
+ */
121
+ options: Record<string, {
122
+ literal: boolean;
123
+ value?: OptionValue;
124
+ }>;
125
+ /**
126
+ * Set when the plugin call is commented out in the file. Its options stay on disk but are not
127
+ * readable, so `options` is empty until it is enabled again.
128
+ */
129
+ disabled?: true;
130
+ };
131
+ /**
132
+ * One `defineConfig(...)` entry. A config file that exports a single object has exactly one.
133
+ */
134
+ export type ConfigView = {
135
+ /**
136
+ * The entry's `name`, when it sets one. Studio labels the config picker with it.
137
+ */
138
+ name?: string;
139
+ /**
140
+ * Each plugin call in the entry, with its top-level option keys.
141
+ */
142
+ plugins: Array<PluginView>;
143
+ };
144
+ /**
145
+ * What the agent found in the user's config file, so Studio knows which controls it may offer.
146
+ * Absent when the agent could not read the file at all.
147
+ */
148
+ export type ConfigFileView = {
149
+ managed: true;
150
+ /**
151
+ * One entry per config the file exports, in source order. Every {@link ConfigEdit} names
152
+ * which of these it targets through its `config` field.
153
+ */
154
+ configs: Array<ConfigView>;
155
+ } | {
156
+ managed: false;
157
+ /**
158
+ * Why the file is outside what the agent edits, for example a default export that is not a
159
+ * `defineConfig(...)` call. Studio shows this and offers no property-level controls.
160
+ */
161
+ reason: string;
162
+ };
163
+ /**
164
+ * Outcome of a single {@link ConfigEdit}, returned in a {@link ConfigSavedMessage}.
165
+ */
166
+ export type ConfigEditOutcome = {
167
+ edit: ConfigEdit;
168
+ applied: boolean;
169
+ /**
170
+ * Why the edit was refused, absent when it was applied.
171
+ */
172
+ reason?: string;
173
+ };
174
+ /**
175
+ * Typed events sent by the Kubb agent to Studio over WebSocket.
176
+ * Mirrors the single-context-object tuple style of {@link KubbHooks} in `kubb/kit`,
177
+ * using JSON-serializable shapes (e.g. `sources` as a `Record` instead of `Map`,
178
+ * `error` as `{ message; stack? }` instead of `Error`).
179
+ */
180
+ export type KubbHooks = {
181
+ 'kubb:plugin:start': [ctx: {
182
+ plugin: {
183
+ name: string;
184
+ };
185
+ }];
186
+ 'kubb:plugin:end': [ctx: {
187
+ plugin: {
188
+ name: string;
189
+ };
190
+ duration: number;
191
+ success: boolean;
192
+ }];
193
+ 'kubb:build:start': [ctx: {
194
+ config: {
195
+ name?: string;
196
+ };
197
+ adapter: {
198
+ name: string;
199
+ };
200
+ }];
201
+ 'kubb:build:end': [ctx: {
202
+ files: Array<{
203
+ path: string;
204
+ name: string;
205
+ }>;
206
+ outputDir: string;
207
+ }];
208
+ 'kubb:files:processing:start': [ctx: {
209
+ total: number;
210
+ }];
211
+ 'kubb:files:processing:update': [ctx: {
212
+ files: Array<{
213
+ file: string;
214
+ processed: number;
215
+ total: number;
216
+ percentage: number;
217
+ }>;
218
+ }];
219
+ 'kubb:files:processing:end': [ctx: {
220
+ total: number;
221
+ }];
222
+ 'kubb:info': [ctx: {
223
+ message: string;
224
+ info?: string;
225
+ }];
226
+ 'kubb:success': [ctx: {
227
+ message: string;
228
+ info?: string;
229
+ }];
230
+ 'kubb:warn': [ctx: {
231
+ message: string;
232
+ info?: string;
233
+ }];
234
+ 'kubb:error': [ctx: {
235
+ message: string;
236
+ stack?: string;
237
+ }];
238
+ 'kubb:debug': [ctx: {
239
+ logs: Array<string>;
240
+ fileName?: string;
241
+ }];
242
+ 'kubb:generation:start': [ctx: {
243
+ name?: string;
244
+ plugins: number;
245
+ }];
246
+ 'kubb:generation:end': [ctx: {
247
+ config: Config;
248
+ storage: Record<string, string>;
249
+ peerDependencies: Record<string, string>;
250
+ missingDependencies: Array<string>;
251
+ }];
252
+ 'kubb:generation:summary': [ctx: {
253
+ duration: number;
254
+ fileCount: number;
255
+ failedPlugins: number;
256
+ status: 'success' | 'failed';
257
+ }];
258
+ 'kubb:lifecycle:start': [];
259
+ 'kubb:lifecycle:end': [];
260
+ 'kubb:format:start': [];
261
+ 'kubb:format:end': [];
262
+ 'kubb:lint:start': [];
263
+ 'kubb:lint:end': [];
264
+ 'kubb:hooks:start': [];
265
+ 'kubb:hooks:end': [];
266
+ 'kubb:hook:start': [ctx: {
267
+ id?: string;
268
+ command: string;
269
+ args?: Array<string>;
270
+ }];
271
+ 'kubb:hook:line': [ctx: {
272
+ id: string;
273
+ line: string;
274
+ }];
275
+ 'kubb:hook:end': [ctx: {
276
+ id?: string;
277
+ command: string;
278
+ args?: Array<string>;
279
+ success: boolean;
280
+ error?: {
281
+ message: string;
282
+ stack?: string;
283
+ };
284
+ }];
285
+ };
286
+ export type KubbHook = keyof KubbHooks;
287
+ /**
288
+ * Run a generation with the given config. `payload` is the merged config Studio wants generated.
289
+ */
290
+ export type StudioGenerateMessage = {
291
+ type: 'studio:generate';
292
+ jobId: string;
293
+ payload: JSONKubbConfig;
294
+ };
295
+ /**
296
+ * Ask the agent to send a fresh `agent:connect` payload. Permissions are fixed when the host starts
297
+ * the agent; this message only triggers another read of disk config and saved Studio state.
298
+ */
299
+ export type StudioConnectMessage = {
300
+ type: 'studio:connect';
301
+ jobId?: string;
302
+ /**
303
+ * Version of the Studio instance asking, which refreshes what the agent picked up when the
304
+ * session was created. Absent when Studio predates the field.
305
+ */
306
+ version?: string;
307
+ };
308
+ /**
309
+ * Change plugin options in the user's `kubb.config.ts`. Applied only when the agent was granted
310
+ * `allowConfigEdit`; otherwise every edit comes back refused.
311
+ */
312
+ export type StudioSaveMessage = {
313
+ type: 'studio:save';
314
+ jobId: string;
315
+ edits: Array<ConfigEdit>;
316
+ };
317
+ /**
318
+ * Anything Studio asks the agent to do. Each command is its own `type`, so a handler switches once
319
+ * instead of reading a `type` and then a nested `command` field.
320
+ */
321
+ export type CommandMessage = StudioGenerateMessage | StudioConnectMessage | StudioSaveMessage;
322
+ /**
323
+ * The command names, for a host that needs the list rather than the union.
324
+ */
325
+ export declare const commandTypes: readonly ["studio:generate", "studio:connect", "studio:save"];
326
+ export declare function createJobId(): string;
327
+ /**
328
+ * Identifies the host running the Kubb runtime. Local to the runtime rather than part of the wire:
329
+ * it picks which remedy a refused-input warning suggests, since the Docker agent and the CLI grant
330
+ * `allowInput` different ways.
331
+ */
332
+ export type ClientInfo = {
333
+ /**
334
+ * `cli` for a `kubb studio` connection from a developer's machine, `docker` for the agent image,
335
+ * `ci` for a client embedded directly in an automated pipeline (no `kubb studio` process).
336
+ */
337
+ kind: 'cli' | 'docker' | 'ci';
338
+ };
339
+ /**
340
+ * Payload of the `agent:connect` handshake, sent when the agent attaches to a session. Carries only
341
+ * what Studio renders, with everything about the config under one key.
342
+ */
343
+ export type ConnectMessagePayload = {
344
+ /**
345
+ * Always sent, so a mismatch is visible on both sides: Studio badges the connection with these
346
+ * and the host prints them.
347
+ */
348
+ versions: {
349
+ /**
350
+ * The version of the `@kubb/studio` runtime the agent runs.
351
+ */
352
+ kubb: string;
353
+ /**
354
+ * The version of the host itself (the `kubb.agent` package or the `kubb` CLI).
355
+ */
356
+ agent: string;
357
+ };
358
+ /**
359
+ * The agent's project root (`KUBB_AGENT_ROOT`, or the working directory when unset). This is the
360
+ * workspace that generation runs against.
361
+ */
362
+ root: string;
363
+ /**
364
+ * The baseline every generation starts from.
365
+ */
366
+ config: {
367
+ /**
368
+ * The config path as configured (`KUBB_AGENT_CONFIG`), relative to `root` unless absolute.
369
+ */
370
+ path: string;
371
+ /**
372
+ * What the agent read out of the config file itself, so Studio can render the plugin editor
373
+ * against the real file. Absent when the agent could not read it, or was not granted
374
+ * `allowConfigEdit`.
375
+ */
376
+ file?: ConfigFileView;
377
+ /**
378
+ * Plugins the config registers, with their serialized options.
379
+ */
380
+ plugins?: Array<{
381
+ name: string;
382
+ options?: object;
383
+ }>;
384
+ };
385
+ permissions: AgentPermissions;
386
+ };
387
+ /**
388
+ * What an agent may do in the project it serves. Every one is off unless the host granted it, and
389
+ * a sandbox session narrows them further.
390
+ */
391
+ export type AgentPermissions = {
392
+ /**
393
+ * Whether the agent writes generated files to disk. False for a sandbox agent. For a local
394
+ * agent it mirrors the agent's `KUBB_AGENT_ALLOW_WRITE`.
395
+ */
396
+ allowWrite: boolean;
397
+ /**
398
+ * Whether the agent will accept and generate from an OpenAPI spec supplied by Studio.
399
+ * Always true for a sandbox agent, otherwise it mirrors the agent's own opt-in. Studio reads
400
+ * this to decide whether to send `input`.
401
+ */
402
+ allowInput: boolean;
403
+ /**
404
+ * Whether the agent runs the formatter, the linter, and `output.postGenerate` as child
405
+ * processes after a generation. Always true for the Docker agent, where the image bounds what
406
+ * can run. The CLI runs in the user's own project and defaults it off.
407
+ */
408
+ allowExec: boolean;
409
+ /**
410
+ * Whether the agent may change plugin options in the user's `kubb.config.ts`. Separate from
411
+ * `allowWrite`, which covers generated output: this one edits a hand-authored source file.
412
+ */
413
+ allowConfigEdit: boolean;
414
+ };
415
+ /**
416
+ * Agent → Studio handshake. Sent when the WebSocket opens and again after a `connect` command.
417
+ * Carries the on-disk config baseline, granted permissions, and paths Studio needs to render the editor.
418
+ */
419
+ export type AgentConnectMessage = {
420
+ type: 'agent:connect';
421
+ payload: ConnectMessagePayload;
422
+ };
423
+ /**
424
+ * Reply to a `save` command: what the agent did to the file on disk.
425
+ */
426
+ export type AgentSaveMessage = {
427
+ type: 'agent:save';
428
+ jobId: string;
429
+ payload: {
430
+ /**
431
+ * Per-edit result, in the order the edits were sent.
432
+ */
433
+ outcomes: Array<ConfigEditOutcome>;
434
+ /**
435
+ * Whether the file on disk changed. False when every edit was refused, and when the applied
436
+ * edits produced the text the file already had.
437
+ */
438
+ changed: boolean;
439
+ /**
440
+ * The config file as it now stands, so Studio can re-render without a round trip. Absent when
441
+ * nothing was written. Named to match `config.file` in the connect payload.
442
+ */
443
+ file?: ConfigFileView;
444
+ };
445
+ };
446
+ /**
447
+ * Failure notice from Studio for something that breaks outside a generation, such as a malformed
448
+ * command. The agent's own failures travel as an `agent:data` message carrying a `kubb:error`
449
+ * payload, which keeps them ordered against the generation events around them.
450
+ */
451
+ export type StudioErrorMessage = {
452
+ type: 'studio:error';
453
+ message: string;
454
+ };
455
+ /**
456
+ * Heartbeat sent by the Agent to Studio so the connection is not treated as idle.
457
+ */
458
+ export type AgentPingMessage = {
459
+ type: 'agent:ping';
460
+ };
461
+ /**
462
+ * Studio's reply to an `agent:ping`, confirming the connection is still alive.
463
+ */
464
+ export type StudioPingMessage = {
465
+ type: 'studio:ping';
466
+ };
467
+ /**
468
+ * Studio's acknowledgement that an `agent:connect` handshake was received and the session is
469
+ * fully registered: the connection now counts as available for job dispatch. Distinct from the
470
+ * socket merely being open, which is not yet the same thing.
471
+ */
472
+ export type StudioReadyMessage = {
473
+ type: 'studio:ready';
474
+ };
475
+ /**
476
+ * Disconnect message sent from Studio to Agent when the session is expired or revoked.
477
+ * The agent should close the connection without reconnecting.
478
+ */
479
+ export type StudioDisconnectMessage = {
480
+ type: 'studio:disconnect';
481
+ reason: 'expired' | 'revoked';
482
+ };
483
+ /**
484
+ * The agent going away, so Studio marks the session offline instead of waiting out the heartbeat
485
+ * window. The mirror of {@link StudioDisconnectMessage}.
486
+ *
487
+ * Only sent for a shutdown. An expired or revoked session was Studio's own decision, so echoing it
488
+ * back says nothing new.
489
+ */
490
+ export type AgentDisconnectMessage = {
491
+ type: 'agent:disconnect';
492
+ reason: 'shutdown';
493
+ };
494
+ /**
495
+ * Payload of an `agent:data` message: a single Kubb generation event forwarded to Studio in real time.
496
+ * Generic over the hook name so `data` is typed to that hook's context tuple.
497
+ */
498
+ export type DataMessagePayload<T extends KubbHook = KubbHook> = {
499
+ /**
500
+ * The Kubb hook this event is for (e.g. `kubb:plugin:start`).
501
+ */
502
+ type: T;
503
+ /**
504
+ * The hook's context tuple, matching `KubbHooks[type]`.
505
+ */
506
+ data: KubbHooks[T];
507
+ /**
508
+ * When the agent emitted the event, epoch milliseconds.
509
+ */
510
+ timestamp: number;
511
+ /**
512
+ * Monotonic per-connection counter stamped in the order the agent emits events. Studio orders the
513
+ * event log by this, since `timestamp` has millisecond resolution and a full generation fires
514
+ * dozens of events per tick, and the relay can deliver them out of order.
515
+ */
516
+ seq: number;
517
+ };
518
+ /**
519
+ * Envelope for a single generation event streamed from Agent to Studio. Wraps a
520
+ * {@link DataMessagePayload} so both sides can switch on `type: 'agent:data'`.
521
+ */
522
+ export type DataMessage<T extends KubbHook = KubbHook> = {
523
+ type: 'agent:data';
524
+ jobId: string;
525
+ payload: DataMessagePayload<T>;
526
+ };
527
+ /**
528
+ * Response returned by the Studio `/api/agent/sessions` endpoint.
529
+ */
530
+ export type AgentConnectResponse = {
531
+ /**
532
+ * WebSocket URL the agent opens to reach the session, with the session token embedded.
533
+ */
534
+ wsUrl: string;
535
+ /**
536
+ * When the session expires and the wsUrl stops working (ISO 8601).
537
+ */
538
+ expiresAt: string;
539
+ /**
540
+ * When the session was revoked (ISO 8601), or null while it is still valid.
541
+ */
542
+ revokedAt: string | null;
543
+ /**
544
+ * Opaque session token, also embedded in `wsUrl`. Store it to revoke the session later.
545
+ */
546
+ sessionId: string;
547
+ /**
548
+ * Short readable identifier for this connection, used in logs (e.g. brave-otter).
549
+ */
550
+ slug: string | null;
551
+ /**
552
+ * Whether this session belongs to a shared sandbox agent rather than an owned one.
553
+ */
554
+ isSandbox: boolean;
555
+ /**
556
+ * The Studio instance's own version. Reported here rather than only on `studio:connect`, so the
557
+ * agent knows it before it announces itself and can name both sides from the first connect.
558
+ * Absent when Studio predates the field.
559
+ */
560
+ version?: string;
561
+ };
562
+ /**
563
+ * Every message that can cross the agent WebSocket, in either direction. Narrow it with the
564
+ * `is*Message` guards below before reading a variant's fields.
565
+ */
566
+ export type AgentMessage = CommandMessage | DataMessage | AgentConnectMessage | AgentSaveMessage | AgentPingMessage | AgentDisconnectMessage | StudioErrorMessage | StudioPingMessage | StudioReadyMessage | StudioDisconnectMessage;
567
+ export declare function isCommandMessage(msg: AgentMessage): msg is CommandMessage;
568
+ /**
569
+ * Type guard to narrow a data message to a specific event type.
570
+ *
571
+ * @example
572
+ * ```ts
573
+ * if (isDataMessage(msg, 'kubb:plugin:start')) {
574
+ * // msg.payload.data is now typed as [ctx: { plugin: { name: string } }]
575
+ * const pluginName = msg.payload.data[0].plugin.name
576
+ * }
577
+ * ```
578
+ */
579
+ export declare function isDataMessage<T extends KubbHook>(msg: AgentMessage, type?: T): msg is DataMessage<T>;
580
+ export declare function isStudioPingMessage(msg: AgentMessage): msg is StudioPingMessage;
581
+ export declare function isStudioReadyMessage(msg: AgentMessage): msg is StudioReadyMessage;
582
+ export declare function isDisconnectMessage(msg: AgentMessage): msg is StudioDisconnectMessage;
583
+ //#endregion
584
+ //# sourceMappingURL=protocol.d.ts.map
package/dist/protocol.js CHANGED
@@ -8,6 +8,9 @@ const commandTypes = [
8
8
  "studio:connect",
9
9
  "studio:save"
10
10
  ];
11
+ function createJobId() {
12
+ return crypto.randomUUID();
13
+ }
11
14
  function isCommandMessage(msg) {
12
15
  return commandTypes.includes(msg.type);
13
16
  }
@@ -35,6 +38,6 @@ function isDisconnectMessage(msg) {
35
38
  return msg.type === "studio:disconnect";
36
39
  }
37
40
  //#endregion
38
- export { commandTypes, isCommandMessage, isDataMessage, isDisconnectMessage, isStudioPingMessage, isStudioReadyMessage };
41
+ export { commandTypes, createJobId, isCommandMessage, isDataMessage, isDisconnectMessage, isStudioPingMessage, isStudioReadyMessage };
39
42
 
40
43
  //# sourceMappingURL=protocol.js.map