@builder.io/ai-utils 0.100.0 → 0.100.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builder.io/ai-utils",
3
- "version": "0.100.0",
3
+ "version": "0.100.2",
4
4
  "description": "Builder.io AI utils",
5
5
  "files": [
6
6
  "src"
package/src/codegen.d.ts CHANGED
@@ -385,8 +385,21 @@ export declare const GetScreenshotToolInputSchema: z.ZodObject<{
385
385
  height: z.ZodOptional<z.ZodNumber>;
386
386
  }, z.core.$strip>;
387
387
  export type GetScreenshotToolInput = z.infer<typeof GetScreenshotToolInputSchema>;
388
+ /**
389
+ * `projectId` and `routedBy` are telemetry only and never reach the model or
390
+ * the classification path — they exist so an audit of real traffic
391
+ * (`scripts/judge-safety-audit.ts`) can say which project a verdict belonged
392
+ * to and whether the legacy ACL would have blocked the command. Both are
393
+ * optional because a pod running an older dev-tools build won't send them.
394
+ */
388
395
  export declare const JudgeCommandSafetyInputSchema: z.ZodObject<{
389
396
  command: z.ZodString;
397
+ projectId: z.ZodOptional<z.ZodString>;
398
+ routedBy: z.ZodOptional<z.ZodEnum<{
399
+ "allowlist-miss": "allowlist-miss";
400
+ "network-client": "network-client";
401
+ tier2: "tier2";
402
+ }>>;
390
403
  }, z.core.$strip>;
391
404
  export type JudgeCommandSafetyInput = z.infer<typeof JudgeCommandSafetyInputSchema>;
392
405
  export declare const JudgeCommandSafetyResultSchema: z.ZodObject<{
package/src/codegen.js CHANGED
@@ -583,6 +583,13 @@ export const GetScreenshotToolInputSchema = z
583
583
  height: z.number().optional(),
584
584
  })
585
585
  .meta({ title: "GetScreenshotToolInput" });
586
+ /**
587
+ * `projectId` and `routedBy` are telemetry only and never reach the model or
588
+ * the classification path — they exist so an audit of real traffic
589
+ * (`scripts/judge-safety-audit.ts`) can say which project a verdict belonged
590
+ * to and whether the legacy ACL would have blocked the command. Both are
591
+ * optional because a pod running an older dev-tools build won't send them.
592
+ */
586
593
  export const JudgeCommandSafetyInputSchema = z
587
594
  .object({
588
595
  // Bounded so a caller can't force multi-megabyte payloads through this
@@ -591,6 +598,18 @@ export const JudgeCommandSafetyInputSchema = z
591
598
  command: z.string().max(20000).meta({
592
599
  description: "The shell command to classify.",
593
600
  }),
601
+ projectId: z.string().max(200).optional().meta({
602
+ description: "Diagnostic only: the Fusion project the command was run in. Never used in classification.",
603
+ }),
604
+ // Reported as a single value with the client's own precedence — a command
605
+ // can trip more than one of these, and only the first two mean the legacy
606
+ // ACL would have denied it.
607
+ routedBy: z
608
+ .enum(["tier2", "allowlist-miss", "network-client"])
609
+ .optional()
610
+ .meta({
611
+ description: "Diagnostic only: why the sandbox sent this command to the judge. Never used in classification.",
612
+ }),
594
613
  })
595
614
  .meta({ title: "JudgeCommandSafetyInput" });
596
615
  export const JudgeCommandSafetyResultSchema = z
package/src/events.d.ts CHANGED
@@ -767,6 +767,37 @@ export declare const FusionShapeAssembledV1: {
767
767
  eventName: "fusion.shape.assembled";
768
768
  version: "1";
769
769
  };
