@withgauge/cli 0.4.0 → 0.5.0

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.
Files changed (2) hide show
  1. package/dist/index.js +1106 -588
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -21,7 +21,6 @@ __export(batteries_exports, {
21
21
  BATTERY_AGENTS: () => BATTERY_AGENTS,
22
22
  BATTERY_CADENCES: () => BATTERY_CADENCES,
23
23
  BATTERY_MAX_LIMITS: () => BATTERY_MAX_LIMITS,
24
- BATTERY_SCENARIOS: () => BATTERY_SCENARIOS,
25
24
  MAX_SAMPLES_PER_CYCLE: () => MAX_SAMPLES_PER_CYCLE,
26
25
  batchDetailSchema: () => batchDetailSchema,
27
26
  batchListQuerySchema: () => batchListQuerySchema,
@@ -82,7 +81,6 @@ var BATTERY_CADENCES = [
82
81
  "MONTHLY",
83
82
  "DAYS_PER_WEEK"
84
83
  ];
85
- var BATTERY_SCENARIOS = ["GREENFIELD", "MIGRATION"];
86
84
  var batteryAgentSchema = z2.enum(BATTERY_AGENTS);
87
85
  var BATTERY_MAX_LIMITS = {
88
86
  maxTurns: 30,
@@ -109,7 +107,6 @@ var batteryScheduleSpecSchema = z2.object({
109
107
  limits: batteryLimitsSchema.optional()
110
108
  });
111
109
  var batteryDefaultsSchema = z2.object({
112
- scenario: z2.enum(BATTERY_SCENARIOS).optional(),
113
110
  isBranded: z2.boolean().optional(),
114
111
  topic: z2.string().optional(),
115
112
  tags: z2.array(z2.string()).optional(),
@@ -123,7 +120,6 @@ var batteryPromptSpecSchema = z2.object({
123
120
  /** Idempotency key, unique per org (→ Prompt.externalKey). */
124
121
  key: z2.string().min(1),
125
122
  text: z2.string().min(1),
126
- scenario: z2.enum(BATTERY_SCENARIOS).optional(),
127
123
  isBranded: z2.boolean().optional(),
128
124
  topic: z2.string().optional(),
129
125
  tags: z2.array(z2.string()).optional(),
@@ -342,54 +338,657 @@ var listBrandsQuerySchema = listQuerySchema.extend({
342
338
  });
343
339
  var brandListResponseSchema = listResponseSchema(brandSchema);
344
340
 
345
- // ../packages/api-schemas/src/device.ts
341
+ // ../packages/api-schemas/src/checkpoints.ts
346
342
  import { z as z5 } from "zod";
347
- var deviceAuthorizeRequestSchema = z5.object({
343
+ var CHECKPOINT_STORE_VERSION = 2;
344
+ var ALIGNED_CHECKPOINT_SUPERVISOR_ARTIFACT = "0.0.76-byok-ha-26071639";
345
+ var ALIGNED_RUNSC_VERSION = "release-20260112.0";
346
+ var ALIGNED_RUNSC_PLATFORM = "systrap";
347
+ var SHA256_PATTERN = /^sha256:[0-9a-f]{64}$/;
348
+ var CHECKPOINT_ARTIFACT_PATTERN = /^alg-checkpoint:v2:sha256:[0-9a-f]{64}$/;
349
+ var sha256DigestSchema = z5.custom(
350
+ (value) => typeof value === "string" && SHA256_PATTERN.test(value),
351
+ "expected a sha256:<64 lowercase hex> digest"
352
+ );
353
+ var checkpointArtifactRefSchema = z5.custom(
354
+ (value) => typeof value === "string" && CHECKPOINT_ARTIFACT_PATTERN.test(value),
355
+ "expected an alg-checkpoint:v2 artifact reference"
356
+ );
357
+ var publicArtifactScopeSchema = z5.object({ kind: z5.literal("public") });
358
+ var orgArtifactScopeSchema = z5.object({
359
+ kind: z5.literal("org"),
360
+ organizationId: z5.string().min(1)
361
+ });
362
+ var artifactScopeSchema = z5.discriminatedUnion("kind", [
363
+ publicArtifactScopeSchema,
364
+ orgArtifactScopeSchema
365
+ ]);
366
+ function scopesMatch(left, right) {
367
+ return left.kind === right.kind && (left.kind === "public" || right.kind === "org" && left.organizationId === right.organizationId);
368
+ }
369
+ function manifestScopeReferenceViolation(manifestScope, referenced) {
370
+ if (referenced === void 0) return null;
371
+ if (referenced.kind === "public") return null;
372
+ if (scopesMatch(manifestScope, referenced)) return null;
373
+ if (manifestScope.kind === "public") {
374
+ return "a public manifest must not reference an org-scoped object";
375
+ }
376
+ return "a manifest must not reference another organization's object";
377
+ }
378
+ var checkpointStorePrincipalSchema = z5.discriminatedUnion("kind", [
379
+ z5.object({ kind: z5.literal("system") }),
380
+ z5.object({
381
+ kind: z5.literal("organization"),
382
+ organizationId: z5.string().min(1)
383
+ })
384
+ ]);
385
+ var checkpointChunkSchema = z5.object({
386
+ ordinal: z5.number().int().nonnegative(),
387
+ digest: sha256DigestSchema,
388
+ rawDigest: sha256DigestSchema,
389
+ rawBytes: z5.number().int().positive(),
390
+ storedBytes: z5.number().int().positive()
391
+ });
392
+ var chunkedPayloadSchema = z5.object({
393
+ format: z5.enum([
394
+ "canonical-workspace-chunked-zstd-v1",
395
+ "runsc-checkpoint-chunked-zstd-v1",
396
+ "overlay-upper-chunked-zstd-v1"
397
+ ]),
398
+ chunks: z5.array(checkpointChunkSchema).min(1).superRefine((chunks, context) => {
399
+ for (const [index, chunk] of chunks.entries()) {
400
+ if (chunk.ordinal !== index) {
401
+ context.addIssue({
402
+ code: "custom",
403
+ message: `chunk ordinal ${chunk.ordinal} must equal position ${index}`,
404
+ path: [index, "ordinal"]
405
+ });
406
+ }
407
+ }
408
+ })
409
+ });
410
+ var canonicalBaselinePayloadSchema = chunkedPayloadSchema.extend({
411
+ format: z5.literal("canonical-workspace-chunked-zstd-v1")
412
+ });
413
+ var nydusBaselineBlobSchema = z5.object({
414
+ nydusBlobId: z5.string().regex(/^[0-9a-f]{64}$/),
415
+ object: checkpointChunkSchema,
416
+ /**
417
+ * CAS scope this blob's object actually lives in, when it is NOT the manifest's own
418
+ * (ALG-197 S0). A `--chunk-dict` build inherits its dict's blobs by reference, and the
419
+ * dict is usually a PUBLIC baseline while the built artifact is an ORG conversation
420
+ * checkpoint — without this the manifest can only name `cas/v2/org/<id>/…`, where the
421
+ * inherited object was never stored.
422
+ *
423
+ * ORG→PUBLIC only; the direction is enforced by
424
+ * `workspaceBaselineManifestV2Schema`'s refinement, not by convention.
425
+ *
426
+ * Emitted ONLY when it differs from the manifest scope: manifests are content-addressed
427
+ * over canonical JSON, so an always-present field would change every existing digest
428
+ * and churn every `artifactRef`. Absent ⇒ the manifest's own scope.
429
+ */
430
+ scope: artifactScopeSchema.optional()
431
+ });
432
+ var nydusBaselinePayloadSchema = z5.object({
433
+ format: z5.literal("nydus-rafs-v6"),
434
+ fsVersion: z5.literal(6),
435
+ /** Always the manifest's own scope: a build always produces its own bootstrap, so
436
+ * only inherited BLOBS can be foreign. Confining the override to where a foreign
437
+ * scope is possible is what keeps the invariant checkable. */
438
+ bootstrap: checkpointChunkSchema,
439
+ blobs: z5.array(nydusBaselineBlobSchema)
440
+ });
441
+ var workspaceBaselinePayloadSchema = z5.discriminatedUnion("format", [
442
+ canonicalBaselinePayloadSchema,
443
+ nydusBaselinePayloadSchema
444
+ ]);
445
+ var workspaceBaselineManifestV2Schema = z5.object({
446
+ schemaVersion: z5.literal(CHECKPOINT_STORE_VERSION),
447
+ kind: z5.literal("workspace-baseline"),
448
+ scope: artifactScopeSchema,
449
+ workspaceRoot: sha256DigestSchema,
450
+ payload: workspaceBaselinePayloadSchema,
451
+ repo: z5.object({
452
+ canonicalUrl: z5.string().url(),
453
+ requestedRef: z5.string().min(1),
454
+ resolvedCommit: z5.string().regex(/^[0-9a-f]{40,64}$/)
455
+ }),
456
+ recipe: z5.object({
457
+ digest: sha256DigestSchema,
458
+ sandboxImageDigest: sha256DigestSchema,
459
+ architecture: z5.string().min(1)
460
+ })
461
+ }).superRefine((manifest, context) => {
462
+ if (manifest.payload.format !== "nydus-rafs-v6") return;
463
+ for (const [index, blob] of manifest.payload.blobs.entries()) {
464
+ const violation = manifestScopeReferenceViolation(
465
+ manifest.scope,
466
+ blob.scope
467
+ );
468
+ if (violation) {
469
+ context.addIssue({
470
+ code: "custom",
471
+ message: violation,
472
+ path: ["payload", "blobs", index, "scope"]
473
+ });
474
+ }
475
+ }
476
+ });
477
+ var checkpointBoundaryV2Schema = z5.object({
478
+ kind: z5.enum(["tool_call", "assistant_message", "user_message"]),
479
+ turn: z5.number().int().nonnegative(),
480
+ ordinal: z5.number().int().nonnegative(),
481
+ toolName: z5.string().optional(),
482
+ url: z5.string().url().optional()
483
+ });
484
+ var memoryDiskManifestV2Schema = z5.object({
485
+ schemaVersion: z5.literal(CHECKPOINT_STORE_VERSION),
486
+ kind: z5.literal("runsc-memory-disk"),
487
+ scope: orgArtifactScopeSchema,
488
+ boundary: checkpointBoundaryV2Schema,
489
+ memory: chunkedPayloadSchema.extend({
490
+ format: z5.literal("runsc-checkpoint-chunked-zstd-v1")
491
+ }),
492
+ disk: z5.object({
493
+ baselineArtifact: checkpointArtifactRefSchema,
494
+ baselineScope: artifactScopeSchema,
495
+ baselineWorkspaceRoot: sha256DigestSchema,
496
+ delta: chunkedPayloadSchema.extend({
497
+ format: z5.literal("overlay-upper-chunked-zstd-v1")
498
+ })
499
+ }),
500
+ runtime: z5.object({
501
+ runscVersion: z5.string().min(1),
502
+ platform: z5.string().min(1),
503
+ configDigest: sha256DigestSchema,
504
+ supervisorArtifact: z5.string().min(1),
505
+ architecture: z5.string().min(1)
506
+ }),
507
+ memorySharing: z5.literal("none")
508
+ });
509
+ var workspaceSourceSchema = z5.discriminatedUnion("kind", [
510
+ z5.object({
511
+ kind: z5.literal("nvme-baseline"),
512
+ artifact: checkpointArtifactRefSchema,
513
+ workspaceRoot: sha256DigestSchema,
514
+ scope: artifactScopeSchema
515
+ }),
516
+ z5.object({
517
+ kind: z5.literal("memory-disk"),
518
+ artifact: checkpointArtifactRefSchema,
519
+ boundary: checkpointBoundaryV2Schema
520
+ }),
521
+ z5.object({
522
+ kind: z5.literal("legacy-ebs"),
523
+ volumeSnapshot: z5.string().min(1),
524
+ resumeSessionId: z5.string().min(1).optional()
525
+ })
526
+ ]);
527
+ var baselinePayloadFormatSchema = z5.enum([
528
+ "canonical-workspace-chunked-zstd-v1",
529
+ "runsc-checkpoint-chunked-zstd-v1",
530
+ "overlay-upper-chunked-zstd-v1",
531
+ "nydus-rafs-v6"
532
+ ]);
533
+ var checkpointStoreCapabilitiesSchema = z5.object({
534
+ storeVersion: z5.literal(CHECKPOINT_STORE_VERSION),
535
+ manifestSchemas: z5.array(z5.literal(CHECKPOINT_STORE_VERSION)).min(1),
536
+ payloadFormats: z5.array(baselinePayloadFormatSchema),
537
+ runtime: z5.object({
538
+ runscVersion: z5.literal(ALIGNED_RUNSC_VERSION),
539
+ platform: z5.literal(ALIGNED_RUNSC_PLATFORM),
540
+ supervisorArtifact: z5.literal(ALIGNED_CHECKPOINT_SUPERVISOR_ARTIFACT)
541
+ })
542
+ });
543
+
544
+ // ../packages/api-schemas/src/cli-auth.ts
545
+ import { z as z6 } from "zod";
546
+ var PKCE_VERIFIER_PATTERN = /^[A-Za-z0-9._~-]{43,128}$/;
547
+ var cliAuthorizationTokenRequestSchema = z6.object({
548
+ code: z6.string().min(1).max(512),
549
+ codeVerifier: z6.string().regex(PKCE_VERIFIER_PATTERN)
550
+ });
551
+ var cliAuthorizationTokenResponseSchema = z6.object({
552
+ accessToken: z6.string(),
553
+ tokenType: z6.literal("bearer"),
554
+ expiresAt: z6.string().nullable()
555
+ });
556
+
557
+ // ../packages/api-schemas/src/dashboards.ts
558
+ import { z as z9 } from "zod";
559
+
560
+ // ../packages/api-schemas/src/query.ts
561
+ import { z as z8 } from "zod";
562
+
563
+ // ../packages/api-schemas/src/stats.ts
564
+ import { z as z7 } from "zod";
565
+ var BRAND_KINDS2 = ["OWNED", "COMPETITOR", "OTHER"];
566
+ var brandKindSchema2 = z7.enum(BRAND_KINDS2);
567
+ var brandRankingSchema = z7.object({
568
+ rank: z7.number().int(),
569
+ brandId: z7.string(),
570
+ brandName: z7.string(),
571
+ kind: brandKindSchema2,
572
+ installs: z7.number().int(),
573
+ installRate: z7.number(),
574
+ mentionRate: z7.number(),
575
+ /** Movement between the two most recent batch windows; null if not ranked in both. */
576
+ deltaRank: z7.number().int().nullable()
577
+ });
578
+ var packageRateSchema = z7.object({
579
+ ecosystem: z7.string(),
580
+ name: z7.string(),
581
+ brandName: z7.string().optional(),
582
+ kind: brandKindSchema2.optional(),
583
+ installs: z7.number().int(),
584
+ rate: z7.number()
585
+ });
586
+ var brandRateSchema = z7.object({
587
+ brandId: z7.string(),
588
+ brandName: z7.string(),
589
+ kind: brandKindSchema2,
590
+ installs: z7.number().int(),
591
+ rate: z7.number()
592
+ });
593
+ var brandFunnelRowSchema = z7.object({
594
+ brandId: z7.string(),
595
+ brandName: z7.string(),
596
+ kind: brandKindSchema2,
597
+ mentionRate: z7.number(),
598
+ installRate: z7.number()
599
+ });
600
+ var domainRateSchema = z7.object({
601
+ domain: z7.string(),
602
+ runs: z7.number().int(),
603
+ rate: z7.number(),
604
+ requests: z7.number().int(),
605
+ brandName: z7.string().optional(),
606
+ owned: z7.boolean().optional()
607
+ });
608
+ var statsFreshnessSchema = z7.object({
609
+ /** Newest run-ingest time across the org (ISO), or null if nothing ingested. */
610
+ watermark: z7.string().nullable(),
611
+ /** Runs that succeeded recently but haven't landed in the warehouse yet. */
612
+ pending: z7.number().int(),
613
+ /** False when the freshness read itself failed (distinguish from genuine zero). */
614
+ available: z7.boolean()
615
+ });
616
+ var statsResponseSchema = (item) => z7.object({ items: z7.array(item), freshness: statsFreshnessSchema });
617
+ var rankingsResponseSchema = statsResponseSchema(brandRankingSchema);
618
+ var installsResponseSchema = statsResponseSchema(packageRateSchema);
619
+ var brandsResponseSchema = statsResponseSchema(brandRateSchema);
620
+ var funnelResponseSchema = statsResponseSchema(brandFunnelRowSchema);
621
+ var domainsResponseSchema = statsResponseSchema(domainRateSchema);
622
+
623
+ // ../packages/api-schemas/src/query.ts
624
+ var DATASETS = [
625
+ "runs",
626
+ "installs",
627
+ "mentions",
628
+ "web",
629
+ "citations",
630
+ "network",
631
+ "files",
632
+ "tokens",
633
+ "brand_rollup"
634
+ ];
635
+ var datasetSchema = z8.enum(DATASETS);
636
+ var WHERE_OPS = [
637
+ "eq",
638
+ "neq",
639
+ "in",
640
+ "notIn",
641
+ "contains",
642
+ "gt",
643
+ "gte",
644
+ "lt",
645
+ "lte"
646
+ ];
647
+ var whereOpSchema = z8.enum(WHERE_OPS);
648
+ var GRANULARITIES = ["day", "week", "month"];
649
+ var granularitySchema = z8.enum(GRANULARITIES);
650
+ var DEFAULT_QUERY_LIMIT = 50;
651
+ var MAX_QUERY_LIMIT = 1e3;
652
+ var scalar = z8.union([z8.string(), z8.number(), z8.boolean()]);
653
+ var whereClauseSchema = z8.object({
654
+ dimension: z8.string().min(1),
655
+ op: whereOpSchema,
656
+ value: z8.union([scalar, z8.array(scalar)])
657
+ });
658
+ var queryFiltersSchema = z8.object({
659
+ prompt: z8.string(),
660
+ topic: z8.array(z8.string()),
661
+ tag: z8.array(z8.string()),
662
+ repo: z8.array(z8.string()),
663
+ language: z8.array(z8.string()),
664
+ framework: z8.array(z8.string()),
665
+ size: z8.array(z8.string()),
666
+ agent: z8.array(z8.string()),
667
+ /** Persona UserProfile ids; the NO_PERSONA sentinel = default judge. */
668
+ persona: z8.array(z8.string()),
669
+ model: z8.array(z8.string()),
670
+ scenario: z8.array(z8.string()),
671
+ experiment: z8.array(z8.string()),
672
+ branded: z8.boolean()
673
+ }).partial();
674
+ var dateRangeSchema = z8.object({
675
+ since: z8.string(),
676
+ until: z8.string(),
677
+ lastDays: z8.number().int().positive()
678
+ }).partial();
679
+ var orderBySchema = z8.object({
680
+ /** A selected dimension or metric name. */
681
+ key: z8.string().min(1),
682
+ dir: z8.enum(["asc", "desc"]).default("desc")
683
+ });
684
+ var querySpecSchema = z8.object({
685
+ dataset: datasetSchema.default("runs"),
686
+ dimensions: z8.array(z8.string()).default([]),
687
+ metrics: z8.array(z8.string()).min(1, "at least one metric is required"),
688
+ filters: queryFiltersSchema.default({}),
689
+ where: z8.array(whereClauseSchema).default([]),
690
+ dateRange: dateRangeSchema.optional(),
691
+ orderBy: z8.array(orderBySchema).default([]),
692
+ limit: z8.number().int().min(1).max(MAX_QUERY_LIMIT).default(DEFAULT_QUERY_LIMIT),
693
+ granularity: granularitySchema.default("day"),
694
+ /** When true, the response echoes the compiled SQL (params bound, not inlined). */
695
+ explain: z8.boolean().default(false)
696
+ });
697
+ var columnKindSchema = z8.enum(["dimension", "metric"]);
698
+ var queryColumnSchema = z8.object({
699
+ key: z8.string(),
700
+ kind: columnKindSchema
701
+ });
702
+ var queryRowSchema = z8.record(
703
+ z8.string(),
704
+ z8.union([z8.string(), z8.number(), z8.boolean(), z8.null()])
705
+ );
706
+ var queryResponseSchema = z8.object({
707
+ columns: z8.array(queryColumnSchema),
708
+ rows: z8.array(queryRowSchema),
709
+ /** Present only when the request set explain=true. */
710
+ sql: z8.string().optional(),
711
+ freshness: statsFreshnessSchema
712
+ });
713
+ var fieldTypeSchema = z8.enum([
714
+ "string",
715
+ "number",
716
+ "rate",
717
+ "date",
718
+ "boolean"
719
+ ]);
720
+ var fieldSchema = z8.object({
721
+ name: z8.string(),
722
+ type: fieldTypeSchema,
723
+ /** One-line human/agent hint. */
724
+ description: z8.string().optional()
725
+ });
726
+ var datasetMetaSchema = z8.object({
727
+ name: datasetSchema,
728
+ grain: z8.string(),
729
+ dimensions: z8.array(fieldSchema),
730
+ metrics: z8.array(fieldSchema)
731
+ });
732
+ var metadataResponseSchema = z8.object({
733
+ datasets: z8.array(datasetMetaSchema)
734
+ });
735
+
736
+ // ../packages/api-schemas/src/dashboards.ts
737
+ var VIZ_TYPES = ["line", "bar", "table", "kpi"];
738
+ var vizTypeSchema = z9.enum(VIZ_TYPES);
739
+ var widgetEncodingSchema = z9.object({
740
+ x: z9.string(),
741
+ // dimension key for the x axis (line)
742
+ series: z9.string(),
743
+ // dimension key split into one series per value (line)
744
+ y: z9.array(z9.string())
745
+ // metric keys for the value axis
746
+ }).partial();
747
+ var widgetFields = {
748
+ id: z9.string().min(1),
749
+ title: z9.string(),
750
+ viz: vizTypeSchema,
751
+ spec: querySpecSchema,
752
+ // 12-col grid placement.
753
+ x: z9.number().int().min(0).max(11),
754
+ y: z9.number().int().min(0),
755
+ w: z9.number().int().min(1).max(12),
756
+ h: z9.number().int().min(1),
757
+ encoding: widgetEncodingSchema.optional()
758
+ };
759
+ var widgetSchema = z9.object(widgetFields).refine((w) => w.x + w.w <= 12, {
760
+ message: "widget spills past the 12-column grid (x + w must be \u2264 12)"
761
+ });
762
+ var widgetPatchSchema = z9.object(widgetFields).partial();
763
+ var dashboardFiltersSchema = z9.object({
764
+ filters: queryFiltersSchema,
765
+ dateRange: dateRangeSchema
766
+ }).partial();
767
+ var overlayPatchSchema = z9.object({
768
+ name: z9.string(),
769
+ defaultFilters: dashboardFiltersSchema,
770
+ widgets: z9.record(z9.string(), widgetPatchSchema.nullable()),
771
+ // Explicit widget-id ordering (for reordering and from-scratch widgets).
772
+ order: z9.array(z9.string())
773
+ }).partial();
774
+ var resolvedDashboardSchema = z9.object({
775
+ key: z9.string(),
776
+ name: z9.string(),
777
+ widgets: z9.array(widgetSchema),
778
+ defaultFilters: dashboardFiltersSchema,
779
+ hasOrgOverlay: z9.boolean(),
780
+ hasUserOverlay: z9.boolean()
781
+ });
782
+ var dashboardTemplateSchema = z9.object({
783
+ key: z9.string().min(1),
784
+ name: z9.string(),
785
+ description: z9.string().optional(),
786
+ widgets: z9.array(widgetSchema),
787
+ defaultFilters: dashboardFiltersSchema.optional()
788
+ });
789
+ var dashboardSummarySchema = z9.object({
790
+ key: z9.string(),
791
+ name: z9.string(),
792
+ source: z9.enum(["template", "org", "user"]),
793
+ isUserDefault: z9.boolean(),
794
+ isOrgDefault: z9.boolean()
795
+ });
796
+
797
+ // ../packages/api-schemas/src/device.ts
798
+ import { z as z10 } from "zod";
799
+ var deviceAuthorizeRequestSchema = z10.object({
348
800
  /** Device label (the CLI's hostname) for display + token naming. */
349
- deviceName: z5.string().trim().max(64).optional(),
801
+ deviceName: z10.string().trim().max(64).optional(),
350
802
  /** Optional: email a magic-link that lands on the approval page pre-scoped
351
803
  * to this device (best-effort — the printed URL always works regardless). */
352
- email: z5.string().trim().email().max(320).optional()
804
+ email: z10.string().trim().email().max(320).optional()
353
805
  });
354
- var deviceAuthorizeResponseSchema = z5.object({
806
+ var deviceAuthorizeResponseSchema = z10.object({
355
807
  /** The one-time secret the CLI polls with (never shown again). */
356
- deviceCode: z5.string(),
808
+ deviceCode: z10.string(),
357
809
  /** Short human-typed code the user confirms in the browser (e.g. WXYZ-1234). */
358
- userCode: z5.string(),
810
+ userCode: z10.string(),
359
811
  /** Where the user approves (e.g. https://…/cli/authorize). */
360
- verificationUri: z5.string(),
812
+ verificationUri: z10.string(),
361
813
  /** verificationUri with the code pre-filled, for one-click / QR. */
362
- verificationUriComplete: z5.string(),
814
+ verificationUriComplete: z10.string(),
363
815
  /** Minimum seconds between polls. */
364
- interval: z5.number().int().positive(),
816
+ interval: z10.number().int().positive(),
365
817
  /** Seconds until the device code expires. */
366
- expiresIn: z5.number().int().positive(),
818
+ expiresIn: z10.number().int().positive(),
367
819
  /** Whether a magic-link email was dispatched (best-effort). */
368
- emailSent: z5.boolean()
820
+ emailSent: z10.boolean()
369
821
  });
370
- var deviceTokenRequestSchema = z5.object({
371
- deviceCode: z5.string().min(1)
822
+ var deviceTokenRequestSchema = z10.object({
823
+ deviceCode: z10.string().min(1)
372
824
  });
373
- var deviceTokenApprovedSchema = z5.object({
374
- status: z5.literal("approved"),
825
+ var deviceTokenApprovedSchema = z10.object({
826
+ status: z10.literal("approved"),
375
827
  /** The `gauge_…` bearer secret. Store it now — never returned again. */
376
- accessToken: z5.string(),
377
- tokenType: z5.literal("bearer"),
828
+ accessToken: z10.string(),
829
+ tokenType: z10.literal("bearer"),
378
830
  /** ISO-8601 expiry, or null for no expiry. */
379
- expiresAt: z5.string().nullable()
831
+ expiresAt: z10.string().nullable()
380
832
  });
381
- var deviceTokenResultSchema = z5.discriminatedUnion("status", [
833
+ var deviceTokenResultSchema = z10.discriminatedUnion("status", [
382
834
  // Not yet approved — keep polling at `interval`.
383
- z5.object({ status: z5.literal("pending") }),
835
+ z10.object({ status: z10.literal("pending") }),
384
836
  // Polled faster than `interval` — back off by `interval` seconds.
385
- z5.object({ status: z5.literal("slow_down"), interval: z5.number().int() }),
837
+ z10.object({ status: z10.literal("slow_down"), interval: z10.number().int() }),
386
838
  // The user explicitly denied the request. Stop.
387
- z5.object({ status: z5.literal("denied") }),
839
+ z10.object({ status: z10.literal("denied") }),
388
840
  // The device code expired or is unknown/already-redeemed. Stop and restart.
389
- z5.object({ status: z5.literal("expired") }),
841
+ z10.object({ status: z10.literal("expired") }),
390
842
  deviceTokenApprovedSchema
391
843
  ]);
392
844
 
845
+ // ../packages/api-schemas/src/experiments.ts
846
+ import { z as z11 } from "zod";
847
+ var contentExperimentIntentSchema = z11.object({
848
+ sourceRunId: z11.string().min(1),
849
+ problemText: z11.string().trim().min(1)
850
+ });
851
+ var EXPERIMENT_STATUSES = [
852
+ "DRAFT",
853
+ "GENERATING",
854
+ "RUNNING",
855
+ "SYNTHESIZING",
856
+ "COMPLETE",
857
+ "PARTIAL",
858
+ "FAILED",
859
+ "CANCELED"
860
+ ];
861
+ var experimentStatusSchema = z11.enum(EXPERIMENT_STATUSES);
862
+ var EXPERIMENT_ORIGINS = ["USER_NAMED", "DETECTED"];
863
+ var experimentOriginSchema = z11.enum(EXPERIMENT_ORIGINS);
864
+ var VARIANT_KINDS = ["CANDIDATE"];
865
+ var variantKindSchema = z11.enum(VARIANT_KINDS);
866
+ var SUPPORT_CLASSES = [
867
+ "RECOMMENDED",
868
+ "PROMISING",
869
+ "NOT_SUPPORTED",
870
+ "NOT_EVALUABLE"
871
+ ];
872
+ var supportClassSchema = z11.enum(SUPPORT_CLASSES);
873
+ var createExperimentBodySchema = contentExperimentIntentSchema.extend({
874
+ candidates: z11.number().int().optional(),
875
+ samples: z11.number().int().optional()
876
+ });
877
+ var launchExperimentBodySchema = z11.object({
878
+ samples: z11.number().int().optional()
879
+ });
880
+ var experimentListQuerySchema = z11.object({
881
+ status: experimentStatusSchema.optional(),
882
+ since: z11.string().optional(),
883
+ limit: z11.coerce.number().int().min(1).max(100).default(50)
884
+ });
885
+ var experimentSummarySchema = z11.object({
886
+ id: z11.string(),
887
+ status: experimentStatusSchema,
888
+ sourceRunId: z11.string(),
889
+ problemText: z11.string(),
890
+ origin: experimentOriginSchema,
891
+ cohortLabel: z11.string(),
892
+ createdAt: z11.string()
893
+ });
894
+ var experimentListResponseSchema = listResponseSchema(
895
+ experimentSummarySchema
896
+ );
897
+ var variantSummarySchema = z11.object({
898
+ id: z11.string(),
899
+ key: z11.string(),
900
+ kind: variantKindSchema,
901
+ title: z11.string(),
902
+ hypothesis: z11.string(),
903
+ supportClass: supportClassSchema.nullable(),
904
+ effect: z11.number().nullable(),
905
+ invalidReason: z11.string().nullable(),
906
+ batchId: z11.string().nullable()
907
+ });
908
+ var variantRefSchema = z11.object({
909
+ key: z11.string(),
910
+ title: z11.string(),
911
+ effect: z11.number().nullable(),
912
+ consistency: z11.string().nullable(),
913
+ note: z11.string().nullable()
914
+ });
915
+ var recommendationSchema = z11.object({
916
+ evaluatorVersion: z11.string(),
917
+ summary: z11.string(),
918
+ groups: z11.object({
919
+ recommended: z11.array(variantRefSchema),
920
+ promising: z11.array(variantRefSchema),
921
+ notSupported: z11.array(variantRefSchema),
922
+ notEvaluable: z11.array(variantRefSchema)
923
+ }),
924
+ tradeoffs: z11.array(z11.string())
925
+ });
926
+ var jsonValue = z11.unknown();
927
+ var experimentDetailSchema = z11.object({
928
+ id: z11.string(),
929
+ status: experimentStatusSchema,
930
+ sourceRunId: z11.string(),
931
+ problemText: z11.string(),
932
+ origin: experimentOriginSchema,
933
+ evaluationContract: jsonValue,
934
+ recommendation: recommendationSchema.nullable(),
935
+ cohortLabel: z11.string(),
936
+ createdAt: z11.string(),
937
+ variants: z11.array(variantSummarySchema)
938
+ });
939
+ var createdExperimentSchema = z11.object({
940
+ id: z11.string(),
941
+ status: experimentStatusSchema,
942
+ cohortLabel: z11.string(),
943
+ sourceCheckpointId: z11.string().nullable(),
944
+ checkpointTurn: z11.number().int().nullable(),
945
+ contract: jsonValue,
946
+ variants: z11.array(
947
+ z11.object({
948
+ id: z11.string(),
949
+ key: z11.string(),
950
+ kind: variantKindSchema,
951
+ invalidReason: z11.string().nullable()
952
+ })
953
+ )
954
+ });
955
+ var plannedVariantSchema = z11.object({
956
+ key: z11.string(),
957
+ kind: variantKindSchema,
958
+ title: z11.string(),
959
+ hypothesis: z11.string(),
960
+ webFixtureSha256: z11.string(),
961
+ invalidReason: z11.string().nullable()
962
+ });
963
+ var experimentPlanSchema = z11.object({
964
+ sourceRunId: z11.string(),
965
+ organizationId: z11.string(),
966
+ problemText: z11.string(),
967
+ origin: experimentOriginSchema,
968
+ contract: jsonValue,
969
+ variants: z11.array(plannedVariantSchema),
970
+ samples: z11.number().int(),
971
+ estimatedForks: z11.number().int()
972
+ });
973
+ var launchResultSchema = z11.object({
974
+ experimentId: z11.string(),
975
+ forks: z11.array(
976
+ z11.object({
977
+ variantId: z11.string(),
978
+ key: z11.string(),
979
+ batchId: z11.string(),
980
+ runIds: z11.array(z11.string())
981
+ })
982
+ ),
983
+ skipped: z11.array(
984
+ z11.object({
985
+ variantId: z11.string(),
986
+ key: z11.string(),
987
+ reason: z11.string()
988
+ })
989
+ )
990
+ });
991
+
393
992
  // ../packages/api-schemas/src/keys.ts
394
993
  var keys_exports = {};
395
994
  __export(keys_exports, {
@@ -400,69 +999,69 @@ __export(keys_exports, {
400
999
  setProviderKeyBodySchema: () => setProviderKeyBodySchema,
401
1000
  setProviderKeyResponseSchema: () => setProviderKeyResponseSchema
402
1001
  });
403
- import { z as z6 } from "zod";
1002
+ import { z as z12 } from "zod";
404
1003
  var PROVIDER_TYPES = ["anthropic", "openai"];
405
- var providerTypeSchema = z6.enum(PROVIDER_TYPES);
406
- var setProviderKeyBodySchema = z6.object({
1004
+ var providerTypeSchema = z12.enum(PROVIDER_TYPES);
1005
+ var setProviderKeyBodySchema = z12.object({
407
1006
  /** The raw provider API key. Verified + stored server-side (AWS Secrets
408
1007
  * Manager); never persisted in the app DB and never echoed back. */
409
- key: z6.string().min(1)
1008
+ key: z12.string().min(1)
410
1009
  });
411
- var setProviderKeyResponseSchema = z6.object({
1010
+ var setProviderKeyResponseSchema = z12.object({
412
1011
  providerType: providerTypeSchema,
413
- last4: z6.string()
1012
+ last4: z12.string()
414
1013
  });
415
- var providerKeySchema = z6.object({
1014
+ var providerKeySchema = z12.object({
416
1015
  providerType: providerTypeSchema,
417
- last4: z6.string(),
418
- createdAt: z6.string(),
1016
+ last4: z12.string(),
1017
+ createdAt: z12.string(),
419
1018
  /** When the key was last saved/rotated. */
420
- updatedAt: z6.string()
1019
+ updatedAt: z12.string()
421
1020
  });
422
1021
  var providerKeyListResponseSchema = listResponseSchema(providerKeySchema);
423
1022
 
424
1023
  // ../packages/api-schemas/src/me.ts
425
- import { z as z7 } from "zod";
426
- var meUserSchema = z7.object({
427
- id: z7.string(),
428
- email: z7.string().nullable(),
429
- isSuperuser: z7.boolean()
1024
+ import { z as z13 } from "zod";
1025
+ var meUserSchema = z13.object({
1026
+ id: z13.string(),
1027
+ email: z13.string().nullable(),
1028
+ isSuperuser: z13.boolean()
430
1029
  });
431
- var meOrgSchema = z7.object({
432
- slug: z7.string(),
1030
+ var meOrgSchema = z13.object({
1031
+ slug: z13.string(),
433
1032
  // Gauge's immutable Organization.public_id; null for LOCAL orgs.
434
- publicId: z7.string().nullable(),
435
- name: z7.string()
1033
+ publicId: z13.string().nullable(),
1034
+ name: z13.string()
436
1035
  });
437
- var meResponseSchema = z7.object({
1036
+ var meResponseSchema = z13.object({
438
1037
  user: meUserSchema,
439
1038
  // Membership-scoped for normal users; superusers see every org (mirrors the
440
1039
  // web tier's userOrgs).
441
- orgs: z7.array(meOrgSchema)
1040
+ orgs: z13.array(meOrgSchema)
442
1041
  });
443
1042
 
444
1043
  // ../packages/api-schemas/src/orgs.ts
445
- import { z as z8 } from "zod";
446
- var createOrgRequestSchema = z8.object({
1044
+ import { z as z14 } from "zod";
1045
+ var createOrgRequestSchema = z14.object({
447
1046
  /** Workspace display name; the slug is derived server-side. */
448
- name: z8.string().trim().min(1).max(200),
1047
+ name: z14.string().trim().min(1).max(200),
449
1048
  /** Optional company site (logo source; stamped onto the org). */
450
- website: z8.string().trim().max(300).optional()
1049
+ website: z14.string().trim().max(300).optional()
451
1050
  });
452
- var createOrgResponseSchema = z8.object({
453
- slug: z8.string(),
454
- name: z8.string(),
1051
+ var createOrgResponseSchema = z14.object({
1052
+ slug: z14.string(),
1053
+ name: z14.string(),
455
1054
  // LOCAL orgs never have a Gauge publicId.
456
- publicId: z8.string().nullable()
1055
+ publicId: z14.string().nullable()
457
1056
  });
458
1057
 
459
1058
  // ../packages/api-schemas/src/prompts.ts
460
- import { z as z13 } from "zod";
1059
+ import { z as z19 } from "zod";
461
1060
 
462
1061
  // ../packages/api-schemas/src/schedules.ts
463
- import { z as z9 } from "zod";
1062
+ import { z as z15 } from "zod";
464
1063
  var AGENTS = ["CLAUDE_CODE", "CODEX_CLI", "CURSOR"];
465
- var agentSchema = z9.enum(AGENTS);
1064
+ var agentSchema = z15.enum(AGENTS);
466
1065
  var CADENCES = [
467
1066
  "NONE",
468
1067
  "DAILY",
@@ -470,104 +1069,152 @@ var CADENCES = [
470
1069
  "MONTHLY",
471
1070
  "DAYS_PER_WEEK"
472
1071
  ];
473
- var cadenceSchema = z9.enum(CADENCES);
474
- var daysPerWeekSchema = z9.number().int().min(1).max(7);
475
- var scheduleRepoSchema = z9.object({
476
- repoUrl: z9.string(),
477
- /** Branch/ref; null = the repo's default branch. */
478
- repoRef: z9.string().nullable()
479
- });
480
- var scheduleSchema = z9.object({
481
- id: z9.string(),
482
- name: z9.string(),
1072
+ var cadenceSchema = z15.enum(CADENCES);
1073
+ var daysPerWeekSchema = z15.number().int().min(1).max(7);
1074
+ var scheduleRepoSchema = z15.object({
1075
+ repoUrl: z15.string().nullable(),
1076
+ /** Branch/ref; null = the repo's default branch (always null for greenfield). */
1077
+ repoRef: z15.string().nullable()
1078
+ });
1079
+ var scheduleAgentConfigSchema = z15.object({
1080
+ agent: agentSchema,
1081
+ models: z15.array(z15.string().min(1)).default([])
1082
+ });
1083
+ var scheduleAgentConfigInputSchema = z15.object({
1084
+ agent: agentSchema,
1085
+ models: z15.array(z15.string().min(1)).optional(),
1086
+ model: z15.string().min(1).nullish()
1087
+ }).transform(({ agent, models, model }) => ({
1088
+ agent,
1089
+ models: models ?? (model ? [model] : [])
1090
+ }));
1091
+ var scheduleSchema = z15.object({
1092
+ id: z15.string(),
1093
+ name: z15.string(),
483
1094
  cadence: cadenceSchema,
484
1095
  /** Only set when cadence is DAYS_PER_WEEK (1–7). */
485
- daysPerWeek: z9.number().int().nullable(),
486
- samplesPerCycle: z9.number().int(),
487
- agents: z9.array(agentSchema),
488
- /** Pinned model id; null = the agent's default. */
489
- model: z9.string().nullable(),
490
- /** Repo targets in stable expansion order; empty = the default scaffold. */
491
- repos: z9.array(scheduleRepoSchema),
1096
+ daysPerWeek: z15.number().int().nullable(),
1097
+ samplesPerCycle: z15.number().int(),
1098
+ /** Authoritative per-agent configuration. */
1099
+ agentConfigs: z15.array(scheduleAgentConfigSchema),
1100
+ /** Deprecated compatibility projection of agentConfigs. */
1101
+ agents: z15.array(agentSchema),
1102
+ /** Deprecated: null for schedules with per-agent pins. */
1103
+ model: z15.string().nullable(),
1104
+ /** Repo targets in stable expansion order; empty = the default scaffold. A
1105
+ * null-repoUrl entry is greenfield alongside named repos. */
1106
+ repos: z15.array(scheduleRepoSchema),
492
1107
  /** Cohort label for experiment analysis; null outside labeled experiments. */
493
- experiment: z9.string().nullable(),
494
- enabled: z9.boolean(),
495
- lastExpandedAt: z9.string().nullable(),
496
- /** Member prompt ids, in stable expansion order. */
497
- promptIds: z9.array(z9.string()),
498
- promptCount: z9.number().int(),
499
- createdAt: z9.string(),
500
- updatedAt: z9.string()
1108
+ experiment: z15.string().nullable(),
1109
+ enabled: z15.boolean(),
1110
+ lastExpandedAt: z15.string().nullable(),
1111
+ /** Membership tag ids — the schedule runs the live union of these tags'
1112
+ * prompts (resolved at dispatch, not stored). */
1113
+ tagIds: z15.array(z15.string()),
1114
+ tagCount: z15.number().int(),
1115
+ /** Persona matrix (ALG-155): member UserProfile ids, in stable expansion
1116
+ * order. Empty = the default, unconfigured HaikuJudge (no persona). */
1117
+ profileIds: z15.array(z15.string()),
1118
+ /** ALG-155.1: when profileIds is non-empty, also expand once per (prompt ×
1119
+ * repo) with no persona alongside the persona batches. Ignored when
1120
+ * profileIds is empty (always the implicit default judge). */
1121
+ includeDefaultPersona: z15.boolean(),
1122
+ createdAt: z15.string(),
1123
+ updatedAt: z15.string()
501
1124
  });
502
1125
  var scheduleListResponseSchema = listResponseSchema(scheduleSchema);
503
- var scheduleRepoInputSchema = z9.object({
504
- repoUrl: z9.string().min(1),
505
- repoRef: z9.string().min(1).nullish()
1126
+ var scheduleRepoInputSchema = z15.object({
1127
+ /** null/omitted = the greenfield scaffold as an explicit target. */
1128
+ repoUrl: z15.string().min(1).nullish(),
1129
+ repoRef: z15.string().min(1).nullish()
506
1130
  });
507
- var createScheduleBodySchema = z9.object({
508
- name: z9.string().min(1, "name is required"),
1131
+ var createScheduleBodyObject = z15.object({
1132
+ name: z15.string().min(1, "name is required"),
509
1133
  cadence: cadenceSchema.default("NONE"),
510
1134
  daysPerWeek: daysPerWeekSchema.optional(),
511
- samplesPerCycle: z9.number().int().min(1).default(1),
512
- agents: z9.array(agentSchema).min(1, "Select at least one agent"),
513
- model: z9.string().min(1).nullish(),
514
- /** Repo targets; empty = the default scaffold (greenfield). */
515
- repos: z9.array(scheduleRepoInputSchema).default([]),
516
- /** Member prompt ids (resolved by the caller — tag→prompt resolution is a
517
- * UI-side authoring convenience, never stored). */
518
- promptIds: z9.array(z9.string().min(1)).default([]),
519
- enabled: z9.boolean().default(true)
520
- });
521
- var updateScheduleBodySchema = z9.object({
522
- name: z9.string().min(1).optional(),
1135
+ samplesPerCycle: z15.number().int().min(1).default(1),
1136
+ /** Preferred paired representation (per-agent model tiers). */
1137
+ agentConfigs: z15.array(scheduleAgentConfigInputSchema).min(1).optional(),
1138
+ /** Legacy shared-model input, accepted during the API transition. */
1139
+ agents: z15.array(agentSchema).min(1, "Select at least one agent").optional(),
1140
+ model: z15.string().min(1).nullish(),
1141
+ /** Repo targets; empty = the default scaffold (greenfield). Add a
1142
+ * null-repoUrl entry to run greenfield alongside named repos. */
1143
+ repos: z15.array(scheduleRepoInputSchema).default([]),
1144
+ /** Membership tag ids — the schedule runs the live union of these tags'
1145
+ * prompts (specs/schedules-tags-migration.md). Must belong to the org. */
1146
+ tagIds: z15.array(z15.string().min(1)).default([]),
1147
+ /** Persona matrix (ALG-155): member UserProfile ids. Empty/omitted = the
1148
+ * default, unconfigured HaikuJudge (no persona). */
1149
+ profileIds: z15.array(z15.string().min(1)).default([]),
1150
+ /** ALG-155.1: also expand once per (prompt × repo) with no persona
1151
+ * alongside the persona batches, when profileIds is non-empty. Ignored
1152
+ * when profileIds is empty. */
1153
+ includeDefaultPersona: z15.boolean().default(false),
1154
+ enabled: z15.boolean().default(true)
1155
+ });
1156
+ var createScheduleBodySchema = createScheduleBodyObject.refine(
1157
+ (body) => body.agentConfigs !== void 0 || body.agents !== void 0,
1158
+ {
1159
+ message: "Select at least one agent (agentConfigs or agents)",
1160
+ path: ["agentConfigs"]
1161
+ }
1162
+ );
1163
+ var updateScheduleBodySchema = z15.object({
1164
+ name: z15.string().min(1).optional(),
523
1165
  cadence: cadenceSchema.optional(),
524
1166
  daysPerWeek: daysPerWeekSchema.optional(),
525
- samplesPerCycle: z9.number().int().min(1).optional(),
526
- agents: z9.array(agentSchema).min(1, "Select at least one agent").optional(),
527
- model: z9.string().min(1).nullish(),
528
- repos: z9.array(scheduleRepoInputSchema).optional(),
529
- promptIds: z9.array(z9.string().min(1)).optional(),
530
- enabled: z9.boolean().optional()
531
- });
532
- var runScheduleResponseSchema = z9.object({
533
- batchIds: z9.array(z9.string()),
534
- runIds: z9.array(z9.string()),
535
- blocked: z9.enum(["insufficient_credits", "needs_provider_key"]).optional(),
536
- notReady: z9.array(
537
- z9.object({
538
- repoUrl: z9.string(),
539
- status: z9.enum(["building", "failed", "none"])
1167
+ samplesPerCycle: z15.number().int().min(1).optional(),
1168
+ /** Full replacement of the enabled agent/model set (per-agent model tiers). */
1169
+ agentConfigs: z15.array(scheduleAgentConfigInputSchema).min(1).optional(),
1170
+ /** Legacy shared-model input, accepted during the API transition. */
1171
+ agents: z15.array(agentSchema).min(1, "Select at least one agent").optional(),
1172
+ model: z15.string().min(1).nullish(),
1173
+ repos: z15.array(scheduleRepoInputSchema).optional(),
1174
+ tagIds: z15.array(z15.string().min(1)).optional(),
1175
+ profileIds: z15.array(z15.string().min(1)).optional(),
1176
+ includeDefaultPersona: z15.boolean().optional(),
1177
+ enabled: z15.boolean().optional()
1178
+ });
1179
+ var runScheduleResponseSchema = z15.object({
1180
+ batchIds: z15.array(z15.string()),
1181
+ runIds: z15.array(z15.string()),
1182
+ blocked: z15.enum(["insufficient_credits", "needs_provider_key"]).optional(),
1183
+ notReady: z15.array(
1184
+ z15.object({
1185
+ repoUrl: z15.string(),
1186
+ status: z15.enum(["building", "failed", "none"])
540
1187
  })
541
1188
  ).optional()
542
1189
  });
543
1190
 
544
1191
  // ../packages/api-schemas/src/tags.ts
545
- import { z as z10 } from "zod";
546
- var tagSchema = z10.object({
547
- id: z10.string(),
548
- name: z10.string(),
1192
+ import { z as z16 } from "zod";
1193
+ var tagSchema = z16.object({
1194
+ id: z16.string(),
1195
+ name: z16.string(),
549
1196
  /** A Mantine palette name (e.g. "blue", "grape"); unknown values are
550
1197
  * normalized server-side to the default ("gray"). */
551
- color: z10.string()
1198
+ color: z16.string()
552
1199
  });
553
- var createTagBodySchema = z10.object({
554
- name: z10.string().min(1),
555
- color: z10.string().optional()
1200
+ var createTagBodySchema = z16.object({
1201
+ name: z16.string().min(1),
1202
+ color: z16.string().optional()
556
1203
  });
557
- var updateTagBodySchema = z10.object({
558
- name: z10.string().min(1).optional(),
559
- color: z10.string().optional()
1204
+ var updateTagBodySchema = z16.object({
1205
+ name: z16.string().min(1).optional(),
1206
+ color: z16.string().optional()
560
1207
  });
561
1208
  var tagListResponseSchema = listResponseSchema(tagSchema);
562
1209
 
563
1210
  // ../packages/api-schemas/src/topics.ts
564
- import { z as z11 } from "zod";
565
- var topicSchema = z11.object({
566
- id: z11.string(),
567
- name: z11.string()
1211
+ import { z as z17 } from "zod";
1212
+ var topicSchema = z17.object({
1213
+ id: z17.string(),
1214
+ name: z17.string()
568
1215
  });
569
- var createTopicBodySchema = z11.object({
570
- name: z11.string().min(1, "name is required")
1216
+ var createTopicBodySchema = z17.object({
1217
+ name: z17.string().min(1, "name is required")
571
1218
  });
572
1219
  var topicListResponseSchema = listResponseSchema(topicSchema);
573
1220
 
@@ -577,31 +1224,31 @@ __export(web_fixtures_exports, {
577
1224
  MAX_WEB_FIXTURE_BYTES: () => MAX_WEB_FIXTURE_BYTES,
578
1225
  webFixtureSchema: () => webFixtureSchema
579
1226
  });
580
- import { z as z12 } from "zod";
1227
+ import { z as z18 } from "zod";
581
1228
  var MAX_WEB_FIXTURE_BYTES = 1e6;
582
1229
  function withoutFragment(raw) {
583
1230
  const fragment = raw.indexOf("#");
584
1231
  return fragment === -1 ? raw : raw.slice(0, fragment);
585
1232
  }
586
- var searchResultSchema = z12.object({
587
- title: z12.string().min(1),
588
- url: z12.url().transform(withoutFragment),
589
- snippet: z12.string()
590
- });
591
- var searchFixtureSchema = z12.object({
592
- query: z12.string().trim().min(1),
593
- results: z12.array(searchResultSchema)
594
- });
595
- var pageFixtureSchema = z12.object({
596
- url: z12.url().transform(withoutFragment),
597
- status: z12.int().min(100).max(599).default(200),
598
- contentType: z12.string().trim().min(1).default("text/html"),
599
- body: z12.string()
600
- });
601
- var webFixtureSchema = z12.object({
602
- version: z12.literal(1),
603
- searches: z12.array(searchFixtureSchema).default([]),
604
- pages: z12.array(pageFixtureSchema).default([])
1233
+ var searchResultSchema = z18.object({
1234
+ title: z18.string().min(1),
1235
+ url: z18.url().transform(withoutFragment),
1236
+ snippet: z18.string()
1237
+ });
1238
+ var searchFixtureSchema = z18.object({
1239
+ query: z18.string().trim().min(1),
1240
+ results: z18.array(searchResultSchema)
1241
+ });
1242
+ var pageFixtureSchema = z18.object({
1243
+ url: z18.url().transform(withoutFragment),
1244
+ status: z18.int().min(100).max(599).default(200),
1245
+ contentType: z18.string().trim().min(1).default("text/html"),
1246
+ body: z18.string()
1247
+ });
1248
+ var webFixtureSchema = z18.object({
1249
+ version: z18.literal(1),
1250
+ searches: z18.array(searchFixtureSchema).default([]),
1251
+ pages: z18.array(pageFixtureSchema).default([])
605
1252
  }).superRefine((fixture, ctx) => {
606
1253
  const queries = /* @__PURE__ */ new Set();
607
1254
  fixture.searches.forEach((entry, index) => {
@@ -635,290 +1282,118 @@ var webFixtureSchema = z12.object({
635
1282
  });
636
1283
 
637
1284
  // ../packages/api-schemas/src/prompts.ts
638
- var SCENARIOS = ["GREENFIELD", "MIGRATION"];
639
- var scenarioSchema = z13.enum(SCENARIOS);
640
- var promptSummarySchema = z13.object({
641
- id: z13.string(),
642
- text: z13.string(),
643
- scenario: scenarioSchema,
644
- isBranded: z13.boolean(),
1285
+ var promptSummarySchema = z19.object({
1286
+ id: z19.string(),
1287
+ text: z19.string(),
1288
+ isBranded: z19.boolean(),
645
1289
  /** Battery-spec identity (idempotent applies); null for UI/CLI-created prompts. */
646
- externalKey: z13.string().nullable(),
1290
+ externalKey: z19.string().nullable(),
647
1291
  topic: topicSchema.nullable(),
648
- tags: z13.array(tagSchema),
649
- scheduleCount: z13.number().int(),
650
- createdAt: z13.string()
1292
+ tags: z19.array(tagSchema),
1293
+ scheduleCount: z19.number().int(),
1294
+ createdAt: z19.string()
651
1295
  });
652
- var promptScheduleRefSchema = z13.object({
653
- id: z13.string(),
654
- name: z13.string(),
1296
+ var promptScheduleRefSchema = z19.object({
1297
+ id: z19.string(),
1298
+ name: z19.string(),
655
1299
  cadence: cadenceSchema,
656
- daysPerWeek: z13.number().int().nullable(),
657
- enabled: z13.boolean()
1300
+ daysPerWeek: z19.number().int().nullable(),
1301
+ enabled: z19.boolean()
658
1302
  });
659
1303
  var promptDetailSchema = promptSummarySchema.extend({
660
- schedules: z13.array(promptScheduleRefSchema)
1304
+ schedules: z19.array(promptScheduleRefSchema)
661
1305
  });
662
1306
  var promptListResponseSchema = listResponseSchema(promptSummarySchema);
663
1307
  var listPromptsQuerySchema = listQuerySchema.extend({
664
- topic: z13.string().min(1).optional(),
665
- tag: z13.string().min(1).optional(),
666
- q: z13.string().min(1).optional()
667
- });
668
- var createPromptBodySchema = z13.object({
669
- text: z13.string().min(1, "text is required"),
670
- scenario: scenarioSchema.default("GREENFIELD"),
671
- isBranded: z13.boolean().default(false),
672
- topic: z13.string().min(1).optional(),
673
- tags: z13.array(z13.string().min(1)).default([])
674
- });
675
- var updatePromptBodySchema = z13.object({
676
- text: z13.string().min(1).optional(),
677
- isBranded: z13.boolean().optional(),
678
- topicId: z13.string().min(1).nullish(),
679
- tags: z13.array(z13.string().min(1)).optional()
680
- });
681
- var runPromptBodySchema = z13.object({
682
- agents: z13.array(agentSchema).min(1, "Select at least one agent").default(["CLAUDE_CODE", "CODEX_CLI"]),
683
- repoUrl: z13.string().min(1).nullish(),
684
- repoRef: z13.string().min(1).nullish(),
685
- samplesPerCycle: z13.number().int().min(1).max(10).default(1),
686
- webFixture: webFixtureSchema.optional()
687
- });
688
- var runPromptResponseSchema = z13.object({
689
- batchIds: z13.array(z13.string()),
690
- runIds: z13.array(z13.string())
691
- });
692
-
693
- // ../packages/api-schemas/src/query.ts
694
- import { z as z15 } from "zod";
695
-
696
- // ../packages/api-schemas/src/stats.ts
697
- import { z as z14 } from "zod";
698
- var BRAND_KINDS2 = ["OWNED", "COMPETITOR", "OTHER"];
699
- var brandKindSchema2 = z14.enum(BRAND_KINDS2);
700
- var brandRankingSchema = z14.object({
701
- rank: z14.number().int(),
702
- brandId: z14.string(),
703
- brandName: z14.string(),
704
- kind: brandKindSchema2,
705
- installs: z14.number().int(),
706
- installRate: z14.number(),
707
- mentionRate: z14.number(),
708
- /** Movement between the two most recent batch windows; null if not ranked in both. */
709
- deltaRank: z14.number().int().nullable()
710
- });
711
- var packageRateSchema = z14.object({
712
- ecosystem: z14.string(),
713
- name: z14.string(),
714
- brandName: z14.string().optional(),
715
- kind: brandKindSchema2.optional(),
716
- installs: z14.number().int(),
717
- rate: z14.number()
718
- });
719
- var brandRateSchema = z14.object({
720
- brandId: z14.string(),
721
- brandName: z14.string(),
722
- kind: brandKindSchema2,
723
- installs: z14.number().int(),
724
- rate: z14.number()
725
- });
726
- var brandFunnelRowSchema = z14.object({
727
- brandId: z14.string(),
728
- brandName: z14.string(),
729
- kind: brandKindSchema2,
730
- mentionRate: z14.number(),
731
- installRate: z14.number()
732
- });
733
- var domainRateSchema = z14.object({
734
- domain: z14.string(),
735
- runs: z14.number().int(),
736
- rate: z14.number(),
737
- requests: z14.number().int(),
738
- brandName: z14.string().optional(),
739
- owned: z14.boolean().optional()
740
- });
741
- var statsFreshnessSchema = z14.object({
742
- /** Newest run-ingest time across the org (ISO), or null if nothing ingested. */
743
- watermark: z14.string().nullable(),
744
- /** Runs that succeeded recently but haven't landed in the warehouse yet. */
745
- pending: z14.number().int(),
746
- /** False when the freshness read itself failed (distinguish from genuine zero). */
747
- available: z14.boolean()
748
- });
749
- var statsResponseSchema = (item) => z14.object({ items: z14.array(item), freshness: statsFreshnessSchema });
750
- var rankingsResponseSchema = statsResponseSchema(brandRankingSchema);
751
- var installsResponseSchema = statsResponseSchema(packageRateSchema);
752
- var brandsResponseSchema = statsResponseSchema(brandRateSchema);
753
- var funnelResponseSchema = statsResponseSchema(brandFunnelRowSchema);
754
- var domainsResponseSchema = statsResponseSchema(domainRateSchema);
755
-
756
- // ../packages/api-schemas/src/query.ts
757
- var DATASETS = [
758
- "runs",
759
- "installs",
760
- "mentions",
761
- "web",
762
- "network",
763
- "files",
764
- "tokens"
765
- ];
766
- var datasetSchema = z15.enum(DATASETS);
767
- var WHERE_OPS = [
768
- "eq",
769
- "neq",
770
- "in",
771
- "notIn",
772
- "contains",
773
- "gt",
774
- "gte",
775
- "lt",
776
- "lte"
777
- ];
778
- var whereOpSchema = z15.enum(WHERE_OPS);
779
- var GRANULARITIES = ["day", "week", "month"];
780
- var granularitySchema = z15.enum(GRANULARITIES);
781
- var DEFAULT_QUERY_LIMIT = 50;
782
- var MAX_QUERY_LIMIT = 1e3;
783
- var scalar = z15.union([z15.string(), z15.number(), z15.boolean()]);
784
- var whereClauseSchema = z15.object({
785
- dimension: z15.string().min(1),
786
- op: whereOpSchema,
787
- value: z15.union([scalar, z15.array(scalar)])
788
- });
789
- var queryFiltersSchema = z15.object({
790
- prompt: z15.string(),
791
- topic: z15.array(z15.string()),
792
- tag: z15.array(z15.string()),
793
- repo: z15.array(z15.string()),
794
- language: z15.array(z15.string()),
795
- framework: z15.array(z15.string()),
796
- size: z15.array(z15.string()),
797
- agent: z15.array(z15.string()),
798
- model: z15.array(z15.string()),
799
- scenario: z15.array(z15.string()),
800
- experiment: z15.array(z15.string()),
801
- branded: z15.boolean()
802
- }).partial();
803
- var dateRangeSchema = z15.object({
804
- since: z15.string(),
805
- until: z15.string(),
806
- lastDays: z15.number().int().positive()
807
- }).partial();
808
- var orderBySchema = z15.object({
809
- /** A selected dimension or metric name. */
810
- key: z15.string().min(1),
811
- dir: z15.enum(["asc", "desc"]).default("desc")
1308
+ topic: z19.string().min(1).optional(),
1309
+ tag: z19.string().min(1).optional(),
1310
+ q: z19.string().min(1).optional()
812
1311
  });
813
- var querySpecSchema = z15.object({
814
- dataset: datasetSchema.default("runs"),
815
- dimensions: z15.array(z15.string()).default([]),
816
- metrics: z15.array(z15.string()).min(1, "at least one metric is required"),
817
- filters: queryFiltersSchema.default({}),
818
- where: z15.array(whereClauseSchema).default([]),
819
- dateRange: dateRangeSchema.optional(),
820
- orderBy: z15.array(orderBySchema).default([]),
821
- limit: z15.number().int().min(1).max(MAX_QUERY_LIMIT).default(DEFAULT_QUERY_LIMIT),
822
- granularity: granularitySchema.default("day"),
823
- /** When true, the response echoes the compiled SQL (params bound, not inlined). */
824
- explain: z15.boolean().default(false)
825
- });
826
- var columnKindSchema = z15.enum(["dimension", "metric"]);
827
- var queryColumnSchema = z15.object({
828
- key: z15.string(),
829
- kind: columnKindSchema
830
- });
831
- var queryRowSchema = z15.record(
832
- z15.string(),
833
- z15.union([z15.string(), z15.number(), z15.boolean(), z15.null()])
834
- );
835
- var queryResponseSchema = z15.object({
836
- columns: z15.array(queryColumnSchema),
837
- rows: z15.array(queryRowSchema),
838
- /** Present only when the request set explain=true. */
839
- sql: z15.string().optional(),
840
- freshness: statsFreshnessSchema
1312
+ var createPromptBodySchema = z19.object({
1313
+ text: z19.string().min(1, "text is required"),
1314
+ isBranded: z19.boolean().default(false),
1315
+ topic: z19.string().min(1).optional(),
1316
+ tags: z19.array(z19.string().min(1)).default([])
841
1317
  });
842
- var fieldTypeSchema = z15.enum([
843
- "string",
844
- "number",
845
- "rate",
846
- "date",
847
- "boolean"
848
- ]);
849
- var fieldSchema = z15.object({
850
- name: z15.string(),
851
- type: fieldTypeSchema,
852
- /** One-line human/agent hint. */
853
- description: z15.string().optional()
1318
+ var updatePromptBodySchema = z19.object({
1319
+ text: z19.string().min(1).optional(),
1320
+ isBranded: z19.boolean().optional(),
1321
+ topicId: z19.string().min(1).nullish(),
1322
+ tags: z19.array(z19.string().min(1)).optional()
854
1323
  });
855
- var datasetMetaSchema = z15.object({
856
- name: datasetSchema,
857
- grain: z15.string(),
858
- dimensions: z15.array(fieldSchema),
859
- metrics: z15.array(fieldSchema)
1324
+ var runPromptBodySchema = z19.object({
1325
+ /** Preferred paired representation; each agent may pin its own model tiers. */
1326
+ agentConfigs: z19.array(scheduleAgentConfigInputSchema).min(1).optional(),
1327
+ /** Legacy agent set (no per-agent pins), kept during the API transition. */
1328
+ agents: z19.array(agentSchema).min(1, "Select at least one agent").default(["CLAUDE_CODE", "CODEX_CLI"]),
1329
+ repoUrl: z19.string().min(1).nullish(),
1330
+ repoRef: z19.string().min(1).nullish(),
1331
+ samplesPerCycle: z19.number().int().min(1).max(10).default(1),
1332
+ webFixture: webFixtureSchema.optional()
860
1333
  });
861
- var metadataResponseSchema = z15.object({
862
- datasets: z15.array(datasetMetaSchema)
1334
+ var runPromptResponseSchema = z19.object({
1335
+ batchIds: z19.array(z19.string()),
1336
+ runIds: z19.array(z19.string()),
1337
+ blocked: z19.enum(["insufficient_credits", "needs_provider_key"]).optional()
863
1338
  });
864
1339
 
865
1340
  // ../packages/api-schemas/src/repos.ts
866
- import { z as z16 } from "zod";
1341
+ import { z as z20 } from "zod";
867
1342
  var REPO_SIZE_BUCKETS = [
868
1343
  "small",
869
1344
  "medium",
870
1345
  "large",
871
1346
  "xlarge"
872
1347
  ];
873
- var repoSizeBucketSchema = z16.enum(REPO_SIZE_BUCKETS);
874
- var repoSchema = z16.object({
875
- url: z16.string(),
876
- name: z16.string(),
877
- isSystem: z16.boolean(),
878
- languages: z16.array(z16.string()),
879
- frameworks: z16.array(z16.string()),
1348
+ var repoSizeBucketSchema = z20.enum(REPO_SIZE_BUCKETS);
1349
+ var repoSchema = z20.object({
1350
+ url: z20.string(),
1351
+ name: z20.string(),
1352
+ isSystem: z20.boolean(),
1353
+ languages: z20.array(z20.string()),
1354
+ frameworks: z20.array(z20.string()),
880
1355
  /** Faceted labels (complexity:L2, buildable:yes, stack:nextjs, …). */
881
- tags: z16.array(z16.string()),
882
- primaryLanguage: z16.string(),
883
- sizeKb: z16.number(),
1356
+ tags: z20.array(z20.string()),
1357
+ primaryLanguage: z20.string(),
1358
+ sizeKb: z20.number(),
884
1359
  sizeBucket: repoSizeBucketSchema.nullable(),
885
- stars: z16.number()
1360
+ stars: z20.number()
886
1361
  });
887
1362
  var repoListResponseSchema = listResponseSchema(repoSchema);
888
- var addRepoBodySchema = z16.object({
889
- url: z16.string().min(1, "url is required"),
1363
+ var addRepoBodySchema = z20.object({
1364
+ url: z20.string().min(1, "url is required"),
890
1365
  /**
891
1366
  * Reserved (accepted, not yet persisted): the catalog keys repos by URL only
892
1367
  * — `fact_repo` has no ref column and metadata sync always reads the default
893
1368
  * branch. Kept in the wire format so `gauge repos add --ref` is stable once
894
1369
  * the catalog learns refs.
895
1370
  */
896
- ref: z16.string().min(1).optional(),
1371
+ ref: z20.string().min(1).optional(),
897
1372
  /** Display name; defaults to the `owner/repo` label of the URL. */
898
- name: z16.string().min(1).optional(),
1373
+ name: z20.string().min(1).optional(),
899
1374
  /** Manual override; defaults to frameworks detected from the repo's manifests. */
900
- frameworks: z16.array(z16.string()).optional(),
901
- tags: z16.array(z16.string()).optional()
1375
+ frameworks: z20.array(z20.string()).optional(),
1376
+ tags: z20.array(z20.string()).optional()
902
1377
  });
903
- var updateRepoBodySchema = z16.object({
904
- url: z16.string().min(1, "url is required"),
905
- name: z16.string().min(1).optional(),
906
- frameworks: z16.array(z16.string()).optional(),
907
- tags: z16.array(z16.string()).optional()
1378
+ var updateRepoBodySchema = z20.object({
1379
+ url: z20.string().min(1, "url is required"),
1380
+ name: z20.string().min(1).optional(),
1381
+ frameworks: z20.array(z20.string()).optional(),
1382
+ tags: z20.array(z20.string()).optional()
908
1383
  });
909
- var resyncRepoBodySchema = z16.object({
910
- url: z16.string().min(1, "url is required")
1384
+ var resyncRepoBodySchema = z20.object({
1385
+ url: z20.string().min(1, "url is required")
911
1386
  });
912
- var deleteRepoQuerySchema = z16.object({
913
- url: z16.string().min(1, "url is required")
1387
+ var deleteRepoQuerySchema = z20.object({
1388
+ url: z20.string().min(1, "url is required")
914
1389
  });
915
- var repoSyncResultSchema = z16.object({
1390
+ var repoSyncResultSchema = z20.object({
916
1391
  repo: repoSchema,
917
- synced: z16.boolean()
1392
+ synced: z20.boolean()
918
1393
  });
919
1394
 
920
1395
  // ../packages/api-schemas/src/runs.ts
921
- import { z as z17 } from "zod";
1396
+ import { z as z21 } from "zod";
922
1397
  var RUN_STATUSES = [
923
1398
  "QUEUED",
924
1399
  "CLAIMED",
@@ -929,69 +1404,104 @@ var RUN_STATUSES = [
929
1404
  "TIMED_OUT",
930
1405
  "CANCELED"
931
1406
  ];
932
- var runStatusSchema = z17.enum(RUN_STATUSES);
1407
+ var runStatusSchema = z21.enum(RUN_STATUSES);
933
1408
  var AGENTS2 = ["CLAUDE_CODE", "CODEX_CLI", "CURSOR"];
934
- var agentSchema2 = z17.enum(AGENTS2);
935
- var runStatusFilterSchema = z17.string().transform(
1409
+ var agentSchema2 = z21.enum(AGENTS2);
1410
+ var runStatusFilterSchema = z21.string().transform(
936
1411
  (raw) => raw.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean)
937
- ).pipe(z17.array(runStatusSchema).min(1));
1412
+ ).pipe(z21.array(runStatusSchema).min(1));
938
1413
  var runListQuerySchema = listQuerySchema.extend({
939
1414
  status: runStatusFilterSchema.optional(),
940
- batch: z17.string().optional(),
941
- prompt: z17.string().optional(),
942
- experiment: z17.string().optional(),
943
- since: z17.string().optional()
1415
+ batch: z21.string().optional(),
1416
+ prompt: z21.string().optional(),
1417
+ experiment: z21.string().optional(),
1418
+ since: z21.string().optional()
944
1419
  });
945
- var runListItemSchema = z17.object({
946
- id: z17.string(),
1420
+ var runListItemSchema = z21.object({
1421
+ id: z21.string(),
947
1422
  status: runStatusSchema,
948
1423
  agent: agentSchema2,
949
- model: z17.string(),
950
- promptId: z17.string(),
1424
+ model: z21.string(),
1425
+ promptId: z21.string(),
951
1426
  /** First ~80 chars of the batch's prompt snapshot, whitespace-collapsed. */
952
- promptSnippet: z17.string(),
953
- batchId: z17.string(),
954
- experiment: z17.string().nullable(),
955
- turns: z17.number().int().nullable(),
956
- usdCost: z17.number().nullable(),
957
- durationMs: z17.number().int().nullable(),
958
- exitReason: z17.string().nullable(),
959
- createdAt: z17.string(),
960
- startedAt: z17.string().nullable(),
961
- finishedAt: z17.string().nullable()
1427
+ promptSnippet: z21.string(),
1428
+ batchId: z21.string(),
1429
+ experiment: z21.string().nullable(),
1430
+ turns: z21.number().int().nullable(),
1431
+ usdCost: z21.number().nullable(),
1432
+ durationMs: z21.number().int().nullable(),
1433
+ exitReason: z21.string().nullable(),
1434
+ createdAt: z21.string(),
1435
+ startedAt: z21.string().nullable(),
1436
+ finishedAt: z21.string().nullable(),
1437
+ /** Fork lineage (fork-simulations WS1): the source run this was forked from,
1438
+ * or null for an organic run. Forks are excluded from aggregate analytics but
1439
+ * kept visible; consumers badge on these fields. */
1440
+ parentRunId: z21.string().nullable(),
1441
+ /** Set when this run is a fetch-fork simulation variant (injected web
1442
+ * content); null otherwise. Distinguishes a "Simulation" badge from a plain
1443
+ * conversation fork. */
1444
+ fetchForkPlanId: z21.string().nullable()
962
1445
  });
963
1446
  var runListResponseSchema = listResponseSchema(runListItemSchema);
964
1447
  var runDetailSchema = runListItemSchema.omit({ promptSnippet: true }).extend({
965
- promptText: z17.string(),
966
- attempt: z17.number().int(),
967
- cancelRequested: z17.boolean(),
968
- failureReason: z17.string().nullable(),
969
- repoUrl: z17.string().nullable(),
970
- repoRef: z17.string().nullable(),
971
- scenario: z17.string(),
972
- funding: z17.string(),
1448
+ promptText: z21.string(),
1449
+ attempt: z21.number().int(),
1450
+ cancelRequested: z21.boolean(),
1451
+ failureReason: z21.string().nullable(),
1452
+ repoUrl: z21.string().nullable(),
1453
+ repoRef: z21.string().nullable(),
1454
+ scenario: z21.string(),
1455
+ funding: z21.string(),
973
1456
  /** Raw harness usage write-back (token counts etc.); shape may evolve. */
974
- usage: z17.unknown().nullable(),
1457
+ usage: z21.unknown().nullable(),
975
1458
  /** Artifact pointer: a working-tree diff exists at GET /runs/{id}/diff. */
976
- hasDiff: z17.boolean(),
977
- claimedAt: z17.string().nullable()
1459
+ hasDiff: z21.boolean(),
1460
+ claimedAt: z21.string().nullable()
978
1461
  });
979
- var cancelRunResponseSchema = z17.object({
980
- id: z17.string(),
1462
+ var cancelRunResponseSchema = z21.object({
1463
+ id: z21.string(),
981
1464
  status: runStatusSchema,
982
- cancelRequested: z17.boolean(),
983
- note: z17.string().optional()
1465
+ cancelRequested: z21.boolean(),
1466
+ note: z21.string().optional()
1467
+ });
1468
+ var forkRunBodySchema = z21.object({
1469
+ prompt: z21.string().trim().min(1).max(2e4),
1470
+ turn: z21.number().int().min(0).optional(),
1471
+ webFixture: webFixtureSchema.optional()
984
1472
  });
985
- var forkRunBodySchema = z17.object({
986
- prompt: z17.string().trim().min(1).max(2e4),
987
- turn: z17.number().int().min(0).optional()
1473
+ var forkRunResponseSchema = z21.object({
1474
+ runId: z21.string(),
1475
+ batchId: z21.string(),
1476
+ parentRunId: z21.string(),
1477
+ checkpointId: z21.string(),
1478
+ turn: z21.number().int().min(0)
988
1479
  });
989
- var forkRunResponseSchema = z17.object({
990
- runId: z17.string(),
991
- batchId: z17.string(),
992
- parentRunId: z17.string(),
993
- checkpointId: z17.string(),
994
- turn: z17.number().int().min(0)
1480
+ var fetchForkAtFetchBodySchema = z21.object({
1481
+ boundarySeq: z21.string().min(1),
1482
+ injectedContent: z21.string(),
1483
+ prompts: z21.array(z21.string()).min(1)
1484
+ });
1485
+ var fetchForkAtFetchResponseSchema = z21.object({
1486
+ planId: z21.string()
1487
+ });
1488
+ var fetchForkPlanStatusSchema = z21.enum([
1489
+ "DRAFT",
1490
+ "SURGERY_RUNNING",
1491
+ "SURGERY_READY",
1492
+ "FORKED",
1493
+ "FAILED"
1494
+ ]);
1495
+ var fetchForkPlanResponseSchema = z21.object({
1496
+ id: z21.string(),
1497
+ status: fetchForkPlanStatusSchema,
1498
+ boundaryUrl: z21.string(),
1499
+ boundaryTurn: z21.number().int(),
1500
+ prompts: z21.array(z21.string()),
1501
+ surgicalCheckpointId: z21.string().nullable(),
1502
+ forkBatchId: z21.string().nullable(),
1503
+ errorText: z21.string().nullable(),
1504
+ forkedRunIds: z21.array(z21.string())
995
1505
  });
996
1506
  var RUN_INSIGHT_STATUSES = [
997
1507
  "PENDING",
@@ -1000,72 +1510,72 @@ var RUN_INSIGHT_STATUSES = [
1000
1510
  "FAILED",
1001
1511
  "SKIPPED"
1002
1512
  ];
1003
- var runInsightStatusSchema = z17.enum(RUN_INSIGHT_STATUSES);
1004
- var insightPassSchema = z17.object({
1513
+ var runInsightStatusSchema = z21.enum(RUN_INSIGHT_STATUSES);
1514
+ var insightPassSchema = z21.object({
1005
1515
  status: runInsightStatusSchema,
1006
- model: z17.string().nullable(),
1007
- inputTokens: z17.number().int().nullable(),
1008
- outputTokens: z17.number().int().nullable(),
1009
- usdCost: z17.number().nullable(),
1010
- error: z17.string().nullable()
1011
- });
1012
- var runDecisionSchema = z17.object({
1013
- index: z17.number().int(),
1014
- category: z17.string(),
1015
- categoryRaw: z17.string().nullable(),
1016
- chosenName: z17.string(),
1017
- chosenEcosystem: z17.string().nullable(),
1018
- chosenPackage: z17.string().nullable(),
1019
- reversed: z17.boolean(),
1020
- detail: z17.unknown()
1021
- });
1022
- var runImplementationSchema = z17.object({
1023
- brandName: z17.string(),
1024
- ecosystem: z17.string().nullable(),
1025
- package: z17.string().nullable(),
1026
- verdict: z17.string(),
1027
- docConsulted: z17.boolean(),
1028
- detail: z17.unknown()
1029
- });
1030
- var runInsightResponseSchema = z17.object({
1031
- runId: z17.string(),
1516
+ model: z21.string().nullable(),
1517
+ inputTokens: z21.number().int().nullable(),
1518
+ outputTokens: z21.number().int().nullable(),
1519
+ usdCost: z21.number().nullable(),
1520
+ error: z21.string().nullable()
1521
+ });
1522
+ var runDecisionSchema = z21.object({
1523
+ index: z21.number().int(),
1524
+ category: z21.string(),
1525
+ categoryRaw: z21.string().nullable(),
1526
+ chosenName: z21.string(),
1527
+ chosenEcosystem: z21.string().nullable(),
1528
+ chosenPackage: z21.string().nullable(),
1529
+ reversed: z21.boolean(),
1530
+ detail: z21.unknown()
1531
+ });
1532
+ var runImplementationSchema = z21.object({
1533
+ brandName: z21.string(),
1534
+ ecosystem: z21.string().nullable(),
1535
+ package: z21.string().nullable(),
1536
+ verdict: z21.string(),
1537
+ docConsulted: z21.boolean(),
1538
+ detail: z21.unknown()
1539
+ });
1540
+ var runInsightResponseSchema = z21.object({
1541
+ runId: z21.string(),
1032
1542
  decision: insightPassSchema,
1033
1543
  implementation: insightPassSchema,
1034
- decisions: z17.array(runDecisionSchema),
1035
- implementations: z17.array(runImplementationSchema)
1544
+ decisions: z21.array(runDecisionSchema),
1545
+ implementations: z21.array(runImplementationSchema)
1036
1546
  });
1037
- var runEventSchema = z17.looseObject({
1038
- run_id: z17.string(),
1039
- seq: z17.number(),
1040
- turn: z17.number(),
1041
- ts: z17.string(),
1042
- type: z17.string()
1547
+ var runEventSchema = z21.looseObject({
1548
+ run_id: z21.string(),
1549
+ seq: z21.number(),
1550
+ turn: z21.number(),
1551
+ ts: z21.string(),
1552
+ type: z21.string()
1043
1553
  });
1044
1554
 
1045
1555
  // ../packages/api-schemas/src/tokens.ts
1046
- import { z as z18 } from "zod";
1047
- var apiTokenSchema = z18.object({
1048
- id: z18.string(),
1049
- name: z18.string(),
1556
+ import { z as z22 } from "zod";
1557
+ var apiTokenSchema = z22.object({
1558
+ id: z22.string(),
1559
+ name: z22.string(),
1050
1560
  /** Last 4 chars of the plaintext, for recognizability (non-secret). */
1051
- last4: z18.string(),
1052
- expiresAt: z18.iso.datetime().nullable(),
1053
- lastUsedAt: z18.iso.datetime().nullable(),
1054
- createdAt: z18.iso.datetime(),
1055
- revokedAt: z18.iso.datetime().nullable()
1056
- });
1057
- var createTokenRequestSchema = z18.object({
1058
- name: z18.string().min(1).max(100),
1561
+ last4: z22.string(),
1562
+ expiresAt: z22.iso.datetime().nullable(),
1563
+ lastUsedAt: z22.iso.datetime().nullable(),
1564
+ createdAt: z22.iso.datetime(),
1565
+ revokedAt: z22.iso.datetime().nullable()
1566
+ });
1567
+ var createTokenRequestSchema = z22.object({
1568
+ name: z22.string().min(1).max(100),
1059
1569
  /** ISO-8601 datetime; omit for no expiry. */
1060
- expiresAt: z18.iso.datetime({ offset: true }).optional()
1570
+ expiresAt: z22.iso.datetime({ offset: true }).optional()
1061
1571
  });
1062
1572
  var createTokenResponseSchema = apiTokenSchema.extend({
1063
- token: z18.string()
1573
+ token: z22.string()
1064
1574
  });
1065
1575
  var listTokensResponseSchema = listResponseSchema(apiTokenSchema);
1066
1576
 
1067
1577
  // src/commands/apply.ts
1068
- import { z as z19 } from "zod";
1578
+ import { z as z23 } from "zod";
1069
1579
 
1070
1580
  // src/version.ts
1071
1581
  import { createRequire } from "module";
@@ -1400,13 +1910,11 @@ var EXAMPLE_SPEC = {
1400
1910
  prompts: [
1401
1911
  {
1402
1912
  key: "add-healthcheck",
1403
- text: "Add a /health endpoint that returns 200 OK.",
1404
- scenario: "GREENFIELD"
1913
+ text: "Add a /health endpoint that returns 200 OK."
1405
1914
  },
1406
1915
  {
1407
1916
  key: "migrate-to-vitest",
1408
1917
  text: "Migrate the test suite from Jest to Vitest.",
1409
- scenario: "MIGRATION",
1410
1918
  schedules: [
1411
1919
  {
1412
1920
  repoUrl: "https://github.com/acme/api",
@@ -1515,7 +2023,7 @@ function register(program2) {
1515
2023
  ).option("-f, --file <path>", "battery spec JSON file").option("--dry-run", "print the plan without applying").option("--schema", "print the battery spec JSON Schema and exit").option("--example", "print a minimal example battery spec and exit").action(
1516
2024
  async (opts, command) => {
1517
2025
  if (opts.schema) {
1518
- printJson(z19.toJSONSchema(batteries_exports.batterySpecSchema));
2026
+ printJson(z23.toJSONSchema(batteries_exports.batterySpecSchema));
1519
2027
  return;
1520
2028
  }
1521
2029
  if (opts.example) {
@@ -1553,12 +2061,15 @@ function register(program2) {
1553
2061
  var auth_exports = {};
1554
2062
  __export(auth_exports, {
1555
2063
  deviceLogin: () => deviceLogin,
2064
+ parseLoopbackCallback: () => parseLoopbackCallback,
2065
+ readStdin: () => readStdin,
1556
2066
  register: () => register2
1557
2067
  });
1558
2068
  import { spawn } from "child_process";
1559
- import { randomBytes } from "crypto";
2069
+ import { createHash, randomBytes } from "crypto";
1560
2070
  import { createServer } from "http";
1561
2071
  import { hostname } from "os";
2072
+ import { createInterface } from "readline";
1562
2073
  import { setTimeout as sleep } from "timers/promises";
1563
2074
 
1564
2075
  // src/lib/paginate.ts
@@ -1580,7 +2091,6 @@ async function fetchAllPages(client, path, query = {}) {
1580
2091
  // src/commands/auth.ts
1581
2092
  var LOGIN_TIMEOUT_MS = 2 * 60 * 1e3;
1582
2093
  var TOKEN_PREFIX = "gauge_";
1583
- var MAX_CALLBACK_BODY_BYTES = 16 * 1024;
1584
2094
  function tokenSource() {
1585
2095
  if (process.env.GAUGE_API_TOKEN?.trim()) return "env";
1586
2096
  return resolveToken() ? "file" : "none";
@@ -1588,6 +2098,13 @@ function tokenSource() {
1588
2098
  async function fetchMe(client) {
1589
2099
  return client.get("/api/v1/me");
1590
2100
  }
2101
+ function parseLoopbackCallback(rawUrl, expectedState) {
2102
+ const url = new URL(rawUrl ?? "/", "http://127.0.0.1");
2103
+ if (url.pathname !== "/callback") return null;
2104
+ const code = url.searchParams.get("code");
2105
+ if (url.searchParams.get("state") !== expectedState || !code) return null;
2106
+ return code;
2107
+ }
1591
2108
  function printIdentity(me) {
1592
2109
  const orgs = me.orgs.map((o) => o.slug).join(", ") || "(none)";
1593
2110
  const su = me.user.isSuperuser ? " (superuser)" : "";
@@ -1609,63 +2126,33 @@ function openBrowser(url) {
1609
2126
  }
1610
2127
  async function browserLogin() {
1611
2128
  const state = randomBytes(16).toString("base64url");
2129
+ const codeVerifier = randomBytes(32).toString("base64url");
2130
+ const codeChallenge = createHash("sha256").update(codeVerifier).digest("base64url");
1612
2131
  const server = createServer();
1613
- const tokenPromise = new Promise((resolve, reject) => {
2132
+ const codePromise = new Promise((resolve, reject) => {
1614
2133
  server.on("request", (req, res) => {
1615
2134
  const url = new URL(req.url ?? "/", "http://127.0.0.1");
1616
2135
  if (url.pathname !== "/callback") {
1617
2136
  res.writeHead(404).end();
1618
2137
  return;
1619
2138
  }
1620
- if (req.method === "OPTIONS") {
1621
- res.writeHead(204, {
1622
- "access-control-allow-origin": "*",
1623
- "access-control-allow-methods": "POST",
1624
- "access-control-allow-headers": "content-type",
1625
- "access-control-allow-private-network": "true"
1626
- }).end();
2139
+ if (req.method !== "GET") {
2140
+ res.writeHead(405, { allow: "GET" }).end();
1627
2141
  return;
1628
2142
  }
1629
- if (req.method !== "POST") {
1630
- res.writeHead(405, { allow: "POST" }).end();
2143
+ const code = parseLoopbackCallback(req.url, state);
2144
+ if (!code) {
2145
+ res.writeHead(400, {
2146
+ "content-type": "text/plain; charset=utf-8"
2147
+ });
2148
+ res.end("Invalid callback. Retry gauge auth login.");
1631
2149
  return;
1632
2150
  }
1633
- let body = "";
1634
- let overflowed = false;
1635
- req.on("data", (chunk) => {
1636
- if (overflowed) return;
1637
- body += chunk;
1638
- if (body.length > MAX_CALLBACK_BODY_BYTES) {
1639
- overflowed = true;
1640
- body = "";
1641
- res.writeHead(413, {
1642
- "content-type": "text/plain; charset=utf-8",
1643
- "access-control-allow-origin": "*"
1644
- });
1645
- res.end("Callback body too large.");
1646
- }
1647
- });
1648
- req.on("end", () => {
1649
- if (overflowed) return;
1650
- const params = new URLSearchParams(body);
1651
- const token = params.get("token");
1652
- if (params.get("state") !== state || !token) {
1653
- res.writeHead(400, {
1654
- "content-type": "text/plain; charset=utf-8",
1655
- "access-control-allow-origin": "*"
1656
- });
1657
- res.end(
1658
- "Invalid callback (state mismatch). Retry `gauge auth login`."
1659
- );
1660
- return;
1661
- }
1662
- res.writeHead(200, {
1663
- "content-type": "text/plain; charset=utf-8",
1664
- "access-control-allow-origin": "*"
1665
- });
1666
- res.end("Authorized \u2014 return to your terminal.");
1667
- resolve(token);
2151
+ res.writeHead(200, {
2152
+ "content-type": "text/plain; charset=utf-8"
1668
2153
  });
2154
+ res.end("Authorized. Return to your terminal.");
2155
+ resolve(code);
1669
2156
  });
1670
2157
  server.on(
1671
2158
  "error",
@@ -1685,27 +2172,46 @@ async function browserLogin() {
1685
2172
  authorizeUrl.searchParams.set("port", String(address.port));
1686
2173
  authorizeUrl.searchParams.set("state", state);
1687
2174
  authorizeUrl.searchParams.set("name", hostname() || "this device");
2175
+ authorizeUrl.searchParams.set("code_challenge", codeChallenge);
2176
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
1688
2177
  console.log("Opening your browser to authorize the Gauge CLI\u2026");
1689
2178
  console.log(`If it doesn't open, visit:
1690
2179
 
1691
2180
  ${authorizeUrl}
1692
2181
  `);
2182
+ console.log("Waiting for browser authorization\u2026");
2183
+ console.log(
2184
+ "No local network access or using SSH? Re-run with gauge auth login --device."
2185
+ );
1693
2186
  openBrowser(authorizeUrl.toString());
1694
2187
  let timer;
1695
2188
  try {
1696
- const token = await Promise.race([
1697
- tokenPromise,
2189
+ const code = await Promise.race([
2190
+ codePromise,
1698
2191
  new Promise((_, reject) => {
1699
2192
  timer = setTimeout(() => {
1700
2193
  reject(
1701
2194
  new CliError(
1702
2195
  "network",
1703
- "Timed out waiting for browser authorization (2 minutes). Retry, or use `gauge auth login --with-token`."
2196
+ "Timed out waiting for browser authorization (2 minutes). Retry, or use gauge auth login --device."
1704
2197
  )
1705
2198
  );
1706
2199
  }, LOGIN_TIMEOUT_MS);
1707
2200
  })
1708
2201
  ]);
2202
+ const raw = await bootstrapPost("/api/v1/cli/token", {
2203
+ code,
2204
+ codeVerifier
2205
+ });
2206
+ const parsed = cliAuthorizationTokenResponseSchema.safeParse(raw);
2207
+ if (!parsed.success) {
2208
+ throw new CliError(
2209
+ "internal",
2210
+ "Unexpected response from the CLI token endpoint."
2211
+ );
2212
+ }
2213
+ const exchange = parsed.data;
2214
+ const token = exchange.accessToken;
1709
2215
  const me = await fetchMe(new ApiClient({ token }));
1710
2216
  saveToken(token);
1711
2217
  console.log(`Token saved to ${credentialsPath()}`);
@@ -1717,7 +2223,7 @@ async function browserLogin() {
1717
2223
  }
1718
2224
  }
1719
2225
  var DEVICE_ENDPOINT = "/api/v1/device";
1720
- async function devicePost(path, body) {
2226
+ async function bootstrapPost(path, body) {
1721
2227
  const base = resolveBaseUrl().replace(/\/+$/, "");
1722
2228
  let res;
1723
2229
  try {
@@ -1748,13 +2254,13 @@ async function devicePost(path, body) {
1748
2254
  }
1749
2255
  throw new CliError(
1750
2256
  "internal",
1751
- `Device request failed: HTTP ${res.status} ${res.statusText}`.trim()
2257
+ `Authentication request failed: HTTP ${res.status} ${res.statusText}`.trim()
1752
2258
  );
1753
2259
  }
1754
2260
  return JSON.parse(text);
1755
2261
  }
1756
2262
  async function deviceLogin(opts) {
1757
- const start = await devicePost(
2263
+ const start = await bootstrapPost(
1758
2264
  `${DEVICE_ENDPOINT}/authorize`,
1759
2265
  { deviceName: hostname() || "this device", email: opts.email }
1760
2266
  );
@@ -1776,7 +2282,7 @@ async function deviceLogin(opts) {
1776
2282
  await sleep(interval * 1e3);
1777
2283
  let raw;
1778
2284
  try {
1779
- raw = await devicePost(`${DEVICE_ENDPOINT}/token`, {
2285
+ raw = await bootstrapPost(`${DEVICE_ENDPOINT}/token`, {
1780
2286
  deviceCode: start.deviceCode
1781
2287
  });
1782
2288
  } catch (e) {
@@ -1812,14 +2318,13 @@ async function deviceLogin(opts) {
1812
2318
  );
1813
2319
  case "approved": {
1814
2320
  const token = result.accessToken;
1815
- saveToken(token);
1816
2321
  try {
1817
2322
  const me = await fetchMe(new ApiClient({ token }));
1818
2323
  return { token, me };
1819
2324
  } catch (e) {
1820
2325
  throw new CliError(
1821
2326
  "network",
1822
- `Signed in and token saved to ${credentialsPath()}, but couldn't load your profile (${e instanceof Error ? e.message : String(e)}). Run \`gauge whoami\` to retry.`
2327
+ `Authorization succeeded, but the issued token could not be verified (${e instanceof Error ? e.message : String(e)}). Re-run to try again; existing credentials were not changed.`
1823
2328
  );
1824
2329
  }
1825
2330
  }
@@ -1835,14 +2340,22 @@ async function deviceLogin(opts) {
1835
2340
  "Timed out waiting for browser approval. Re-run to try again."
1836
2341
  );
1837
2342
  }
1838
- async function readStdin() {
2343
+ async function readStdin(input = process.stdin) {
2344
+ if (input.isTTY) {
2345
+ const lines = createInterface({ input, crlfDelay: Infinity });
2346
+ for await (const line of lines) {
2347
+ lines.close();
2348
+ return line;
2349
+ }
2350
+ return "";
2351
+ }
1839
2352
  let data = "";
1840
- for await (const chunk of process.stdin) data += chunk;
2353
+ for await (const chunk of input) data += chunk;
1841
2354
  return data;
1842
2355
  }
1843
2356
  async function withTokenLogin() {
1844
2357
  if (process.stdin.isTTY) {
1845
- console.error("Paste your API token, then press Enter and Ctrl-D:");
2358
+ console.error("Paste your API token, then press Enter:");
1846
2359
  }
1847
2360
  const token = (await readStdin()).trim();
1848
2361
  if (!token.startsWith(TOKEN_PREFIX)) {
@@ -1902,14 +2415,23 @@ async function whoami(output) {
1902
2415
  }
1903
2416
  function register2(program2) {
1904
2417
  const auth = program2.command("auth").description("Authenticate the CLI (personal access tokens)");
1905
- auth.command("login").description("Log in via the browser (localhost callback flow)").option("--with-token", "read a token from stdin (headless machines)").option(
2418
+ auth.command("login").description("Log in via your browser (localhost callback flow)").option("--with-token", "read a token from stdin (headless machines)").option(
1906
2419
  "--device",
1907
- "device-authorization flow: print a URL + code to approve elsewhere (no loopback listener; agent/remote-friendly)"
2420
+ "use a device code instead (no local network access required)"
1908
2421
  ).option(
1909
2422
  "--email <email>",
1910
2423
  "with --device: also email a sign-in link to this address"
1911
2424
  ).action(
1912
2425
  async (opts) => {
2426
+ if (opts.withToken && opts.device) {
2427
+ throw new CliError(
2428
+ "usage",
2429
+ "Choose only one of --with-token or --device."
2430
+ );
2431
+ }
2432
+ if (opts.email && !opts.device) {
2433
+ throw new CliError("usage", "--email requires --device.");
2434
+ }
1913
2435
  if (opts.device) {
1914
2436
  const { token, me } = await deviceLogin({ email: opts.email });
1915
2437
  saveToken(token);
@@ -2668,8 +3190,7 @@ function toRow2(p) {
2668
3190
  topic: p.topic?.name ?? "",
2669
3191
  tags: p.tags.map((t) => t.name).join(", "),
2670
3192
  schedules: p.scheduleCount,
2671
- branded: p.isBranded ? "yes" : "",
2672
- scenario: p.scenario
3193
+ branded: p.isBranded ? "yes" : ""
2673
3194
  };
2674
3195
  }
2675
3196
  var DEFAULT_RUN_AGENTS = ["CLAUDE_CODE", "CODEX_CLI"];
@@ -2706,7 +3227,6 @@ function register10(program2) {
2706
3227
  return;
2707
3228
  }
2708
3229
  console.log(`id: ${prompt.id}`);
2709
- console.log(`scenario: ${prompt.scenario}`);
2710
3230
  console.log(`branded: ${prompt.isBranded}`);
2711
3231
  console.log(`topic: ${prompt.topic?.name ?? "-"}`);
2712
3232
  console.log(
@@ -2730,7 +3250,7 @@ function register10(program2) {
2730
3250
  console.log("scheduled via: (none)");
2731
3251
  }
2732
3252
  });
2733
- group.command("create").description("Create a prompt").option("--text <text>", "prompt text").option("--file <path>", 'read prompt text from a file ("-" for stdin)').option("--scenario <scenario>", "greenfield | migration", "greenfield").option("--branded", "mark as a branded prompt").option("--topic <name>", "topic (created if new)").option(
3253
+ group.command("create").description("Create a prompt").option("--text <text>", "prompt text").option("--file <path>", 'read prompt text from a file ("-" for stdin)').option("--branded", "mark as a branded prompt").option("--topic <name>", "topic (created if new)").option(
2734
3254
  "--tag <name>",
2735
3255
  "tag name (repeatable; created if new)",
2736
3256
  collect2,
@@ -2738,18 +3258,10 @@ function register10(program2) {
2738
3258
  ).action(
2739
3259
  async (opts, cmd) => {
2740
3260
  const org = resolveOrg(cmd);
2741
- const scenario = opts.scenario.trim().toUpperCase();
2742
- if (scenario !== "GREENFIELD" && scenario !== "MIGRATION") {
2743
- throw new CliError(
2744
- "usage",
2745
- `invalid --scenario "${opts.scenario}" (expected: greenfield | migration)`
2746
- );
2747
- }
2748
3261
  const created = await createClient().post(
2749
3262
  promptsPath(org),
2750
3263
  {
2751
3264
  text: readPromptText(opts),
2752
- scenario,
2753
3265
  isBranded: opts.branded ?? false,
2754
3266
  topic: opts.topic,
2755
3267
  tags: opts.tag
@@ -2758,8 +3270,9 @@ function register10(program2) {
2758
3270
  if (resolveOutput(cmd) === "json") printJson(created);
2759
3271
  else {
2760
3272
  console.log(`Created prompt ${created.id}`);
3273
+ const firstTag = created.tags[0];
2761
3274
  console.log(
2762
- `Run it now with \`gauge prompts run ${created.id}\`, or add it to a schedule set with \`gauge schedules create --name <name> --prompt ${created.id} --agent claude-code\``
3275
+ `Run it now with \`gauge prompts run ${created.id}\`, or schedule it via its tags with ` + (firstTag ? `\`gauge schedules create --name <name> --tag ${firstTag.id} --agent claude-code\`` : `\`gauge schedules create --name <name> --tag <tag-id> --agent claude-code\` (tag the prompt first: \`gauge prompts edit ${created.id} --tag <name>\`)`)
2763
3276
  );
2764
3277
  }
2765
3278
  }
@@ -3240,8 +3753,10 @@ function passLine(label, pass) {
3240
3753
  if (pass.error) bits.push(`error: ${compact(pass.error, 60)}`);
3241
3754
  return `${label.padEnd(20)} ${bits.join(" ")}`;
3242
3755
  }
3243
- function influencesVia(detail) {
3244
- const raw = detail?.influences;
3756
+ function decisionVia(detail) {
3757
+ const d = detail;
3758
+ if (typeof d?.source === "string") return d.source;
3759
+ const raw = d?.influences;
3245
3760
  if (!Array.isArray(raw)) return "";
3246
3761
  const types = [];
3247
3762
  for (const inf of raw) {
@@ -3264,7 +3779,7 @@ Decisions (${insight.decisions.length})`);
3264
3779
  arena: d.category === "other" && d.categoryRaw ? d.categoryRaw : d.category,
3265
3780
  chosen: d.chosenPackage ?? d.chosenName,
3266
3781
  reversed: d.reversed ? "yes" : "",
3267
- via: influencesVia(d.detail)
3782
+ via: decisionVia(d.detail)
3268
3783
  })),
3269
3784
  "table"
3270
3785
  );
@@ -3547,6 +4062,7 @@ function reposLabel(repos) {
3547
4062
  if (repos.length === 0) return "(default scaffold)";
3548
4063
  if (repos.length === 1) {
3549
4064
  const r = repos[0];
4065
+ if (r.repoUrl === null) return "(default scaffold)";
3550
4066
  return r.repoRef ? `${r.repoUrl}@${r.repoRef}` : r.repoUrl;
3551
4067
  }
3552
4068
  return `${repos.length} repos`;
@@ -3562,7 +4078,7 @@ function toRow5(s) {
3562
4078
  days: s.daysPerWeek ?? "",
3563
4079
  agents: s.agents.join(", "),
3564
4080
  repos: reposLabel(s.repos),
3565
- prompts: s.promptCount,
4081
+ tags: s.tagCount,
3566
4082
  enabled: s.enabled ? "yes" : "no",
3567
4083
  experiment: s.experiment ?? ""
3568
4084
  };
@@ -3603,13 +4119,13 @@ function register14(program2) {
3603
4119
  else printItems(res.items.map(toRow5), "table");
3604
4120
  });
3605
4121
  group.command("create").description(
3606
- "Create an org schedule: a named prompt set + agents + cadence + repo"
4122
+ "Create an org schedule: a named tag set + agents + cadence + repo"
3607
4123
  ).requiredOption("--name <name>", "schedule name").requiredOption(
3608
4124
  "--agent <agents>",
3609
4125
  "comma-separated agents, e.g. claude-code,codex"
3610
4126
  ).option(
3611
- "--prompt <id>",
3612
- "member prompt id (repeatable)",
4127
+ "--tag <id>",
4128
+ "membership tag id \u2014 the schedule runs the union of its tags (repeatable)",
3613
4129
  collect4,
3614
4130
  []
3615
4131
  ).option("--repo <url>", "repository URL (default: the Gauge scaffold)").option("--ref <ref>", "branch, tag, or commit (with --repo)").option("--cadence <cadence>", CADENCE_CHOICES.join(" | "), "none").option("--days-per-week <n>", "1-7 (with --cadence days-per-week)").option("--samples <n>", "samples per cycle (default: 1)").option("--model <id>", "pin a model id (default: the agent's default)").option("--disabled", "create the schedule disabled").action(
@@ -3623,7 +4139,7 @@ function register14(program2) {
3623
4139
  cadence: parseCadence(opts.cadence),
3624
4140
  samplesPerCycle: opts.samples !== void 0 ? parseSamples(opts.samples) : 1,
3625
4141
  repos: opts.repo !== void 0 ? reposFromOpts(opts.repo, opts.ref) : [],
3626
- promptIds: opts.prompt,
4142
+ tagIds: opts.tag,
3627
4143
  enabled: !opts.disabled
3628
4144
  };
3629
4145
  if (opts.daysPerWeek !== void 0)
@@ -3637,12 +4153,12 @@ function register14(program2) {
3637
4153
  else console.log(`Created schedule ${schedule.id}`);
3638
4154
  }
3639
4155
  );
3640
- group.command("edit <id>").description("Update a schedule (repos and prompts are full replacements)").option("--name <name>", "rename the schedule").option("--agent <agents>", "comma-separated agents").option(
3641
- "--prompt <id>",
3642
- "member prompt id \u2014 replaces the whole set (repeatable)",
4156
+ group.command("edit <id>").description("Update a schedule (repos and tags are full replacements)").option("--name <name>", "rename the schedule").option("--agent <agents>", "comma-separated agents").option(
4157
+ "--tag <id>",
4158
+ "membership tag id \u2014 replaces the whole set (repeatable)",
3643
4159
  collect4,
3644
4160
  []
3645
- ).option("--clear-prompts", "remove all member prompts").option("--repo <url>", "set a single repo target").option("--ref <ref>", "branch, tag, or commit (with --repo)").option("--clear-repos", "reset to the default scaffold (no repos)").option("--cadence <cadence>", CADENCE_CHOICES.join(" | ")).option("--days-per-week <n>", "1-7 (with cadence days-per-week)").option("--samples <n>", "samples per cycle").option("--model <id>", "pin a model id").option("--clear-model", "use the agent's default model").option("--enable", "enable the schedule").option("--disable", "disable the schedule").action(
4161
+ ).option("--clear-tags", "remove all membership tags").option("--repo <url>", "set a single repo target").option("--ref <ref>", "branch, tag, or commit (with --repo)").option("--clear-repos", "reset to the default scaffold (no repos)").option("--cadence <cadence>", CADENCE_CHOICES.join(" | ")).option("--days-per-week <n>", "1-7 (with cadence days-per-week)").option("--samples <n>", "samples per cycle").option("--model <id>", "pin a model id").option("--clear-model", "use the agent's default model").option("--enable", "enable the schedule").option("--disable", "disable the schedule").action(
3646
4162
  async (id, opts, cmd) => {
3647
4163
  const body = {};
3648
4164
  if (opts.name !== void 0) body.name = opts.name;
@@ -3664,10 +4180,10 @@ function register14(program2) {
3664
4180
  if (opts.clearRepos) body.repos = [];
3665
4181
  else if (opts.repo !== void 0)
3666
4182
  body.repos = reposFromOpts(opts.repo, opts.ref);
3667
- if (opts.prompt.length > 0 && opts.clearPrompts)
3668
- throw new CliError("usage", "--prompt and --clear-prompts conflict");
3669
- if (opts.clearPrompts) body.promptIds = [];
3670
- else if (opts.prompt.length > 0) body.promptIds = opts.prompt;
4183
+ if (opts.tag.length > 0 && opts.clearTags)
4184
+ throw new CliError("usage", "--tag and --clear-tags conflict");
4185
+ if (opts.clearTags) body.tagIds = [];
4186
+ else if (opts.tag.length > 0) body.tagIds = opts.tag;
3671
4187
  if (opts.enable && opts.disable)
3672
4188
  throw new CliError("usage", "--enable and --disable conflict");
3673
4189
  if (opts.enable) body.enabled = true;
@@ -3694,7 +4210,9 @@ function register14(program2) {
3694
4210
  return;
3695
4211
  }
3696
4212
  if (result.runIds.length === 0) {
3697
- console.log("No runs enqueued (the schedule has no member prompts)");
4213
+ console.log(
4214
+ "No runs enqueued (the schedule's tags resolve to no prompts)"
4215
+ );
3698
4216
  return;
3699
4217
  }
3700
4218
  console.log(