@builder.io/ai-utils 0.100.0 → 0.100.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/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.1",
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;
@@ -1398,7 +1429,7 @@ export declare const HostingCustomDomainDelegationCheckV1: {
1398
1429
  eventName: "hosting.custom-domain.delegation-check";
1399
1430
  version: "1";
1400
1431
  };
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;
1432
+ 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 | ProjectSnapshotCapturedV1 | ProjectSnapshotCreatedV1 | ProjectSnapshotFailedV1 | ProjectSnapshotReadyCheckV1 | ProjectSnapshotPodWatchV1 | McpPrototypePulledV1 | HostingCustomDomainCertCheckV1 | HostingCustomDomainServingCheckV1 | HostingCustomDomainDelegationCheckV1;
1402
1433
  export interface ModelPermissionRequiredEvent {
1403
1434
  type: "assistant.model.permission.required";
1404
1435
  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",
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<{
@@ -4261,6 +4313,7 @@ export declare const ProjectTemplateSchema: z.ZodObject<{
4261
4313
  }, z.core.$strip>, z.ZodObject<{
4262
4314
  kind: z.ZodLiteral<"attach-design-system">;
4263
4315
  designSystemId: z.ZodString;
4316
+ designSystemName: z.ZodString;
4264
4317
  }, z.core.$strip>], "kind">>>;
4265
4318
  }, z.core.$strip>>;
4266
4319
  }, z.core.$strip>>;
@@ -4271,6 +4324,7 @@ export declare const ProjectTemplateSchema: z.ZodObject<{
4271
4324
  questionId: z.ZodString;
4272
4325
  optionId: z.ZodOptional<z.ZodString>;
4273
4326
  designSystemId: z.ZodOptional<z.ZodString>;
4327
+ designSystemName: z.ZodOptional<z.ZodString>;
4274
4328
  skipped: z.ZodBoolean;
4275
4329
  delegated: z.ZodBoolean;
4276
4330
  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(),
@@ -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", () => {