770
+ export type FusionShapeResolvedV1 = FusionEventVariant<"fusion.shape.resolved", {
771
+ projectId: string;
772
+ questionnaireId: string;
773
+ catalogVersion: string;
774
+ resolvedAt: string;
775
+ }, {}, 1>;
776
+ export declare const FusionShapeResolvedV1: {
777
+ eventName: "fusion.shape.resolved";
778
+ version: "1";
779
+ };
780
+ type FusionShapeQuestionEventData = {
781
+ projectId: string;
782
+ questionnaireId: string;
783
+ catalogVersion: string;
784
+ questionId: string;
785
+ chosenOptionId: string;
786
+ skipped: boolean;
787
+ delegated: boolean;
788
+ llmOptionId?: string;
789
+ guessOptionId?: string;
790
+ };
791
+ export type FusionShapeQuestionAnsweredV1 = FusionEventVariant<"fusion.shape.question.answered", FusionShapeQuestionEventData, {}, 1>;
792
+ export declare const FusionShapeQuestionAnsweredV1: {
793
+ eventName: "fusion.shape.question.answered";
794
+ version: "1";
795
+ };
796
+ export type FusionShapeQuestionSkippedV1 = FusionEventVariant<"fusion.shape.question.skipped", FusionShapeQuestionEventData, {}, 1>;
797
+ export declare const FusionShapeQuestionSkippedV1: {
798
+ eventName: "fusion.shape.question.skipped";
799
+ version: "1";
800
+ };
770
801
  export type SetupAgentCompletedV1 = FusionEventVariant<"fusion.setup.completed", {
771
802
  proposedConfigId: string;
772
803
  projectId: string;
@@ -934,6 +965,7 @@ export type ProjectSnapshotRefreshV1 = FusionEventVariant<"project.snapshot.refr
934
965
  * producer.
935
966
  */
936
967
  goldenTemplateId?: string;
968
+ gitSha?: string;
937
969
  }, {
938
970
  projectId: string;
939
971
  }, 1>;
@@ -941,6 +973,32 @@ export declare const ProjectSnapshotRefreshV1: {
941
973
  eventName: "project.snapshot.refresh";
942
974
  version: "1";
943
975
  };
976
+ export type ProjectSnapshotGoldenWatchdogV1 = FusionEventVariant<"project.snapshot.golden.watchdog", {
977
+ projectId: string;
978
+ triggerEventId: string;
979
+ goldenTemplateId: "agent-native-starter";
980
+ deadlineAtMs: number;
981
+ }, {
982
+ projectId: string;
983
+ }, 1>;
984
+ export declare const ProjectSnapshotGoldenWatchdogV1: {
985
+ eventName: "project.snapshot.golden.watchdog";
986
+ version: "1";
987
+ };
988
+ export type ProjectSnapshotGoldenRetryV1 = FusionEventVariant<"project.snapshot.golden.retry", {
989
+ projectId: string;
990
+ triggerEventId: string;
991
+ source: "project.snapshot.refresh";
992
+ gitSha?: string;
993
+ goldenTemplateId: "agent-native-starter";
994
+ retryAttempt: number;
995
+ }, {
996
+ projectId: string;
997
+ }, 1>;
998
+ export declare const ProjectSnapshotGoldenRetryV1: {
999
+ eventName: "project.snapshot.golden.retry";
1000
+ version: "1";
1001
+ };
944
1002
  export type ProjectSnapshotCapturedV1 = FusionEventVariant<"project.snapshot.captured", {
945
1003
  projectId: string;
946
1004
  snapshotName: string;
@@ -960,6 +1018,7 @@ export type ProjectSnapshotCreatedV1 = FusionEventVariant<"project.snapshot.crea
960
1018
  gitSha: string;
961
1019
  triggerEventId: string;
962
1020
  durationMs: number;
1021
+ goldenTemplateId?: string;
963
1022
  }, {
964
1023
  projectId: string;
965
1024
  }, 1>;
@@ -972,6 +1031,7 @@ export type ProjectSnapshotFailedV1 = FusionEventVariant<"project.snapshot.faile
972
1031
  triggerEventId: string;
973
1032
  reason: string;
