@trojanbox-vcp-test/contracts 0.1.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.
package/dist/index.js CHANGED
@@ -1,2352 +1 @@
1
- import { z } from "zod";
2
- import { SiteEditOperationRequestSchema } from "./site-edit-operation.js";
3
- export * from "./site-edit-capability.js";
4
- export * from "./site-edit-class-name-source.js";
5
- export * from "./site-edit-event.js";
6
- export * from "./site-edit-identity.js";
7
- export * from "./site-edit-operation.js";
8
- export * from "./site-edit-patch-plan.js";
9
- export * from "./site-edit-render-document.js";
10
- export * from "./user-facing-copy.js";
11
- export const ClarifyQuestionTypeSchema = z.enum([
12
- "text-options",
13
- "motion-slider",
14
- ]);
15
- export const MotionLevelSchema = z.enum([
16
- "none",
17
- "subtle",
18
- "moderate",
19
- "expressive",
20
- ]);
21
- export const ArchetypeProposalSchema = z.object({
22
- skill_name: z.string().min(1),
23
- rationale: z.string().min(4).max(200),
24
- confidence: z.enum(["high", "medium", "low"]).optional(),
25
- });
26
- export const ClarifyModelOutputSchema = z.object({
27
- questions: z
28
- .array(z.object({
29
- id: z.string(),
30
- type: ClarifyQuestionTypeSchema,
31
- question: z.string(),
32
- tag: z.string(),
33
- aiThinking: z.string(),
34
- options: z.array(z.object({
35
- value: z.string(),
36
- label: z.string(),
37
- desc: z.string().optional(),
38
- impact: z.string().optional(),
39
- isRecommended: z.boolean().optional(),
40
- })),
41
- source: z.enum(["ai-detected", "always-ask"]),
42
- sourceDetail: z.string(),
43
- }))
44
- .min(1)
45
- .max(4),
46
- archetypeProposals: z.array(ArchetypeProposalSchema).min(1).max(5).optional(),
47
- });
48
- export const ClarifyQuestionsSchema = z.object({
49
- questions: z
50
- .array(z.object({
51
- id: z.string(),
52
- type: ClarifyQuestionTypeSchema,
53
- question: z.string(),
54
- tag: z.string(),
55
- aiThinking: z.string(),
56
- options: z.array(z.object({
57
- value: z.string(),
58
- label: z.string(),
59
- desc: z.string().optional(),
60
- impact: z.string().optional(),
61
- isRecommended: z.boolean().optional(),
62
- })),
63
- source: z.enum(["ai-detected", "always-ask"]),
64
- sourceDetail: z.string(),
65
- }))
66
- .min(1)
67
- .max(4),
68
- });
69
- export const ClarifyRunInputSchema = z.object({
70
- tenant_id: z.string().min(1),
71
- site_id: z.string().min(1),
72
- brief_id: z.string().min(1),
73
- brief: z.string().min(20).max(1000),
74
- });
75
- export const ClarifyStreamEventSchema = z.discriminatedUnion("type", [
76
- z.object({
77
- type: z.literal("run.started"),
78
- runId: z.string().min(1),
79
- at: z.string().min(1),
80
- }),
81
- z.object({
82
- type: z.literal("skill.selecting"),
83
- category: z.literal("page-generation"),
84
- available: z
85
- .array(z.object({ id: z.string().min(1), name: z.string().min(1) }))
86
- .max(20),
87
- at: z.string().min(1),
88
- }),
89
- z.object({
90
- type: z.literal("skill.selected"),
91
- category: z.literal("page-generation"),
92
- selected: z.object({
93
- id: z.string().min(1),
94
- name: z.string().min(1),
95
- reason: z.string().min(1).max(200),
96
- }),
97
- at: z.string().min(1),
98
- }),
99
- z.object({
100
- type: z.literal("clarify.partial"),
101
- object: z.unknown(),
102
- at: z.string().min(1),
103
- }),
104
- z.object({
105
- /**
106
- * 归一化后的 archetype 提案,catalog ≥ 2 时由 Clarify agent emit。
107
- * spec §5.4 给前端渲挑卡区用;catalog=1 dormant 路径下不发该事件。
108
- */
109
- type: z.literal("clarify.archetype_proposals"),
110
- proposals: z.array(ArchetypeProposalSchema).min(1).max(5),
111
- at: z.string().min(1),
112
- }),
113
- z.object({
114
- type: z.literal("clarify.finished"),
115
- questions_id: z.string().min(1),
116
- at: z.string().min(1),
117
- }),
118
- z.object({
119
- type: z.literal("run.failed"),
120
- error_code: z.string().min(1),
121
- message: z.string().min(1),
122
- at: z.string().min(1),
123
- }),
124
- ]);
125
- export const SiteStatusSchema = z.enum([
126
- "draft",
127
- "brief_submitted",
128
- "clarifying",
129
- "sitemap_ready",
130
- "workspace_ready",
131
- "deployed",
132
- "archived",
133
- "error",
134
- ]);
135
- const SITE_STATUS_TRANSITIONS = {
136
- draft: ["brief_submitted", "archived", "error"],
137
- brief_submitted: ["clarifying", "archived", "error"],
138
- clarifying: ["sitemap_ready", "archived", "error"],
139
- sitemap_ready: ["workspace_ready", "archived", "error"],
140
- workspace_ready: ["deployed", "archived", "error"],
141
- deployed: ["workspace_ready", "archived", "error"],
142
- archived: [],
143
- error: ["draft", "brief_submitted", "clarifying", "sitemap_ready"],
144
- };
145
- export function assertSiteStatusTransition(from, to) {
146
- if (!SITE_STATUS_TRANSITIONS[from].includes(to)) {
147
- throw new Error(`Invalid site status transition: ${from} -> ${to}`);
148
- }
149
- return to;
150
- }
151
- /**
152
- * 建站生命周期状态机(决策 #20):与站点 `status` 正交,专门表达
153
- * Step 2/3 规划态与首轮生成的可写窗口。
154
- *
155
- * - `planning`:Step 2/3 可反复修改答案/sitemap,全部版本化落库。
156
- * - `initial_generation_running`:首轮 run 进行中,冻结生成输入(brief /
157
- * answers / sitemap 写入口拒绝)。
158
- * - `generated`:首轮生成成功,Step 2/3 锁定为只读,改动只能经 Step 4。
159
- */
160
- export const SiteGenerationStateSchema = z.enum([
161
- "planning",
162
- "initial_generation_running",
163
- "generated",
164
- ]);
165
- const SITE_GENERATION_STATE_TRANSITIONS = {
166
- // 起首轮 run:planning -> running。
167
- planning: ["initial_generation_running"],
168
- // 首轮成功 -> generated;失败回滚 -> planning(保证用户可重试)。
169
- initial_generation_running: ["generated", "planning"],
170
- // 终态:首轮成功后只能经 Step 4 workspace operation,不回退规划态。
171
- generated: [],
172
- };
173
- export function assertSiteGenerationStateTransition(from, to) {
174
- if (from === to) {
175
- return to;
176
- }
177
- if (!SITE_GENERATION_STATE_TRANSITIONS[from].includes(to)) {
178
- throw new Error(`Invalid site generation state transition: ${from} -> ${to}`);
179
- }
180
- return to;
181
- }
182
- /**
183
- * 把一个 workspace run 生命周期事件映射为目标生成态(决策 #20)。
184
- * 仅 workspace agent 的首轮 run 推进生成态;非 workspace 或无关事件返回
185
- * `null`(不推进)。返回值仍需经 `assertSiteGenerationStateTransition`
186
- * 校验合法性,确保非法转移被拒绝。
187
- *
188
- * - `run.started` -> `initial_generation_running`
189
- * - `run.finished` -> `generated`
190
- * - `run.failed` -> `planning`(回滚到可重试的非锁定态)
191
- */
192
- export function resolveGenerationStateForRunLifecycle(input) {
193
- if (input.agent_type !== "workspace") {
194
- return null;
195
- }
196
- // 已锁定(generated)的站点不再被任何 run 事件改回规划态。
197
- if (input.current_state === "generated") {
198
- return null;
199
- }
200
- switch (input.event_type) {
201
- case "run.started":
202
- return input.current_state === "planning"
203
- ? "initial_generation_running"
204
- : null;
205
- case "run.finished":
206
- return input.current_state === "initial_generation_running"
207
- ? "generated"
208
- : null;
209
- case "run.failed":
210
- return input.current_state === "initial_generation_running"
211
- ? "planning"
212
- : null;
213
- default:
214
- return null;
215
- }
216
- }
217
- /**
218
- * Step 2/3 写入口在非 `planning` 态被命中时返回的结构化锁定错误码。
219
- * 不可静默吞,不可允许重新编辑。
220
- */
221
- export const SITE_PLANNING_FROZEN_ERROR_CODE = "SITE_PLANNING_INPUT_FROZEN";
222
- export const SITE_PLANNING_LOCKED_ERROR_CODE = "SITE_PLANNING_LOCKED";
223
- export const CreateSiteInputSchema = z.object({
224
- tenant_id: z.string().min(1),
225
- owner_user_id: z.string().min(1),
226
- name: z.string().min(1).max(120),
227
- brief: z.string().min(20).max(1000),
228
- });
229
- export const CreateSiteBriefRequestSchema = z.object({
230
- name: z.string().min(1).max(120),
231
- brief: z.string().min(20).max(1000),
232
- });
233
- export const SiteRecordSchema = z.object({
234
- id: z.string().min(1),
235
- tenant_id: z.string().min(1),
236
- owner_user_id: z.string().min(1),
237
- name: z.string().min(1),
238
- slug: z.string().min(1),
239
- status: SiteStatusSchema,
240
- generation_state: SiteGenerationStateSchema,
241
- planning_locked_at: z.string().min(1).nullable(),
242
- current_sitemap_id: z.string().min(1).nullable(),
243
- current_snapshot_id: z.string().min(1).nullable(),
244
- deployed_url: z.string().url().nullable(),
245
- schema_version: z.literal(1),
246
- created_at: z.string().min(1),
247
- updated_at: z.string().min(1),
248
- });
249
- export const BriefRecordSchema = z.object({
250
- id: z.string().min(1),
251
- tenant_id: z.string().min(1),
252
- site_id: z.string().min(1),
253
- body: z.string().min(1),
254
- source: z.enum(["user", "import", "system"]),
255
- created_at: z.string().min(1),
256
- updated_at: z.string().min(1),
257
- });
258
- export const CreateSiteBriefResponseSchema = z.object({
259
- site: SiteRecordSchema,
260
- brief: BriefRecordSchema,
261
- next_step: z.literal("clarify"),
262
- });
263
- export const AgentRunStatusSchema = z.enum([
264
- "queued",
265
- "running",
266
- "succeeded",
267
- "failed",
268
- "cancelled",
269
- ]);
270
- export const AgentRunTypeSchema = z.enum(["clarify", "sitemap", "workspace"]);
271
- export const AgentRunKindSchema = z.enum([
272
- "clarify",
273
- "sitemap",
274
- "initial_generation",
275
- "iteration",
276
- ]);
277
- export const AgentModelRouteSchema = z.enum([
278
- "clarify",
279
- "sitemap",
280
- "workspace",
281
- "summarize",
282
- ]);
283
- export const AgentRunRecordSchema = z.object({
284
- id: z.string().min(1),
285
- tenant_id: z.string().min(1),
286
- site_id: z.string().min(1),
287
- agent_type: AgentRunTypeSchema,
288
- run_kind: AgentRunKindSchema,
289
- status: AgentRunStatusSchema,
290
- model_route: AgentModelRouteSchema,
291
- started_at: z.string().min(1).nullable(),
292
- finished_at: z.string().min(1).nullable(),
293
- error_code: z.string().min(1).nullable(),
294
- created_at: z.string().min(1),
295
- });
296
- export const CreateAgentRunRequestSchema = z
297
- .object({
298
- run_id: z.string().min(1).optional(),
299
- site_id: z.string().min(1),
300
- agent_type: AgentRunTypeSchema,
301
- run_kind: AgentRunKindSchema.optional(),
302
- model_route: AgentModelRouteSchema,
303
- input: z.record(z.string(), z.unknown()).optional(),
304
- })
305
- .superRefine((value, ctx) => {
306
- if (containsSensitiveData(value.input)) {
307
- ctx.addIssue({
308
- code: "custom",
309
- path: ["input"],
310
- message: "Agent run input must not contain secrets",
311
- });
312
- }
313
- });
314
- export const CreateAgentRunResponseSchema = z.object({
315
- agent_run: AgentRunRecordSchema,
316
- next_step: z.literal("stream_events"),
317
- });
318
- export const SnapshotStatusSchema = z.enum([
319
- "draft",
320
- "candidate",
321
- "current",
322
- "failed",
323
- ]);
324
- export const SnapshotRecordSchema = z.object({
325
- id: z.string().min(1),
326
- tenant_id: z.string().min(1),
327
- site_id: z.string().min(1),
328
- version: z.number().int().positive(),
329
- manifest_hash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
330
- object_key: z.string().min(1),
331
- reason: z.enum([
332
- "initial_generation",
333
- "workspace_edit",
334
- "pre_deploy",
335
- "manual_save",
336
- "rollback",
337
- ]),
338
- status: SnapshotStatusSchema,
339
- created_at: z.string().min(1),
340
- });
341
- export const PersistSiteSnapshotRequestSchema = z.object({
342
- snapshot_id: z.string().min(1).optional(),
343
- manifest_hash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
344
- object_key: z.string().min(1),
345
- reason: SnapshotRecordSchema.shape.reason,
346
- status: SnapshotStatusSchema.default("candidate"),
347
- });
348
- export const PersistSiteSnapshotResponseSchema = z.object({
349
- site: SiteRecordSchema,
350
- snapshot: SnapshotRecordSchema,
351
- next_step: z.literal("workspace"),
352
- });
353
- export const PromoteSiteSnapshotResponseSchema = z.object({
354
- site: SiteRecordSchema,
355
- snapshot: SnapshotRecordSchema,
356
- next_step: z.literal("workspace"),
357
- });
358
- /**
359
- * 删除一个 candidate snapshot(清理被取代的中间快照)。
360
- * 仅允许删除 status=candidate、非当前 current_snapshot_id、且未被任何
361
- * site_versions 引用的快照;其余一律拒绝(硬安全网)。
362
- */
363
- export const DeleteSiteSnapshotResponseSchema = z.object({
364
- status: z.literal("deleted"),
365
- snapshot_id: z.string().min(1),
366
- });
367
- /**
368
- * 站点版本历史记录(决策 #8/#9):DB 是事实源,sandbox git 是事务层。
369
- * 每条记录把一个 promote 过的 snapshot 版本 ↔ sandbox accepted git commit ↔
370
- * 源 workspace run 绑定,作为恢复到任一历史版本的依据。
371
- */
372
- export const SiteVersionRecordSchema = z.object({
373
- id: z.string().min(1),
374
- tenant_id: z.string().min(1),
375
- site_id: z.string().min(1),
376
- snapshot_id: z.string().min(1),
377
- version: z.number().int().positive(),
378
- accepted_commit: z.string().min(1),
379
- source_run_id: z.string().min(1).nullable(),
380
- created_at: z.string().min(1),
381
- });
382
- export const RecordSnapshotVersionRequestSchema = z.object({
383
- accepted_commit: z.string().min(1),
384
- source_run_id: z.string().min(1).optional(),
385
- });
386
- export const RecordSnapshotVersionResponseSchema = z.object({
387
- site_version: SiteVersionRecordSchema,
388
- next_step: z.literal("workspace"),
389
- });
390
- export const ListSiteVersionsResponseSchema = z.object({
391
- site_versions: z.array(SiteVersionRecordSchema),
392
- });
393
- export const RestoreSiteSnapshotResponseSchema = z.object({
394
- site: SiteRecordSchema,
395
- snapshot: SnapshotRecordSchema,
396
- site_version: SiteVersionRecordSchema,
397
- next_step: z.literal("workspace"),
398
- });
399
- export const DeploymentStatusSchema = z.enum([
400
- "queued",
401
- "preparing_source",
402
- "building",
403
- "artifact_ready",
404
- "deploying",
405
- "released",
406
- "lock_failed",
407
- "source_prepare_failed",
408
- "build_failed",
409
- "artifact_fetch_failed",
410
- "artifact_validation_failed",
411
- "deploy_failed",
412
- "cleanup_failed",
413
- ]);
414
- export const DeploymentRecordSchema = z.object({
415
- id: z.string().min(1),
416
- tenant_id: z.string().min(1),
417
- site_id: z.string().min(1),
418
- snapshot_id: z.string().min(1),
419
- version: z.number().int().positive(),
420
- status: DeploymentStatusSchema,
421
- provider: z.enum(["cloudflare"]),
422
- url: z.string().url().nullable(),
423
- error_code: z.string().min(1).nullable(),
424
- provider_deployment_id: z.string().min(1).nullable(),
425
- created_at: z.string().min(1),
426
- updated_at: z.string().min(1),
427
- });
428
- export const CreateDeploymentRequestSchema = z
429
- .object({
430
- snapshot_id: z.string().min(1).optional(),
431
- })
432
- .default({});
433
- export const CreateDeploymentResponseSchema = z.object({
434
- deployment: DeploymentRecordSchema,
435
- });
436
- export const ApiErrorEnvelopeSchema = z.object({
437
- error: z.object({
438
- code: z.string().min(1),
439
- message: z.string().min(1),
440
- details: z.unknown().optional(),
441
- request_id: z.string().min(1).optional(),
442
- retryable: z.boolean().default(false),
443
- }),
444
- });
445
- export const DesignTokensSchema = z.object({
446
- colors: z.record(z.string(), z.string()).default({}),
447
- typography: z.record(z.string(), z.string()).default({}),
448
- spacing: z.record(z.string(), z.string()).default({}),
449
- motion: z.record(z.string(), z.string()).default({}),
450
- });
451
- export const VisualThemeSchema = z.object({
452
- theme_id: z.string().min(1),
453
- paletteIntent: z.string().min(1),
454
- tone: z.string().min(1),
455
- mediaMood: z.string().min(1),
456
- /**
457
- * Clarify motion-slider 答案对应的用户期望动效强度。可选:
458
- * 未答 motion-slider 时不写,DesignPlan 自由派生。
459
- */
460
- motionLevel: MotionLevelSchema.optional(),
461
- });
462
- export const BlockMediaIntentSchema = z.object({
463
- query: z.string().min(1),
464
- keywords: z.array(z.string()).default([]),
465
- orientation: z.enum(["landscape", "portrait", "square"]).optional(),
466
- role: z.enum([
467
- "hero",
468
- "section",
469
- "card",
470
- "gallery",
471
- "testimonial",
472
- "decorative",
473
- ]),
474
- altHint: z.string().min(1),
475
- });
476
- export const SiteMediaIntentSchema = z.object({
477
- id: z.string().min(1),
478
- role: z.enum(["site_background", "nav_background", "footer_background"]),
479
- query: z.string().min(1),
480
- keywords: z.array(z.string()).default([]),
481
- treatment: z.enum(["cover", "fixed-cover", "subtle-texture"]),
482
- altHint: z.string().optional(),
483
- });
484
- export const MediaAttributionSchema = z.object({
485
- provider: z.enum(["unsplash", "pexels"]),
486
- providerLabel: z.enum(["Unsplash", "Pexels"]),
487
- providerHref: z.string().url(),
488
- photoHref: z.string().url().optional(),
489
- photographerName: z.string().optional(),
490
- photographerHref: z.string().url().optional(),
491
- requiresAttribution: z.boolean(),
492
- });
493
- export const MediaAssetSchema = z.object({
494
- src: z.string().min(1),
495
- alt: z.string().min(1),
496
- width: z.number().int().positive().optional(),
497
- height: z.number().int().positive().optional(),
498
- provider: z.enum(["unsplash", "pexels", "placeholder"]).optional(),
499
- providerId: z.string().optional(),
500
- photoUrl: z.string().url().optional(),
501
- photographer: z.string().optional(),
502
- photographerUrl: z.string().url().optional(),
503
- credit: z.string().optional(),
504
- attribution: MediaAttributionSchema.optional(),
505
- });
506
- export const SkillSelectionSourceSchema = z.enum([
507
- /** 用户没操作 → 默认锁定第 1 张推荐卡。 */
508
- "system_recommended",
509
- /** 用户从 3 张主卡里选了一张。 */
510
- "user_picked",
511
- /** 用户展开「看更多」从扩展列表里选了一张。 */
512
- "user_picked_extended",
513
- /** catalog ≤ 1 或归一化全 fail,回退到 generic-website。 */
514
- "deterministic_fallback",
515
- ]);
516
- export const SkillSelectionSchema = z.object({
517
- id: z.string().min(1),
518
- name: z.string().min(1),
519
- category: z.literal("page-generation"),
520
- version: z.string().min(1).optional(),
521
- reason: z.string().min(1).max(200),
522
- source: SkillSelectionSourceSchema.default("system_recommended"),
523
- });
524
- const intentString = z.string().min(1).max(2000);
525
- const recipeRef = z.string().min(1).max(120);
526
- export const SiteDesignContextSchema = z.object({
527
- visualDirection: intentString,
528
- brandFeeling: intentString,
529
- paletteIntent: intentString,
530
- typographyIntent: intentString,
531
- density: z.string().min(1),
532
- motionLevel: z.string().min(1),
533
- mediaStrategy: intentString,
534
- compositionRules: z.array(intentString).max(20),
535
- avoidPatterns: z.array(intentString).max(20),
536
- // Optional structured font choice consumed by the deterministic root layout
537
- // to wire `next/font/google` (`--font-heading` / `--font-body`).
538
- fonts: z
539
- .object({
540
- heading: z.string().min(1),
541
- body: z.string().min(1),
542
- })
543
- .optional(),
544
- // Optional concrete design tokens for the deterministic CSS materializer.
545
- // Color values are seed names or hex strings (e.g. "slate", "#1f2937"); a
546
- // deterministic color materializer resolves them later.
547
- colorSeeds: z
548
- .object({
549
- primary: z.string().min(1).max(40),
550
- accent: z.string().min(1).max(40),
551
- neutral: z.string().min(1).max(40),
552
- supporting: z.array(z.string().min(1).max(40)).max(4).optional(),
553
- })
554
- .optional(),
555
- surfaceMode: z.enum(["light", "dark"]).optional(),
556
- radius: z.enum(["none", "sm", "md", "lg", "xl"]).optional(),
557
- });
558
- export const RouteGenerationCardSchema = z.object({
559
- routeGoal: intentString,
560
- narrativeArc: intentString,
561
- firstViewportIntent: intentString,
562
- visualContinuity: intentString,
563
- sectionRhythm: intentString,
564
- avoidPatterns: z.array(intentString).max(20),
565
- displayTitle: z.string().min(1).max(24).optional(),
566
- displayDescription: z.string().min(1).max(60).optional(),
567
- // Optional per-page SEO copy. Optional so older route cards still validate.
568
- metaTitle: z.string().min(1).max(120).optional(),
569
- metaDescription: z.string().min(1).max(320).optional(),
570
- });
571
- export const ActivityKindSchema = z.enum([
572
- "model_call",
573
- "validation",
574
- "repair",
575
- "preview",
576
- "worker_group",
577
- ]);
578
- export const BlockGenerationContextSchema = z.object({
579
- sectionRole: intentString,
580
- contentIntent: intentString,
581
- layoutIntent: intentString,
582
- visualIntent: intentString,
583
- mediaIntent: intentString,
584
- motionIntent: intentString,
585
- copyTone: intentString,
586
- displayTitle: z.string().min(1).max(24).optional(),
587
- displayDescription: z.string().min(1).max(60).optional(),
588
- ctaIntent: intentString.optional(),
589
- continuityWithPrevious: intentString.optional(),
590
- avoidRepeating: z.array(intentString).max(20).optional(),
591
- industryRecipeRefs: z.array(recipeRef).max(12).optional(),
592
- templateRecipeRefs: z.array(recipeRef).max(12).optional(),
593
- });
594
- export const DesignPlanSchema = z.object({
595
- schemaVersion: z.literal(1).default(1),
596
- siteDesignContext: SiteDesignContextSchema,
597
- routeCards: z.record(z.string().min(1), RouteGenerationCardSchema),
598
- blockContexts: z.record(z.string().min(1), BlockGenerationContextSchema),
599
- selectedSkillPacks: z.array(SkillSelectionSchema).max(3).optional(),
600
- // Optional site-level brand identity. Optional so older design plans still
601
- // validate.
602
- branding: z
603
- .object({
604
- siteName: z.string().min(1).max(120),
605
- tagline: z.string().min(1).max(200).optional(),
606
- primaryCta: z
607
- .object({
608
- label: z.string().min(1).max(60),
609
- target: z.string().min(1).max(200),
610
- })
611
- .optional(),
612
- trustSignals: z.array(z.string().min(1).max(60)).max(6).optional(),
613
- })
614
- .optional(),
615
- });
616
- export const BlockSchema = z
617
- .object({
618
- id: z.string(),
619
- type: z.string(),
620
- variant: z.string().optional(),
621
- order: z.number(),
622
- props: z.record(z.string(), z.unknown()),
623
- enabled: z.boolean(),
624
- meta: z
625
- .object({
626
- aiGenerated: z.boolean(),
627
- userEdited: z.boolean(),
628
- lastEditedAt: z.string(),
629
- lastEditedBy: z.enum(["ai", "user"]),
630
- })
631
- .optional(),
632
- })
633
- .strict();
634
- export const PageSchema = z
635
- .object({
636
- id: z.string(),
637
- slug: z.string(),
638
- title: z.string(),
639
- blocks: z.array(BlockSchema).min(1),
640
- layout: z.enum(["default", "centered", "fullwidth"]).optional(),
641
- navigation: z.object({
642
- showInHeader: z.boolean(),
643
- showInFooter: z.boolean(),
644
- order: z.number(),
645
- }),
646
- })
647
- .strict();
648
- export const SitemapSchema = z
649
- .object({
650
- version: z.number().int().positive(),
651
- pages: z.array(PageSchema).min(1),
652
- navigation: z.object({
653
- primaryLinks: z.array(z.object({ label: z.string(), href: z.string() })),
654
- footerLinks: z.array(z.object({ label: z.string(), href: z.string() })),
655
- }),
656
- integrations: z
657
- .object({
658
- cms: z.unknown().optional(),
659
- analytics: z.unknown().optional(),
660
- })
661
- .optional(),
662
- meta: z.object({
663
- generatedAt: z.string(),
664
- generatedBy: z.literal("sitemap-agent"),
665
- source_brief_id: z.string().optional(),
666
- source_answer_ids: z.array(z.string()).optional(),
667
- }),
668
- /**
669
- * Clarify 阶段选定的 page-generation skill。必填:服务端在 LLM 流结束后
670
- * 注入。LLM 输出本身不带该字段(见 {@link SitemapModelOutputSchema})。
671
- */
672
- skillSelection: SkillSelectionSchema,
673
- /**
674
- * 由 motion-slider / archetype 派生的视觉主题;服务端在 sitemap 落库前
675
- * 注入。LLM 输出本身不带该字段。
676
- */
677
- visualTheme: VisualThemeSchema.optional(),
678
- })
679
- .strict();
680
- /**
681
- * 提供给 streamObject 用于 LLM 输出的 sitemap schema 子集。
682
- * skillSelection / visualTheme 是服务端注入字段,LLM 不输出。
683
- */
684
- export const SitemapModelOutputSchema = SitemapSchema.omit({
685
- skillSelection: true,
686
- visualTheme: true,
687
- });
688
- export const SitemapEditActorSchema = z.enum(["ai", "user"]);
689
- const SitemapEditBaseInputSchema = z.object({
690
- site_id: z.string().min(1),
691
- page_id: z.string().min(1),
692
- edited_by: SitemapEditActorSchema.default("ai"),
693
- source_agent_run_id: z.string().min(1).optional(),
694
- });
695
- export const SitemapMoveBlockInputSchema = SitemapEditBaseInputSchema.extend({
696
- block_id: z.string().min(1),
697
- target_index: z.number().int().min(0),
698
- });
699
- export const SitemapDeleteBlockInputSchema = SitemapEditBaseInputSchema.extend({
700
- block_id: z.string().min(1),
701
- });
702
- export const SitemapChangeBlockVariantInputSchema = SitemapEditBaseInputSchema.extend({
703
- block_id: z.string().min(1),
704
- variant: z.string().min(1).nullable(),
705
- });
706
- export const SitemapUpdateBlockPropsInputSchema = SitemapEditBaseInputSchema.extend({
707
- block_id: z.string().min(1),
708
- props: z.record(z.string(), z.unknown()),
709
- mode: z.enum(["replace", "merge"]).default("replace"),
710
- });
711
- export const SitemapAddBlockInputSchema = SitemapEditBaseInputSchema.extend({
712
- block: z.object({
713
- id: z.string().min(1),
714
- type: z.string().min(1),
715
- variant: z.string().min(1).optional(),
716
- props: z.record(z.string(), z.unknown()).default({}),
717
- insert_index: z.number().int().min(0).optional(),
718
- }),
719
- });
720
- export const SitemapEditOperationSchema = z.enum([
721
- "move_block",
722
- "delete_block",
723
- "change_block_variant",
724
- "update_block_props",
725
- "add_block",
726
- ]);
727
- export const SitemapEditErrorCodeSchema = z.enum([
728
- "SITEMAP_EDIT_INVALID",
729
- "SITEMAP_API_NOT_CONFIGURED",
730
- "SITEMAP_NOT_FOUND",
731
- "SITEMAP_PAGE_NOT_FOUND",
732
- "SITEMAP_BLOCK_NOT_FOUND",
733
- "SITEMAP_BLOCK_ALREADY_EXISTS",
734
- "SITEMAP_EDIT_FAILED",
735
- ]);
736
- export const SitemapEditSuccessSchema = z.object({
737
- status: z.literal("updated"),
738
- operation: SitemapEditOperationSchema,
739
- site_id: z.string().min(1),
740
- sitemap_id: z.string().min(1),
741
- version: z.number().int().positive(),
742
- changed_pages: z.array(z.string().min(1)).min(1),
743
- requires_code_patch: z.literal(true),
744
- });
745
- export const SitemapEditFailureSchema = z.object({
746
- status: z.literal("failed"),
747
- code: SitemapEditErrorCodeSchema,
748
- message: z.string().min(1),
749
- retryable: z.boolean().default(false),
750
- details: z.unknown().optional(),
751
- });
752
- export const SitemapEditResultSchema = z.discriminatedUnion("status", [
753
- SitemapEditSuccessSchema,
754
- SitemapEditFailureSchema,
755
- ]);
756
- export const SitemapAnswerSchema = z.object({
757
- question_id: z.string().min(1),
758
- value: z.string().min(1),
759
- label: z.string().min(1).optional(),
760
- /** 该题的澄清问题原文,供 Step 3 prompt 还原「LLM 在问什么」。 */
761
- question: z.string().min(1).optional(),
762
- /** 所选项的可读标签(区别于内部 value),供 prompt 渲染人类可读答案。 */
763
- option_label: z.string().min(1).optional(),
764
- /**
765
- * motion-slider 答案对应的归一化动效强度。仅在 question.type === "motion-slider"
766
- * 时由服务端写入;其它题型不携带。下游 sitemap-finalization 抽出后写入
767
- * visualTheme.motionLevel,DesignPlan 据此锁 siteDesignContext.motionLevel。
768
- */
769
- motion_level: MotionLevelSchema.optional(),
770
- });
771
- export const SitemapRunInputSchema = z.object({
772
- tenant_id: z.string().min(1),
773
- site_id: z.string().min(1),
774
- brief_id: z.string().min(1),
775
- brief: z.string().min(20).max(1000),
776
- answers: z.array(SitemapAnswerSchema).min(1).max(10),
777
- /**
778
- * Clarify 阶段持久化的 archetype 选择。由调用方(agent runner / API)
779
- * 从 clarify_sessions.selected_archetype 读出,传入 sitemap agent。
780
- * sitemap.service 直接 inject 进生成的 sitemap.skillSelection,不再
781
- * 调 loadForSite 自荐。
782
- */
783
- skillSelection: SkillSelectionSchema,
784
- });
785
- export const SitemapGenerationStageSchema = z.enum([
786
- "planning",
787
- "generating",
788
- "validating",
789
- "ready",
790
- ]);
791
- export const SitemapStreamEventSchema = z.discriminatedUnion("type", [
792
- z.object({
793
- type: z.literal("run.started"),
794
- runId: z.string().min(1),
795
- at: z.string().min(1),
796
- }),
797
- z.object({
798
- type: z.literal("sitemap.generating"),
799
- stage: SitemapGenerationStageSchema,
800
- message: z.string().min(1).optional(),
801
- at: z.string().min(1),
802
- }),
803
- z.object({
804
- type: z.literal("sitemap.partial"),
805
- object: z.unknown(),
806
- at: z.string().min(1),
807
- }),
808
- z.object({
809
- type: z.literal("sitemap.generated"),
810
- sitemap_id: z.string().min(1),
811
- sitemap: SitemapSchema,
812
- at: z.string().min(1),
813
- }),
814
- z.object({
815
- type: z.literal("run.failed"),
816
- error_code: z.string().min(1),
817
- message: z.string().min(1),
818
- at: z.string().min(1),
819
- }),
820
- ]);
821
- export const SitemapRecordSchema = z.object({
822
- id: z.string().min(1),
823
- tenant_id: z.string().min(1),
824
- site_id: z.string().min(1),
825
- version: z.number().int().positive(),
826
- sitemap: SitemapSchema,
827
- source_agent_run_id: z.string().min(1).nullable(),
828
- created_at: z.string().min(1),
829
- updated_at: z.string().min(1),
830
- });
831
- export const PersistSiteSitemapRequestSchema = z.object({
832
- sitemap_id: z.string().min(1).optional(),
833
- sitemap: SitemapSchema,
834
- source_agent_run_id: z.string().min(1).optional(),
835
- });
836
- export const PersistSiteSitemapResponseSchema = z.object({
837
- site: SiteRecordSchema,
838
- sitemap: SitemapRecordSchema,
839
- next_step: z.literal("workspace"),
840
- });
841
- /** 持久化的 clarify_sessions 行(Step 2 用户答案落库记录)。 */
842
- export const ClarifySessionRecordSchema = z.object({
843
- id: z.string().min(1),
844
- tenant_id: z.string().min(1),
845
- site_id: z.string().min(1),
846
- brief_id: z.string().min(1),
847
- questions: ClarifyQuestionsSchema,
848
- answers: z.array(SitemapAnswerSchema),
849
- /**
850
- * Clarify 阶段用户确认/默认锁定的 archetype skill。catalog=1 时由
851
- * 服务端直填 deterministic_fallback;catalog≥2 时按前端挑卡结果。
852
- * sitemap agent 启动时从此处读出作为 SitemapRunInput.skillSelection。
853
- */
854
- selected_archetype: SkillSelectionSchema.optional(),
855
- completed_at: z.string().min(1).nullable(),
856
- created_at: z.string().min(1),
857
- updated_at: z.string().min(1),
858
- });
859
- export const PersistClarifyAnswersRequestSchema = z.object({
860
- answers: z.array(SitemapAnswerSchema).min(1),
861
- /** 用户作答时渲染的澄清问题,clarify_sessions.questions 非空所需的完整记录。 */
862
- questions: ClarifyQuestionsSchema,
863
- /**
864
- * 用户挑选的 archetype(catalog≥2 路径才会有,含 source 与 rationale)。
865
- * 缺失时(catalog=1 dormant 路径)服务端填 deterministic_fallback。
866
- */
867
- selected_archetype: SkillSelectionSchema.optional(),
868
- });
869
- export const PersistClarifyAnswersResponseSchema = z.object({
870
- clarify_session: ClarifySessionRecordSchema,
871
- });
872
- export const DesignPlanRecordSchema = z.object({
873
- id: z.string().min(1),
874
- tenant_id: z.string().min(1),
875
- site_id: z.string().min(1),
876
- version: z.number().int().positive(),
877
- design_plan: DesignPlanSchema,
878
- source_agent_run_id: z.string().min(1).nullable(),
879
- created_at: z.string().min(1),
880
- updated_at: z.string().min(1),
881
- });
882
- export const PersistSiteDesignPlanRequestSchema = z.object({
883
- design_plan_id: z.string().min(1).optional(),
884
- design_plan: DesignPlanSchema,
885
- source_agent_run_id: z.string().min(1).optional(),
886
- });
887
- export const PersistSiteDesignPlanResponseSchema = z.object({
888
- design_plan: DesignPlanRecordSchema,
889
- });
890
- export const WorkspaceRunKindSchema = z.enum([
891
- "initial_generation",
892
- "iteration",
893
- ]);
894
- export const AgentEventTypeSchema = z.enum([
895
- "run.started",
896
- "message.delta",
897
- "user.message",
898
- "plan.updated",
899
- "clarify.partial",
900
- "clarify.archetype_proposals",
901
- "clarify.finished",
902
- "sitemap.generating",
903
- "sitemap.partial",
904
- "sitemap.generated",
905
- "sitemap.updated",
906
- "sitemap.resync.failed",
907
- "block.changed",
908
- "tool.started",
909
- "tool.finished",
910
- "workspace.plan.created",
911
- "workspace.worker.updated",
912
- "workspace.task.updated",
913
- "file.changed",
914
- "snapshot.created",
915
- "preview.preparing",
916
- "preview.ready",
917
- "preview.build.started",
918
- "preview.build.succeeded",
919
- "preview.build.failed",
920
- "run.failed",
921
- "run.finished",
922
- "media_resolution.started",
923
- "media_resolution.finished",
924
- "skill.selecting",
925
- "skill.selected",
926
- "activity.started",
927
- "activity.updated",
928
- "activity.finished",
929
- "activity.failed",
930
- ]);
931
- export const AgentPlanStepSchema = z.object({
932
- id: z.string().min(1),
933
- title: z.string().min(1),
934
- status: z.enum(["pending", "running", "completed", "failed"]),
935
- });
936
- export const WorkspaceWorkerStatusSchema = z.enum([
937
- "pending",
938
- "running",
939
- "completed",
940
- "completed_with_skips",
941
- "failed",
942
- "skipped",
943
- ]);
944
- export const WorkspaceWorkerPhaseSchema = z.enum([
945
- "style_media",
946
- "chrome",
947
- "sections",
948
- "layout",
949
- "pages",
950
- "detect_typecheck",
951
- "repair",
952
- "finalize",
953
- "sitemap_resync",
954
- "preview",
955
- ]);
956
- export const WorkspaceDiagnosticSchema = z.object({
957
- code: z.string().min(1),
958
- message: z.string().min(1),
959
- path: z.string().min(1).optional(),
960
- task_id: z.string().min(1).optional(),
961
- });
962
- export const SnapshotFilePathSchema = z
963
- .string()
964
- .min(1)
965
- .refine((path) => isSafeSnapshotPath(path), {
966
- message: "Snapshot file paths must be safe relative POSIX paths without traversal.",
967
- });
968
- export const WorkspaceExecutionDiagnosticsSchema = z.object({
969
- deduped_paths: z.array(SnapshotFilePathSchema),
970
- skipped_tasks: z.array(z.string().min(1)),
971
- failed_tasks: z.array(z.string().min(1)),
972
- fallback_files: z.array(z.string().min(1)),
973
- applied_paths: z.array(SnapshotFilePathSchema),
974
- });
975
- export const WorkspaceWorkerGroupSchema = z.object({
976
- group_id: z.string().min(1),
977
- phase: WorkspaceWorkerPhaseSchema,
978
- title: z.string().min(1),
979
- status: WorkspaceWorkerStatusSchema,
980
- task_ids: z.array(z.string().min(1)),
981
- depends_on_groups: z.array(z.string().min(1)),
982
- target_paths: z.array(SnapshotFilePathSchema),
983
- });
984
- export const WorkspacePlanTaskKindSchema = z.enum([
985
- "style",
986
- "media",
987
- "chrome",
988
- "section",
989
- "layout",
990
- "page",
991
- ]);
992
- export const WorkspacePlanTaskSchema = z.object({
993
- task_id: z.string().min(1),
994
- group_id: z.string().min(1),
995
- kind: WorkspacePlanTaskKindSchema,
996
- target_path: SnapshotFilePathSchema,
997
- block_id: z.string().min(1).optional(),
998
- block_type: z.string().min(1).optional(),
999
- block_variant: z.string().min(1).optional(),
1000
- block_order: z.number().int().nonnegative().optional(),
1001
- page_id: z.string().min(1).optional(),
1002
- page_slug: z.string().min(1).optional(),
1003
- page_title: z.string().min(1).optional(),
1004
- title: z.string().min(1).max(60).optional(),
1005
- description: z.string().min(1).max(160).optional(),
1006
- status: WorkspaceWorkerStatusSchema,
1007
- required_reads: z.array(SnapshotFilePathSchema).optional(),
1008
- });
1009
- export const WorkspacePlanDependencySchema = z.object({
1010
- from_group_id: z.string().min(1),
1011
- to_group_id: z.string().min(1),
1012
- reason: z.enum([
1013
- "style_media",
1014
- "chrome",
1015
- "sections",
1016
- "layout",
1017
- "page_composition",
1018
- "quality_gate",
1019
- ]),
1020
- });
1021
- export const WorkspaceExecutionPlanSchema = z.object({
1022
- plan_id: z.string().min(1),
1023
- run_kind: WorkspaceRunKindSchema,
1024
- model_route: z.object({
1025
- planner: z.literal("workspace_planner"),
1026
- worker: z.literal("workspace"),
1027
- }),
1028
- groups: z.array(WorkspaceWorkerGroupSchema),
1029
- tasks: z.array(WorkspacePlanTaskSchema),
1030
- dependencies: z.array(WorkspacePlanDependencySchema),
1031
- expected_outputs: z.array(SnapshotFilePathSchema),
1032
- diagnostics: WorkspaceExecutionDiagnosticsSchema,
1033
- });
1034
- export const WorkspaceWorkerResultSchema = z.object({
1035
- task_id: z.string().min(1),
1036
- patch: z.unknown().optional(),
1037
- snapshot_id: z.string().min(1).optional(),
1038
- read_files: z.array(SnapshotFilePathSchema),
1039
- diagnostics: z.array(WorkspaceDiagnosticSchema),
1040
- status: WorkspaceWorkerStatusSchema,
1041
- });
1042
- export const WorkspacePlanSummarySchema = z.object({
1043
- worker_count: z.number().int().nonnegative(),
1044
- task_count: z.number().int().nonnegative(),
1045
- group_count: z.number().int().nonnegative(),
1046
- });
1047
- export const WorkspaceTaskCountsSchema = z.object({
1048
- pending: z.number().int().nonnegative(),
1049
- running: z.number().int().nonnegative(),
1050
- completed: z.number().int().nonnegative(),
1051
- completed_with_skips: z.number().int().nonnegative(),
1052
- failed: z.number().int().nonnegative(),
1053
- skipped: z.number().int().nonnegative(),
1054
- });
1055
- export const AiSdkUiTextPartSchema = z.object({
1056
- type: z.literal("text"),
1057
- text: z.string(),
1058
- state: z.enum(["streaming", "done"]).optional(),
1059
- });
1060
- export const AiSdkUiReasoningPartSchema = z.object({
1061
- type: z.literal("reasoning"),
1062
- text: z.string(),
1063
- state: z.enum(["streaming", "done"]).optional(),
1064
- providerMetadata: z.record(z.string(), z.unknown()).optional(),
1065
- });
1066
- export const AiSdkUiFilePartSchema = z.object({
1067
- type: z.literal("file"),
1068
- mediaType: z.string().min(1),
1069
- filename: z.string().min(1).optional(),
1070
- url: z.string().min(1),
1071
- });
1072
- export const AiSdkUiSourceUrlPartSchema = z.object({
1073
- type: z.literal("source-url"),
1074
- sourceId: z.string().min(1),
1075
- url: z.string().min(1),
1076
- title: z.string().min(1).optional(),
1077
- providerMetadata: z.record(z.string(), z.unknown()).optional(),
1078
- });
1079
- export const AiSdkUiSourceDocumentPartSchema = z.object({
1080
- type: z.literal("source-document"),
1081
- sourceId: z.string().min(1),
1082
- mediaType: z.string().min(1),
1083
- title: z.string().min(1),
1084
- filename: z.string().min(1).optional(),
1085
- providerMetadata: z.record(z.string(), z.unknown()).optional(),
1086
- });
1087
- export const AiSdkUiDataPartSchema = z.object({
1088
- type: z.string().regex(/^data-[a-zA-Z0-9_-]+$/),
1089
- id: z.string().min(1).optional(),
1090
- data: z.unknown(),
1091
- });
1092
- export const AiSdkUiToolPartSchema = z.object({
1093
- type: z.string().regex(/^tool-[a-zA-Z0-9_-]+$/),
1094
- toolCallId: z.string().min(1),
1095
- state: z.enum([
1096
- "input-streaming",
1097
- "input-available",
1098
- "output-available",
1099
- "output-error",
1100
- ]),
1101
- input: z.unknown().optional(),
1102
- output: z.unknown().optional(),
1103
- errorText: z.string().min(1).optional(),
1104
- });
1105
- export const AiSdkUiErrorPartSchema = z.object({
1106
- type: z.literal("error"),
1107
- errorText: z.string().min(1),
1108
- });
1109
- export const AiSdkUiStepStartPartSchema = z.object({
1110
- type: z.literal("step-start"),
1111
- });
1112
- export const AiSdkUiMessagePartSchema = z.union([
1113
- AiSdkUiTextPartSchema,
1114
- AiSdkUiReasoningPartSchema,
1115
- AiSdkUiFilePartSchema,
1116
- AiSdkUiSourceUrlPartSchema,
1117
- AiSdkUiSourceDocumentPartSchema,
1118
- AiSdkUiDataPartSchema,
1119
- AiSdkUiToolPartSchema,
1120
- AiSdkUiErrorPartSchema,
1121
- AiSdkUiStepStartPartSchema,
1122
- ]);
1123
- export const AgentEventSchema = z.discriminatedUnion("type", [
1124
- z.object({
1125
- type: z.literal("run.started"),
1126
- runId: z.string().min(1),
1127
- at: z.string().min(1),
1128
- }),
1129
- z.object({
1130
- type: z.literal("message.delta"),
1131
- text: z.string().min(1),
1132
- at: z.string().min(1),
1133
- }),
1134
- z.object({
1135
- type: z.literal("user.message"),
1136
- client_message_id: z.string().min(1),
1137
- message_id: z.string().min(1),
1138
- parts: z.array(AiSdkUiMessagePartSchema).min(1),
1139
- in_reply_to_tool_call_id: z.string().min(1).optional(),
1140
- at: z.string().min(1),
1141
- }),
1142
- z.object({
1143
- type: z.literal("plan.updated"),
1144
- steps: z.array(AgentPlanStepSchema),
1145
- at: z.string().min(1),
1146
- }),
1147
- z.object({
1148
- type: z.literal("clarify.partial"),
1149
- object: z.unknown(),
1150
- at: z.string().min(1),
1151
- }),
1152
- z.object({
1153
- /**
1154
- * 归一化后的 archetype 提案,catalog ≥ 2 时由 Clarify agent emit。
1155
- * spec §5.4 给前端渲挑卡区用;catalog=1 dormant 路径下不发该事件。
1156
- */
1157
- type: z.literal("clarify.archetype_proposals"),
1158
- proposals: z.array(ArchetypeProposalSchema).min(1).max(5),
1159
- at: z.string().min(1),
1160
- }),
1161
- z.object({
1162
- type: z.literal("clarify.finished"),
1163
- questions_id: z.string().min(1),
1164
- at: z.string().min(1),
1165
- }),
1166
- z.object({
1167
- type: z.literal("sitemap.generating"),
1168
- stage: SitemapGenerationStageSchema,
1169
- message: z.string().min(1).optional(),
1170
- at: z.string().min(1),
1171
- }),
1172
- z.object({
1173
- type: z.literal("sitemap.partial"),
1174
- object: z.unknown(),
1175
- at: z.string().min(1),
1176
- }),
1177
- z.object({
1178
- type: z.literal("sitemap.generated"),
1179
- sitemap_id: z.string().min(1),
1180
- sitemap: SitemapSchema,
1181
- at: z.string().min(1),
1182
- }),
1183
- z.object({
1184
- type: z.literal("sitemap.updated"),
1185
- sitemap_id: z.string().min(1),
1186
- version: z.number().int().positive(),
1187
- reason: z.string().min(1),
1188
- at: z.string().min(1),
1189
- }),
1190
- z.object({
1191
- type: z.literal("sitemap.resync.failed"),
1192
- error_code: z.string().min(1),
1193
- message: z.string().min(1),
1194
- retryable: z.boolean(),
1195
- diagnostics: z.unknown().optional(),
1196
- at: z.string().min(1),
1197
- }),
1198
- z.object({
1199
- type: z.literal("block.changed"),
1200
- block_id: z.string().min(1),
1201
- change_type: z.enum(["add", "update", "delete", "move"]),
1202
- at: z.string().min(1),
1203
- }),
1204
- z.object({
1205
- type: z.literal("tool.started"),
1206
- tool_call_id: z.string().min(1),
1207
- name: z.string().min(1),
1208
- summary: z.string().min(1),
1209
- at: z.string().min(1),
1210
- }),
1211
- z.object({
1212
- type: z.literal("tool.finished"),
1213
- tool_call_id: z.string().min(1),
1214
- name: z.string().min(1),
1215
- result_summary: z.string().min(1),
1216
- at: z.string().min(1),
1217
- }),
1218
- z
1219
- .object({
1220
- type: z.literal("workspace.plan.created"),
1221
- plan_id: z.string().min(1),
1222
- run_kind: WorkspaceRunKindSchema,
1223
- groups: z.array(WorkspaceWorkerGroupSchema),
1224
- tasks: z.array(WorkspacePlanTaskSchema),
1225
- dependencies: z.array(WorkspacePlanDependencySchema),
1226
- expected_outputs: z.array(SnapshotFilePathSchema),
1227
- diagnostics: WorkspaceExecutionDiagnosticsSchema,
1228
- summary: WorkspacePlanSummarySchema,
1229
- at: z.string().min(1),
1230
- })
1231
- .strict(),
1232
- z
1233
- .object({
1234
- type: z.literal("workspace.worker.updated"),
1235
- group_id: z.string().min(1),
1236
- phase: WorkspaceWorkerPhaseSchema,
1237
- status: WorkspaceWorkerStatusSchema,
1238
- task_counts: WorkspaceTaskCountsSchema,
1239
- target_paths: z.array(SnapshotFilePathSchema),
1240
- diagnostics: z.array(z.string().min(1)),
1241
- at: z.string().min(1),
1242
- })
1243
- .strict(),
1244
- z
1245
- .object({
1246
- type: z.literal("workspace.task.updated"),
1247
- task_id: z.string().min(1),
1248
- group_id: z.string().min(1),
1249
- status: WorkspaceWorkerStatusSchema,
1250
- target_path: SnapshotFilePathSchema,
1251
- read_files_count: z.number().int().nonnegative(),
1252
- diagnostics: z.array(z.string().min(1)),
1253
- at: z.string().min(1),
1254
- })
1255
- .strict(),
1256
- z.object({
1257
- type: z.literal("file.changed"),
1258
- path: z.string().min(1),
1259
- change_type: z.enum(["create", "update", "delete"]),
1260
- diff: z.string().optional(),
1261
- at: z.string().min(1),
1262
- }),
1263
- z.object({
1264
- type: z.literal("snapshot.created"),
1265
- snapshot_id: z.string().min(1),
1266
- manifest_hash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
1267
- at: z.string().min(1),
1268
- }),
1269
- z.object({
1270
- type: z.literal("preview.preparing"),
1271
- at: z.string().min(1),
1272
- }),
1273
- z.object({
1274
- type: z.literal("preview.ready"),
1275
- url: z.string().url(),
1276
- at: z.string().min(1),
1277
- }),
1278
- z.object({
1279
- type: z.literal("preview.build.started"),
1280
- snapshot_id: z.string().min(1),
1281
- at: z.string().min(1),
1282
- }),
1283
- z.object({
1284
- type: z.literal("preview.build.succeeded"),
1285
- snapshot_id: z.string().min(1),
1286
- at: z.string().min(1),
1287
- }),
1288
- z.object({
1289
- type: z.literal("preview.build.failed"),
1290
- snapshot_id: z.string().min(1),
1291
- message: z.string().min(1),
1292
- diagnostics: z.string().min(1),
1293
- retryable: z.boolean(),
1294
- at: z.string().min(1),
1295
- }),
1296
- z.object({
1297
- type: z.literal("run.failed"),
1298
- error_code: z.string().min(1),
1299
- message: z.string().min(1),
1300
- at: z.string().min(1),
1301
- }),
1302
- z.object({
1303
- type: z.literal("run.finished"),
1304
- snapshot_id: z.string().min(1),
1305
- at: z.string().min(1),
1306
- }),
1307
- z.object({
1308
- type: z.literal("media_resolution.started"),
1309
- slot_count: z.number().int().nonnegative(),
1310
- at: z.string().datetime(),
1311
- }),
1312
- z.object({
1313
- type: z.literal("media_resolution.finished"),
1314
- slot_count: z.number().int().nonnegative(),
1315
- provider_counts: z.object({
1316
- unsplash: z.number().int().nonnegative(),
1317
- pexels: z.number().int().nonnegative(),
1318
- placeholder: z.number().int().nonnegative(),
1319
- }),
1320
- fallback_count: z.number().int().nonnegative(),
1321
- error_codes: z.array(z.string()),
1322
- at: z.string().datetime(),
1323
- }),
1324
- z.object({
1325
- type: z.literal("skill.selecting"),
1326
- category: z.literal("page-generation"),
1327
- available: z
1328
- .array(z.object({ id: z.string().min(1), name: z.string().min(1) }))
1329
- .max(20),
1330
- at: z.string().min(1),
1331
- }),
1332
- z.object({
1333
- type: z.literal("skill.selected"),
1334
- category: z.literal("page-generation"),
1335
- selected: z.object({
1336
- id: z.string().min(1),
1337
- name: z.string().min(1),
1338
- reason: z.string().min(1).max(200),
1339
- }),
1340
- at: z.string().min(1),
1341
- }),
1342
- z.object({
1343
- type: z.literal("activity.started"),
1344
- activity_id: z.string().min(1),
1345
- parent_activity_id: z.string().min(1).optional(),
1346
- kind: ActivityKindSchema,
1347
- title: z.string().min(1).max(200),
1348
- detail: z.string().max(360).optional(),
1349
- locks_input: z.boolean(),
1350
- at: z.string().min(1),
1351
- }),
1352
- z.object({
1353
- type: z.literal("activity.updated"),
1354
- activity_id: z.string().min(1),
1355
- title: z.string().min(1).max(200).optional(),
1356
- detail: z.string().max(360).optional(),
1357
- at: z.string().min(1),
1358
- }),
1359
- z.object({
1360
- type: z.literal("activity.finished"),
1361
- activity_id: z.string().min(1),
1362
- at: z.string().min(1),
1363
- }),
1364
- z.object({
1365
- type: z.literal("activity.failed"),
1366
- activity_id: z.string().min(1),
1367
- detail: z.string().max(360).optional(),
1368
- at: z.string().min(1),
1369
- }),
1370
- ]);
1371
- export const AgentEventRecordSchema = z.object({
1372
- id: z.string().min(1),
1373
- tenant_id: z.string().min(1),
1374
- site_id: z.string().min(1),
1375
- agent_run_id: z.string().min(1),
1376
- sequence: z.number().int().positive(),
1377
- event_type: AgentEventTypeSchema,
1378
- payload: AgentEventSchema,
1379
- created_at: z.string().min(1),
1380
- });
1381
- export const AppendAgentEventRequestSchema = z
1382
- .object({
1383
- event_type: AgentEventTypeSchema,
1384
- payload: AgentEventSchema,
1385
- })
1386
- .superRefine((value, ctx) => {
1387
- if (value.event_type !== value.payload.type) {
1388
- ctx.addIssue({
1389
- code: "custom",
1390
- path: ["payload", "type"],
1391
- message: "payload.type must match event_type",
1392
- });
1393
- }
1394
- if (containsSensitiveData(value.payload)) {
1395
- ctx.addIssue({
1396
- code: "custom",
1397
- path: ["payload"],
1398
- message: "AgentEvent payload must not contain secrets",
1399
- });
1400
- }
1401
- });
1402
- // AppendAgentEvent 响应使用判别联合:
1403
- // - status: "appended" -> 新事件刚刚落库;next_cursor 是新事件 sequence。
1404
- // - status: "duplicate_ignored" -> user.message 命中 (run_id, client_message_id)
1405
- // 去重索引,event 始终回传已存在的那条事件,next_cursor 也是该事件的 sequence,
1406
- // 绝不回退到 0,避免客户端重放整段事件流。
1407
- export const AppendAgentEventResponseSchema = z.discriminatedUnion("status", [
1408
- z.object({
1409
- status: z.literal("appended"),
1410
- agent_run: AgentRunRecordSchema,
1411
- event: AgentEventRecordSchema,
1412
- next_cursor: z.number().int().nonnegative(),
1413
- }),
1414
- z.object({
1415
- status: z.literal("duplicate_ignored"),
1416
- agent_run: AgentRunRecordSchema,
1417
- event: AgentEventRecordSchema,
1418
- next_cursor: z.number().int().nonnegative(),
1419
- }),
1420
- ]);
1421
- export const ListAgentEventsResponseSchema = z.object({
1422
- events: z.array(AgentEventRecordSchema),
1423
- // 可选:per-run 事件分页返回游标;站点级跨 run 历史(时间序、一次取全)
1424
- // 不分页,故省略该字段。
1425
- next_cursor: z.number().int().nonnegative().optional(),
1426
- });
1427
- export const ListAgentEventsQuerySchema = z.object({
1428
- after_sequence: z.coerce.number().int().nonnegative().default(0),
1429
- });
1430
- export const ApiContractStatusSchema = z.enum([
1431
- "implemented",
1432
- "skeleton",
1433
- "planned",
1434
- ]);
1435
- export const RestApiMethodSchema = z.enum(["GET", "POST", "PATCH", "DELETE"]);
1436
- export const REST_API_ENDPOINTS = [
1437
- {
1438
- method: "GET",
1439
- path: "/health",
1440
- tag: "system",
1441
- summary: "API health check.",
1442
- status: "implemented",
1443
- response_schema: "ApiHealth",
1444
- },
1445
- {
1446
- method: "POST",
1447
- path: "/sites",
1448
- tag: "sites",
1449
- summary: "Create a site and Step 1 brief in the current dev context.",
1450
- status: "implemented",
1451
- request_body_schema: "CreateSiteBriefRequestSchema",
1452
- response_schema: "CreateSiteBriefResponseSchema",
1453
- },
1454
- {
1455
- method: "GET",
1456
- path: "/sites",
1457
- tag: "sites",
1458
- summary: "List current tenant sites.",
1459
- status: "implemented",
1460
- response_schema: "SiteRecordSchema[]",
1461
- },
1462
- {
1463
- method: "GET",
1464
- path: "/sites/:site_id",
1465
- tag: "sites",
1466
- summary: "Get one tenant-scoped site.",
1467
- status: "implemented",
1468
- response_schema: "SiteRecordSchema",
1469
- },
1470
- {
1471
- method: "POST",
1472
- path: "/sites/:site_id/sitemap",
1473
- tag: "sitemaps",
1474
- summary: "Persist generated sitemap and advance the site to sitemap_ready.",
1475
- status: "implemented",
1476
- request_body_schema: "PersistSiteSitemapRequestSchema",
1477
- response_schema: "PersistSiteSitemapResponseSchema",
1478
- },
1479
- {
1480
- method: "GET",
1481
- path: "/sites/:site_id/sitemap",
1482
- tag: "sitemaps",
1483
- summary: "Read the current sitemap for a site.",
1484
- status: "implemented",
1485
- response_schema: "SitemapRecordSchema",
1486
- },
1487
- {
1488
- method: "POST",
1489
- path: "/sites/:site_id/clarify/answers",
1490
- tag: "clarify",
1491
- summary: "Persist the Step 2 clarify answers (and the answered questions) into the site's clarify session.",
1492
- status: "implemented",
1493
- request_body_schema: "PersistClarifyAnswersRequestSchema",
1494
- response_schema: "PersistClarifyAnswersResponseSchema",
1495
- },
1496
- {
1497
- method: "POST",
1498
- path: "/internal/sites/:site_id/design-plan",
1499
- tag: "design-plans",
1500
- summary: "Persist a generated design plan version for a site (internal agent-only write).",
1501
- status: "implemented",
1502
- request_body_schema: "PersistSiteDesignPlanRequestSchema",
1503
- response_schema: "PersistSiteDesignPlanResponseSchema",
1504
- notes: [
1505
- "Guarded by the internal agent token; only the Workspace/Sitemap agent writes design plans.",
1506
- ],
1507
- },
1508
- {
1509
- method: "GET",
1510
- path: "/internal/sites/:site_id/design-plan",
1511
- tag: "design-plans",
1512
- summary: "Read the current (latest version) design plan for a site (internal agent-only read).",
1513
- status: "implemented",
1514
- response_schema: "DesignPlanRecordSchema",
1515
- notes: [
1516
- "Guarded by the internal agent token; only the Workspace/Sitemap agent reads design plans.",
1517
- ],
1518
- },
1519
- {
1520
- method: "GET",
1521
- path: "/sites/:site_id/design-plan",
1522
- tag: "design-plans",
1523
- summary: "Read the current (latest version) design plan for a site so Workspace UI can inspect the generated design contract.",
1524
- status: "implemented",
1525
- response_schema: "DesignPlanRecordSchema",
1526
- },
1527
- {
1528
- method: "GET",
1529
- path: "/sites/:site_id/brief",
1530
- tag: "briefs",
1531
- summary: "Read the persisted Step 1 brief for a site so the Workspace Agent can seed first full-site generation without a new write surface.",
1532
- status: "implemented",
1533
- response_schema: "BriefRecordSchema",
1534
- },
1535
- {
1536
- method: "POST",
1537
- path: "/sites/:site_id/snapshots",
1538
- tag: "snapshots",
1539
- summary: "Persist snapshot metadata without changing the current site snapshot.",
1540
- status: "implemented",
1541
- request_body_schema: "PersistSiteSnapshotRequestSchema",
1542
- response_schema: "PersistSiteSnapshotResponseSchema",
1543
- },
1544
- {
1545
- method: "POST",
1546
- path: "/sites/:site_id/snapshots/:snapshot_id/promote",
1547
- tag: "snapshots",
1548
- summary: "Promote a site snapshot as the current workspace version.",
1549
- status: "implemented",
1550
- response_schema: "PromoteSiteSnapshotResponseSchema",
1551
- },
1552
- {
1553
- method: "GET",
1554
- path: "/sites/:site_id/snapshots/:snapshot_id",
1555
- tag: "snapshots",
1556
- summary: "Read one tenant-scoped snapshot metadata record for a site.",
1557
- status: "implemented",
1558
- response_schema: "SnapshotRecordSchema",
1559
- },
1560
- {
1561
- method: "DELETE",
1562
- path: "/sites/:site_id/snapshots/:snapshot_id",
1563
- tag: "snapshots",
1564
- summary: "Delete a candidate snapshot (cleanup of superseded intermediate snapshots; refuses non-candidate/current/referenced).",
1565
- status: "implemented",
1566
- response_schema: "DeleteSiteSnapshotResponseSchema",
1567
- },
1568
- {
1569
- method: "POST",
1570
- path: "/agent-runs",
1571
- tag: "agent-runs",
1572
- summary: "Create an agent run for event persistence and replay.",
1573
- status: "implemented",
1574
- request_body_schema: "CreateAgentRunRequestSchema",
1575
- response_schema: "CreateAgentRunResponseSchema",
1576
- },
1577
- {
1578
- method: "POST",
1579
- path: "/agent-runs/:run_id/events",
1580
- tag: "agent-runs",
1581
- summary: "Append one normalized AgentEvent to a run.",
1582
- status: "implemented",
1583
- request_body_schema: "AppendAgentEventRequestSchema",
1584
- response_schema: "AppendAgentEventResponseSchema",
1585
- },
1586
- {
1587
- method: "GET",
1588
- path: "/agent-runs/:run_id/events",
1589
- tag: "agent-runs",
1590
- summary: "Replay AgentEvents after a run-local sequence cursor.",
1591
- status: "implemented",
1592
- response_schema: "ListAgentEventsResponseSchema",
1593
- },
1594
- {
1595
- method: "GET",
1596
- path: "/briefs",
1597
- tag: "briefs",
1598
- summary: "Brief resource summary endpoint until concrete brief APIs land.",
1599
- status: "skeleton",
1600
- },
1601
- {
1602
- method: "GET",
1603
- path: "/clarify",
1604
- tag: "clarify",
1605
- summary: "Clarify resource summary endpoint; persisted answers write through POST /sites/:site_id/clarify/answers.",
1606
- status: "skeleton",
1607
- },
1608
- {
1609
- method: "GET",
1610
- path: "/sitemaps",
1611
- tag: "sitemaps",
1612
- summary: "Sitemap resource summary endpoint until collection APIs land.",
1613
- status: "skeleton",
1614
- },
1615
- {
1616
- method: "GET",
1617
- path: "/snapshots",
1618
- tag: "snapshots",
1619
- summary: "Snapshot resource summary endpoint until collection APIs land.",
1620
- status: "skeleton",
1621
- },
1622
- {
1623
- method: "GET",
1624
- path: "/sandbox-sessions",
1625
- tag: "sandbox-sessions",
1626
- summary: "Sandbox session resource summary endpoint until preview APIs land.",
1627
- status: "skeleton",
1628
- },
1629
- {
1630
- method: "GET",
1631
- path: "/deployments",
1632
- tag: "deployments",
1633
- summary: "Deployment resource summary endpoint until publish APIs land.",
1634
- status: "skeleton",
1635
- },
1636
- {
1637
- method: "GET",
1638
- path: "/usage",
1639
- tag: "usage",
1640
- summary: "Usage resource summary endpoint until cost summaries land.",
1641
- status: "skeleton",
1642
- },
1643
- {
1644
- method: "GET",
1645
- path: "/audit",
1646
- tag: "audit",
1647
- summary: "Audit resource summary endpoint until audit queries land.",
1648
- status: "skeleton",
1649
- },
1650
- {
1651
- method: "POST",
1652
- path: "/sites/:site_id/workspace/runs",
1653
- tag: "workspace",
1654
- summary: "Start an asynchronous Workspace Agent run from the current snapshot.",
1655
- status: "implemented",
1656
- request_body_schema: "StartWorkspaceRunRequestSchema",
1657
- response_schema: "StartWorkspaceRunResponseSchema",
1658
- notes: [
1659
- "Long-running work must be event-driven and must not block API transactions.",
1660
- ],
1661
- },
1662
- {
1663
- method: "GET",
1664
- path: "/sites/:site_id/workspace/runs/latest",
1665
- tag: "workspace",
1666
- summary: "Look up the latest workspace Agent run for a site so Step 4 re-entry can replay persisted events without re-triggering the model.",
1667
- status: "implemented",
1668
- response_schema: "LatestWorkspaceRunResponseSchema",
1669
- },
1670
- {
1671
- method: "POST",
1672
- path: "/sites/:site_id/preview-sessions",
1673
- tag: "sandbox-sessions",
1674
- summary: "Persist or update an on-demand preview session for a site.",
1675
- status: "implemented",
1676
- request_body_schema: "PersistPreviewSessionRequestSchema",
1677
- response_schema: "PersistPreviewSessionResponseSchema",
1678
- },
1679
- {
1680
- method: "GET",
1681
- path: "/sites/:site_id/preview-sessions/current",
1682
- tag: "sandbox-sessions",
1683
- summary: "Read the latest tenant-scoped preview session for a site.",
1684
- status: "implemented",
1685
- response_schema: "SandboxSessionSchema",
1686
- },
1687
- {
1688
- method: "POST",
1689
- path: "/sites/:site_id/deployments",
1690
- tag: "deployments",
1691
- summary: "Queue an explicit user-confirmed deployment from a snapshot.",
1692
- status: "implemented",
1693
- request_body_schema: "CreateDeploymentRequestSchema",
1694
- response_schema: "CreateDeploymentResponseSchema",
1695
- notes: [
1696
- "The API returns after creating the deployment record; build and Cloudflare publish run through deploy-service.",
1697
- ],
1698
- },
1699
- {
1700
- method: "GET",
1701
- path: "/sites/:site_id/deployments/:deployment_id",
1702
- tag: "deployments",
1703
- summary: "Read one tenant-scoped deployment for status polling.",
1704
- status: "implemented",
1705
- response_schema: "DeploymentRecordSchema",
1706
- },
1707
- {
1708
- method: "GET",
1709
- path: "/sites/:site_id/cms/collections",
1710
- tag: "cms",
1711
- summary: "List CMS collections for a site.",
1712
- status: "planned",
1713
- },
1714
- {
1715
- method: "POST",
1716
- path: "/sites/:site_id/cms/collections",
1717
- tag: "cms",
1718
- summary: "Create a CMS collection bound to generated content.",
1719
- status: "planned",
1720
- },
1721
- {
1722
- method: "GET",
1723
- path: "/sites/:site_id/cms/collections/:collection_id/entries",
1724
- tag: "cms",
1725
- summary: "List CMS entries for a collection.",
1726
- status: "planned",
1727
- },
1728
- {
1729
- method: "POST",
1730
- path: "/sites/:site_id/cms/collections/:collection_id/entries",
1731
- tag: "cms",
1732
- summary: "Create a CMS entry.",
1733
- status: "planned",
1734
- },
1735
- {
1736
- method: "PATCH",
1737
- path: "/sites/:site_id/cms/collections/:collection_id/entries/:entry_id",
1738
- tag: "cms",
1739
- summary: "Update a CMS entry.",
1740
- status: "planned",
1741
- },
1742
- {
1743
- method: "POST",
1744
- path: "/sites/:site_id/snapshots/:snapshot_id/version-record",
1745
- tag: "versions",
1746
- summary: "Record the sandbox accepted git commit for a promoted snapshot version.",
1747
- status: "implemented",
1748
- request_body_schema: "RecordSnapshotVersionRequestSchema",
1749
- response_schema: "RecordSnapshotVersionResponseSchema",
1750
- },
1751
- {
1752
- method: "GET",
1753
- path: "/sites/:site_id/versions",
1754
- tag: "versions",
1755
- summary: "List snapshot-backed site versions.",
1756
- status: "implemented",
1757
- response_schema: "ListSiteVersionsResponseSchema",
1758
- },
1759
- {
1760
- method: "POST",
1761
- path: "/sites/:site_id/versions/:snapshot_id/restore",
1762
- tag: "versions",
1763
- summary: "Restore a site to an earlier snapshot version.",
1764
- status: "implemented",
1765
- response_schema: "RestoreSiteSnapshotResponseSchema",
1766
- },
1767
- {
1768
- method: "GET",
1769
- path: "/sites/:site_id/domains",
1770
- tag: "domains",
1771
- summary: "List custom domains for a site.",
1772
- status: "planned",
1773
- },
1774
- {
1775
- method: "POST",
1776
- path: "/sites/:site_id/domains",
1777
- tag: "domains",
1778
- summary: "Attach a custom domain to a site.",
1779
- status: "planned",
1780
- },
1781
- {
1782
- method: "GET",
1783
- path: "/admin/tenants",
1784
- tag: "admin",
1785
- summary: "Admin tenant listing.",
1786
- status: "planned",
1787
- },
1788
- {
1789
- method: "GET",
1790
- path: "/usage/summary",
1791
- tag: "usage",
1792
- summary: "Summarize tenant usage and cost controls.",
1793
- status: "planned",
1794
- },
1795
- ];
1796
- export const SSE_STREAMS = [
1797
- {
1798
- method: "POST",
1799
- path: "/v1/agent/clarify/:site_id",
1800
- tag: "clarify",
1801
- summary: "Stream Step 2 clarify questions as SSE.",
1802
- status: "implemented",
1803
- request_body_schema: "ClarifyRunInputSchema without tenant_id/site_id",
1804
- event_schema: "ClarifyStreamEventSchema",
1805
- event_order: ["run.started", "clarify.partial", "clarify.finished"],
1806
- },
1807
- {
1808
- method: "POST",
1809
- path: "/v1/agent/sitemap/:site_id",
1810
- tag: "sitemap",
1811
- summary: "Stream Step 3 sitemap generation as SSE.",
1812
- status: "implemented",
1813
- request_body_schema: "SitemapRunInputSchema without tenant_id/site_id",
1814
- event_schema: "SitemapStreamEventSchema",
1815
- event_order: ["run.started", "sitemap.generating", "sitemap.generated"],
1816
- },
1817
- ];
1818
- export const AiSdkUiMessageSchema = z.object({
1819
- id: z.string().min(1),
1820
- role: z.enum(["system", "user", "assistant"]),
1821
- metadata: z.unknown().optional(),
1822
- parts: z.array(AiSdkUiMessagePartSchema).min(1),
1823
- });
1824
- export const StartWorkspaceRunRequestSchema = z
1825
- .object({
1826
- base_snapshot_id: z.string().min(1).optional(),
1827
- message: AiSdkUiMessageSchema.optional(),
1828
- })
1829
- .superRefine((value, ctx) => {
1830
- if (containsSensitiveData(value.message)) {
1831
- ctx.addIssue({
1832
- code: "custom",
1833
- path: ["message"],
1834
- message: "Workspace startup message must not contain secrets",
1835
- });
1836
- }
1837
- });
1838
- export const WorkspaceSocketDescriptorSchema = z.object({
1839
- path: z.string().regex(/^\/v1\/workspace\/sites\/[^/]+\/socket$/),
1840
- run_id: z.string().min(1),
1841
- base_snapshot_id: z.string().min(1),
1842
- run_kind: WorkspaceRunKindSchema,
1843
- });
1844
- export const StartWorkspaceRunResponseSchema = z.object({
1845
- agent_run: AgentRunRecordSchema,
1846
- websocket: WorkspaceSocketDescriptorSchema,
1847
- next_step: z.literal("workspace_socket"),
1848
- });
1849
- /**
1850
- * 最新一次 workspace run 查询响应(Step 4 再次进入回显用)。
1851
- *
1852
- * 重进 Step 4 时前端据此发现该 site 已有的 workspace run,按
1853
- * `GET /agent-runs/:run_id/events` 回放历史对话与 agent 操作,
1854
- * **不重新发起 `POST /workspace/runs`**(那会重复触发模型)。
1855
- * 该 site 从未跑过 workspace run 时端点返回 404,前端据此进入“无历史”路径。
1856
- */
1857
- export const LatestWorkspaceRunResponseSchema = z.object({
1858
- agent_run: AgentRunRecordSchema,
1859
- });
1860
- export const WorkspaceWebSocketMessageTypeSchema = z.enum([
1861
- "client.message.create",
1862
- "client.run.cancel",
1863
- "client.tool.approve",
1864
- "server.run.started",
1865
- "server.assistant.delta",
1866
- "server.tool.started",
1867
- "server.tool.completed",
1868
- "workspace.plan.created",
1869
- "workspace.worker.updated",
1870
- "workspace.task.updated",
1871
- "server.patch.applied",
1872
- "server.sitemap.updated",
1873
- "server.snapshot.created",
1874
- "server.preview.invalidated",
1875
- "preview.build.started",
1876
- "preview.build.succeeded",
1877
- "preview.build.failed",
1878
- "server.run.finished",
1879
- "server.run.failed",
1880
- "server.error",
1881
- "server.activity.started",
1882
- "server.activity.updated",
1883
- "server.activity.finished",
1884
- "server.activity.failed",
1885
- ]);
1886
- const WorkspaceEnvelopeBaseSchema = z.object({
1887
- id: z.string().min(1),
1888
- tenant_id: z.string().min(1),
1889
- site_id: z.string().min(1),
1890
- run_id: z.string().min(1).optional(),
1891
- correlation_id: z.string().min(1).optional(),
1892
- seq: z.number().int().positive().optional(),
1893
- sent_at: z.string().min(1),
1894
- });
1895
- export const WorkspaceClientMessageSchema = z.discriminatedUnion("type", [
1896
- WorkspaceEnvelopeBaseSchema.extend({
1897
- type: z.literal("client.message.create"),
1898
- payload: z.object({
1899
- client_message_id: z.string().min(1),
1900
- in_reply_to_tool_call_id: z.string().min(1).optional(),
1901
- message: AiSdkUiMessageSchema,
1902
- base_snapshot_id: z.string().min(1).optional(),
1903
- }),
1904
- }),
1905
- WorkspaceEnvelopeBaseSchema.extend({
1906
- type: z.literal("client.run.cancel"),
1907
- payload: z.object({
1908
- run_id: z.string().min(1),
1909
- reason: z.string().min(1).optional(),
1910
- }),
1911
- }),
1912
- WorkspaceEnvelopeBaseSchema.extend({
1913
- type: z.literal("client.tool.approve"),
1914
- payload: z.object({
1915
- tool_call_id: z.string().min(1),
1916
- decision: z.enum(["approve", "reject"]),
1917
- reason: z.string().min(1).optional(),
1918
- }),
1919
- }),
1920
- ]);
1921
- export const WorkspaceServerMessageSchema = z.discriminatedUnion("type", [
1922
- WorkspaceEnvelopeBaseSchema.extend({
1923
- type: z.literal("server.run.started"),
1924
- payload: z.object({
1925
- run_id: z.string().min(1),
1926
- agent_type: z.literal("workspace"),
1927
- }),
1928
- }),
1929
- WorkspaceEnvelopeBaseSchema.extend({
1930
- type: z.literal("server.assistant.delta"),
1931
- payload: z.object({
1932
- message_id: z.string().min(1),
1933
- parts: z.array(AiSdkUiMessagePartSchema).min(1),
1934
- status: z.enum(["streaming", "ready"]),
1935
- }),
1936
- }),
1937
- WorkspaceEnvelopeBaseSchema.extend({
1938
- type: z.literal("server.tool.started"),
1939
- payload: z.object({
1940
- tool_call_id: z.string().min(1),
1941
- name: z.string().min(1),
1942
- summary: z.string().min(1),
1943
- }),
1944
- }),
1945
- WorkspaceEnvelopeBaseSchema.extend({
1946
- type: z.literal("server.tool.completed"),
1947
- payload: z.object({
1948
- tool_call_id: z.string().min(1),
1949
- name: z.string().min(1),
1950
- result_summary: z.string().min(1),
1951
- }),
1952
- }),
1953
- WorkspaceEnvelopeBaseSchema.extend({
1954
- type: z.literal("workspace.plan.created"),
1955
- payload: z.object({
1956
- plan_id: z.string().min(1),
1957
- run_kind: WorkspaceRunKindSchema,
1958
- groups: z.array(WorkspaceWorkerGroupSchema),
1959
- tasks: z.array(WorkspacePlanTaskSchema),
1960
- dependencies: z.array(WorkspacePlanDependencySchema),
1961
- expected_outputs: z.array(SnapshotFilePathSchema),
1962
- diagnostics: WorkspaceExecutionDiagnosticsSchema,
1963
- summary: WorkspacePlanSummarySchema,
1964
- }),
1965
- }),
1966
- WorkspaceEnvelopeBaseSchema.extend({
1967
- type: z.literal("workspace.worker.updated"),
1968
- payload: z.object({
1969
- group_id: z.string().min(1),
1970
- phase: WorkspaceWorkerPhaseSchema,
1971
- status: WorkspaceWorkerStatusSchema,
1972
- task_counts: WorkspaceTaskCountsSchema,
1973
- target_paths: z.array(SnapshotFilePathSchema),
1974
- diagnostics: z.array(z.string().min(1)),
1975
- }),
1976
- }),
1977
- WorkspaceEnvelopeBaseSchema.extend({
1978
- type: z.literal("workspace.task.updated"),
1979
- payload: z.object({
1980
- task_id: z.string().min(1),
1981
- group_id: z.string().min(1),
1982
- status: WorkspaceWorkerStatusSchema,
1983
- target_path: SnapshotFilePathSchema,
1984
- read_files_count: z.number().int().nonnegative(),
1985
- diagnostics: z.array(z.string().min(1)),
1986
- }),
1987
- }),
1988
- WorkspaceEnvelopeBaseSchema.extend({
1989
- type: z.literal("server.patch.applied"),
1990
- payload: z.object({
1991
- patch_batch_id: z.string().min(1),
1992
- changed_files: z.array(z.string().min(1)),
1993
- sitemap_resync_queued: z.boolean(),
1994
- }),
1995
- }),
1996
- WorkspaceEnvelopeBaseSchema.extend({
1997
- type: z.literal("server.sitemap.updated"),
1998
- payload: z.object({
1999
- sitemap_id: z.string().min(1),
2000
- version: z.number().int().positive(),
2001
- reason: z.string().min(1),
2002
- }),
2003
- }),
2004
- WorkspaceEnvelopeBaseSchema.extend({
2005
- type: z.literal("server.snapshot.created"),
2006
- payload: z.object({
2007
- snapshot_id: z.string().min(1),
2008
- manifest_hash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
2009
- }),
2010
- }),
2011
- WorkspaceEnvelopeBaseSchema.extend({
2012
- type: z.literal("server.preview.invalidated"),
2013
- payload: z.object({
2014
- reason: z.string().min(1),
2015
- next_preview_url: z.string().url().optional(),
2016
- }),
2017
- }),
2018
- WorkspaceEnvelopeBaseSchema.extend({
2019
- type: z.literal("preview.build.started"),
2020
- payload: z.object({
2021
- snapshot_id: z.string().min(1),
2022
- }),
2023
- }),
2024
- WorkspaceEnvelopeBaseSchema.extend({
2025
- type: z.literal("preview.build.succeeded"),
2026
- payload: z.object({
2027
- snapshot_id: z.string().min(1),
2028
- }),
2029
- }),
2030
- WorkspaceEnvelopeBaseSchema.extend({
2031
- type: z.literal("preview.build.failed"),
2032
- payload: z.object({
2033
- snapshot_id: z.string().min(1),
2034
- message: z.string().min(1),
2035
- diagnostics: z.string().min(1),
2036
- retryable: z.boolean(),
2037
- }),
2038
- }),
2039
- WorkspaceEnvelopeBaseSchema.extend({
2040
- type: z.literal("server.run.finished"),
2041
- payload: z.object({
2042
- run_id: z.string().min(1),
2043
- snapshot_id: z.string().min(1),
2044
- }),
2045
- }),
2046
- WorkspaceEnvelopeBaseSchema.extend({
2047
- type: z.literal("server.run.failed"),
2048
- payload: z.object({
2049
- run_id: z.string().min(1),
2050
- error_code: z.string().min(1),
2051
- message: z.string().min(1),
2052
- retryable: z.boolean(),
2053
- }),
2054
- }),
2055
- WorkspaceEnvelopeBaseSchema.extend({
2056
- type: z.literal("server.error"),
2057
- payload: z.object({
2058
- code: z.string().min(1),
2059
- message: z.string().min(1),
2060
- retryable: z.boolean(),
2061
- }),
2062
- }),
2063
- WorkspaceEnvelopeBaseSchema.extend({
2064
- type: z.literal("server.activity.started"),
2065
- payload: z.object({
2066
- activity_id: z.string().min(1),
2067
- parent_activity_id: z.string().min(1).optional(),
2068
- kind: ActivityKindSchema,
2069
- title: z.string().min(1).max(200),
2070
- detail: z.string().max(360).optional(),
2071
- locks_input: z.boolean(),
2072
- }),
2073
- }),
2074
- WorkspaceEnvelopeBaseSchema.extend({
2075
- type: z.literal("server.activity.updated"),
2076
- payload: z.object({
2077
- activity_id: z.string().min(1),
2078
- title: z.string().min(1).max(200).optional(),
2079
- detail: z.string().max(360).optional(),
2080
- }),
2081
- }),
2082
- WorkspaceEnvelopeBaseSchema.extend({
2083
- type: z.literal("server.activity.finished"),
2084
- payload: z.object({
2085
- activity_id: z.string().min(1),
2086
- }),
2087
- }),
2088
- WorkspaceEnvelopeBaseSchema.extend({
2089
- type: z.literal("server.activity.failed"),
2090
- payload: z.object({
2091
- activity_id: z.string().min(1),
2092
- detail: z.string().max(360).optional(),
2093
- }),
2094
- }),
2095
- ]);
2096
- export const WorkspaceWebSocketMessageSchema = z.union([
2097
- WorkspaceClientMessageSchema,
2098
- WorkspaceServerMessageSchema,
2099
- ]);
2100
- export const WORKSPACE_WEBSOCKET_CONTRACT = {
2101
- path: "/v1/workspace/sites/:site_id/socket",
2102
- protocol: "ws",
2103
- status: "implemented",
2104
- inbound_message_schema: "WorkspaceClientMessageSchema",
2105
- outbound_message_schema: "WorkspaceServerMessageSchema",
2106
- ai_sdk_ui_compatible: true,
2107
- notes: [
2108
- "Assistant UI output is carried as AI SDK UIMessage parts, including text, data-*, and tool-* parts.",
2109
- "Operational AgentEvents remain persisted separately for replay and audit.",
2110
- ],
2111
- };
2112
- export const SnapshotContentHashSchema = z
2113
- .string()
2114
- .regex(/^sha256:[a-f0-9]{64}$/);
2115
- export const ApplyPatchOperationSchema = z.enum(["create", "update", "delete"]);
2116
- export const ApplyPatchBatchPostActionSchema = z.enum([
2117
- "sitemap_resync",
2118
- "smoke_test",
2119
- "prepare_preview",
2120
- ]);
2121
- export const ApplyPatchBatchPatchSchema = z
2122
- .object({
2123
- path: SnapshotFilePathSchema,
2124
- operation: ApplyPatchOperationSchema,
2125
- expected_hash: SnapshotContentHashSchema.optional(),
2126
- full_content: z
2127
- .string()
2128
- .describe("Complete file content for create/update patches. It is passed as a JSON string, so every double quote in source code must be valid JSON; avoid ASCII double quotes inside JSX attribute values and use corner quotes like 「生日快乐」 for visitor-facing quoted examples.")
2129
- .optional(),
2130
- })
2131
- .strict()
2132
- .superRefine((value, ctx) => {
2133
- const hasFullContent = value.full_content !== undefined;
2134
- if (value.operation === "delete") {
2135
- if (hasFullContent) {
2136
- ctx.addIssue({
2137
- code: "custom",
2138
- path: ["full_content"],
2139
- message: "delete patches must not include full_content",
2140
- });
2141
- }
2142
- return;
2143
- }
2144
- if (!hasFullContent) {
2145
- ctx.addIssue({
2146
- code: "custom",
2147
- path: ["full_content"],
2148
- message: "create/update patches must include full_content",
2149
- });
2150
- }
2151
- });
2152
- export const MediaRequestOwnerSchema = z.object({
2153
- kind: z.enum(["block", "page", "site", "chrome"]),
2154
- id: z.string().min(1).max(120),
2155
- });
2156
- export const WorkspaceMediaRequestSchema = z.object({
2157
- base_key: z
2158
- .string()
2159
- .min(1)
2160
- .max(120)
2161
- .regex(/^[A-Za-z0-9._:-]+$/)
2162
- .refine((value) => !value.includes(".."), {
2163
- message: "base_key must not contain '..'",
2164
- }),
2165
- owner: MediaRequestOwnerSchema,
2166
- count: z.number().int().min(1).max(12),
2167
- query: z.string().min(1).max(400),
2168
- role: z.enum([
2169
- "hero",
2170
- "section",
2171
- "card",
2172
- "gallery",
2173
- "testimonial",
2174
- "decorative",
2175
- "site_background",
2176
- "nav_background",
2177
- "footer_background",
2178
- ]),
2179
- orientation: z.enum(["landscape", "portrait", "square"]).optional(),
2180
- altHint: z.string().min(1).max(300),
2181
- });
2182
- export const ApplyPatchBatchInputSchema = z
2183
- .object({
2184
- site_id: z.string().min(1),
2185
- base_snapshot_id: z.string().min(1),
2186
- reason: z.string().min(1),
2187
- patches: z.array(ApplyPatchBatchPatchSchema).min(1),
2188
- media_requests: z.array(WorkspaceMediaRequestSchema).max(24).optional(),
2189
- post_actions: z.array(ApplyPatchBatchPostActionSchema).optional(),
2190
- })
2191
- .superRefine((value, ctx) => {
2192
- const seenPaths = new Set();
2193
- for (const [index, patch] of value.patches.entries()) {
2194
- if (seenPaths.has(patch.path)) {
2195
- ctx.addIssue({
2196
- code: "custom",
2197
- path: ["patches", index, "path"],
2198
- message: `Duplicate patch path: ${patch.path}`,
2199
- });
2200
- }
2201
- seenPaths.add(patch.path);
2202
- }
2203
- });
2204
- export const WorkspaceDirectEditSiteEditRouteSchema = z.object({
2205
- routeId: z.string().min(1),
2206
- entryFile: SnapshotFilePathSchema,
2207
- });
2208
- export const WorkspaceDirectEditRequestSchema = z
2209
- .object({
2210
- baseSnapshotId: z.string().min(1).optional(),
2211
- reason: z.string().min(1),
2212
- patches: z.array(ApplyPatchBatchPatchSchema).min(1).optional(),
2213
- siteEditOperation: SiteEditOperationRequestSchema.optional(),
2214
- siteEditRoutes: z
2215
- .array(WorkspaceDirectEditSiteEditRouteSchema)
2216
- .min(1)
2217
- .optional(),
2218
- postActions: z.array(ApplyPatchBatchPostActionSchema).optional(),
2219
- })
2220
- .superRefine((value, ctx) => {
2221
- const hasPatches = value.patches !== undefined;
2222
- const hasSiteEditOperation = value.siteEditOperation !== undefined;
2223
- if (hasPatches === hasSiteEditOperation) {
2224
- ctx.addIssue({
2225
- code: "custom",
2226
- path: ["patches"],
2227
- message: "Direct edit requests must include exactly one of patches or siteEditOperation.",
2228
- });
2229
- }
2230
- if (hasSiteEditOperation && !value.siteEditRoutes) {
2231
- ctx.addIssue({
2232
- code: "custom",
2233
- path: ["siteEditRoutes"],
2234
- message: "siteEditRoutes is required for siteEditOperation.",
2235
- });
2236
- }
2237
- if (!value.patches) {
2238
- return;
2239
- }
2240
- const seenPaths = new Set();
2241
- for (const [index, patch] of value.patches.entries()) {
2242
- if (seenPaths.has(patch.path)) {
2243
- ctx.addIssue({
2244
- code: "custom",
2245
- path: ["patches", index, "path"],
2246
- message: `Duplicate patch path: ${patch.path}`,
2247
- });
2248
- }
2249
- seenPaths.add(patch.path);
2250
- }
2251
- });
2252
- export const ApplyPatchBatchErrorCodeSchema = z.enum([
2253
- "BASE_SNAPSHOT_NOT_FOUND",
2254
- "PATCH_TARGET_NOT_FOUND",
2255
- "PATCH_TARGET_ALREADY_EXISTS",
2256
- "PATCH_EXPECTED_HASH_MISMATCH",
2257
- "PATCH_DIFF_UNSUPPORTED",
2258
- "PATCH_PROTECTED_FILE",
2259
- "PATCH_VALIDATION_FAILED",
2260
- "PATCH_MEDIA_REFERENCE_NOT_DECLARED",
2261
- "PATCH_BATCH_INVALID",
2262
- "PATCH_BATCH_FAILED",
2263
- ]);
2264
- export const ApplyPatchBatchSuccessSchema = z.object({
2265
- status: z.literal("applied"),
2266
- patch_batch_id: z.string().min(1),
2267
- site_id: z.string().min(1),
2268
- base_snapshot_id: z.string().min(1),
2269
- snapshot_id: z.string().min(1),
2270
- manifest_hash: SnapshotContentHashSchema,
2271
- object_key: z.string().min(1),
2272
- changed_files: z.array(SnapshotFilePathSchema).min(1),
2273
- post_actions_queued: z.array(ApplyPatchBatchPostActionSchema),
2274
- });
2275
- export const ApplyPatchBatchFailureSchema = z.object({
2276
- status: z.literal("failed"),
2277
- code: ApplyPatchBatchErrorCodeSchema,
2278
- message: z.string().min(1),
2279
- retryable: z.boolean().default(false),
2280
- details: z.unknown().optional(),
2281
- });
2282
- export const ApplyPatchBatchResultSchema = z.discriminatedUnion("status", [
2283
- ApplyPatchBatchSuccessSchema,
2284
- ApplyPatchBatchFailureSchema,
2285
- ]);
2286
- export const WorkspaceDirectEditResponseSchema = z.object({
2287
- result: ApplyPatchBatchResultSchema,
2288
- post_action_results: z.record(z.string(), z.unknown()).optional(),
2289
- });
2290
- export function containsSensitiveData(value) {
2291
- if (typeof value === "string") {
2292
- return /authorization\s*:|bearer\s+|token\s*=|secret\s*=|api[_-]?key\s*=|access[_\s-]?key\s*=/i.test(value);
2293
- }
2294
- if (!value || typeof value !== "object") {
2295
- return false;
2296
- }
2297
- if (Array.isArray(value)) {
2298
- return value.some((item) => containsSensitiveData(item));
2299
- }
2300
- return Object.entries(value).some(([key, entry]) => isSensitiveObjectKey(key) || containsSensitiveData(entry));
2301
- }
2302
- function isSensitiveObjectKey(key) {
2303
- const normalized = key
2304
- .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
2305
- .replace(/\s+/g, "_")
2306
- .toLowerCase();
2307
- return /(^|[_-])(authorization|token|secret|api[_-]?key|apikey|access[_-]?key|accesskey)([_-]|$)/.test(normalized);
2308
- }
2309
- function isSafeSnapshotPath(path) {
2310
- const segments = path.split("/");
2311
- return (path.length > 0 &&
2312
- !path.startsWith("/") &&
2313
- !path.includes("\\") &&
2314
- segments.every((segment) => segment !== "" && segment !== "." && segment !== ".."));
2315
- }
2316
- export const SandboxSessionStatusSchema = z.enum([
2317
- "idle",
2318
- "creating",
2319
- "restoring_snapshot",
2320
- "installing_dependencies",
2321
- "starting_preview",
2322
- "ready",
2323
- "active",
2324
- "stopping",
2325
- "stopped",
2326
- "failed",
2327
- ]);
2328
- export const SandboxSessionSchema = z.object({
2329
- id: z.string().min(1),
2330
- tenant_id: z.string().min(1),
2331
- site_id: z.string().min(1),
2332
- sandbox_id: z.string().min(1).nullable(),
2333
- status: SandboxSessionStatusSchema,
2334
- source_snapshot_id: z.string().min(1).nullable(),
2335
- last_snapshot_id: z.string().min(1).nullable(),
2336
- preview_url: z.string().url().nullable(),
2337
- last_activity_at: z.string().min(1).nullable(),
2338
- created_at: z.string().min(1),
2339
- updated_at: z.string().min(1),
2340
- });
2341
- export const PersistPreviewSessionRequestSchema = z.object({
2342
- session_id: z.string().min(1).optional(),
2343
- sandbox_id: z.string().min(1).optional(),
2344
- source_snapshot_id: z.string().min(1).optional(),
2345
- last_snapshot_id: z.string().min(1),
2346
- status: SandboxSessionStatusSchema,
2347
- preview_url: z.string().url().optional(),
2348
- });
2349
- export const PersistPreviewSessionResponseSchema = z.object({
2350
- preview_session: SandboxSessionSchema,
2351
- next_step: z.literal("preview"),
2352
- });
1
+ import{z as e}from"zod";import{z as n}from"zod";import{z as h}from"zod";var Oe=h.object({code:h.string().min(1),message:h.string().min(1)}),an=h.object({code:h.string().min(1),message:h.string().min(1)});function F(i){return h.object({ok:h.literal(!0),data:i})}function De(i){let a={ok:h.literal(!1),error:Oe.extend({code:i.codeSchema})};return i.currentSchema&&(a.current=i.currentSchema.optional()),i.diagnosticsSchema&&(a.diagnostics=h.array(i.diagnosticsSchema).optional()),i.dataSchema&&(a.data=i.dataSchema.optional()),h.object(a)}function I(i){return h.discriminatedUnion("ok",[F(i.dataSchema),De({codeSchema:i.codeSchema,currentSchema:i.currentSchema,diagnosticsSchema:i.diagnosticsSchema,dataSchema:i.failureDataSchema})])}var x=n.enum(["update-text","remove-node","insert-child","move-node","replace-rich-text-content","insert-rich-text-block","remove-rich-text-block","set-media-field","set-component-slot-content","set-object-field","insert-object-field","remove-object-field","update-array-item","insert-array-item","remove-array-item","move-array-item","replace-conditional-expression","set-conditional-branch-content","set-jsx-prop","remove-jsx-prop","set-class-name","add-class-token","remove-class-token","set-style-property","set-style-properties","set-css-module-class","set-directive","remove-directive","set-route-export","set-metadata-field","set-generate-metadata"]),u=n.lazy(()=>n.union([n.string(),n.number(),n.boolean(),n.null(),n.array(u),n.record(n.string(),u)])),ee=n.discriminatedUnion("kind",[n.object({kind:n.literal("node"),key:n.string().min(1)}),n.object({kind:n.literal("route"),routeId:n.string().min(1)})]),te=n.enum(["display","position","top","right","bottom","left","zIndex","flexDirection","flexWrap","flexGrow","flexShrink","flexBasis","order","gridTemplateColumns","gridTemplateRows","columns","gridColumn","gridRow","gap","gapX","gapY","spaceX","spaceY","alignItems","justifyContent","marginTop","marginRight","marginBottom","marginLeft","paddingTop","paddingRight","paddingBottom","paddingLeft","width","height","minWidth","minHeight","maxWidth","maxHeight","overflow","fontFamily","fontSize","fontWeight","lineHeight","letterSpacing","textAlign","textTransform","textDecoration","textOverflow","textIndent","writingMode","whiteSpace","wordBreak","lineClamp","fontVariantNumeric","screenReaderOnly","color","backgroundColor","backgroundImage","borderStyle","borderWidth","borderRadius","borderColor","objectFit","objectPosition","aspectRatio","opacity","boxShadow","transform","transformOrigin","transitionProperty","transitionDuration","transitionTimingFunction","animation","pointerEvents","cursor","userSelect","fontStyle","textUnderlineOffset","scrollMarginTop","alignSelf","flex","outlineStyle","resize","ringWidth","ringColor","backdropFilter","overscrollBehavior","divideWidth","divideColor"]),ne=n.enum(["hover","active","focus","disabled"]),ie=n.enum(["sm","md","lg","xl","2xl"]),J=n.union([n.object({relation:n.enum(["before","after"]),anchorKey:n.string().min(1)}),n.object({relation:n.enum(["prepend","append"]),parentKey:n.string().min(1)})]),Ne=n.discriminatedUnion("kind",[n.object({kind:n.literal("native-tag"),tag:n.string().min(1),text:n.string().optional()}),n.object({kind:n.literal("component-call"),component:n.object({source:n.string().min(1),exportName:n.string().min(1)}),props:n.record(n.string(),n.unknown()).optional()})]),Le=n.discriminatedUnion("kind",[n.object({kind:n.literal("update-text"),segmentIndex:n.number().int().min(0),value:n.string()}),n.object({kind:n.literal("remove-node")}),n.object({kind:n.literal("insert-child"),node:Ne,position:J}),n.object({kind:n.literal("move-node"),target:J,preserveBindings:n.boolean().optional()}),n.object({kind:n.literal("replace-rich-text-content"),field:n.string().min(1),value:u}),n.object({kind:n.literal("insert-rich-text-block"),field:n.string().min(1),index:n.number().int().min(0),block:u}),n.object({kind:n.literal("remove-rich-text-block"),field:n.string().min(1),index:n.number().int().min(0)}),n.object({kind:n.literal("set-media-field"),field:n.enum(["src","alt","poster","caption","width","height"]),value:u}),n.object({kind:n.literal("set-component-slot-content"),slotName:n.string().min(1),value:u}),n.object({kind:n.literal("set-object-field"),segmentIndex:n.number().int().min(0),value:u}),n.object({kind:n.literal("insert-object-field"),segmentIndex:n.number().int().min(0),field:n.string().min(1),value:u}),n.object({kind:n.literal("remove-object-field"),segmentIndex:n.number().int().min(0),field:n.string().min(1).optional()}),n.object({kind:n.literal("update-array-item"),segmentIndex:n.number().int().min(0),value:u,index:n.number().int().min(0).optional()}),n.object({kind:n.literal("insert-array-item"),segmentIndex:n.number().int().min(0),index:n.number().int().min(0),value:u}),n.object({kind:n.literal("remove-array-item"),segmentIndex:n.number().int().min(0),index:n.number().int().min(0).optional()}),n.object({kind:n.literal("move-array-item"),segmentIndex:n.number().int().min(0),toIndex:n.number().int().min(0),fromIndex:n.number().int().min(0).optional()}),n.object({kind:n.literal("replace-conditional-expression"),nextExpression:n.string().min(1)}),n.object({kind:n.literal("set-conditional-branch-content"),branch:n.enum(["then","else"]),content:n.object({jsx:n.string().min(1)})}),n.object({kind:n.literal("set-jsx-prop"),name:n.string().min(1),value:u.nullable()}),n.object({kind:n.literal("remove-jsx-prop"),name:n.string().min(1)}),n.object({kind:n.literal("set-class-name"),value:n.string()}),n.object({kind:n.literal("add-class-token"),token:n.string().min(1)}),n.object({kind:n.literal("remove-class-token"),token:n.string().min(1)}),n.object({kind:n.literal("set-style-property"),property:n.string().min(1),value:u.nullable()}),n.object({kind:n.literal("set-style-properties"),properties:n.record(n.string(),u.nullable())}),n.object({kind:n.literal("set-css-module-class"),from:n.string().min(1),to:n.string().min(1)}),n.object({kind:n.literal("set-directive"),value:n.enum(["use client","use server"])}),n.object({kind:n.literal("remove-directive"),value:n.enum(["use client","use server"])}),n.object({kind:n.literal("set-route-export"),name:n.string().min(1),value:u}),n.object({kind:n.literal("set-metadata-field"),field:n.string().min(1),value:u.nullable()}),n.object({kind:n.literal("set-generate-metadata"),field:n.string().min(1),value:u.nullable()})]),ae=n.enum(["NODE_NOT_FOUND","ROUTE_NOT_FOUND","CAPABILITY_REJECTED","CONSTRAINT_VIOLATED","INVALID_PARAMS","PLAN_FAILED","VERSION_STALE","AST_PARSE_ERROR","UNSUPPORTED_OPERATION","LOCATOR_FAILED","INVALID_TARGET","WRITE_IO_ERROR","CONCURRENT_MODIFIED","ROLLBACK_FAILED","INTERNAL_ERROR"]),se=n.object({code:ae,message:n.string().min(1),details:n.record(n.string(),n.unknown()).optional()}),re=n.object({id:n.string().min(1),siteId:n.string().min(1),baseSnapshotId:n.string().min(1),routeId:n.string().min(1).optional(),kind:x,target:ee,documentVersion:n.number().int().nonnegative(),params:Le}).superRefine((i,a)=>{i.kind!==i.params.kind&&a.addIssue({code:"custom",path:["params","kind"],message:"params.kind must match operation kind"})}),A=n.object({requestId:n.string().min(1),kind:x,target:ee,resultVersion:n.number().int().nonnegative(),affectedFiles:n.array(n.string().min(1)).optional()}),cn=I({dataSchema:A,codeSchema:ae,failureDataSchema:A.partial()});import{z as g}from"zod";var w=g.enum(["component-boundary","repeat-region","conditional-region","fragment-region","opaque-region"]),We=g.enum(["direct","proxy","upstream","readonly","unsupported"]),qe=g.enum(["component-boundary","repeat-region","conditional-region","opaque-region","void-element","read-only","cross-file-required","import-required"]),P=g.object({mode:We,reasonCode:g.string().min(1).optional()}),Ue=g.object({kind:qe,message:g.string().min(1)}),C=g.object({key:g.string().min(1),canUpdateText:g.boolean(),canInsertChild:g.boolean(),canMove:g.boolean(),canRemove:g.boolean(),editModes:g.object({updateText:P.optional(),insertChild:P.optional(),move:P.optional(),remove:P.optional()}).optional(),constraints:g.array(Ue)});import{z as s}from"zod";var f=s.object({start:s.number().int().nonnegative(),end:s.number().int().nonnegative(),startLine:s.number().int().positive().optional(),startColumn:s.number().int().nonnegative().optional(),endLine:s.number().int().positive().optional(),endColumn:s.number().int().nonnegative().optional()}).superRefine((i,a)=>{i.end<i.start&&a.addIssue({code:"custom",path:["end"],message:"end must be greater than or equal to start"})}),oe=s.object({code:s.enum(["missing-class-name","unsupported-attribute-name","source-locator-warning","invalid-new-attr","version-conflict","write-failed"]),message:s.string().min(1)}),O=s.object({key:s.string().min(1),routeId:s.string().min(1),filePath:s.string().min(1),componentName:s.string().min(1),sourceKind:s.enum(["missing","stringLiteral","expression"]),attrRaw:s.string().min(1).nullable(),valueRaw:s.string().min(1).nullable(),attrRange:f.nullable(),valueRange:f.nullable(),openingElementRange:f,version:s.object({documentVersion:s.number().int().nonnegative(),contentHash:s.string().min(1),parserVersion:s.string().min(1)}),diagnostics:s.array(oe)}).superRefine((i,a)=>{if(i.sourceKind==="missing"){(i.attrRaw!==null||i.valueRaw!==null||i.attrRange!==null||i.valueRange!==null)&&a.addIssue({code:"custom",message:"missing className source must not include attr raw or range"});return}(i.attrRaw===null||i.valueRaw===null||i.attrRange===null||i.valueRange===null)&&a.addIssue({code:"custom",message:"present className source must include attr raw and ranges"})}),gn=O,hn=F(O),Fe=s.object({source:s.enum(["style-panel","class-source-editor"]),operation:s.enum(["replace-static-classname","replace-expression","create-attribute","remove-attribute"])}),_n=s.object({key:s.string().min(1),routeId:s.string().min(1).optional(),filePath:s.string().min(1),expectedVersion:s.object({documentVersion:s.number().int().nonnegative(),contentHash:s.string().min(1)}),oldAttrRaw:s.string().min(1).nullable(),oldAttrRange:f.nullable(),openingElementRange:f,newAttrRaw:s.string().min(1).nullable(),intent:Fe}),Me=s.enum(["node_not_found","document_version_stale","file_hash_mismatch","range_mismatch","old_attr_mismatch","invalid_new_attr","unsupported_target","write_failed"]),Sn=I({dataSchema:O,codeSchema:Me,currentSchema:O,diagnosticsSchema:oe});import{z as r}from"zod";var kn=r.discriminatedUnion("type",[r.object({type:r.literal("site-edit.document.changed"),siteId:r.string().min(1),snapshotId:r.string().min(1),routeId:r.string().min(1),version:r.number().int().nonnegative(),at:r.string().min(1)}),r.object({type:r.literal("site-edit.operation.planned"),siteId:r.string().min(1),operationId:r.string().min(1),baseSnapshotId:r.string().min(1),changedFiles:r.array(r.string().min(1)),at:r.string().min(1)}),r.object({type:r.literal("site-edit.operation.completed"),siteId:r.string().min(1),result:A,at:r.string().min(1)}),r.object({type:r.literal("site-edit.operation.failed"),siteId:r.string().min(1),requestId:r.string().min(1),error:se,at:r.string().min(1)}),r.object({type:r.literal("site-edit.capability.changed"),siteId:r.string().min(1),routeId:r.string().min(1),keys:r.array(r.string().min(1)),at:r.string().min(1)})]);import{z as k}from"zod";var D="::",jn=k.object({file:k.string().min(1),component:k.string().min(1),structuralPath:k.string().min(1),key:k.string().min(1)}).superRefine((i,a)=>{let m=Ge(i.file,i.component,i.structuralPath);i.key!==m&&a.addIssue({code:"custom",path:["key"],message:"key must match file::component::structuralPath"})});function Ge(i,a,m){return`${i}${D}${a}${D}${m}`}function Rn(i){let[a,m,..._]=i.split(D);return!a||!m||_.length===0?null:{file:a,component:m,structuralPath:_.join(D)}}import{z as l}from"zod";var Be=l.string().min(1).refine(i=>!i.startsWith("/")&&!i.includes(".."),{message:"Patch paths must be safe relative POSIX paths."}),He=l.string().regex(/^sha256:[a-f0-9]{64}$/),Ke=l.object({path:Be,operation:l.enum(["create","update","delete"]),expectedHash:He.optional(),fullContent:l.string().optional()}).superRefine((i,a)=>{i.operation==="delete"&&i.fullContent!==void 0&&a.addIssue({code:"custom",path:["fullContent"],message:"delete patches must not include fullContent"}),i.operation!=="delete"&&i.fullContent===void 0&&a.addIssue({code:"custom",path:["fullContent"],message:"create/update patches must include fullContent"})}),An=l.object({siteId:l.string().min(1),baseSnapshotId:l.string().min(1),operationId:l.string().min(1),reason:l.string().min(1),patches:l.array(Ke).min(1),changedRouteIds:l.array(l.string().min(1)),diagnostics:l.array(l.object({code:l.string().min(1),message:l.string().min(1),path:l.string().min(1).optional()})).default([])}).superRefine((i,a)=>{let m=new Set;for(let[_,d]of i.patches.entries())m.has(d.path)&&a.addIssue({code:"custom",path:["patches",_,"path"],message:`Duplicate patch path: ${d.path}`}),m.add(d.path)});import{z as t}from"zod";var Ve=t.object({canUpdateText:t.boolean(),canInsertChild:t.boolean(),canMove:t.boolean(),canRemove:t.boolean()}),ze=t.object({key:t.string().min(1),tag:t.string().min(1),label:t.string().min(1),parentKey:t.string().min(1).nullable(),childKeys:t.array(t.string().min(1)),operationSummary:Ve}),qn=t.object({siteId:t.string().min(1),snapshotId:t.string().min(1),routeId:t.string().min(1),version:t.number().int().nonnegative(),rootKeys:t.array(t.string().min(1)),entries:t.array(ze)}),M=t.enum(["api-field","cms-field","i18n-message","config-entry"]),$e=t.object({kind:t.enum(["literal","binding","imported-binding","repeat-template"]),file:t.string().min(1),expression:t.string().min(1),bindingName:t.string().min(1).optional(),path:t.array(t.union([t.string(),t.number()])).optional()}),ce=t.object({index:t.number().int().min(0),value:t.string(),editable:t.boolean(),source:$e.nullable()}),b=t.object({key:t.string().min(1),label:t.string().min(1),tag:t.string().min(1)}),Un=t.object({key:t.string().min(1),canUpdateText:t.boolean(),canInsertChild:t.boolean(),canMove:t.boolean(),canRemove:t.boolean(),boundaryKind:w.nullable(),isOpaque:t.boolean()}),me=t.object({kind:t.enum(["jsx-node","component-proxy","value-binding","route-export"]),file:t.string().min(1),componentName:t.string().min(1),isProxy:t.boolean()}),le=t.object({kind:t.enum(["jsx-node","value-path","route-export","external-entry"]),file:t.string().min(1).optional(),isProxy:t.boolean(),displayPath:t.string().min(1).optional(),sourceType:M.optional(),sourceId:t.string().min(1).optional()}),pe=t.object({kind:t.union([t.enum(["jsx-literal","component-prop","binding","imported-binding","object-field","array-item","repeat-template","conditional-branch"]),M]),file:t.string().min(1),displayPath:t.string().min(1),externalSource:t.object({sourceType:M,sourceId:t.string().min(1),adapterId:t.string().min(1).optional()}).optional()}),Ye=t.object({kind:pe.shape.kind,file:t.string().min(1),displayName:t.string().min(1),canEditHere:t.boolean()}),N=t.object({finalSource:pe.nullable(),chain:t.array(Ye),confidence:t.enum(["exact","safe-derived","partial","unknown"]),editMode:t.enum(["direct","proxy","upstream","readonly","unsupported"]),diagnostics:t.array(t.object({code:t.string().min(1),message:t.string().min(1)}))}),Xe=t.object({kind:t.literal("css-style-model"),properties:t.array(t.object({property:te,value:t.union([t.string(),t.number(),t.boolean(),t.null()]),resolvedValue:t.union([t.string(),t.number(),t.boolean(),t.null()]).optional(),breakpoint:ie.optional(),state:ne.optional(),variants:t.array(t.string().min(1)).optional(),options:t.array(t.union([t.string(),t.number()])).optional(),editable:t.boolean(),diagnostics:t.array(t.object({code:t.string().min(1),message:t.string().min(1)})).optional(),operationBoundary:t.array(x).optional()}))}),Fn=t.union([t.record(t.string(),t.unknown()),Xe]),de=t.object({kind:t.literal("class-name-source"),className:t.string(),sourceKind:t.enum(["missing","static-attribute","static-expression","dynamic-expression"]),editable:t.boolean(),operationBoundary:t.array(x),sourcePath:t.string().min(1).optional(),diagnostics:t.array(t.object({code:t.enum(["missing-class-name","dynamic-binding","non-string-binding"]),message:t.string().min(1)})).optional()}),Mn=t.object({key:t.string().min(1),tag:t.string().min(1),componentName:t.string().min(1),sourceFile:t.string().min(1),label:t.string().min(1),capabilities:C,writeTarget:me,effectiveWriteTarget:le.optional(),provenanceChain:N.optional(),componentSemantic:t.record(t.string(),t.unknown()).optional(),contentModel:t.record(t.string(),t.unknown()).optional(),mediaModel:t.record(t.string(),t.unknown()).optional(),styleSource:de.optional(),conditional:t.record(t.string(),t.unknown()).optional(),textSegments:t.array(ce),boundaryKind:w.nullable(),isOpaque:t.boolean(),ancestors:t.array(b),children:t.array(b),siblings:t.array(b)}),Gn=t.object({key:t.string().min(1),tag:t.string().min(1),label:t.string().min(1),capabilities:t.object({constraints:C.shape.constraints}),isOpaque:t.boolean(),provenanceChain:t.object({editMode:N.shape.editMode,diagnostics:N.shape.diagnostics}).optional(),ancestors:t.array(b)}),Bn=t.object({key:t.string().min(1),componentName:t.string().min(1),sourceFile:t.string().min(1),capabilities:C,writeTarget:me,effectiveWriteTarget:le.optional(),provenanceChain:N.optional(),componentSemantic:t.record(t.string(),t.unknown()).optional(),textSegments:t.array(ce),boundaryKind:w.nullable(),children:t.array(b),siblings:t.array(b)}),Hn=t.object({key:t.string().min(1),styleSource:de.optional()}),Kn=t.object({key:t.string().min(1),contentModel:t.record(t.string(),t.unknown()).optional()}),Vn=t.object({key:t.string().min(1),mediaModel:t.record(t.string(),t.unknown()).optional()});var $n={PATCH_VALIDATION_FAILED:"The code didn't pass validation. Try describing the change more specifically.",PATCH_BATCH_FAILED:"The site code couldn't be generated. Please regenerate the site.",PATCH_BATCH_INVALID:"The change couldn't be applied. Try simpler instructions.",WORKSPACE_TOOL_RESULT_INVALID:"This change couldn't be completed and was rolled back. Please try again.",WORKSPACE_TOOL_FAILED:"A tool step failed. Please try again.",WORKSPACE_TOOL_RESULT_MISSING:"The tool didn't return a usable result. Please try again.",WORKSPACE_MODEL_STREAM_FAILED:"The model stream ended unexpectedly. Please try again.",WORKSPACE_EDIT_NOT_APPLIED:"No change was applied. Try describing the change differently.",WORKSPACE_INITIAL_EXECUTION_FAILED:"Initial generation failed. Please retry from the brief.",WORKSPACE_INITIAL_GENERATION_CHECK_FAILED:"Initial generation could not be verified. Please retry.",WORKSPACE_INITIAL_GENERATION_FINALIZE_FAILED:"Initial generation could not finalize. Please retry.",WORKSPACE_SOCKET_DEAD:"The workspace connection was lost. Please retry.",WORKSPACE_RUN_CANCELLED:"The run was cancelled.",WORKSPACE_RUN_REQUEST_FAILED:"Couldn't start the workspace. Please try again.",WORKSPACE_RUN_BAD_RESPONSE:"The server response was malformed. Please try again.",WORKSPACE_SOCKET_UNAVAILABLE:"Workspace connection unavailable. Please try again.",WORKSPACE_SOCKET_ERROR:"The workspace connection had an error. Please try again.",WORKSPACE_SOCKET_CLOSED:"The workspace connection closed. Please try again.",SITE_SNAPSHOT_REQUIRED:"This site has no usable snapshot yet. Complete Step 3 first.",AGENT_TIMEOUT:"That took longer than expected. Try breaking the change into smaller pieces.",SANDBOX_NOT_AVAILABLE:"The preview environment isn't ready. Your edits have still been saved.",PREVIEW_BUILD_FAILED:"Preview is available, but the production build failed. Fix the reported build error before deploying.",PREVIEW_BUILD_NOT_CONFIGURED:"Preview is available, but the production build check is not configured.",PREVIEW_BUILD_SANDBOX_NOT_FOUND:"Preview is available, but the build check could not find the active preview sandbox.",WS_CONNECTION_ERROR:"Connection lost. Reconnecting\u2026",USER_MESSAGE_PERSIST_FAILED:"Your message wasn't saved. Please send it again.",CLARIFICATION_REPLY_STALE:"That question has expired. Please tell me what you'd like to do now.",WORKSPACE_RUN_IN_FLIGHT:"Another session is already running. Please try again in a moment.",GENERIC:"Something went wrong. Please try again."},Yn={UNDO_OR_ROLLBACK:"I can't roll back from chat. Use the version history at the top right to pick a restore point.",HISTORY_RECALL:"Tell me what you'd like to change now\u2014I'll work from the current page state.",OUT_OF_SCOPE:"That's outside what I can do from chat. Try the corresponding panel on the right."},Xn={CARD_HEADER:"Needs your confirmation",FREE_TEXT_PLACEHOLDER:"Or describe what you'd like instead",SUBMIT_LABEL:"Submit"},Qn={SEND_FAILED_RETRY:"Send failed \u2014 tap to retry"};var L=e.object({heading:e.string().min(1).max(60).optional(),body:e.string().min(1).max(60).optional(),paletteIntent:e.string().min(1).max(120).optional(),surfaceMode:e.enum(["light","dark"]).optional(),radius:e.enum(["none","sm","md","lg","xl"]).optional(),density:e.enum(["compact","comfortable","editorial"]).optional(),colorSeeds:e.object({primary:e.string().min(1).max(40),accent:e.string().min(1).max(40),neutral:e.string().min(1).max(40),supporting:e.array(e.string().min(1).max(40)).max(4).optional()}).optional()}),W=e.object({protocol:e.enum(["phone","form","download","route","external"]),ctaLabel:e.string().min(1).max(40),ctaTarget:e.string().min(1).max(200).optional(),requiresOwnerDetail:e.boolean().optional()}),ge=e.enum(["text-options","motion-slider"]),he=e.enum(["none","subtle","moderate","expressive"]),B=e.object({skill_name:e.string().min(1),rationale:e.string().min(4).max(200),confidence:e.enum(["high","medium","low"]).optional()}),ti=e.object({questions:e.array(e.object({id:e.string(),type:ge,question:e.string(),tag:e.string(),aiThinking:e.string(),options:e.array(e.object({value:e.string(),label:e.string(),desc:e.string().optional(),impact:e.string().optional(),isRecommended:e.boolean().optional(),visualHints:L.optional(),conversionHints:W.optional()})),source:e.enum(["ai-detected","always-ask"]),sourceDetail:e.string()})).min(1).max(5),archetypeProposals:e.array(B).min(1).max(5).optional()}),_e=e.object({questions:e.array(e.object({id:e.string(),type:ge,question:e.string(),tag:e.string(),aiThinking:e.string(),options:e.array(e.object({value:e.string(),label:e.string(),desc:e.string().optional(),impact:e.string().optional(),isRecommended:e.boolean().optional(),visualHints:L.optional(),conversionHints:W.optional()})),source:e.enum(["ai-detected","always-ask"]),sourceDetail:e.string()})).min(1).max(5)}),ni=e.object({tenant_id:e.string().min(1),site_id:e.string().min(1),brief_id:e.string().min(1),brief:e.string().min(20).max(1e3)}),ii=e.discriminatedUnion("type",[e.object({type:e.literal("run.started"),runId:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("skill.selecting"),category:e.literal("page-generation"),available:e.array(e.object({id:e.string().min(1),name:e.string().min(1)})).max(20),at:e.string().min(1)}),e.object({type:e.literal("skill.selected"),category:e.literal("page-generation"),selected:e.object({id:e.string().min(1),name:e.string().min(1),reason:e.string().min(1).max(200)}),at:e.string().min(1)}),e.object({type:e.literal("clarify.partial"),object:e.unknown(),at:e.string().min(1)}),e.object({type:e.literal("clarify.archetype_proposals"),proposals:e.array(B).min(1).max(5),at:e.string().min(1)}),e.object({type:e.literal("clarify.finished"),questions_id:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("run.failed"),error_code:e.string().min(1),message:e.string().min(1),at:e.string().min(1)})]),Qe=e.enum(["draft","brief_submitted","clarifying","sitemap_ready","workspace_ready","deployed","archived","error"]),Ze={draft:["brief_submitted","archived","error"],brief_submitted:["clarifying","archived","error"],clarifying:["sitemap_ready","archived","error"],sitemap_ready:["workspace_ready","archived","error"],workspace_ready:["deployed","archived","error"],deployed:["workspace_ready","archived","error"],archived:[],error:["draft","brief_submitted","clarifying","sitemap_ready"]};function ai(i,a){if(!Ze[i].includes(a))throw new Error(`Invalid site status transition: ${i} -> ${a}`);return a}var Je=e.enum(["planning","initial_generation_running","generated"]),et={planning:["initial_generation_running"],initial_generation_running:["generated","planning"],generated:[]};function si(i,a){if(i===a)return a;if(!et[i].includes(a))throw new Error(`Invalid site generation state transition: ${i} -> ${a}`);return a}function ri(i){if(i.agent_type!=="workspace"||i.current_state==="generated")return null;switch(i.event_type){case"run.started":return i.current_state==="planning"?"initial_generation_running":null;case"run.finished":return i.current_state==="initial_generation_running"?"generated":null;case"run.failed":return i.current_state==="initial_generation_running"?"planning":null;default:return null}}var oi="SITE_PLANNING_INPUT_FROZEN",ci="SITE_PLANNING_LOCKED",mi=e.object({tenant_id:e.string().min(1),owner_user_id:e.string().min(1),name:e.string().min(1).max(120),brief:e.string().min(20).max(1e3)}),li=e.object({name:e.string().min(1).max(120),brief:e.string().min(20).max(1e3)}),j=e.object({id:e.string().min(1),tenant_id:e.string().min(1),owner_user_id:e.string().min(1),name:e.string().min(1),slug:e.string().min(1),status:Qe,generation_state:Je,planning_locked_at:e.string().min(1).nullable(),current_sitemap_id:e.string().min(1).nullable(),current_snapshot_id:e.string().min(1).nullable(),deployed_url:e.string().url().nullable(),schema_version:e.literal(1),created_at:e.string().min(1),updated_at:e.string().min(1)}),tt=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),body:e.string().min(1),source:e.enum(["user","import","system"]),created_at:e.string().min(1),updated_at:e.string().min(1)}),pi=e.object({site:j,brief:tt,next_step:e.literal("clarify")}),nt=e.enum(["queued","running","succeeded","failed","cancelled"]),Se=e.enum(["clarify","sitemap","workspace"]),be=e.enum(["clarify","sitemap","initial_generation","iteration"]),ye=e.enum(["clarify","sitemap","workspace","summarize"]),v=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),agent_type:Se,run_kind:be,status:nt,model_route:ye,started_at:e.string().min(1).nullable(),finished_at:e.string().min(1).nullable(),error_code:e.string().min(1).nullable(),created_at:e.string().min(1)}),di=e.object({run_id:e.string().min(1).optional(),site_id:e.string().min(1),agent_type:Se,run_kind:be.optional(),model_route:ye,input:e.record(e.string(),e.unknown()).optional()}).superRefine((i,a)=>{E(i.input)&&a.addIssue({code:"custom",path:["input"],message:"Agent run input must not contain secrets"})}),ui=e.object({agent_run:v,next_step:e.literal("stream_events")}),xe=e.enum(["draft","candidate","current","failed"]),q=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),version:e.number().int().positive(),manifest_hash:e.string().regex(/^sha256:[a-f0-9]{64}$/),object_key:e.string().min(1),reason:e.enum(["initial_generation","workspace_edit","pre_deploy","manual_save","rollback"]),status:xe,created_at:e.string().min(1)}),gi=e.object({snapshot_id:e.string().min(1).optional(),manifest_hash:e.string().regex(/^sha256:[a-f0-9]{64}$/),object_key:e.string().min(1),reason:q.shape.reason,status:xe.default("candidate")}),hi=e.object({site:j,snapshot:q,next_step:e.literal("workspace")}),_i=e.object({site:j,snapshot:q,next_step:e.literal("workspace")}),Si=e.object({status:e.literal("deleted"),snapshot_id:e.string().min(1)}),H=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),snapshot_id:e.string().min(1),version:e.number().int().positive(),accepted_commit:e.string().min(1),source_run_id:e.string().min(1).nullable(),created_at:e.string().min(1)}),bi=e.object({accepted_commit:e.string().min(1),source_run_id:e.string().min(1).optional()}),yi=e.object({site_version:H,next_step:e.literal("workspace")}),xi=e.object({site_versions:e.array(H)}),fi=e.object({site:j,snapshot:q,site_version:H,next_step:e.literal("workspace")}),it=e.enum(["queued","preparing_source","building","artifact_ready","deploying","released","lock_failed","source_prepare_failed","build_failed","artifact_fetch_failed","artifact_validation_failed","deploy_failed","cleanup_failed"]),at=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),snapshot_id:e.string().min(1),version:e.number().int().positive(),status:it,provider:e.enum(["cloudflare"]),url:e.string().url().nullable(),error_code:e.string().min(1).nullable(),provider_deployment_id:e.string().min(1).nullable(),created_at:e.string().min(1),updated_at:e.string().min(1)}),ki=e.object({snapshot_id:e.string().min(1).optional()}).default({}),vi=e.object({deployment:at}),Ei=e.object({error:e.object({code:e.string().min(1),message:e.string().min(1),details:e.unknown().optional(),request_id:e.string().min(1).optional(),retryable:e.boolean().default(!1)})}),ji=e.object({colors:e.record(e.string(),e.string()).default({}),typography:e.record(e.string(),e.string()).default({}),spacing:e.record(e.string(),e.string()).default({}),motion:e.record(e.string(),e.string()).default({})}),st=e.object({theme_id:e.string().min(1),paletteIntent:e.string().min(1),tone:e.string().min(1),mediaMood:e.string().min(1),motionLevel:he.optional(),userVisualHints:L.optional()}),rt=e.object({question:e.string().min(1),answer:e.string().min(1)}),Ri=e.object({query:e.string().min(1),keywords:e.array(e.string()).default([]),orientation:e.enum(["landscape","portrait","square"]).optional(),role:e.enum(["hero","section","card","gallery","testimonial","decorative"]),altHint:e.string().min(1)}),Ti=e.object({id:e.string().min(1),role:e.enum(["site_background","nav_background","footer_background"]),query:e.string().min(1),keywords:e.array(e.string()).default([]),treatment:e.enum(["cover","fixed-cover","subtle-texture"]),altHint:e.string().optional()}),ot=e.object({provider:e.enum(["unsplash","pexels"]),providerLabel:e.enum(["Unsplash","Pexels"]),providerHref:e.string().url(),photoHref:e.string().url().optional(),photographerName:e.string().optional(),photographerHref:e.string().url().optional(),requiresAttribution:e.boolean()}),Ii=e.object({src:e.string().min(1),alt:e.string().min(1),width:e.number().int().positive().optional(),height:e.number().int().positive().optional(),provider:e.enum(["unsplash","pexels","placeholder"]).optional(),providerId:e.string().optional(),photoUrl:e.string().url().optional(),photographer:e.string().optional(),photographerUrl:e.string().url().optional(),credit:e.string().optional(),attribution:ot.optional()}),ct=e.enum(["system_recommended","user_picked","user_picked_extended","deterministic_fallback"]),R=e.object({id:e.string().min(1),name:e.string().min(1),category:e.literal("page-generation"),version:e.string().min(1).optional(),reason:e.string().min(1).max(200),source:ct.default("system_recommended")}),c=e.string().min(1).max(2e3),ue=e.string().min(1).max(120),mt=e.object({visualDirection:c,brandFeeling:c,paletteIntent:c,typographyIntent:c,density:e.string().min(1),motionLevel:e.string().min(1),mediaStrategy:c,compositionRules:e.array(c).max(20),avoidPatterns:e.array(c).max(20),fonts:e.object({heading:e.string().min(1),body:e.string().min(1)}).optional(),colorSeeds:e.object({primary:e.string().min(1).max(40),accent:e.string().min(1).max(40),neutral:e.string().min(1).max(40),supporting:e.array(e.string().min(1).max(40)).max(4).optional()}).optional(),surfaceMode:e.enum(["light","dark"]).optional(),radius:e.enum(["none","sm","md","lg","xl"]).optional()}),lt=e.object({routeGoal:c,narrativeArc:c,firstViewportIntent:c,visualContinuity:c,sectionRhythm:c,avoidPatterns:e.array(c).max(20),displayTitle:e.string().min(1).max(24).optional(),displayDescription:e.string().min(1).max(60).optional(),metaTitle:e.string().min(1).max(120).optional(),metaDescription:e.string().min(1).max(320).optional()}),fe=e.enum(["model_call","validation","repair","preview","worker_group"]),pt=e.object({sectionRole:c,contentIntent:c,layoutIntent:c,visualIntent:c,mediaIntent:c,motionIntent:c,copyTone:c,displayTitle:e.string().min(1).max(24).optional(),displayDescription:e.string().min(1).max(60).optional(),ctaIntent:c.optional(),continuityWithPrevious:c.optional(),avoidRepeating:e.array(c).max(20).optional(),industryRecipeRefs:e.array(ue).max(12).optional(),templateRecipeRefs:e.array(ue).max(12).optional()}),ke=e.object({schemaVersion:e.literal(1).default(1),siteDesignContext:mt,routeCards:e.record(e.string().min(1),lt),blockContexts:e.record(e.string().min(1),pt),selectedSkillPacks:e.array(R).max(3).optional(),branding:e.object({siteName:e.string().min(1).max(120),tagline:e.string().min(1).max(200).optional(),primaryCta:e.object({label:e.string().min(1).max(60),target:e.string().min(1).max(200)}).optional(),trustSignals:e.array(e.string().min(1).max(60)).max(6).optional()}).optional()}),dt=e.object({id:e.string(),type:e.string(),variant:e.string().optional(),order:e.number(),props:e.record(e.string(),e.unknown()),enabled:e.boolean(),meta:e.object({aiGenerated:e.boolean(),userEdited:e.boolean(),lastEditedAt:e.string(),lastEditedBy:e.enum(["ai","user"]),userInstruction:e.string().optional()}).optional()}).strict(),ut=e.object({id:e.string(),slug:e.string(),title:e.string(),blocks:e.array(dt).min(1),layout:e.enum(["default","centered","fullwidth"]).optional(),navigation:e.object({showInHeader:e.boolean(),showInFooter:e.boolean(),order:e.number()})}).strict(),T=e.object({version:e.number().int().positive(),pages:e.array(ut).min(1),navigation:e.object({primaryLinks:e.array(e.object({label:e.string(),href:e.string()})),footerLinks:e.array(e.object({label:e.string(),href:e.string()}))}),integrations:e.object({cms:e.unknown().optional(),analytics:e.unknown().optional()}).optional(),meta:e.object({generatedAt:e.string(),generatedBy:e.literal("sitemap-agent"),source_brief_id:e.string().optional(),source_answer_ids:e.array(e.string()).optional()}),skillSelection:R,visualTheme:st.optional(),userChoices:e.array(rt).optional(),confirmedChoices:e.object({conversion:W.optional()}).optional()}).strict(),Ai=T.omit({skillSelection:!0,visualTheme:!0,userChoices:!0,confirmedChoices:!0}),gt=e.enum(["ai","user"]),y=e.object({site_id:e.string().min(1),page_id:e.string().min(1),edited_by:gt.default("ai"),source_agent_run_id:e.string().min(1).optional()}),Pi=y.extend({block_id:e.string().min(1),target_index:e.number().int().min(0)}),ht=y.extend({block_id:e.string().min(1)}),_t=y.extend({block_id:e.string().min(1),instruction:e.string()}),wi=y.extend({block_id:e.string().min(1),variant:e.string().min(1).nullable()}),Ci=y.extend({block_id:e.string().min(1),props:e.record(e.string(),e.unknown()),mode:e.enum(["replace","merge"]).default("replace")}),Oi=y.extend({block:e.object({id:e.string().min(1),type:e.string().min(1),variant:e.string().min(1).optional(),props:e.record(e.string(),e.unknown()).default({}),insert_index:e.number().int().min(0).optional()})}),St=e.enum(["move_block","delete_block","update_block_instruction","change_block_variant","update_block_props","add_block"]),Di=e.discriminatedUnion("operation",[e.object({operation:e.literal("delete_block"),input:ht}).strict(),e.object({operation:e.literal("update_block_instruction"),input:_t}).strict()]),bt=e.enum(["SITEMAP_EDIT_INVALID","SITEMAP_API_NOT_CONFIGURED","SITEMAP_NOT_FOUND","SITEMAP_PAGE_NOT_FOUND","SITEMAP_BLOCK_NOT_FOUND","SITEMAP_BLOCK_ALREADY_EXISTS","SITEMAP_EDIT_FAILED"]),yt=e.object({status:e.literal("updated"),operation:St,site_id:e.string().min(1),sitemap_id:e.string().min(1),version:e.number().int().positive(),changed_pages:e.array(e.string().min(1)).min(1),requires_code_patch:e.literal(!0)}),xt=e.object({status:e.literal("failed"),code:bt,message:e.string().min(1),retryable:e.boolean().default(!1),details:e.unknown().optional()}),Ni=e.discriminatedUnion("status",[yt,xt]),K=e.object({question_id:e.string().min(1),value:e.string().min(1),label:e.string().min(1).optional(),question:e.string().min(1).optional(),option_label:e.string().min(1).optional(),motion_level:he.optional(),visual_tonality:L.optional(),conversion:W.optional()}),Li=e.object({tenant_id:e.string().min(1),site_id:e.string().min(1),brief_id:e.string().min(1),brief:e.string().min(20).max(1e3),answers:e.array(K).min(1).max(10),skillSelection:R}),ve=e.enum(["planning","generating","validating","ready"]),Wi=e.discriminatedUnion("type",[e.object({type:e.literal("run.started"),runId:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("sitemap.generating"),stage:ve,message:e.string().min(1).optional(),at:e.string().min(1)}),e.object({type:e.literal("sitemap.partial"),object:e.unknown(),at:e.string().min(1)}),e.object({type:e.literal("sitemap.generated"),sitemap_id:e.string().min(1),sitemap:T,at:e.string().min(1)}),e.object({type:e.literal("run.failed"),error_code:e.string().min(1),message:e.string().min(1),at:e.string().min(1)})]),ft=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),version:e.number().int().positive(),sitemap:T,source_agent_run_id:e.string().min(1).nullable(),created_at:e.string().min(1),updated_at:e.string().min(1)}),qi=e.object({sitemap_id:e.string().min(1).optional(),sitemap:T,source_agent_run_id:e.string().min(1).optional()}),Ui=e.object({site:j,sitemap:ft,next_step:e.literal("workspace")}),kt=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),brief_id:e.string().min(1),questions:_e,answers:e.array(K),selected_archetype:R.optional(),completed_at:e.string().min(1).nullable(),created_at:e.string().min(1),updated_at:e.string().min(1)}),Fi=e.object({answers:e.array(K).min(1),questions:_e,selected_archetype:R.optional()}),Mi=e.object({clarify_session:kt}),vt=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),version:e.number().int().positive(),design_plan:ke,source_agent_run_id:e.string().min(1).nullable(),created_at:e.string().min(1),updated_at:e.string().min(1)}),Gi=e.object({design_plan_id:e.string().min(1).optional(),design_plan:ke,source_agent_run_id:e.string().min(1).optional()}),Bi=e.object({design_plan:vt}),U=e.enum(["initial_generation","iteration"]),Ee=e.enum(["run.started","message.delta","user.message","plan.updated","clarify.partial","clarify.archetype_proposals","clarify.finished","sitemap.generating","sitemap.partial","sitemap.generated","sitemap.updated","sitemap.resync.failed","block.changed","tool.started","tool.finished","workspace.plan.created","workspace.worker.updated","workspace.task.updated","file.changed","snapshot.created","preview.preparing","preview.ready","preview.build.started","preview.build.succeeded","preview.build.failed","run.failed","run.finished","media_resolution.started","media_resolution.finished","skill.selecting","skill.selected","activity.started","activity.updated","activity.finished","activity.failed"]),Et=e.object({id:e.string().min(1),title:e.string().min(1),status:e.enum(["pending","running","completed","failed"])}),S=e.enum(["pending","running","completed","completed_with_skips","failed","skipped"]),V=e.enum(["style_media","chrome","sections","layout","pages","detect_typecheck","repair","finalize","sitemap_resync","preview"]),jt=e.object({code:e.string().min(1),message:e.string().min(1),path:e.string().min(1).optional(),task_id:e.string().min(1).optional()}),p=e.string().min(1).refine(i=>en(i),{message:"Snapshot file paths must be safe relative POSIX paths without traversal."}),z=e.object({deduped_paths:e.array(p),skipped_tasks:e.array(e.string().min(1)),failed_tasks:e.array(e.string().min(1)),fallback_files:e.array(e.string().min(1)),applied_paths:e.array(p)}),$=e.object({group_id:e.string().min(1),phase:V,title:e.string().min(1),status:S,task_ids:e.array(e.string().min(1)),depends_on_groups:e.array(e.string().min(1)),target_paths:e.array(p)}),Rt=e.enum(["style","media","chrome","section","layout","page"]),Y=e.object({task_id:e.string().min(1),group_id:e.string().min(1),kind:Rt,target_path:p,block_id:e.string().min(1).optional(),block_type:e.string().min(1).optional(),block_variant:e.string().min(1).optional(),block_order:e.number().int().nonnegative().optional(),user_instruction:e.string().min(1).optional(),page_id:e.string().min(1).optional(),page_slug:e.string().min(1).optional(),page_title:e.string().min(1).optional(),title:e.string().min(1).max(60).optional(),description:e.string().min(1).max(160).optional(),status:S,required_reads:e.array(p).optional()}),X=e.object({from_group_id:e.string().min(1),to_group_id:e.string().min(1),reason:e.enum(["style_media","chrome","sections","layout","page_composition","quality_gate"])}),Hi=e.object({plan_id:e.string().min(1),run_kind:U,model_route:e.object({planner:e.literal("workspace_planner"),worker:e.literal("workspace")}),groups:e.array($),tasks:e.array(Y),dependencies:e.array(X),expected_outputs:e.array(p),diagnostics:z}),Ki=e.object({task_id:e.string().min(1),patch:e.unknown().optional(),snapshot_id:e.string().min(1).optional(),read_files:e.array(p),diagnostics:e.array(jt),status:S}),je=e.object({worker_count:e.number().int().nonnegative(),task_count:e.number().int().nonnegative(),group_count:e.number().int().nonnegative()}),Re=e.object({pending:e.number().int().nonnegative(),running:e.number().int().nonnegative(),completed:e.number().int().nonnegative(),completed_with_skips:e.number().int().nonnegative(),failed:e.number().int().nonnegative(),skipped:e.number().int().nonnegative()}),Tt=e.object({type:e.literal("text"),text:e.string(),state:e.enum(["streaming","done"]).optional()}),It=e.object({type:e.literal("reasoning"),text:e.string(),state:e.enum(["streaming","done"]).optional(),providerMetadata:e.record(e.string(),e.unknown()).optional()}),At=e.object({type:e.literal("file"),mediaType:e.string().min(1),filename:e.string().min(1).optional(),url:e.string().min(1)}),Pt=e.object({type:e.literal("source-url"),sourceId:e.string().min(1),url:e.string().min(1),title:e.string().min(1).optional(),providerMetadata:e.record(e.string(),e.unknown()).optional()}),wt=e.object({type:e.literal("source-document"),sourceId:e.string().min(1),mediaType:e.string().min(1),title:e.string().min(1),filename:e.string().min(1).optional(),providerMetadata:e.record(e.string(),e.unknown()).optional()}),Ct=e.object({type:e.string().regex(/^data-[a-zA-Z0-9_-]+$/),id:e.string().min(1).optional(),data:e.unknown()}),Ot=e.object({type:e.string().regex(/^tool-[a-zA-Z0-9_-]+$/),toolCallId:e.string().min(1),state:e.enum(["input-streaming","input-available","output-available","output-error"]),input:e.unknown().optional(),output:e.unknown().optional(),errorText:e.string().min(1).optional()}),Dt=e.object({type:e.literal("error"),errorText:e.string().min(1)}),Nt=e.object({type:e.literal("step-start")}),Q=e.union([Tt,It,At,Pt,wt,Ct,Ot,Dt,Nt]),Te=e.discriminatedUnion("type",[e.object({type:e.literal("run.started"),runId:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("message.delta"),text:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("user.message"),client_message_id:e.string().min(1),message_id:e.string().min(1),parts:e.array(Q).min(1),in_reply_to_tool_call_id:e.string().min(1).optional(),at:e.string().min(1)}),e.object({type:e.literal("plan.updated"),steps:e.array(Et),at:e.string().min(1)}),e.object({type:e.literal("clarify.partial"),object:e.unknown(),at:e.string().min(1)}),e.object({type:e.literal("clarify.archetype_proposals"),proposals:e.array(B).min(1).max(5),at:e.string().min(1)}),e.object({type:e.literal("clarify.finished"),questions_id:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("sitemap.generating"),stage:ve,message:e.string().min(1).optional(),at:e.string().min(1)}),e.object({type:e.literal("sitemap.partial"),object:e.unknown(),at:e.string().min(1)}),e.object({type:e.literal("sitemap.generated"),sitemap_id:e.string().min(1),sitemap:T,at:e.string().min(1)}),e.object({type:e.literal("sitemap.updated"),sitemap_id:e.string().min(1),version:e.number().int().positive(),reason:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("sitemap.resync.failed"),error_code:e.string().min(1),message:e.string().min(1),retryable:e.boolean(),diagnostics:e.unknown().optional(),at:e.string().min(1)}),e.object({type:e.literal("block.changed"),block_id:e.string().min(1),change_type:e.enum(["add","update","delete","move"]),at:e.string().min(1)}),e.object({type:e.literal("tool.started"),tool_call_id:e.string().min(1),name:e.string().min(1),summary:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("tool.finished"),tool_call_id:e.string().min(1),name:e.string().min(1),result_summary:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("workspace.plan.created"),plan_id:e.string().min(1),run_kind:U,groups:e.array($),tasks:e.array(Y),dependencies:e.array(X),expected_outputs:e.array(p),diagnostics:z,summary:je,at:e.string().min(1)}).strict(),e.object({type:e.literal("workspace.worker.updated"),group_id:e.string().min(1),phase:V,status:S,task_counts:Re,target_paths:e.array(p),diagnostics:e.array(e.string().min(1)),at:e.string().min(1)}).strict(),e.object({type:e.literal("workspace.task.updated"),task_id:e.string().min(1),group_id:e.string().min(1),status:S,target_path:p,read_files_count:e.number().int().nonnegative(),diagnostics:e.array(e.string().min(1)),at:e.string().min(1)}).strict(),e.object({type:e.literal("file.changed"),path:e.string().min(1),change_type:e.enum(["create","update","delete"]),diff:e.string().optional(),at:e.string().min(1)}),e.object({type:e.literal("snapshot.created"),snapshot_id:e.string().min(1),manifest_hash:e.string().regex(/^sha256:[a-f0-9]{64}$/),at:e.string().min(1)}),e.object({type:e.literal("preview.preparing"),at:e.string().min(1)}),e.object({type:e.literal("preview.ready"),url:e.string().url(),at:e.string().min(1)}),e.object({type:e.literal("preview.build.started"),snapshot_id:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("preview.build.succeeded"),snapshot_id:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("preview.build.failed"),snapshot_id:e.string().min(1),message:e.string().min(1),diagnostics:e.string().min(1),retryable:e.boolean(),at:e.string().min(1)}),e.object({type:e.literal("run.failed"),error_code:e.string().min(1),message:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("run.finished"),snapshot_id:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("media_resolution.started"),slot_count:e.number().int().nonnegative(),at:e.string().datetime()}),e.object({type:e.literal("media_resolution.finished"),slot_count:e.number().int().nonnegative(),provider_counts:e.object({unsplash:e.number().int().nonnegative(),pexels:e.number().int().nonnegative(),placeholder:e.number().int().nonnegative()}),fallback_count:e.number().int().nonnegative(),error_codes:e.array(e.string()),at:e.string().datetime()}),e.object({type:e.literal("skill.selecting"),category:e.literal("page-generation"),available:e.array(e.object({id:e.string().min(1),name:e.string().min(1)})).max(20),at:e.string().min(1)}),e.object({type:e.literal("skill.selected"),category:e.literal("page-generation"),selected:e.object({id:e.string().min(1),name:e.string().min(1),reason:e.string().min(1).max(200)}),at:e.string().min(1)}),e.object({type:e.literal("activity.started"),activity_id:e.string().min(1),parent_activity_id:e.string().min(1).optional(),kind:fe,title:e.string().min(1).max(200),detail:e.string().max(360).optional(),locks_input:e.boolean(),at:e.string().min(1)}),e.object({type:e.literal("activity.updated"),activity_id:e.string().min(1),title:e.string().min(1).max(200).optional(),detail:e.string().max(360).optional(),at:e.string().min(1)}),e.object({type:e.literal("activity.finished"),activity_id:e.string().min(1),at:e.string().min(1)}),e.object({type:e.literal("activity.failed"),activity_id:e.string().min(1),detail:e.string().max(360).optional(),at:e.string().min(1)})]),G=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),agent_run_id:e.string().min(1),sequence:e.number().int().positive(),event_type:Ee,payload:Te,created_at:e.string().min(1)}),Vi=e.object({event_type:Ee,payload:Te}).superRefine((i,a)=>{i.event_type!==i.payload.type&&a.addIssue({code:"custom",path:["payload","type"],message:"payload.type must match event_type"}),E(i.payload)&&a.addIssue({code:"custom",path:["payload"],message:"AgentEvent payload must not contain secrets"})}),zi=e.discriminatedUnion("status",[e.object({status:e.literal("appended"),agent_run:v,event:G,next_cursor:e.number().int().nonnegative()}),e.object({status:e.literal("duplicate_ignored"),agent_run:v,event:G,next_cursor:e.number().int().nonnegative()})]),$i=e.object({events:e.array(G),next_cursor:e.number().int().nonnegative().optional()}),Yi=e.object({after_sequence:e.coerce.number().int().nonnegative().default(0)}),Xi=e.enum(["implemented","skeleton","planned"]),Qi=e.enum(["GET","POST","PATCH","DELETE"]),Zi=[{method:"GET",path:"/health",tag:"system",summary:"API health check.",status:"implemented",response_schema:"ApiHealth"},{method:"POST",path:"/sites",tag:"sites",summary:"Create a site and Step 1 brief in the current dev context.",status:"implemented",request_body_schema:"CreateSiteBriefRequestSchema",response_schema:"CreateSiteBriefResponseSchema"},{method:"GET",path:"/sites",tag:"sites",summary:"List current tenant sites.",status:"implemented",response_schema:"SiteRecordSchema[]"},{method:"GET",path:"/sites/:site_id",tag:"sites",summary:"Get one tenant-scoped site.",status:"implemented",response_schema:"SiteRecordSchema"},{method:"GET",path:"/sites/:site_id/workspace/source-files",tag:"sites",summary:"List source files available in the ready preview sandbox.",status:"implemented",response_schema:"WorkspaceSourceFileListItemSchema[]"},{method:"GET",path:"/sites/:site_id/workspace/source-file",tag:"sites",summary:"Read a source file from the ready preview sandbox.",status:"implemented",query_schema:"WorkspaceSourceFilePathQuerySchema",response_schema:"WorkspaceSourceFileResponseSchema"},{method:"POST",path:"/sites/:site_id/sitemap",tag:"sitemaps",summary:"Persist generated sitemap and advance the site to sitemap_ready.",status:"implemented",request_body_schema:"PersistSiteSitemapRequestSchema",response_schema:"PersistSiteSitemapResponseSchema"},{method:"GET",path:"/sites/:site_id/sitemap",tag:"sitemaps",summary:"Read the current sitemap for a site.",status:"implemented",response_schema:"SitemapRecordSchema"},{method:"POST",path:"/sites/:site_id/clarify/answers",tag:"clarify",summary:"Persist the Step 2 clarify answers (and the answered questions) into the site's clarify session.",status:"implemented",request_body_schema:"PersistClarifyAnswersRequestSchema",response_schema:"PersistClarifyAnswersResponseSchema"},{method:"POST",path:"/internal/sites/:site_id/design-plan",tag:"design-plans",summary:"Persist a generated design plan version for a site (internal agent-only write).",status:"implemented",request_body_schema:"PersistSiteDesignPlanRequestSchema",response_schema:"PersistSiteDesignPlanResponseSchema",notes:["Guarded by the internal agent token; only the Workspace/Sitemap agent writes design plans."]},{method:"GET",path:"/internal/sites/:site_id/design-plan",tag:"design-plans",summary:"Read the current (latest version) design plan for a site (internal agent-only read).",status:"implemented",response_schema:"DesignPlanRecordSchema",notes:["Guarded by the internal agent token; only the Workspace/Sitemap agent reads design plans."]},{method:"GET",path:"/sites/:site_id/design-plan",tag:"design-plans",summary:"Read the current (latest version) design plan for a site so Workspace UI can inspect the generated design contract.",status:"implemented",response_schema:"DesignPlanRecordSchema"},{method:"GET",path:"/sites/:site_id/brief",tag:"briefs",summary:"Read the persisted Step 1 brief for a site so the Workspace Agent can seed first full-site generation without a new write surface.",status:"implemented",response_schema:"BriefRecordSchema"},{method:"POST",path:"/sites/:site_id/snapshots",tag:"snapshots",summary:"Persist snapshot metadata without changing the current site snapshot.",status:"implemented",request_body_schema:"PersistSiteSnapshotRequestSchema",response_schema:"PersistSiteSnapshotResponseSchema"},{method:"POST",path:"/sites/:site_id/snapshots/:snapshot_id/promote",tag:"snapshots",summary:"Promote a site snapshot as the current workspace version.",status:"implemented",response_schema:"PromoteSiteSnapshotResponseSchema"},{method:"GET",path:"/sites/:site_id/snapshots/:snapshot_id",tag:"snapshots",summary:"Read one tenant-scoped snapshot metadata record for a site.",status:"implemented",response_schema:"SnapshotRecordSchema"},{method:"DELETE",path:"/sites/:site_id/snapshots/:snapshot_id",tag:"snapshots",summary:"Delete a candidate snapshot (cleanup of superseded intermediate snapshots; refuses non-candidate/current/referenced).",status:"implemented",response_schema:"DeleteSiteSnapshotResponseSchema"},{method:"POST",path:"/agent-runs",tag:"agent-runs",summary:"Create an agent run for event persistence and replay.",status:"implemented",request_body_schema:"CreateAgentRunRequestSchema",response_schema:"CreateAgentRunResponseSchema"},{method:"POST",path:"/agent-runs/:run_id/events",tag:"agent-runs",summary:"Append one normalized AgentEvent to a run.",status:"implemented",request_body_schema:"AppendAgentEventRequestSchema",response_schema:"AppendAgentEventResponseSchema"},{method:"GET",path:"/agent-runs/:run_id/events",tag:"agent-runs",summary:"Replay AgentEvents after a run-local sequence cursor.",status:"implemented",response_schema:"ListAgentEventsResponseSchema"},{method:"GET",path:"/briefs",tag:"briefs",summary:"Brief resource summary endpoint until concrete brief APIs land.",status:"skeleton"},{method:"GET",path:"/clarify",tag:"clarify",summary:"Clarify resource summary endpoint; persisted answers write through POST /sites/:site_id/clarify/answers.",status:"skeleton"},{method:"GET",path:"/sitemaps",tag:"sitemaps",summary:"Sitemap resource summary endpoint until collection APIs land.",status:"skeleton"},{method:"GET",path:"/snapshots",tag:"snapshots",summary:"Snapshot resource summary endpoint until collection APIs land.",status:"skeleton"},{method:"GET",path:"/sandbox-sessions",tag:"sandbox-sessions",summary:"Sandbox session resource summary endpoint until preview APIs land.",status:"skeleton"},{method:"GET",path:"/deployments",tag:"deployments",summary:"Deployment resource summary endpoint until publish APIs land.",status:"skeleton"},{method:"GET",path:"/usage",tag:"usage",summary:"Usage resource summary endpoint until cost summaries land.",status:"skeleton"},{method:"GET",path:"/audit",tag:"audit",summary:"Audit resource summary endpoint until audit queries land.",status:"skeleton"},{method:"POST",path:"/sites/:site_id/workspace/runs",tag:"workspace",summary:"Start an asynchronous Workspace Agent run from the current snapshot.",status:"implemented",request_body_schema:"StartWorkspaceRunRequestSchema",response_schema:"StartWorkspaceRunResponseSchema",notes:["Long-running work must be event-driven and must not block API transactions."]},{method:"GET",path:"/sites/:site_id/workspace/runs/latest",tag:"workspace",summary:"Look up the latest workspace Agent run for a site so Step 4 re-entry can replay persisted events without re-triggering the model.",status:"implemented",response_schema:"LatestWorkspaceRunResponseSchema"},{method:"POST",path:"/sites/:site_id/preview-sessions",tag:"sandbox-sessions",summary:"Persist or update an on-demand preview session for a site.",status:"implemented",request_body_schema:"PersistPreviewSessionRequestSchema",response_schema:"PersistPreviewSessionResponseSchema"},{method:"GET",path:"/sites/:site_id/preview-sessions/current",tag:"sandbox-sessions",summary:"Read the latest tenant-scoped preview session for a site.",status:"implemented",response_schema:"SandboxSessionSchema"},{method:"POST",path:"/sites/:site_id/deployments",tag:"deployments",summary:"Queue an explicit user-confirmed deployment from a snapshot.",status:"implemented",request_body_schema:"CreateDeploymentRequestSchema",response_schema:"CreateDeploymentResponseSchema",notes:["The API returns after creating the deployment record; build and Cloudflare publish run through deploy-service."]},{method:"GET",path:"/sites/:site_id/deployments/current",tag:"deployments",summary:"Read the latest deployment for workspace refresh recovery.",status:"implemented",response_schema:"DeploymentRecordSchema"},{method:"GET",path:"/sites/:site_id/deployments/:deployment_id",tag:"deployments",summary:"Read one tenant-scoped deployment for status polling.",status:"implemented",response_schema:"DeploymentRecordSchema"},{method:"GET",path:"/sites/:site_id/cms/collections",tag:"cms",summary:"List CMS collections for a site.",status:"planned"},{method:"POST",path:"/sites/:site_id/cms/collections",tag:"cms",summary:"Create a CMS collection bound to generated content.",status:"planned"},{method:"GET",path:"/sites/:site_id/cms/collections/:collection_id/entries",tag:"cms",summary:"List CMS entries for a collection.",status:"planned"},{method:"POST",path:"/sites/:site_id/cms/collections/:collection_id/entries",tag:"cms",summary:"Create a CMS entry.",status:"planned"},{method:"PATCH",path:"/sites/:site_id/cms/collections/:collection_id/entries/:entry_id",tag:"cms",summary:"Update a CMS entry.",status:"planned"},{method:"POST",path:"/sites/:site_id/snapshots/:snapshot_id/version-record",tag:"versions",summary:"Record the sandbox accepted git commit for a promoted snapshot version.",status:"implemented",request_body_schema:"RecordSnapshotVersionRequestSchema",response_schema:"RecordSnapshotVersionResponseSchema"},{method:"GET",path:"/sites/:site_id/versions",tag:"versions",summary:"List snapshot-backed site versions.",status:"implemented",response_schema:"ListSiteVersionsResponseSchema"},{method:"POST",path:"/sites/:site_id/versions/:snapshot_id/restore",tag:"versions",summary:"Restore a site to an earlier snapshot version.",status:"implemented",response_schema:"RestoreSiteSnapshotResponseSchema"},{method:"GET",path:"/sites/:site_id/domains",tag:"domains",summary:"List custom domains for a site.",status:"planned"},{method:"POST",path:"/sites/:site_id/domains",tag:"domains",summary:"Attach a custom domain to a site.",status:"planned"},{method:"GET",path:"/admin/tenants",tag:"admin",summary:"Admin tenant listing.",status:"planned"},{method:"GET",path:"/usage/summary",tag:"usage",summary:"Summarize tenant usage and cost controls.",status:"planned"}],Ji=[{method:"POST",path:"/v1/agent/clarify/:site_id",tag:"clarify",summary:"Stream Step 2 clarify questions as SSE; event_order includes optional skill.selecting, skill.selected, clarify.archetype_proposals, and run.failed on errors.",status:"implemented",request_body_schema:"ClarifyRunInputSchema without tenant_id/site_id",event_schema:"ClarifyStreamEventSchema",event_order:["run.started","skill.selecting","skill.selected","clarify.partial","clarify.archetype_proposals","clarify.finished","run.failed"]},{method:"POST",path:"/v1/agent/sitemap/:site_id",tag:"sitemap",summary:"Stream Step 3 sitemap generation as SSE; event_order includes sitemap.partial and run.failed on errors.",status:"implemented",request_body_schema:"SitemapRunInputSchema without tenant_id/site_id",event_schema:"SitemapStreamEventSchema",event_order:["run.started","sitemap.generating","sitemap.partial","sitemap.generated","run.failed"]}],Ie=e.object({id:e.string().min(1),role:e.enum(["system","user","assistant"]),metadata:e.unknown().optional(),parts:e.array(Q).min(1)}),ea=e.object({base_snapshot_id:e.string().min(1).optional(),message:Ie.optional()}).superRefine((i,a)=>{E(i.message)&&a.addIssue({code:"custom",path:["message"],message:"Workspace startup message must not contain secrets"})}),Lt=e.object({path:e.string().regex(/^\/v1\/workspace\/sites\/[^/]+\/socket$/),run_id:e.string().min(1),base_snapshot_id:e.string().min(1),run_kind:U}),ta=e.object({agent_run:v,websocket:Lt,next_step:e.literal("workspace_socket")}),na=e.object({agent_run:v}),ia=e.enum(["client.message.create","client.run.cancel","client.tool.approve","server.run.started","server.assistant.delta","server.tool.started","server.tool.completed","workspace.plan.created","workspace.worker.updated","workspace.task.updated","server.patch.applied","server.sitemap.updated","server.snapshot.created","server.preview.invalidated","preview.build.started","preview.build.succeeded","preview.build.failed","server.run.finished","server.run.failed","server.error","server.activity.started","server.activity.updated","server.activity.finished","server.activity.failed"]),o=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),run_id:e.string().min(1).optional(),correlation_id:e.string().min(1).optional(),seq:e.number().int().positive().optional(),sent_at:e.string().min(1)}),Wt=e.discriminatedUnion("type",[o.extend({type:e.literal("client.message.create"),payload:e.object({client_message_id:e.string().min(1),in_reply_to_tool_call_id:e.string().min(1).optional(),message:Ie,base_snapshot_id:e.string().min(1).optional()})}),o.extend({type:e.literal("client.run.cancel"),payload:e.object({run_id:e.string().min(1),reason:e.string().min(1).optional()})}),o.extend({type:e.literal("client.tool.approve"),payload:e.object({tool_call_id:e.string().min(1),decision:e.enum(["approve","reject"]),reason:e.string().min(1).optional()})})]),qt=e.discriminatedUnion("type",[o.extend({type:e.literal("server.run.started"),payload:e.object({run_id:e.string().min(1),agent_type:e.literal("workspace")})}),o.extend({type:e.literal("server.assistant.delta"),payload:e.object({message_id:e.string().min(1),parts:e.array(Q).min(1),status:e.enum(["streaming","ready"])})}),o.extend({type:e.literal("server.tool.started"),payload:e.object({tool_call_id:e.string().min(1),name:e.string().min(1),summary:e.string().min(1)})}),o.extend({type:e.literal("server.tool.completed"),payload:e.object({tool_call_id:e.string().min(1),name:e.string().min(1),result_summary:e.string().min(1)})}),o.extend({type:e.literal("workspace.plan.created"),payload:e.object({plan_id:e.string().min(1),run_kind:U,groups:e.array($),tasks:e.array(Y),dependencies:e.array(X),expected_outputs:e.array(p),diagnostics:z,summary:je})}),o.extend({type:e.literal("workspace.worker.updated"),payload:e.object({group_id:e.string().min(1),phase:V,status:S,task_counts:Re,target_paths:e.array(p),diagnostics:e.array(e.string().min(1))})}),o.extend({type:e.literal("workspace.task.updated"),payload:e.object({task_id:e.string().min(1),group_id:e.string().min(1),status:S,target_path:p,read_files_count:e.number().int().nonnegative(),diagnostics:e.array(e.string().min(1))})}),o.extend({type:e.literal("server.patch.applied"),payload:e.object({patch_batch_id:e.string().min(1),changed_files:e.array(e.string().min(1)),sitemap_resync_queued:e.boolean()})}),o.extend({type:e.literal("server.sitemap.updated"),payload:e.object({sitemap_id:e.string().min(1),version:e.number().int().positive(),reason:e.string().min(1)})}),o.extend({type:e.literal("server.snapshot.created"),payload:e.object({snapshot_id:e.string().min(1),manifest_hash:e.string().regex(/^sha256:[a-f0-9]{64}$/)})}),o.extend({type:e.literal("server.preview.invalidated"),payload:e.object({reason:e.string().min(1),next_preview_url:e.string().url().optional()})}),o.extend({type:e.literal("preview.build.started"),payload:e.object({snapshot_id:e.string().min(1)})}),o.extend({type:e.literal("preview.build.succeeded"),payload:e.object({snapshot_id:e.string().min(1)})}),o.extend({type:e.literal("preview.build.failed"),payload:e.object({snapshot_id:e.string().min(1),message:e.string().min(1),diagnostics:e.string().min(1),retryable:e.boolean()})}),o.extend({type:e.literal("server.run.finished"),payload:e.object({run_id:e.string().min(1),snapshot_id:e.string().min(1)})}),o.extend({type:e.literal("server.run.failed"),payload:e.object({run_id:e.string().min(1),error_code:e.string().min(1),message:e.string().min(1),retryable:e.boolean()})}),o.extend({type:e.literal("server.error"),payload:e.object({code:e.string().min(1),message:e.string().min(1),retryable:e.boolean()})}),o.extend({type:e.literal("server.activity.started"),payload:e.object({activity_id:e.string().min(1),parent_activity_id:e.string().min(1).optional(),kind:fe,title:e.string().min(1).max(200),detail:e.string().max(360).optional(),locks_input:e.boolean()})}),o.extend({type:e.literal("server.activity.updated"),payload:e.object({activity_id:e.string().min(1),title:e.string().min(1).max(200).optional(),detail:e.string().max(360).optional()})}),o.extend({type:e.literal("server.activity.finished"),payload:e.object({activity_id:e.string().min(1)})}),o.extend({type:e.literal("server.activity.failed"),payload:e.object({activity_id:e.string().min(1),detail:e.string().max(360).optional()})})]),aa=e.union([Wt,qt]),sa={path:"/v1/workspace/sites/:site_id/socket",protocol:"ws",status:"implemented",inbound_message_schema:"WorkspaceClientMessageSchema",outbound_message_schema:"WorkspaceServerMessageSchema",query_parameters:[{name:"run_id",required:!1,schema:"string",summary:"Workspace run id returned by the API run-start response."},{name:"run_kind",required:!1,schema:"WorkspaceRunKindSchema",summary:"Workspace run mode; initial_generation can auto-start when base_snapshot_id is present."},{name:"base_snapshot_id",required:!1,schema:"string",summary:"Authoritative base snapshot id for this workspace run."}],ai_sdk_ui_compatible:!0,notes:["Assistant UI output is carried as AI SDK UIMessage parts, including text, data-*, and tool-* parts.","Operational AgentEvents remain persisted separately for replay and audit."]},Ae=e.string().regex(/^sha256:[a-f0-9]{64}$/),Ut=e.enum(["create","update","delete"]),Z=e.enum(["sitemap_resync","smoke_test","prepare_preview"]),Ft=e.object({path:p,operation:Ut,expected_hash:Ae.optional(),full_content:e.string().describe("Complete file content for create/update patches. It is passed as a JSON string, so every double quote in source code must be valid JSON; avoid ASCII double quotes inside JSX attribute values and use corner quotes like \u300C\u751F\u65E5\u5FEB\u4E50\u300D for visitor-facing quoted examples.").optional()}).strict().superRefine((i,a)=>{let m=i.full_content!==void 0;if(i.operation==="delete"){m&&a.addIssue({code:"custom",path:["full_content"],message:"delete patches must not include full_content"});return}m||a.addIssue({code:"custom",path:["full_content"],message:"create/update patches must include full_content"})}),Mt=e.object({kind:e.enum(["block","page","site","chrome"]),id:e.string().min(1).max(120)}),Gt=e.object({base_key:e.string().min(1).max(120).regex(/^[A-Za-z0-9._:-]+$/).refine(i=>!i.includes(".."),{message:"base_key must not contain '..'"}),owner:Mt,count:e.number().int().min(1).max(12),query:e.string().min(1).max(400),role:e.enum(["hero","section","card","gallery","testimonial","decorative","site_background","nav_background","footer_background"]),orientation:e.enum(["landscape","portrait","square"]).optional(),altHint:e.string().min(1).max(300)}),ra=e.object({site_id:e.string().min(1),base_snapshot_id:e.string().min(1),reason:e.string().min(1),patches:e.array(Ft).min(1),media_requests:e.array(Gt).max(24).optional(),post_actions:e.array(Z).optional()}).superRefine((i,a)=>{let m=new Set;for(let[_,d]of i.patches.entries())m.has(d.path)&&a.addIssue({code:"custom",path:["patches",_,"path"],message:`Duplicate patch path: ${d.path}`}),m.add(d.path)}),Bt=e.object({path:p}),Ht=e.object({route_id:e.string().min(1),entry_file:p}).strict(),Kt=e.object({files:e.array(Bt).min(1)}).strict(),Vt=e.object({site_edit_operation:re,site_edit_routes:e.array(Ht).min(1),post_actions:e.array(Z).optional()}).strict(),oa=e.union([Kt,Vt]),zt=e.enum(["BASE_SNAPSHOT_NOT_FOUND","PATCH_TARGET_NOT_FOUND","PATCH_TARGET_ALREADY_EXISTS","PATCH_EXPECTED_HASH_MISMATCH","PATCH_DIFF_UNSUPPORTED","PATCH_PROTECTED_FILE","PATCH_VALIDATION_FAILED","PATCH_MEDIA_REFERENCE_NOT_DECLARED","PATCH_BATCH_INVALID","PATCH_BATCH_FAILED"]),$t=e.object({status:e.literal("applied"),patch_batch_id:e.string().min(1),site_id:e.string().min(1),base_snapshot_id:e.string().min(1),snapshot_id:e.string().min(1),manifest_hash:Ae,object_key:e.string().min(1),changed_files:e.array(p).min(1),post_actions_queued:e.array(Z)}),Yt=e.object({status:e.literal("failed"),code:zt,message:e.string().min(1),retryable:e.boolean().default(!1),details:e.unknown().optional()}),ca=e.discriminatedUnion("status",[$t,Yt]),ma=e.object({ok:e.literal(!0)}),Pe=e.string().min(1).refine(i=>{let a=i.split("/"),_=(a.length===1?a[0]:void 0)?.toLowerCase()==="design.md";return!i.startsWith("/")&&!i.includes("\\")&&a.every(d=>!(d.length===0||d==="."||d===".."||d.startsWith(".")||d==="package.json"||d==="recipes"||d==="node_modules"||d.startsWith(".env")))&&(_||["app","components","hooks","lib","public"].includes(a[0]??""))},"Invalid workspace source path"),Xt=e.enum(["text","binary"]),we=e.object({path:Pe,kind:Xt,language:e.string().min(1).nullable(),size_bytes:e.number().int().nonnegative()}),la=e.object({path:Pe}),Qt=we.extend({kind:e.literal("text"),language:e.string().min(1),content:e.string()}),Zt=we.extend({kind:e.literal("binary"),language:e.null(),mime_type:e.string().min(1),content_base64:e.string().min(1)}),pa=e.union([Qt,Zt]);function E(i){return typeof i=="string"?/authorization\s*:|bearer\s+|token\s*=|secret\s*=|api[_-]?key\s*=|access[_\s-]?key\s*=/i.test(i):!i||typeof i!="object"?!1:Array.isArray(i)?i.some(a=>E(a)):Object.entries(i).some(([a,m])=>Jt(a)||E(m))}function Jt(i){let a=i.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/\s+/g,"_").toLowerCase();return/(^|[_-])(authorization|token|secret|api[_-]?key|apikey|access[_-]?key|accesskey)([_-]|$)/.test(a)}function en(i){let a=i.split("/");return i.length>0&&!i.startsWith("/")&&!i.includes("\\")&&a.every(m=>m!==""&&m!=="."&&m!=="..")}var Ce=e.enum(["idle","creating","restoring_snapshot","installing_dependencies","starting_preview","ready","active","stopping","stopped","failed"]),tn=e.object({id:e.string().min(1),tenant_id:e.string().min(1),site_id:e.string().min(1),sandbox_id:e.string().min(1).nullable(),status:Ce,source_snapshot_id:e.string().min(1).nullable(),last_snapshot_id:e.string().min(1).nullable(),preview_url:e.string().url().nullable(),last_activity_at:e.string().min(1).nullable(),created_at:e.string().min(1),updated_at:e.string().min(1)}),da=e.object({session_id:e.string().min(1).optional(),sandbox_id:e.string().min(1).optional(),source_snapshot_id:e.string().min(1).optional(),last_snapshot_id:e.string().min(1),status:Ce,preview_url:e.string().url().optional()}),ua=e.object({preview_session:tn,next_step:e.literal("preview")});export{fe as ActivityKindSchema,G as AgentEventRecordSchema,Te as AgentEventSchema,Ee as AgentEventTypeSchema,ye as AgentModelRouteSchema,Et as AgentPlanStepSchema,be as AgentRunKindSchema,v as AgentRunRecordSchema,nt as AgentRunStatusSchema,Se as AgentRunTypeSchema,Ct as AiSdkUiDataPartSchema,Dt as AiSdkUiErrorPartSchema,At as AiSdkUiFilePartSchema,Q as AiSdkUiMessagePartSchema,Ie as AiSdkUiMessageSchema,It as AiSdkUiReasoningPartSchema,wt as AiSdkUiSourceDocumentPartSchema,Pt as AiSdkUiSourceUrlPartSchema,Nt as AiSdkUiStepStartPartSchema,Tt as AiSdkUiTextPartSchema,Ot as AiSdkUiToolPartSchema,Xi as ApiContractStatusSchema,Ei as ApiErrorEnvelopeSchema,Vi as AppendAgentEventRequestSchema,zi as AppendAgentEventResponseSchema,zt as ApplyPatchBatchErrorCodeSchema,Yt as ApplyPatchBatchFailureSchema,ra as ApplyPatchBatchInputSchema,Ft as ApplyPatchBatchPatchSchema,Z as ApplyPatchBatchPostActionSchema,ca as ApplyPatchBatchResultSchema,$t as ApplyPatchBatchSuccessSchema,Ut as ApplyPatchOperationSchema,B as ArchetypeProposalSchema,pt as BlockGenerationContextSchema,Ri as BlockMediaIntentSchema,dt as BlockSchema,tt as BriefRecordSchema,Qn as CHAT_COPY,Xn as CLARIFICATION_COPY,ti as ClarifyModelOutputSchema,ge as ClarifyQuestionTypeSchema,_e as ClarifyQuestionsSchema,ni as ClarifyRunInputSchema,kt as ClarifySessionRecordSchema,ii as ClarifyStreamEventSchema,W as ConversionHintsSchema,di as CreateAgentRunRequestSchema,ui as CreateAgentRunResponseSchema,ki as CreateDeploymentRequestSchema,vi as CreateDeploymentResponseSchema,li as CreateSiteBriefRequestSchema,pi as CreateSiteBriefResponseSchema,mi as CreateSiteInputSchema,Si as DeleteSiteSnapshotResponseSchema,at as DeploymentRecordSchema,it as DeploymentStatusSchema,vt as DesignPlanRecordSchema,ke as DesignPlanSchema,ji as DesignTokensSchema,$n as ERROR_COPY,na as LatestWorkspaceRunResponseSchema,Yi as ListAgentEventsQuerySchema,$i as ListAgentEventsResponseSchema,xi as ListSiteVersionsResponseSchema,Ii as MediaAssetSchema,ot as MediaAttributionSchema,Mt as MediaRequestOwnerSchema,he as MotionLevelSchema,ut as PageSchema,Fi as PersistClarifyAnswersRequestSchema,Mi as PersistClarifyAnswersResponseSchema,da as PersistPreviewSessionRequestSchema,ua as PersistPreviewSessionResponseSchema,Gi as PersistSiteDesignPlanRequestSchema,Bi as PersistSiteDesignPlanResponseSchema,qi as PersistSiteSitemapRequestSchema,Ui as PersistSiteSitemapResponseSchema,gi as PersistSiteSnapshotRequestSchema,hi as PersistSiteSnapshotResponseSchema,_i as PromoteSiteSnapshotResponseSchema,Yn as REFUSAL_COPY,Zi as REST_API_ENDPOINTS,bi as RecordSnapshotVersionRequestSchema,yi as RecordSnapshotVersionResponseSchema,Qi as RestApiMethodSchema,fi as RestoreSiteSnapshotResponseSchema,lt as RouteGenerationCardSchema,oi as SITE_PLANNING_FROZEN_ERROR_CODE,ci as SITE_PLANNING_LOCKED_ERROR_CODE,Ji as SSE_STREAMS,tn as SandboxSessionSchema,Ce as SandboxSessionStatusSchema,mt as SiteDesignContextSchema,w as SiteEditBoundaryKindSchema,Ue as SiteEditCapabilityConstraintSchema,We as SiteEditCapabilityModeSchema,P as SiteEditCapabilityModeViewSchema,oe as SiteEditClassNameSourceDiagnosticSchema,f as SiteEditClassNameSourceRangeSchema,O as SiteEditClassNameSourceSchema,an as SiteEditCommandDiagnosticSchema,Oe as SiteEditCommandErrorSchema,qe as SiteEditConstraintKindSchema,le as SiteEditEffectiveWriteTargetSchema,kn as SiteEditEventSchema,M as SiteEditExternalSourceKindSchema,hn as SiteEditGetClassNameSourceCommandResultSchema,gn as SiteEditGetClassNameSourceResultSchema,Ne as SiteEditInsertNodeSpecSchema,J as SiteEditMoveTargetSchema,C as SiteEditNodeCapabilitySnapshotSchema,Un as SiteEditObjectCapabilitiesSchema,Kn as SiteEditObjectContentDetailSchema,Mn as SiteEditObjectDetailSchema,Bn as SiteEditObjectEditContextSchema,Vn as SiteEditObjectMediaDetailSchema,Hn as SiteEditObjectStyleDetailSchema,Gn as SiteEditObjectSummarySchema,cn as SiteEditOperationCommandResultSchema,ae as SiteEditOperationErrorCodeSchema,se as SiteEditOperationErrorSchema,Le as SiteEditOperationParamsSchema,A as SiteEditOperationPayloadSchema,re as SiteEditOperationRequestSchema,Ve as SiteEditOperationSummarySchema,ee as SiteEditOperationTargetSchema,x as SiteEditOperationTypeSchema,u as SiteEditOperationValueSchema,Ke as SiteEditPatchPlanPatchSchema,An as SiteEditPatchPlanSchema,N as SiteEditProvenanceChainSchema,Ye as SiteEditProvenanceHopSchema,qn as SiteEditRenderDocumentSchema,b as SiteEditRenderEntryRefSchema,ze as SiteEditRenderEntrySchema,pe as SiteEditSemanticSourceSchema,Me as SiteEditSetClassNameSourceFailureReasonSchema,Fe as SiteEditSetClassNameSourceIntentSchema,_n as SiteEditSetClassNameSourceRequestSchema,Sn as SiteEditSetClassNameSourceResultSchema,jn as SiteEditSourceIdentitySchema,ie as SiteEditStyleBreakpointSchema,Fn as SiteEditStyleModelSchema,te as SiteEditStylePropertySchema,de as SiteEditStyleSourceSchema,ne as SiteEditStyleStateModeSchema,ce as SiteEditTextSegmentSchema,$e as SiteEditTextSourceSchema,me as SiteEditWriteTargetSchema,Je as SiteGenerationStateSchema,Ti as SiteMediaIntentSchema,j as SiteRecordSchema,Qe as SiteStatusSchema,H as SiteVersionRecordSchema,Oi as SitemapAddBlockInputSchema,K as SitemapAnswerSchema,wi as SitemapChangeBlockVariantInputSchema,ht as SitemapDeleteBlockInputSchema,gt as SitemapEditActorSchema,bt as SitemapEditErrorCodeSchema,xt as SitemapEditFailureSchema,St as SitemapEditOperationSchema,Ni as SitemapEditResultSchema,yt as SitemapEditSuccessSchema,ve as SitemapGenerationStageSchema,Ai as SitemapModelOutputSchema,Pi as SitemapMoveBlockInputSchema,ft as SitemapRecordSchema,Li as SitemapRunInputSchema,T as SitemapSchema,Wi as SitemapStreamEventSchema,_t as SitemapUpdateBlockInstructionInputSchema,Ci as SitemapUpdateBlockPropsInputSchema,rt as SitemapUserChoiceSchema,R as SkillSelectionSchema,ct as SkillSelectionSourceSchema,Ae as SnapshotContentHashSchema,p as SnapshotFilePathSchema,q as SnapshotRecordSchema,xe as SnapshotStatusSchema,ea as StartWorkspaceRunRequestSchema,ta as StartWorkspaceRunResponseSchema,L as VisualHintsSchema,st as VisualThemeSchema,sa as WORKSPACE_WEBSOCKET_CONTRACT,Wt as WorkspaceClientMessageSchema,jt as WorkspaceDiagnosticSchema,Bt as WorkspaceDirectEditFileSchema,Kt as WorkspaceDirectEditFilesRequestSchema,Vt as WorkspaceDirectEditOperationRequestSchema,oa as WorkspaceDirectEditRequestSchema,ma as WorkspaceDirectEditResponseSchema,Ht as WorkspaceDirectEditRouteSchema,z as WorkspaceExecutionDiagnosticsSchema,Hi as WorkspaceExecutionPlanSchema,Gt as WorkspaceMediaRequestSchema,X as WorkspacePlanDependencySchema,je as WorkspacePlanSummarySchema,Rt as WorkspacePlanTaskKindSchema,Y as WorkspacePlanTaskSchema,U as WorkspaceRunKindSchema,qt as WorkspaceServerMessageSchema,Di as WorkspaceSitemapEditRequestSchema,Lt as WorkspaceSocketDescriptorSchema,Zt as WorkspaceSourceFileBinaryResponseSchema,Xt as WorkspaceSourceFileKindSchema,we as WorkspaceSourceFileListItemSchema,la as WorkspaceSourceFilePathQuerySchema,pa as WorkspaceSourceFileResponseSchema,Qt as WorkspaceSourceFileTextResponseSchema,Pe as WorkspaceSourcePathSchema,Re as WorkspaceTaskCountsSchema,aa as WorkspaceWebSocketMessageSchema,ia as WorkspaceWebSocketMessageTypeSchema,$ as WorkspaceWorkerGroupSchema,V as WorkspaceWorkerPhaseSchema,Ki as WorkspaceWorkerResultSchema,S as WorkspaceWorkerStatusSchema,si as assertSiteGenerationStateTransition,ai as assertSiteStatusTransition,Ge as computeSiteEditSourceIdentityKey,E as containsSensitiveData,De as createSiteEditCommandFailureSchema,I as createSiteEditCommandResultSchema,F as createSiteEditCommandSuccessSchema,Rn as parseSiteEditSourceIdentityKey,ri as resolveGenerationStateForRunLifecycle};