@builder.io/ai-utils 0.108.0 → 0.109.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.108.0",
3
+ "version": "0.109.1",
4
4
  "description": "Builder.io AI utils",
5
5
  "files": [
6
6
  "src"
package/src/codegen.d.ts CHANGED
@@ -511,6 +511,56 @@ export declare const RecordFrameToolInputSchema: z.ZodObject<{
511
511
  pr_highlight: z.ZodOptional<z.ZodBoolean>;
512
512
  }, z.core.$strip>;
513
513
  export type RecordFrameToolInput = z.infer<typeof RecordFrameToolInputSchema>;
514
+ export declare const StartRecordingToolInputSchema: z.ZodObject<{
515
+ label: z.ZodString;
516
+ }, z.core.$strip>;
517
+ export type StartRecordingToolInput = z.infer<typeof StartRecordingToolInputSchema>;
518
+ export declare const StopRecordingToolInputSchema: z.ZodObject<{}, z.core.$strip>;
519
+ export type StopRecordingToolInput = z.infer<typeof StopRecordingToolInputSchema>;
520
+ export declare const PublishEvidenceToolInputSchema: z.ZodObject<{
521
+ issues: z.ZodArray<z.ZodObject<{
522
+ title: z.ZodString;
523
+ verdict: z.ZodEnum<{
524
+ fixed: "fixed";
525
+ "needs-input": "needs-input";
526
+ "no-ui-change": "no-ui-change";
527
+ "not-reproduced": "not-reproduced";
528
+ }>;
529
+ summary: z.ZodString;
530
+ screenshots: z.ZodArray<z.ZodObject<{
531
+ path: z.ZodString;
532
+ caption: z.ZodString;
533
+ }, z.core.$strip>>;
534
+ recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
535
+ recording_id: z.ZodString;
536
+ }, z.core.$strip>>>;
537
+ }, z.core.$strip>>;
538
+ }, z.core.$strip>;
539
+ export type PublishEvidenceToolInput = z.infer<typeof PublishEvidenceToolInputSchema>;
540
+ export declare const MAX_EVIDENCE_UPLOAD_BYTES: number;
541
+ export declare const EvidenceUploadUrlOptionsSchema: z.ZodObject<{
542
+ contentType: z.ZodEnum<{
543
+ "image/webp": "image/webp";
544
+ "video/mp4": "video/mp4";
545
+ }>;
546
+ size: z.ZodNumber;
547
+ }, z.core.$strip>;
548
+ export type EvidenceUploadUrlOptions = z.infer<typeof EvidenceUploadUrlOptionsSchema>;
549
+ /** What publishing evidence did to the branch's open pull request. */
550
+ export type OpenPRRefresh = {
551
+ status: "no-open-pr";
552
+ } | {
553
+ status: "updated";
554
+ prNumber: number;
555
+ } | {
556
+ status: "failed";
557
+ reason: string;
558
+ };
559
+ export interface EvidenceUploadUrlResult {
560
+ upload_url: string;
561
+ public_url: string;
562
+ required_headers: Record<string, string>;
563
+ }
514
564
  export declare const ReportTestOutcomeToolInputSchema: z.ZodObject<{
515
565
  outcome: z.ZodEnum<{
516
566
  couldnt_verify: "couldnt_verify";
@@ -569,12 +619,29 @@ export interface TimelineFrameMetadata {
569
619
  fileName?: string;
570
620
  image_url?: string;
571
621
  prHighlight?: boolean;
622
+ /** Index into `TimelineRecording.phases` for a frame that belongs to a recording tab. */
623
+ phaseIndex?: number;
572
624
  description?: string;
573
625
  cursorX?: number | null;
574
626
  cursorY?: number | null;
575
627
  viewportWidth?: number;
576
628
  viewportHeight?: number;
577
629
  }
630
+ /** One agent's slice of a merged browser-testing run. */
631
+ export interface TimelineAgentPhase {
632
+ label: string;
633
+ sessionId: string;
634
+ startEventId: number;
635
+ endEventId: number;
636
+ testCaseIds?: string[];
637
+ replayId?: string;
638
+ }
639
+ /** One screen recording published as evidence; the timeline shows a tab for each. */
640
+ export interface TimelineVideoPhase {
641
+ label: string;
642
+ videoUrl: string;
643
+ testCaseIds: string[];
644
+ }
578
645
  export interface TimelineRecording {
579
646
  version: 1;
580
647
  sessionId: string;
@@ -591,14 +658,7 @@ export interface TimelineRecording {
591
658
  description: string;
592
659
  debugInfo?: string;
593
660
  }>;
594
- phases?: Array<{
595
- label: string;
596
- sessionId: string;
597
- startEventId: number;
598
- endEventId: number;
599
- testCaseIds?: string[];
600
- replayId?: string;
601
- }>;
661
+ phases?: Array<TimelineAgentPhase | TimelineVideoPhase>;
602
662
  }
603
663
  export interface TimelineSubmissionMetadata {
604
664
  prNumber?: number;
@@ -1631,6 +1691,29 @@ export declare const CodeGenToolMapSchema: z.ZodObject<{
1631
1691
  description: z.ZodOptional<z.ZodString>;
1632
1692
  pr_highlight: z.ZodOptional<z.ZodBoolean>;
1633
1693
  }, z.core.$strip>;
1694
+ StartRecording: z.ZodObject<{
1695
+ label: z.ZodString;
1696
+ }, z.core.$strip>;
1697
+ StopRecording: z.ZodObject<{}, z.core.$strip>;
1698
+ PublishEvidence: z.ZodObject<{
1699
+ issues: z.ZodArray<z.ZodObject<{
1700
+ title: z.ZodString;
1701
+ verdict: z.ZodEnum<{
1702
+ fixed: "fixed";
1703
+ "needs-input": "needs-input";
1704
+ "no-ui-change": "no-ui-change";
1705
+ "not-reproduced": "not-reproduced";
1706
+ }>;
1707
+ summary: z.ZodString;
1708
+ screenshots: z.ZodArray<z.ZodObject<{
1709
+ path: z.ZodString;
1710
+ caption: z.ZodString;
1711
+ }, z.core.$strip>>;
1712
+ recordings: z.ZodOptional<z.ZodArray<z.ZodObject<{
1713
+ recording_id: z.ZodString;
1714
+ }, z.core.$strip>>>;
1715
+ }, z.core.$strip>>;
1716
+ }, z.core.$strip>;
1634
1717
  SubmitPRReview: z.ZodObject<{
1635
1718
  summary: z.ZodString;
1636
1719
  comments: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -2001,6 +2084,7 @@ export declare const CodeGenToolsSchema: z.ZodEnum<{
2001
2084
  PowerShell: "PowerShell";
2002
2085
  ProposeConfig: "ProposeConfig";
2003
2086
  ProposeEnvVariable: "ProposeEnvVariable";
2087
+ PublishEvidence: "PublishEvidence";
2004
2088
  PullPrototype: "PullPrototype";
2005
2089
  Read: "Read";
2006
2090
  ReadBranch: "ReadBranch";
@@ -2020,6 +2104,8 @@ export declare const CodeGenToolsSchema: z.ZodEnum<{
2020
2104
  SetFileOverride: "SetFileOverride";
2021
2105
  Skill: "Skill";
2022
2106
  SpawnBranch: "SpawnBranch";
2107
+ StartRecording: "StartRecording";
2108
+ StopRecording: "StopRecording";
2023
2109
  SubmitPRReview: "SubmitPRReview";
2024
2110
  TaskCreate: "TaskCreate";
2025
2111
  TaskList: "TaskList";
@@ -2893,6 +2979,7 @@ export declare const CodeGenInputOptionsSchema: z.ZodObject<{
2893
2979
  PowerShell: "PowerShell";
2894
2980
  ProposeConfig: "ProposeConfig";
2895
2981
  ProposeEnvVariable: "ProposeEnvVariable";
2982
+ PublishEvidence: "PublishEvidence";
2896
2983
  PullPrototype: "PullPrototype";
2897
2984
  Read: "Read";
2898
2985
  ReadBranch: "ReadBranch";
@@ -2912,6 +2999,8 @@ export declare const CodeGenInputOptionsSchema: z.ZodObject<{
2912
2999
  SetFileOverride: "SetFileOverride";
2913
3000
  Skill: "Skill";
2914
3001
  SpawnBranch: "SpawnBranch";
3002
+ StartRecording: "StartRecording";
3003
+ StopRecording: "StopRecording";
2915
3004
  SubmitPRReview: "SubmitPRReview";
2916
3005
  TaskCreate: "TaskCreate";
2917
3006
  TaskList: "TaskList";
package/src/codegen.js CHANGED
@@ -751,6 +751,62 @@ export const RecordFrameToolInputSchema = z
751
751
  }),
752
752
  })
753
753
  .meta({ title: "RecordFrameToolInput" });
754
+ export const StartRecordingToolInputSchema = z
755
+ .object({
756
+ label: z.string().meta({
757
+ description: "Timeline tab label for this recording, e.g. 'Production before', 'Figma', 'Local after'.",
758
+ }),
759
+ })
760
+ .meta({ title: "StartRecordingToolInput" });
761
+ export const StopRecordingToolInputSchema = z
762
+ .object({})
763
+ .meta({ title: "StopRecordingToolInput" });
764
+ export const PublishEvidenceToolInputSchema = z
765
+ .object({
766
+ issues: z
767
+ .array(z.object({
768
+ title: z.string().meta({
769
+ description: "The issue as the user would name it.",
770
+ }),
771
+ verdict: z
772
+ .enum(["fixed", "not-reproduced", "needs-input", "no-ui-change"])
773
+ .meta({
774
+ description: "Only 'fixed' issues reach the PR's Verified section; the others stay on the timeline. 'no-ui-change' is for a change with nothing to show in a browser.",
775
+ }),
776
+ summary: z.string().meta({
777
+ description: "One or two sentences: what changed, or why it was not fixed.",
778
+ }),
779
+ screenshots: z
780
+ .array(z.object({
781
+ path: z.string().meta({
782
+ description: "A .png, .jpg or .webp file in the workspace or under ~/.builder.",
783
+ }),
784
+ caption: z.string(),
785
+ }))
786
+ .meta({
787
+ description: "Stills that support the fix; the PR shows them under the recording.",
788
+ }),
789
+ recordings: z
790
+ .array(z.object({
791
+ recording_id: z.string().meta({
792
+ description: "The recording_id StopRecording returned.",
793
+ }),
794
+ }))
795
+ .optional()
796
+ .meta({
797
+ description: "Required for a 'fixed' issue: its verification, recorded on your current code. Older recordings stay on the timeline as comparisons. One timeline tab each.",
798
+ }),
799
+ }))
800
+ .min(1),
801
+ })
802
+ .meta({ title: "PublishEvidenceToolInput" });
803
+ export const MAX_EVIDENCE_UPLOAD_BYTES = 100 * 1024 * 1024;
804
+ export const EvidenceUploadUrlOptionsSchema = z
805
+ .object({
806
+ contentType: z.enum(["video/mp4", "image/webp"]),
807
+ size: z.number().int().positive().max(MAX_EVIDENCE_UPLOAD_BYTES),
808
+ })
809
+ .meta({ title: "EvidenceUploadUrlOptions" });
754
810
  export const ReportTestOutcomeToolInputSchema = z
755
811
  .object({
756
812
  outcome: TestOutcomeSchema.meta({
@@ -1643,6 +1699,9 @@ export const CodeGenToolMapSchema = z.object({
1643
1699
  ExitPlanMode: ExitPlanModeToolInputSchema,
1644
1700
  ReadMcpResource: ReadMcpResourceToolInputSchema,
1645
1701
  RecordFrame: RecordFrameToolInputSchema,
1702
+ StartRecording: StartRecordingToolInputSchema,
1703
+ StopRecording: StopRecordingToolInputSchema,
1704
+ PublishEvidence: PublishEvidenceToolInputSchema,
1646
1705
  SubmitPRReview: SubmitPRReviewToolInputSchema,
1647
1706
  AddComment: AddCommentToolInputSchema,
1648
1707
  ProposeConfig: ProposeConfigToolInputSchema,
package/src/projects.d.ts CHANGED
@@ -1924,7 +1924,14 @@ export interface Project {
1924
1924
  projectType?: "app" | "repo-indexing";
1925
1925
  /** Custom domains associated with this project. */
1926
1926
  domains?: string[];
1927
- /** Whether the project is publicly accessible. */
1927
+ /**
1928
+ * Which members of the owning space can access the project. `"public"` (shown
1929
+ * as "Team" in the UI, and the behavior when absent) admits every space
1930
+ * member, subject to any project limits on their org role; `"private"` admits
1931
+ * only the roles and users in {@link Project.projectAccess}. Org admins and
1932
+ * the project's creator always have access. Grants nothing outside the
1933
+ * space — see {@link Project.isPublic}.
1934
+ */
1928
1935
  accessMode?: "public" | "private";
1929
1936
  /** Fine-grained access control configuration for the project. */
1930
1937
  projectAccess?: ProjectAccessControl;
@@ -1934,7 +1941,12 @@ export interface Project {
1934
1941
  screenshot: string | null;
1935
1942
  /** When true, this project is a built-in example shown to new users. */
1936
1943
  isExample?: boolean;
1937
- /** When true, the project is publicly accessible without authentication. */
1944
+ /**
1945
+ * When true, signed-in users outside the owning space can view and clone the
1946
+ * project. Only example projects and connected fusion-starter projects can be
1947
+ * made public. Independent of {@link Project.accessMode}, which governs members
1948
+ * of the owning space.
1949
+ */
1938
1950
  isPublic?: boolean;
1939
1951
  /** Volume snapshot metadata for restoring container state. */
1940
1952
  snapshotVolume?: {
@@ -2258,6 +2270,11 @@ export declare const ProjectSourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2258
2270
  templateId: z.ZodString;
2259
2271
  }, z.core.$strip>], "kind">;
2260
2272
  export type ProjectSource = z.infer<typeof ProjectSourceSchema>;
2273
+ /** Query string of `GET /projects`. Only `limit` is validated here so far. */
2274
+ export declare const GetProjectsQuerySchema: z.ZodObject<{
2275
+ limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
2276
+ }, z.core.$strip>;
2277
+ export type GetProjectsQuery = z.infer<typeof GetProjectsQuerySchema>;
2261
2278
  /**
2262
2279
  * Request body for `POST /projects/create`. Identity/credentials come from the
2263
2280
  * authenticated request context, never the body.
@@ -3225,6 +3242,12 @@ export declare const DeployFailureReportSchema: z.ZodObject<{
3225
3242
  excerpt: z.ZodOptional<z.ZodString>;
3226
3243
  }, z.core.$strip>;
3227
3244
  export type DeployFailureReport = z.infer<typeof DeployFailureReportSchema>;
3245
+ export declare const DeployFixNotRequestedReasonSchema: z.ZodEnum<{
3246
+ error: "error";
3247
+ "no-branch": "no-branch";
3248
+ "send-failed": "send-failed";
3249
+ }>;
3250
+ export type DeployFixNotRequestedReason = z.infer<typeof DeployFixNotRequestedReasonSchema>;
3228
3251
  export declare const DeployFailureSchema: z.ZodObject<{
3229
3252
  stage: z.ZodOptional<z.ZodEnum<{
3230
3253
  build: "build";
@@ -3244,6 +3267,11 @@ export declare const DeployFailureSchema: z.ZodObject<{
3244
3267
  exitCode: z.ZodOptional<z.ZodNumber>;
3245
3268
  signal: z.ZodOptional<z.ZodString>;
3246
3269
  fixRequested: z.ZodOptional<z.ZodBoolean>;
3270
+ fixNotRequestedReason: z.ZodOptional<z.ZodEnum<{
3271
+ error: "error";
3272
+ "no-branch": "no-branch";
3273
+ "send-failed": "send-failed";
3274
+ }>>;
3247
3275
  }, z.core.$strip>;
3248
3276
  export type DeployFailure = z.infer<typeof DeployFailureSchema>;
3249
3277
  export declare const DeploySchema: z.ZodObject<{
@@ -3295,6 +3323,11 @@ export declare const DeploySchema: z.ZodObject<{
3295
3323
  exitCode: z.ZodOptional<z.ZodNumber>;
3296
3324
  signal: z.ZodOptional<z.ZodString>;
3297
3325
  fixRequested: z.ZodOptional<z.ZodBoolean>;
3326
+ fixNotRequestedReason: z.ZodOptional<z.ZodEnum<{
3327
+ error: "error";
3328
+ "no-branch": "no-branch";
3329
+ "send-failed": "send-failed";
3330
+ }>>;
3298
3331
  }, z.core.$strip>>;
3299
3332
  createdAt: z.ZodNumber;
3300
3333
  completedAt: z.ZodOptional<z.ZodNumber>;
@@ -3421,6 +3454,11 @@ export declare const DeployListItemSchema: z.ZodObject<{
3421
3454
  exitCode: z.ZodOptional<z.ZodNumber>;
3422
3455
  signal: z.ZodOptional<z.ZodString>;
3423
3456
  fixRequested: z.ZodOptional<z.ZodBoolean>;
3457
+ fixNotRequestedReason: z.ZodOptional<z.ZodEnum<{
3458
+ error: "error";
3459
+ "no-branch": "no-branch";
3460
+ "send-failed": "send-failed";
3461
+ }>>;
3424
3462
  }, z.core.$strip>>;
3425
3463
  createdAt: z.ZodNumber;
3426
3464
  completedAt: z.ZodOptional<z.ZodNumber>;
@@ -3681,6 +3719,11 @@ export declare const GetDeploysResponseSchema: z.ZodObject<{
3681
3719
  exitCode: z.ZodOptional<z.ZodNumber>;
3682
3720
  signal: z.ZodOptional<z.ZodString>;
3683
3721
  fixRequested: z.ZodOptional<z.ZodBoolean>;
3722
+ fixNotRequestedReason: z.ZodOptional<z.ZodEnum<{
3723
+ error: "error";
3724
+ "no-branch": "no-branch";
3725
+ "send-failed": "send-failed";
3726
+ }>>;
3684
3727
  }, z.core.$strip>>;
3685
3728
  createdAt: z.ZodNumber;
3686
3729
  completedAt: z.ZodOptional<z.ZodNumber>;
@@ -3743,6 +3786,7 @@ export declare const HostingDomainSchema: z.ZodObject<{
3743
3786
  verifyingSince: z.ZodOptional<z.ZodNumber>;
3744
3787
  attemptId: z.ZodOptional<z.ZodString>;
3745
3788
  verifiedAt: z.ZodOptional<z.ZodNumber>;
3789
+ verifiedBy: z.ZodOptional<z.ZodString>;
3746
3790
  error: z.ZodOptional<z.ZodString>;
3747
3791
  failedStep: z.ZodOptional<z.ZodEnum<{
3748
3792
  dns: "dns";
@@ -3751,6 +3795,16 @@ export declare const HostingDomainSchema: z.ZodObject<{
3751
3795
  routeError: z.ZodOptional<z.ZodString>;
3752
3796
  routeErrorAt: z.ZodOptional<z.ZodNumber>;
3753
3797
  servingConfirmedAt: z.ZodOptional<z.ZodNumber>;
3798
+ servingProbeConfirmedAt: z.ZodOptional<z.ZodNumber>;
3799
+ servingProbeTimedOutAt: z.ZodOptional<z.ZodNumber>;
3800
+ servingProbeAmbiguousAt: z.ZodOptional<z.ZodNumber>;
3801
+ certTeardownStartedAt: z.ZodOptional<z.ZodNumber>;
3802
+ certTeardownReason: z.ZodOptional<z.ZodString>;
3803
+ removalStartedAt: z.ZodOptional<z.ZodNumber>;
3804
+ promotionInProgressAttemptId: z.ZodOptional<z.ZodString>;
3805
+ promotionInProgressCount: z.ZodOptional<z.ZodNumber>;
3806
+ promotionStartedAt: z.ZodOptional<z.ZodNumber>;
3807
+ promotionEpoch: z.ZodOptional<z.ZodString>;
3754
3808
  certIssue: z.ZodOptional<z.ZodString>;
3755
3809
  certIssueAt: z.ZodOptional<z.ZodNumber>;
3756
3810
  createdBy: z.ZodString;
package/src/projects.js CHANGED
@@ -1102,6 +1102,11 @@ export const ProjectSourceSchema = z.discriminatedUnion("kind", [
1102
1102
  z.object({ kind: z.literal("repo"), repoUrl: z.string().url() }),
1103
1103
  z.object({ kind: z.literal("template"), templateId: z.string() }),
1104
1104
  ]);
1105
+ /** Query string of `GET /projects`. Only `limit` is validated here so far. */
1106
+ export const GetProjectsQuerySchema = z.object({
1107
+ /** At most this many projects, counted after access, hidden and DSI filtering. */
1108
+ limit: z.coerce.number().int().min(1).max(1000).optional(),
1109
+ });
1105
1110
  /**
1106
1111
  * Request body for `POST /projects/create`. Identity/credentials come from the
1107
1112
  * authenticated request context, never the body.
@@ -1495,6 +1500,11 @@ export const DeployFailureReportSchema = z.object({
1495
1500
  description: "Head-and-tail excerpt of the failing output, cut on line boundaries. Event only, never persisted.",
1496
1501
  }),
1497
1502
  });
1503
+ export const DeployFixNotRequestedReasonSchema = z.enum([
1504
+ "no-branch",
1505
+ "send-failed",
1506
+ "error",
1507
+ ]);
1498
1508
  export const DeployFailureSchema = z.object({
1499
1509
  stage: DeployFailureStageSchema.optional(),
1500
1510
  owner: DeployFailureOwnerSchema,
@@ -1509,6 +1519,9 @@ export const DeployFailureSchema = z.object({
1509
1519
  fixRequested: z.boolean().optional().meta({
1510
1520
  description: "Whether a Fusion agent fix was dispatched for this failure.",
1511
1521
  }),
1522
+ fixNotRequestedReason: DeployFixNotRequestedReasonSchema.optional().meta({
1523
+ description: "Why a fix this failure qualified for was not dispatched. Absent when the failure never qualified.",
1524
+ }),
1512
1525
  });
1513
1526
  export const DeploySchema = z.object({
1514
1527
  id: z.string(),
@@ -2093,6 +2106,7 @@ export const HostingDomainSchema = z.object({
2093
2106
  description: "Per-verify-attempt nonce, set on entering `verifying`. Delegation-check polls whose attemptId no longer matches are stale (a newer retry superseded them) and stop early.",
2094
2107
  }),
2095
2108
  verifiedAt: z.number().optional(),
2109
+ verifiedBy: z.string().optional(),
2096
2110
  error: z.string().optional(),
2097
2111
  failedStep: z.enum(["dns", "https"]).optional().meta({
2098
2112
  description: "Which setup step failed, set alongside `status: failed` so the UI can attribute the failure. `dns` = delegation verification, `https` = cert/route provisioning.",
@@ -2106,6 +2120,16 @@ export const HostingDomainSchema = z.object({
2106
2120
  servingConfirmedAt: z.number().optional().meta({
2107
2121
  description: "When the domain was confirmed serving over HTTPS: stamped by the serving-check loop once `https://<domain>/` answers over TLS through a Builder route (or by a healthy route recreate on deploy/repair on an `active` domain). Definitive 'serving confirmed' signal for the UI's third setup step, distinct from cert issuance (`status: active`). Never set while `provisioning`.",
2108
2122
  }),
2123
+ servingProbeConfirmedAt: z.number().optional(),
2124
+ servingProbeTimedOutAt: z.number().optional(),
2125
+ servingProbeAmbiguousAt: z.number().optional(),
2126
+ certTeardownStartedAt: z.number().optional(),
2127
+ certTeardownReason: z.string().optional(),
2128
+ removalStartedAt: z.number().optional(),
2129
+ promotionInProgressAttemptId: z.string().optional(),
2130
+ promotionInProgressCount: z.number().optional(),
2131
+ promotionStartedAt: z.number().optional(),
2132
+ promotionEpoch: z.string().optional(),
2109
2133
  certIssue: z.string().optional().meta({
2110
2134
  description: "Non-fatal, user-facing reason Google's latest certificate domain-authorization attempt failed while the domain is `provisioning` (e.g. the `_acme-challenge` CNAME wasn't found). Google keeps retrying, so `status` stays `provisioning`; this drives a warning on the HTTPS step instead of a silent spinner. Cleared when an attempt stops failing or the cert is issued.",
2111
2135
  }),