974
1033
  phase?: "init" | "build" | "dev-server" | "callback";
1034
+ goldenTemplateId?: string;
975
1035
  }, {
976
1036
  projectId: string;
977
1037
  }, 1>;
@@ -996,6 +1056,7 @@ export type ProjectSnapshotReadyCheckV1 = FusionEventVariant<"project.snapshot.r
996
1056
  /** When the VolumeSnapshot was created — used to compute the readiness timeout. */
997
1057
  capturedAtMs: number;
998
1058
  timeoutMs: number;
1059
+ goldenTemplateId?: string;
999
1060
  }, {
1000
1061
  projectId: string;
1001
1062
  }, 1>;
@@ -1398,7 +1459,7 @@ export declare const HostingCustomDomainDelegationCheckV1: {
1398
1459
  eventName: "hosting.custom-domain.delegation-check";
1399
1460
  version: "1";
1400
1461
  };
1401
- export type FusionEvent = ClientDevtoolsSessionStartedEvent | ClientDevtoolsSessionIdleEventV1 | ClientDevtoolsToolCallRequestV1 | ClientDevtoolsToolCallV1 | ClientDevtoolsToolResultV1 | ClientDevtoolsBuildMigratedV1 | ClientDevtoolsBuildCompletedV1 | ClientDevtoolsBuildUploadedV1 | ClientDevtoolsBuildFailedV1 | FusionProjectCreatedV1 | FusionShapeIssuedV1 | FusionShapeAssembledV1 | SetupAgentCompletedV1 | GitPrMergedV1 | GitPrCreatedV1 | GitPrClosedV1 | ForceSetupAgentV1 | ClawMessageSentV1 | CodegenCompletionV1 | CodegenUserPromptV1 | GitWebhooksRegisterV1 | FusionProjectSettingsUpdatedV1 | VideoRecordingCompletedV1 | TimelineRecordingReadyV1 | FusionBranchCreatedV1 | FusionContainerStartedV1 | FusionContainerFailedV1 | FusionBranchFailedV1 | BotMentionGitHubExternalPrV1 | BotMentionGitHubInternalPrV1 | BotMentionGitLabPrV1 | BotMentionBitbucketPrV1 | BotMentionAzurePrV1 | ReviewSubmittedV1 | PrReviewRequestedV1 | FigmaDecodeJobV1 | ProjectSnapshotRefreshV1 | ProjectSnapshotCapturedV1 | ProjectSnapshotCreatedV1 | ProjectSnapshotFailedV1 | ProjectSnapshotReadyCheckV1 | ProjectSnapshotPodWatchV1 | McpPrototypePulledV1 | HostingCustomDomainCertCheckV1 | HostingCustomDomainServingCheckV1 | HostingCustomDomainDelegationCheckV1;
1462
+ export type FusionEvent = ClientDevtoolsSessionStartedEvent | ClientDevtoolsSessionIdleEventV1 | ClientDevtoolsToolCallRequestV1 | ClientDevtoolsToolCallV1 | ClientDevtoolsToolResultV1 | ClientDevtoolsBuildMigratedV1 | ClientDevtoolsBuildCompletedV1 | ClientDevtoolsBuildUploadedV1 | ClientDevtoolsBuildFailedV1 | FusionProjectCreatedV1 | FusionShapeIssuedV1 | FusionShapeAssembledV1 | FusionShapeResolvedV1 | FusionShapeQuestionAnsweredV1 | FusionShapeQuestionSkippedV1 | SetupAgentCompletedV1 | GitPrMergedV1 | GitPrCreatedV1 | GitPrClosedV1 | ForceSetupAgentV1 | ClawMessageSentV1 | CodegenCompletionV1 | CodegenUserPromptV1 | GitWebhooksRegisterV1 | FusionProjectSettingsUpdatedV1 | VideoRecordingCompletedV1 | TimelineRecordingReadyV1 | FusionBranchCreatedV1 | FusionContainerStartedV1 | FusionContainerFailedV1 | FusionBranchFailedV1 | BotMentionGitHubExternalPrV1 | BotMentionGitHubInternalPrV1 | BotMentionGitLabPrV1 | BotMentionBitbucketPrV1 | BotMentionAzurePrV1 | ReviewSubmittedV1 | PrReviewRequestedV1 | FigmaDecodeJobV1 | ProjectSnapshotRefreshV1 | ProjectSnapshotGoldenWatchdogV1 | ProjectSnapshotGoldenRetryV1 | ProjectSnapshotCapturedV1 | ProjectSnapshotCreatedV1 | ProjectSnapshotFailedV1 | ProjectSnapshotReadyCheckV1 | ProjectSnapshotPodWatchV1 | McpPrototypePulledV1 | HostingCustomDomainCertCheckV1 | HostingCustomDomainServingCheckV1 | HostingCustomDomainDelegationCheckV1;
1402
1463
  export interface ModelPermissionRequiredEvent {
1403
1464
  type: "assistant.model.permission.required";
1404
1465
  data: {
package/src/events.js CHANGED
@@ -54,6 +54,18 @@ export const FusionShapeAssembledV1 = {
54
54
  eventName: "fusion.shape.assembled",
55
55
  version: "1",
56
56
  };
57
+ export const FusionShapeResolvedV1 = {
58
+ eventName: "fusion.shape.resolved",
59
+ version: "1",
60
+ };
61
+ export const FusionShapeQuestionAnsweredV1 = {
62
+ eventName: "fusion.shape.question.answered",
63
+ version: "1",
64
+ };
65
+ export const FusionShapeQuestionSkippedV1 = {
66
+ eventName: "fusion.shape.question.skipped",
67
+ version: "1",
68
+ };
57
69
  export const SetupAgentCompletedV1 = {
58
70
  eventName: "fusion.setup.completed",
59
71
  version: "1",
@@ -102,6 +114,14 @@ export const ProjectSnapshotRefreshV1 = {
102
114
  eventName: "project.snapshot.refresh",
103
115
  version: "1",
104
116
  };
117
+ export const ProjectSnapshotGoldenWatchdogV1 = {
118
+ eventName: "project.snapshot.golden.watchdog",
119
+ version: "1",
120
+ };
121
+ export const ProjectSnapshotGoldenRetryV1 = {
122
+ eventName: "project.snapshot.golden.retry",
123
+ version: "1",
124
+ };
105
125
  export const ProjectSnapshotCapturedV1 = {
106
126
  eventName: "project.snapshot.captured",
107
127
  version: "1",
package/src/projects.d.ts CHANGED
@@ -774,6 +774,7 @@ export declare const ShapeEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
774
774
  }, z.core.$strip>, z.ZodObject<{
775
775
  kind: z.ZodLiteral<"attach-design-system">;
776
776
  designSystemId: z.ZodString;
777
+ designSystemName: z.ZodString;
777
778
  }, z.core.$strip>], "kind">;
778
779
  export type ShapeEffect = z.infer<typeof ShapeEffectSchema>;
779
780
  export declare const ShapeOptionEffectSchema: z.ZodObject<{
@@ -785,6 +786,7 @@ export declare const ShapeOptionEffectSchema: z.ZodObject<{
785
786
  }, z.core.$strip>, z.ZodObject<{
786
787
  kind: z.ZodLiteral<"attach-design-system">;
787
788
  designSystemId: z.ZodString;
789
+ designSystemName: z.ZodString;
788
790
  }, z.core.$strip>], "kind">>>;
789
791
  }, z.core.$strip>;
790
792
  export type ShapeOptionEffect = z.infer<typeof ShapeOptionEffectSchema>;
@@ -800,6 +802,7 @@ export declare const ShapeOptionSchema: z.ZodObject<{
800
802
  }, z.core.$strip>, z.ZodObject<{
801
803
  kind: z.ZodLiteral<"attach-design-system">;
802
804
  designSystemId: z.ZodString;
805
+ designSystemName: z.ZodString;
803
806
  }, z.core.$strip>], "kind">>>;
804
807
  }, z.core.$strip>>;
805
808
  }, z.core.$strip>;
@@ -823,6 +826,7 @@ export declare const ShapeQuestionSchema: z.ZodObject<{
823
826
  }, z.core.$strip>, z.ZodObject<{
824
827
  kind: z.ZodLiteral<"attach-design-system">;
825
828
  designSystemId: z.ZodString;
829
+ designSystemName: z.ZodString;
826
830
  }, z.core.$strip>], "kind">>>;
827
831
  }, z.core.$strip>>;
828
832
  }, z.core.$strip>>;
@@ -833,6 +837,7 @@ export declare const ShapeAnswerSchema: z.ZodObject<{
833
837
  questionId: z.ZodString;
834
838
  optionId: z.ZodOptional<z.ZodString>;
835
839
  designSystemId: z.ZodOptional<z.ZodString>;
840
+ designSystemName: z.ZodOptional<z.ZodString>;
836
841
  skipped: z.ZodBoolean;
837
842
  delegated: z.ZodBoolean;
838
843
  resolvedFrom: z.ZodEnum<{
@@ -843,6 +848,49 @@ export declare const ShapeAnswerSchema: z.ZodObject<{
843
848
  guessOptionId: z.ZodOptional<z.ZodString>;
844
849
  }, z.core.$strip>;
845
850
  export type ShapeAnswer = z.infer<typeof ShapeAnswerSchema>;
851
+ export declare const ShapeAnswerInputSchema: z.ZodObject<{
852
+ skipped: z.ZodBoolean;
853
+ delegated: z.ZodBoolean;
854
+ questionId: z.ZodString;
855
+ optionId: z.ZodOptional<z.ZodString>;
856
+ designSystemId: z.ZodOptional<z.ZodString>;
857
+ }, z.core.$strip>;
858
+ export type ShapeAnswerInput = z.infer<typeof ShapeAnswerInputSchema>;
859
+ export declare const GetShapeQuestionnaireOptionsSchema: z.ZodObject<{
860
+ projectId: z.ZodString;
861
+ }, z.core.$strip>;
862
+ export type GetShapeQuestionnaireOptions = z.infer<typeof GetShapeQuestionnaireOptionsSchema>;
863
+ export declare const SubmitShapeAnswersOptionsSchema: z.ZodObject<{
864
+ projectId: z.ZodString;
865
+ questionnaireId: z.ZodString;
866
+ answers: z.ZodArray<z.ZodObject<{
867
+ skipped: z.ZodBoolean;
868
+ delegated: z.ZodBoolean;
869
+ questionId: z.ZodString;
870
+ optionId: z.ZodOptional<z.ZodString>;
871
+ designSystemId: z.ZodOptional<z.ZodString>;
872
+ }, z.core.$strip>>;
873
+ }, z.core.$strip>;
874
+ export type SubmitShapeAnswersOptions = z.infer<typeof SubmitShapeAnswersOptionsSchema>;
875
+ /**
876
+ * A file the client writes into the container's working tree over the
877
+ * launch-server RPC. The server renders the body; the container performs the
878
+ * write; the agent only reads it.
879
+ */
880
+ export declare const ShapeDecisionsFileSchema: z.ZodObject<{
881
+ path: z.ZodString;
882
+ contents: z.ZodString;
883
+ }, z.core.$strip>;
884
+ export type ShapeDecisionsFile = z.infer<typeof ShapeDecisionsFileSchema>;
885
+ export declare const SubmitShapeAnswersResponseSchema: z.ZodObject<{
886
+ prompt: z.ZodString;
887
+ instructionBlock: z.ZodOptional<z.ZodString>;
888
+ decisionsFile: z.ZodOptional<z.ZodObject<{
889
+ path: z.ZodString;
890
+ contents: z.ZodString;
891
+ }, z.core.$strip>>;
892
+ }, z.core.$strip>;
893
+ export type SubmitShapeAnswersResponse = z.infer<typeof SubmitShapeAnswersResponseSchema>;
846
894
  export declare const ShapeQuestionDecisionSchema: z.ZodObject<{
847
895
  questionId: z.ZodString;
848
896
  ask: z.ZodBoolean;
@@ -893,6 +941,7 @@ export declare const ShapeSessionSchema: z.ZodObject<{
893
941
  }, z.core.$strip>, z.ZodObject<{
894
942
  kind: z.ZodLiteral<"attach-design-system">;
895
943
  designSystemId: z.ZodString;
944
+ designSystemName: z.ZodString;
896
945
  }, z.core.$strip>], "kind">>>;
897
946
  }, z.core.$strip>>;
898
947
  }, z.core.$strip>>;
@@ -903,6 +952,7 @@ export declare const ShapeSessionSchema: z.ZodObject<{
903
952
  questionId: z.ZodString;
904
953
  optionId: z.ZodOptional<z.ZodString>;
905
954
  designSystemId: z.ZodOptional<z.ZodString>;
955
+ designSystemName: z.ZodOptional<z.ZodString>;
906
956
  skipped: z.ZodBoolean;
907
957
  delegated: z.ZodBoolean;
908
958
  resolvedFrom: z.ZodEnum<{
@@ -1374,6 +1424,7 @@ export declare const ProjectSettingsSchema: z.ZodObject<{
1374
1424
  }, z.core.$strip>, z.ZodObject<{
1375
1425
  kind: z.ZodLiteral<"attach-design-system">;
1376
1426
  designSystemId: z.ZodString;
1427
+ designSystemName: z.ZodString;
1377
1428
  }, z.core.$strip>], "kind">>>;
1378
1429
  }, z.core.$strip>>;
1379
1430
  }, z.core.$strip>>;
@@ -1384,6 +1435,7 @@ export declare const ProjectSettingsSchema: z.ZodObject<{
1384
1435
  questionId: z.ZodString;
1385
1436
  optionId: z.ZodOptional<z.ZodString>;
1386
1437
  designSystemId: z.ZodOptional<z.ZodString>;
1438
+ designSystemName: z.ZodOptional<z.ZodString>;
1387
1439
  skipped: z.ZodBoolean;
1388
1440
  delegated: z.ZodBoolean;
1389
1441
  resolvedFrom: z.ZodEnum<{
@@ -3362,6 +3414,10 @@ export declare const ReserveSlugResponseSchema: z.ZodObject<{
3362
3414
  slug: z.ZodString;
3363
3415
  }, z.core.$strip>;
3364
3416
  export type ReserveSlugResponse = z.infer<typeof ReserveSlugResponseSchema>;
3417
+ export declare const GoldenSnapshotRefreshRequestSchema: z.ZodObject<{
3418
+ sourceCommitSha: z.ZodString;
3419
+ }, z.core.$strict>;
3420
+ export type GoldenSnapshotRefreshRequest = z.infer<typeof GoldenSnapshotRefreshRequestSchema>;
3365
3421
  export declare const DeployRequestSchema: z.ZodObject<{
3366
3422
  projectId: z.ZodString;
3367
3423
  checkoutBranch: z.ZodOptional<z.ZodString>;
@@ -4261,6 +4317,7 @@ export declare const ProjectTemplateSchema: z.ZodObject<{
4261
4317
  }, z.core.$strip>, z.ZodObject<{
4262
4318
  kind: z.ZodLiteral<"attach-design-system">;
4263
4319
  designSystemId: z.ZodString;
4320
+ designSystemName: z.ZodString;
4264
4321
  }, z.core.$strip>], "kind">>>;
4265
4322
  }, z.core.$strip>>;
4266
4323
  }, z.core.$strip>>;
@@ -4271,6 +4328,7 @@ export declare const ProjectTemplateSchema: z.ZodObject<{
4271
4328
  questionId: z.ZodString;
4272
4329
  optionId: z.ZodOptional<z.ZodString>;
4273
4330
  designSystemId: z.ZodOptional<z.ZodString>;
4331
+ designSystemName: z.ZodOptional<z.ZodString>;
4274
4332
  skipped: z.ZodBoolean;
4275
4333
  delegated: z.ZodBoolean;
4276
4334
  resolvedFrom: z.ZodEnum<{
package/src/projects.js CHANGED
@@ -279,7 +279,10 @@ export const ShapeEffectSchema = z.discriminatedUnion("kind", [
279
279
  }),
280
280
  z.object({
281
281
  kind: z.literal("attach-design-system"),
282
+ /** The permanent join key. */
282
283
  designSystemId: z.string(),
284
+ /** What actually gets written: the field is matched by name downstream. */
285
+ designSystemName: z.string(),
283
286
  }),
284
287
  ]);
285
288
  export const ShapeOptionEffectSchema = z.object({
@@ -302,12 +305,62 @@ export const ShapeAnswerSchema = z.object({
302
305
  questionId: z.string(),
303
306
  optionId: z.string().optional(),
304
307
  designSystemId: z.string().optional(),
308
+ /**
309
+ * Server-resolved from `designSystemId` against the caller's accessible
310
+ * design systems. `settings.designSystems` is matched by name downstream, so
311
+ * the id alone cannot be written there.
312
+ */
313
+ designSystemName: z.string().optional(),
305
314
  skipped: z.boolean(),
306
315
  delegated: z.boolean(),
307
316
  resolvedFrom: z.enum(["user", "llm"]),
308
317
  llmOptionId: z.string().optional(),
309
318
  guessOptionId: z.string().optional(),
310
319
  });
320
+ const ShapeAnswerInputBaseSchema = ShapeAnswerSchema.pick({
321
+ questionId: true,
322
+ optionId: true,
323
+ designSystemId: true,
324
+ skipped: true,
325
+ delegated: true,
326
+ });
327
+ export const ShapeAnswerInputSchema = z.object({
328
+ ...ShapeAnswerInputBaseSchema.shape,
329
+ questionId: ShapeAnswerInputBaseSchema.shape.questionId.trim().min(1),
330
+ optionId: ShapeAnswerInputBaseSchema.shape.optionId
331
+ .unwrap()
332
+ .trim()
333
+ .min(1)
334
+ .optional(),
335
+ designSystemId: ShapeAnswerInputBaseSchema.shape.designSystemId
336
+ .unwrap()
337
+ .trim()
338
+ .min(1)
339
+ .optional(),
340
+ });
341
+ export const GetShapeQuestionnaireOptionsSchema = z.object({
342
+ projectId: z.string().trim().min(1),
343
+ });
344
+ export const SubmitShapeAnswersOptionsSchema = z.object({
345
+ projectId: z.string().trim().min(1),
346
+ questionnaireId: z.string().trim().min(1),
347
+ answers: z.array(ShapeAnswerInputSchema).min(1),
348
+ });
349
+ /**
350
+ * A file the client writes into the container's working tree over the
351
+ * launch-server RPC. The server renders the body; the container performs the
352
+ * write; the agent only reads it.
353
+ */
354
+ export const ShapeDecisionsFileSchema = z.object({
355
+ /** Repository-root relative. */
356
+ path: z.string().min(1),
357
+ contents: z.string().min(1),
358
+ });
359
+ export const SubmitShapeAnswersResponseSchema = z.object({
360
+ prompt: z.string().min(1),
361
+ instructionBlock: z.string().min(1).optional(),
362
+ decisionsFile: ShapeDecisionsFileSchema.optional(),
363
+ });
311
364
  export const ShapeQuestionDecisionSchema = z.object({
312
365
  questionId: z.string(),
313
366
  ask: z.boolean(),
@@ -1728,6 +1781,13 @@ export const ReserveSlugResponseSchema = z.object({
1728
1781
  const gitCommitHashSchema = z
1729
1782
  .string()
1730
1783
  .regex(/^[0-9a-f]{7,40}$/i, "Must be a valid git commit hash (7–40 hex chars)");
1784
+ export const GoldenSnapshotRefreshRequestSchema = z
1785
+ .object({
1786
+ sourceCommitSha: z
1787
+ .string()
1788
+ .regex(/^[0-9a-f]{40}$/i, "Must be exactly 40 hexadecimal characters"),
1789
+ })
1790
+ .strict();
1731
1791
  export const DeployRequestSchema = z.object({
1732
1792
  projectId: z.string(),
1733
1793
  checkoutBranch: z.string().optional(),
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { AGENT_NATIVE_STARTER_REPO, getAgentNativeRootPackageJsonWriteError, getManagedDatabasePackageJsonError, getProjectState, InitialPromptSchema, isProjectDeleted, matchesAgentNativeStarter, ProjectHostingExternalSchema, ProjectHostingSchema, ProjectSettingsExternalSchema, ProjectSettingsSchema, ProjectTemplateOverridesSchema, ShapeSessionSchema, } from "./projects";
2
+ import { AGENT_NATIVE_STARTER_REPO, getAgentNativeRootPackageJsonWriteError, getManagedDatabasePackageJsonError, getProjectState, GetShapeQuestionnaireOptionsSchema, InitialPromptSchema, isProjectDeleted, matchesAgentNativeStarter, ProjectHostingExternalSchema, ProjectHostingSchema, ProjectSettingsExternalSchema, ProjectSettingsSchema, ProjectTemplateOverridesSchema, ShapeSessionSchema, SubmitShapeAnswersOptionsSchema, } from "./projects";
3
3
  describe("project hosting schemas", () => {
4
4
  it("accepts the canonical published branch route", () => {
5
5
  expect(ProjectHostingSchema.parse({ publishedBranchId: "branch-live" })).toEqual({ publishedBranchId: "branch-live" });
@@ -79,6 +79,42 @@ describe("guided onboarding project settings", () => {
79
79
  expect(ProjectSettingsExternalSchema.parse({ shapeSession })).toEqual({});
80
80
  expect(ProjectTemplateOverridesSchema.parse({ settings: { shapeSession } })).toEqual({ settings: {} });
81
81
  });
82
+ it("parses questionnaire endpoint inputs without accepting server fields", () => {
83
+ expect(GetShapeQuestionnaireOptionsSchema.parse({ projectId: "project-1" })).toEqual({ projectId: "project-1" });
84
+ expect(SubmitShapeAnswersOptionsSchema.parse({
85
+ projectId: "project-1",
86
+ questionnaireId: "questionnaire-1",
87
+ answers: [
88
+ {
89
+ questionId: "authentication",
90
+ optionId: "required",
91
+ skipped: false,
92
+ delegated: false,
93
+ resolvedFrom: "llm",
94
+ llmOptionId: "not-required",
95
+ guessOptionId: "not-required",
96
+ },
97
+ ],
98
+ })).toEqual({
99
+ projectId: "project-1",
100
+ questionnaireId: "questionnaire-1",
101
+ answers: [
102
+ {
103
+ questionId: "authentication",
104
+ optionId: "required",
105
+ skipped: false,
106
+ delegated: false,
107
+ },
108
+ ],
109
+ });
110
+ });
111
+ it("requires non-empty questionnaire ids and at least one answer", () => {
112
+ expect(() => SubmitShapeAnswersOptionsSchema.parse({
113
+ projectId: "",
114
+ questionnaireId: "",
115
+ answers: [],
116
+ })).toThrow();
117
+ });
82
118
  });
83
119
  describe("matchesAgentNativeStarter", () => {
84
120
  it("matches when repoName is the starter", () => {