@withgauge/cli 0.3.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 +1690 -525
  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(),
@@ -141,10 +137,10 @@ var batterySpecSchema = z2.object({
141
137
  prompts: z2.array(batteryPromptSpecSchema).min(1)
142
138
  });
143
139
  var batteryPlanScheduleSchema = z2.object({
144
- action: z2.enum(["create", "update"]),
140
+ action: z2.enum(["create", "update", "none"]),
145
141
  repoUrl: z2.string().nullable(),
146
142
  repoRef: z2.string().nullable(),
147
- /** Runs this schedule would enqueue (agents × samples; 0 unless `expand`). */
143
+ /** Runs this target would enqueue (agents × samples; 0 unless `expand`). */
148
144
  runs: z2.number().int()
149
145
  });
150
146
  var batteryPlanPromptSchema = z2.object({
@@ -342,249 +338,282 @@ var listBrandsQuerySchema = listQuerySchema.extend({
342
338
  });
343
339
  var brandListResponseSchema = listResponseSchema(brandSchema);
344
340
 
345
- // ../packages/api-schemas/src/keys.ts
346
- var keys_exports = {};
347
- __export(keys_exports, {
348
- PROVIDER_TYPES: () => PROVIDER_TYPES,
349
- providerKeyListResponseSchema: () => providerKeyListResponseSchema,
350
- providerKeySchema: () => providerKeySchema,
351
- providerTypeSchema: () => providerTypeSchema,
352
- setProviderKeyBodySchema: () => setProviderKeyBodySchema,
353
- setProviderKeyResponseSchema: () => setProviderKeyResponseSchema
354
- });
341
+ // ../packages/api-schemas/src/checkpoints.ts
355
342
  import { z as z5 } from "zod";
356
- var PROVIDER_TYPES = ["anthropic", "openai"];
357
- var providerTypeSchema = z5.enum(PROVIDER_TYPES);
358
- var setProviderKeyBodySchema = z5.object({
359
- /** The raw provider API key. Verified + stored server-side (AWS Secrets
360
- * Manager); never persisted in the app DB and never echoed back. */
361
- key: z5.string().min(1)
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)
362
361
  });
363
- var setProviderKeyResponseSchema = z5.object({
364
- providerType: providerTypeSchema,
365
- last4: z5.string()
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()
366
391
  });
367
- var providerKeySchema = z5.object({
368
- providerType: providerTypeSchema,
369
- last4: z5.string(),
370
- createdAt: z5.string(),
371
- /** When the key was last saved/rotated. */
372
- updatedAt: z5.string()
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
+ })
373
409
  });
374
- var providerKeyListResponseSchema = listResponseSchema(providerKeySchema);
375
-
376
- // ../packages/api-schemas/src/me.ts
377
- import { z as z6 } from "zod";
378
- var meUserSchema = z6.object({
379
- id: z6.string(),
380
- email: z6.string().nullable(),
381
- isSuperuser: z6.boolean()
410
+ var canonicalBaselinePayloadSchema = chunkedPayloadSchema.extend({
411
+ format: z5.literal("canonical-workspace-chunked-zstd-v1")
382
412
  });
383
- var meOrgSchema = z6.object({
384
- slug: z6.string(),
385
- // Gauge's immutable Organization.public_id; null for LOCAL orgs.
386
- publicId: z6.string().nullable(),
387
- name: z6.string()
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()
388
431
  });
389
- var meResponseSchema = z6.object({
390
- user: meUserSchema,
391
- // Membership-scoped for normal users; superusers see every org (mirrors the
392
- // web tier's userOrgs).
393
- orgs: z6.array(meOrgSchema)
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)
394
440
  });
395
-
396
- // ../packages/api-schemas/src/prompts.ts
397
- import { z as z10 } from "zod";
398
-
399
- // ../packages/api-schemas/src/schedules.ts
400
- import { z as z7 } from "zod";
401
- var AGENTS = ["CLAUDE_CODE", "CODEX_CLI", "CURSOR"];
402
- var agentSchema = z7.enum(AGENTS);
403
- var CADENCES = [
404
- "NONE",
405
- "DAILY",
406
- "WEEKLY",
407
- "MONTHLY",
408
- "DAYS_PER_WEEK"
409
- ];
410
- var cadenceSchema = z7.enum(CADENCES);
411
- var daysPerWeekSchema = z7.number().int().min(1).max(7);
412
- var scheduleSchema = z7.object({
413
- id: z7.string(),
414
- promptId: z7.string(),
415
- /** Base repo to run against; null = the default scaffold. */
416
- repoUrl: z7.string().nullable(),
417
- /** Branch/ref; null = the repo's default branch. */
418
- repoRef: z7.string().nullable(),
419
- cadence: cadenceSchema,
420
- /** Only set when cadence is DAYS_PER_WEEK (1–7). */
421
- daysPerWeek: z7.number().int().nullable(),
422
- samplesPerCycle: z7.number().int(),
423
- agents: z7.array(agentSchema),
424
- /** Pinned model id; null = the agent's default. */
425
- model: z7.string().nullable(),
426
- /** Cohort label for experiment analysis; null for ad-hoc schedules. */
427
- experiment: z7.string().nullable(),
428
- createdAt: z7.string(),
429
- updatedAt: z7.string()
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
+ }
430
476
  });
431
- var scheduleListResponseSchema = listResponseSchema(scheduleSchema);
432
- var createScheduleBodySchema = z7.object({
433
- repoUrl: z7.string().min(1).nullish(),
434
- repoRef: z7.string().min(1).nullish(),
435
- cadence: cadenceSchema.default("NONE"),
436
- daysPerWeek: daysPerWeekSchema.optional(),
437
- agents: z7.array(agentSchema).min(1, "Select at least one agent")
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()
438
483
  });
439
- var updateScheduleBodySchema = z7.object({
440
- repoUrl: z7.string().min(1).nullish(),
441
- repoRef: z7.string().min(1).nullish(),
442
- cadence: cadenceSchema.optional(),
443
- daysPerWeek: daysPerWeekSchema.optional(),
444
- agents: z7.array(agentSchema).min(1, "Select at least one agent").optional()
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")
445
508
  });
446
-
447
- // ../packages/api-schemas/src/tags.ts
448
- import { z as z8 } from "zod";
449
- var tagSchema = z8.object({
450
- id: z8.string(),
451
- name: z8.string(),
452
- /** A Mantine palette name (e.g. "blue", "grape"); unknown values are
453
- * normalized server-side to the default ("gray"). */
454
- color: z8.string()
455
- });
456
- var createTagBodySchema = z8.object({
457
- name: z8.string().min(1),
458
- color: z8.string().optional()
459
- });
460
- var updateTagBodySchema = z8.object({
461
- name: z8.string().min(1).optional(),
462
- color: z8.string().optional()
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
+ })
463
542
  });
464
- var tagListResponseSchema = listResponseSchema(tagSchema);
465
543
 
466
- // ../packages/api-schemas/src/topics.ts
467
- import { z as z9 } from "zod";
468
- var topicSchema = z9.object({
469
- id: z9.string(),
470
- name: z9.string()
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)
471
550
  });
472
- var createTopicBodySchema = z9.object({
473
- name: z9.string().min(1, "name is required")
551
+ var cliAuthorizationTokenResponseSchema = z6.object({
552
+ accessToken: z6.string(),
553
+ tokenType: z6.literal("bearer"),
554
+ expiresAt: z6.string().nullable()
474
555
  });
475
- var topicListResponseSchema = listResponseSchema(topicSchema);
476
556
 
477
- // ../packages/api-schemas/src/prompts.ts
478
- var SCENARIOS = ["GREENFIELD", "MIGRATION"];
479
- var scenarioSchema = z10.enum(SCENARIOS);
480
- var promptSummarySchema = z10.object({
481
- id: z10.string(),
482
- text: z10.string(),
483
- scenario: scenarioSchema,
484
- isBranded: z10.boolean(),
485
- /** Battery-spec identity (idempotent applies); null for UI/CLI-created prompts. */
486
- externalKey: z10.string().nullable(),
487
- topic: topicSchema.nullable(),
488
- tags: z10.array(tagSchema),
489
- scheduleCount: z10.number().int(),
490
- createdAt: z10.string()
491
- });
492
- var promptDetailSchema = promptSummarySchema.extend({
493
- schedules: z10.array(scheduleSchema)
494
- });
495
- var promptListResponseSchema = listResponseSchema(promptSummarySchema);
496
- var listPromptsQuerySchema = listQuerySchema.extend({
497
- topic: z10.string().min(1).optional(),
498
- tag: z10.string().min(1).optional(),
499
- q: z10.string().min(1).optional()
500
- });
501
- var createPromptBodySchema = z10.object({
502
- text: z10.string().min(1, "text is required"),
503
- scenario: scenarioSchema.default("GREENFIELD"),
504
- isBranded: z10.boolean().default(false),
505
- topic: z10.string().min(1).optional(),
506
- tags: z10.array(z10.string().min(1)).default([]),
507
- schedules: z10.array(createScheduleBodySchema).default([])
508
- });
509
- var createPromptResponseSchema = promptDetailSchema.extend({
510
- firstRunBlocked: z10.enum(["insufficient_credits", "needs_provider_key"]).optional()
511
- });
512
- var updatePromptBodySchema = z10.object({
513
- text: z10.string().min(1).optional(),
514
- isBranded: z10.boolean().optional(),
515
- topicId: z10.string().min(1).nullish(),
516
- tags: z10.array(z10.string().min(1)).optional()
517
- });
518
- var runPromptBodySchema = z10.object({
519
- agents: z10.array(agentSchema).min(1).optional(),
520
- scheduleIds: z10.array(z10.string().min(1)).min(1).optional()
521
- });
522
- var runPromptResponseSchema = z10.object({
523
- batchIds: z10.array(z10.string()),
524
- runIds: z10.array(z10.string()),
525
- /** Present when SOME schedules hit a billing gate but at least one run was
526
- * enqueued (mirrors the battery apply response; an all-blocked run is a
527
- * 402 error instead). */
528
- blocked: z10.enum(["insufficient_credits", "needs_provider_key"]).optional()
529
- });
557
+ // ../packages/api-schemas/src/dashboards.ts
558
+ import { z as z9 } from "zod";
530
559
 
531
560
  // ../packages/api-schemas/src/query.ts
532
- import { z as z12 } from "zod";
561
+ import { z as z8 } from "zod";
533
562
 
534
563
  // ../packages/api-schemas/src/stats.ts
535
- import { z as z11 } from "zod";
564
+ import { z as z7 } from "zod";
536
565
  var BRAND_KINDS2 = ["OWNED", "COMPETITOR", "OTHER"];
537
- var brandKindSchema2 = z11.enum(BRAND_KINDS2);
538
- var brandRankingSchema = z11.object({
539
- rank: z11.number().int(),
540
- brandId: z11.string(),
541
- brandName: z11.string(),
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(),
542
571
  kind: brandKindSchema2,
543
- installs: z11.number().int(),
544
- installRate: z11.number(),
545
- mentionRate: z11.number(),
572
+ installs: z7.number().int(),
573
+ installRate: z7.number(),
574
+ mentionRate: z7.number(),
546
575
  /** Movement between the two most recent batch windows; null if not ranked in both. */
547
- deltaRank: z11.number().int().nullable()
576
+ deltaRank: z7.number().int().nullable()
548
577
  });
549
- var packageRateSchema = z11.object({
550
- ecosystem: z11.string(),
551
- name: z11.string(),
552
- brandName: z11.string().optional(),
578
+ var packageRateSchema = z7.object({
579
+ ecosystem: z7.string(),
580
+ name: z7.string(),
581
+ brandName: z7.string().optional(),
553
582
  kind: brandKindSchema2.optional(),
554
- installs: z11.number().int(),
555
- rate: z11.number()
583
+ installs: z7.number().int(),
584
+ rate: z7.number()
556
585
  });
557
- var brandRateSchema = z11.object({
558
- brandId: z11.string(),
559
- brandName: z11.string(),
586
+ var brandRateSchema = z7.object({
587
+ brandId: z7.string(),
588
+ brandName: z7.string(),
560
589
  kind: brandKindSchema2,
561
- installs: z11.number().int(),
562
- rate: z11.number()
590
+ installs: z7.number().int(),
591
+ rate: z7.number()
563
592
  });
564
- var brandFunnelRowSchema = z11.object({
565
- brandId: z11.string(),
566
- brandName: z11.string(),
593
+ var brandFunnelRowSchema = z7.object({
594
+ brandId: z7.string(),
595
+ brandName: z7.string(),
567
596
  kind: brandKindSchema2,
568
- mentionRate: z11.number(),
569
- installRate: z11.number()
570
- });
571
- var domainRateSchema = z11.object({
572
- domain: z11.string(),
573
- runs: z11.number().int(),
574
- rate: z11.number(),
575
- requests: z11.number().int(),
576
- brandName: z11.string().optional(),
577
- owned: z11.boolean().optional()
578
- });
579
- var statsFreshnessSchema = z11.object({
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({
580
609
  /** Newest run-ingest time across the org (ISO), or null if nothing ingested. */
581
- watermark: z11.string().nullable(),
610
+ watermark: z7.string().nullable(),
582
611
  /** Runs that succeeded recently but haven't landed in the warehouse yet. */
583
- pending: z11.number().int(),
612
+ pending: z7.number().int(),
584
613
  /** False when the freshness read itself failed (distinguish from genuine zero). */
585
- available: z11.boolean()
614
+ available: z7.boolean()
586
615
  });
587
- var statsResponseSchema = (item) => z11.object({ items: z11.array(item), freshness: statsFreshnessSchema });
616
+ var statsResponseSchema = (item) => z7.object({ items: z7.array(item), freshness: statsFreshnessSchema });
588
617
  var rankingsResponseSchema = statsResponseSchema(brandRankingSchema);
589
618
  var installsResponseSchema = statsResponseSchema(packageRateSchema);
590
619
  var brandsResponseSchema = statsResponseSchema(brandRateSchema);
@@ -597,11 +626,13 @@ var DATASETS = [
597
626
  "installs",
598
627
  "mentions",
599
628
  "web",
629
+ "citations",
600
630
  "network",
601
631
  "files",
602
- "tokens"
632
+ "tokens",
633
+ "brand_rollup"
603
634
  ];
604
- var datasetSchema = z12.enum(DATASETS);
635
+ var datasetSchema = z8.enum(DATASETS);
605
636
  var WHERE_OPS = [
606
637
  "eq",
607
638
  "neq",
@@ -613,150 +644,756 @@ var WHERE_OPS = [
613
644
  "lt",
614
645
  "lte"
615
646
  ];
616
- var whereOpSchema = z12.enum(WHERE_OPS);
647
+ var whereOpSchema = z8.enum(WHERE_OPS);
617
648
  var GRANULARITIES = ["day", "week", "month"];
618
- var granularitySchema = z12.enum(GRANULARITIES);
649
+ var granularitySchema = z8.enum(GRANULARITIES);
619
650
  var DEFAULT_QUERY_LIMIT = 50;
620
651
  var MAX_QUERY_LIMIT = 1e3;
621
- var scalar = z12.union([z12.string(), z12.number(), z12.boolean()]);
622
- var whereClauseSchema = z12.object({
623
- dimension: z12.string().min(1),
652
+ var scalar = z8.union([z8.string(), z8.number(), z8.boolean()]);
653
+ var whereClauseSchema = z8.object({
654
+ dimension: z8.string().min(1),
624
655
  op: whereOpSchema,
625
- value: z12.union([scalar, z12.array(scalar)])
626
- });
627
- var queryFiltersSchema = z12.object({
628
- prompt: z12.string(),
629
- topic: z12.array(z12.string()),
630
- tag: z12.array(z12.string()),
631
- repo: z12.array(z12.string()),
632
- language: z12.array(z12.string()),
633
- framework: z12.array(z12.string()),
634
- size: z12.array(z12.string()),
635
- agent: z12.array(z12.string()),
636
- model: z12.array(z12.string()),
637
- scenario: z12.array(z12.string()),
638
- experiment: z12.array(z12.string()),
639
- branded: z12.boolean()
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()
640
673
  }).partial();
641
- var dateRangeSchema = z12.object({
642
- since: z12.string(),
643
- until: z12.string(),
644
- lastDays: z12.number().int().positive()
674
+ var dateRangeSchema = z8.object({
675
+ since: z8.string(),
676
+ until: z8.string(),
677
+ lastDays: z8.number().int().positive()
645
678
  }).partial();
646
- var orderBySchema = z12.object({
679
+ var orderBySchema = z8.object({
647
680
  /** A selected dimension or metric name. */
648
- key: z12.string().min(1),
649
- dir: z12.enum(["asc", "desc"]).default("desc")
681
+ key: z8.string().min(1),
682
+ dir: z8.enum(["asc", "desc"]).default("desc")
650
683
  });
651
- var querySpecSchema = z12.object({
684
+ var querySpecSchema = z8.object({
652
685
  dataset: datasetSchema.default("runs"),
653
- dimensions: z12.array(z12.string()).default([]),
654
- metrics: z12.array(z12.string()).min(1, "at least one metric is required"),
686
+ dimensions: z8.array(z8.string()).default([]),
687
+ metrics: z8.array(z8.string()).min(1, "at least one metric is required"),
655
688
  filters: queryFiltersSchema.default({}),
656
- where: z12.array(whereClauseSchema).default([]),
689
+ where: z8.array(whereClauseSchema).default([]),
657
690
  dateRange: dateRangeSchema.optional(),
658
- orderBy: z12.array(orderBySchema).default([]),
659
- limit: z12.number().int().min(1).max(MAX_QUERY_LIMIT).default(DEFAULT_QUERY_LIMIT),
691
+ orderBy: z8.array(orderBySchema).default([]),
692
+ limit: z8.number().int().min(1).max(MAX_QUERY_LIMIT).default(DEFAULT_QUERY_LIMIT),
660
693
  granularity: granularitySchema.default("day"),
661
694
  /** When true, the response echoes the compiled SQL (params bound, not inlined). */
662
- explain: z12.boolean().default(false)
695
+ explain: z8.boolean().default(false)
663
696
  });
664
- var columnKindSchema = z12.enum(["dimension", "metric"]);
665
- var queryColumnSchema = z12.object({
666
- key: z12.string(),
697
+ var columnKindSchema = z8.enum(["dimension", "metric"]);
698
+ var queryColumnSchema = z8.object({
699
+ key: z8.string(),
667
700
  kind: columnKindSchema
668
701
  });
669
- var queryRowSchema = z12.record(
670
- z12.string(),
671
- z12.union([z12.string(), z12.number(), z12.boolean(), z12.null()])
702
+ var queryRowSchema = z8.record(
703
+ z8.string(),
704
+ z8.union([z8.string(), z8.number(), z8.boolean(), z8.null()])
672
705
  );
673
- var queryResponseSchema = z12.object({
674
- columns: z12.array(queryColumnSchema),
675
- rows: z12.array(queryRowSchema),
706
+ var queryResponseSchema = z8.object({
707
+ columns: z8.array(queryColumnSchema),
708
+ rows: z8.array(queryRowSchema),
676
709
  /** Present only when the request set explain=true. */
677
- sql: z12.string().optional(),
710
+ sql: z8.string().optional(),
678
711
  freshness: statsFreshnessSchema
679
712
  });
680
- var fieldTypeSchema = z12.enum([
713
+ var fieldTypeSchema = z8.enum([
681
714
  "string",
682
715
  "number",
683
716
  "rate",
684
717
  "date",
685
718
  "boolean"
686
719
  ]);
687
- var fieldSchema = z12.object({
688
- name: z12.string(),
720
+ var fieldSchema = z8.object({
721
+ name: z8.string(),
689
722
  type: fieldTypeSchema,
690
723
  /** One-line human/agent hint. */
691
- description: z12.string().optional()
724
+ description: z8.string().optional()
692
725
  });
693
- var datasetMetaSchema = z12.object({
726
+ var datasetMetaSchema = z8.object({
694
727
  name: datasetSchema,
695
- grain: z12.string(),
696
- dimensions: z12.array(fieldSchema),
697
- metrics: z12.array(fieldSchema)
728
+ grain: z8.string(),
729
+ dimensions: z8.array(fieldSchema),
730
+ metrics: z8.array(fieldSchema)
698
731
  });
699
- var metadataResponseSchema = z12.object({
700
- datasets: z12.array(datasetMetaSchema)
732
+ var metadataResponseSchema = z8.object({
733
+ datasets: z8.array(datasetMetaSchema)
701
734
  });
702
735
 
703
- // ../packages/api-schemas/src/repos.ts
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({
800
+ /** Device label (the CLI's hostname) for display + token naming. */
801
+ deviceName: z10.string().trim().max(64).optional(),
802
+ /** Optional: email a magic-link that lands on the approval page pre-scoped
803
+ * to this device (best-effort — the printed URL always works regardless). */
804
+ email: z10.string().trim().email().max(320).optional()
805
+ });
806
+ var deviceAuthorizeResponseSchema = z10.object({
807
+ /** The one-time secret the CLI polls with (never shown again). */
808
+ deviceCode: z10.string(),
809
+ /** Short human-typed code the user confirms in the browser (e.g. WXYZ-1234). */
810
+ userCode: z10.string(),
811
+ /** Where the user approves (e.g. https://…/cli/authorize). */
812
+ verificationUri: z10.string(),
813
+ /** verificationUri with the code pre-filled, for one-click / QR. */
814
+ verificationUriComplete: z10.string(),
815
+ /** Minimum seconds between polls. */
816
+ interval: z10.number().int().positive(),
817
+ /** Seconds until the device code expires. */
818
+ expiresIn: z10.number().int().positive(),
819
+ /** Whether a magic-link email was dispatched (best-effort). */
820
+ emailSent: z10.boolean()
821
+ });
822
+ var deviceTokenRequestSchema = z10.object({
823
+ deviceCode: z10.string().min(1)
824
+ });
825
+ var deviceTokenApprovedSchema = z10.object({
826
+ status: z10.literal("approved"),
827
+ /** The `gauge_…` bearer secret. Store it now — never returned again. */
828
+ accessToken: z10.string(),
829
+ tokenType: z10.literal("bearer"),
830
+ /** ISO-8601 expiry, or null for no expiry. */
831
+ expiresAt: z10.string().nullable()
832
+ });
833
+ var deviceTokenResultSchema = z10.discriminatedUnion("status", [
834
+ // Not yet approved — keep polling at `interval`.
835
+ z10.object({ status: z10.literal("pending") }),
836
+ // Polled faster than `interval` — back off by `interval` seconds.
837
+ z10.object({ status: z10.literal("slow_down"), interval: z10.number().int() }),
838
+ // The user explicitly denied the request. Stop.
839
+ z10.object({ status: z10.literal("denied") }),
840
+ // The device code expired or is unknown/already-redeemed. Stop and restart.
841
+ z10.object({ status: z10.literal("expired") }),
842
+ deviceTokenApprovedSchema
843
+ ]);
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
+
992
+ // ../packages/api-schemas/src/keys.ts
993
+ var keys_exports = {};
994
+ __export(keys_exports, {
995
+ PROVIDER_TYPES: () => PROVIDER_TYPES,
996
+ providerKeyListResponseSchema: () => providerKeyListResponseSchema,
997
+ providerKeySchema: () => providerKeySchema,
998
+ providerTypeSchema: () => providerTypeSchema,
999
+ setProviderKeyBodySchema: () => setProviderKeyBodySchema,
1000
+ setProviderKeyResponseSchema: () => setProviderKeyResponseSchema
1001
+ });
1002
+ import { z as z12 } from "zod";
1003
+ var PROVIDER_TYPES = ["anthropic", "openai"];
1004
+ var providerTypeSchema = z12.enum(PROVIDER_TYPES);
1005
+ var setProviderKeyBodySchema = z12.object({
1006
+ /** The raw provider API key. Verified + stored server-side (AWS Secrets
1007
+ * Manager); never persisted in the app DB and never echoed back. */
1008
+ key: z12.string().min(1)
1009
+ });
1010
+ var setProviderKeyResponseSchema = z12.object({
1011
+ providerType: providerTypeSchema,
1012
+ last4: z12.string()
1013
+ });
1014
+ var providerKeySchema = z12.object({
1015
+ providerType: providerTypeSchema,
1016
+ last4: z12.string(),
1017
+ createdAt: z12.string(),
1018
+ /** When the key was last saved/rotated. */
1019
+ updatedAt: z12.string()
1020
+ });
1021
+ var providerKeyListResponseSchema = listResponseSchema(providerKeySchema);
1022
+
1023
+ // ../packages/api-schemas/src/me.ts
704
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()
1029
+ });
1030
+ var meOrgSchema = z13.object({
1031
+ slug: z13.string(),
1032
+ // Gauge's immutable Organization.public_id; null for LOCAL orgs.
1033
+ publicId: z13.string().nullable(),
1034
+ name: z13.string()
1035
+ });
1036
+ var meResponseSchema = z13.object({
1037
+ user: meUserSchema,
1038
+ // Membership-scoped for normal users; superusers see every org (mirrors the
1039
+ // web tier's userOrgs).
1040
+ orgs: z13.array(meOrgSchema)
1041
+ });
1042
+
1043
+ // ../packages/api-schemas/src/orgs.ts
1044
+ import { z as z14 } from "zod";
1045
+ var createOrgRequestSchema = z14.object({
1046
+ /** Workspace display name; the slug is derived server-side. */
1047
+ name: z14.string().trim().min(1).max(200),
1048
+ /** Optional company site (logo source; stamped onto the org). */
1049
+ website: z14.string().trim().max(300).optional()
1050
+ });
1051
+ var createOrgResponseSchema = z14.object({
1052
+ slug: z14.string(),
1053
+ name: z14.string(),
1054
+ // LOCAL orgs never have a Gauge publicId.
1055
+ publicId: z14.string().nullable()
1056
+ });
1057
+
1058
+ // ../packages/api-schemas/src/prompts.ts
1059
+ import { z as z19 } from "zod";
1060
+
1061
+ // ../packages/api-schemas/src/schedules.ts
1062
+ import { z as z15 } from "zod";
1063
+ var AGENTS = ["CLAUDE_CODE", "CODEX_CLI", "CURSOR"];
1064
+ var agentSchema = z15.enum(AGENTS);
1065
+ var CADENCES = [
1066
+ "NONE",
1067
+ "DAILY",
1068
+ "WEEKLY",
1069
+ "MONTHLY",
1070
+ "DAYS_PER_WEEK"
1071
+ ];
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(),
1094
+ cadence: cadenceSchema,
1095
+ /** Only set when cadence is DAYS_PER_WEEK (1–7). */
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),
1107
+ /** Cohort label for experiment analysis; null outside labeled experiments. */
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()
1124
+ });
1125
+ var scheduleListResponseSchema = listResponseSchema(scheduleSchema);
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()
1130
+ });
1131
+ var createScheduleBodyObject = z15.object({
1132
+ name: z15.string().min(1, "name is required"),
1133
+ cadence: cadenceSchema.default("NONE"),
1134
+ daysPerWeek: daysPerWeekSchema.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(),
1165
+ cadence: cadenceSchema.optional(),
1166
+ daysPerWeek: daysPerWeekSchema.optional(),
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"])
1187
+ })
1188
+ ).optional()
1189
+ });
1190
+
1191
+ // ../packages/api-schemas/src/tags.ts
1192
+ import { z as z16 } from "zod";
1193
+ var tagSchema = z16.object({
1194
+ id: z16.string(),
1195
+ name: z16.string(),
1196
+ /** A Mantine palette name (e.g. "blue", "grape"); unknown values are
1197
+ * normalized server-side to the default ("gray"). */
1198
+ color: z16.string()
1199
+ });
1200
+ var createTagBodySchema = z16.object({
1201
+ name: z16.string().min(1),
1202
+ color: z16.string().optional()
1203
+ });
1204
+ var updateTagBodySchema = z16.object({
1205
+ name: z16.string().min(1).optional(),
1206
+ color: z16.string().optional()
1207
+ });
1208
+ var tagListResponseSchema = listResponseSchema(tagSchema);
1209
+
1210
+ // ../packages/api-schemas/src/topics.ts
1211
+ import { z as z17 } from "zod";
1212
+ var topicSchema = z17.object({
1213
+ id: z17.string(),
1214
+ name: z17.string()
1215
+ });
1216
+ var createTopicBodySchema = z17.object({
1217
+ name: z17.string().min(1, "name is required")
1218
+ });
1219
+ var topicListResponseSchema = listResponseSchema(topicSchema);
1220
+
1221
+ // ../packages/api-schemas/src/web-fixtures.ts
1222
+ var web_fixtures_exports = {};
1223
+ __export(web_fixtures_exports, {
1224
+ MAX_WEB_FIXTURE_BYTES: () => MAX_WEB_FIXTURE_BYTES,
1225
+ webFixtureSchema: () => webFixtureSchema
1226
+ });
1227
+ import { z as z18 } from "zod";
1228
+ var MAX_WEB_FIXTURE_BYTES = 1e6;
1229
+ function withoutFragment(raw) {
1230
+ const fragment = raw.indexOf("#");
1231
+ return fragment === -1 ? raw : raw.slice(0, fragment);
1232
+ }
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([])
1252
+ }).superRefine((fixture, ctx) => {
1253
+ const queries = /* @__PURE__ */ new Set();
1254
+ fixture.searches.forEach((entry, index) => {
1255
+ if (queries.has(entry.query)) {
1256
+ ctx.addIssue({
1257
+ code: "custom",
1258
+ path: ["searches", index, "query"],
1259
+ message: `duplicate normalized query: ${entry.query}`
1260
+ });
1261
+ }
1262
+ queries.add(entry.query);
1263
+ });
1264
+ const urls = /* @__PURE__ */ new Set();
1265
+ fixture.pages.forEach((entry, index) => {
1266
+ if (urls.has(entry.url)) {
1267
+ ctx.addIssue({
1268
+ code: "custom",
1269
+ path: ["pages", index, "url"],
1270
+ message: `duplicate normalized URL: ${entry.url}`
1271
+ });
1272
+ }
1273
+ urls.add(entry.url);
1274
+ });
1275
+ const bytes = new TextEncoder().encode(JSON.stringify(fixture)).byteLength;
1276
+ if (bytes > MAX_WEB_FIXTURE_BYTES) {
1277
+ ctx.addIssue({
1278
+ code: "custom",
1279
+ message: `serialized fixture is ${bytes} bytes; maximum is ${MAX_WEB_FIXTURE_BYTES}`
1280
+ });
1281
+ }
1282
+ });
1283
+
1284
+ // ../packages/api-schemas/src/prompts.ts
1285
+ var promptSummarySchema = z19.object({
1286
+ id: z19.string(),
1287
+ text: z19.string(),
1288
+ isBranded: z19.boolean(),
1289
+ /** Battery-spec identity (idempotent applies); null for UI/CLI-created prompts. */
1290
+ externalKey: z19.string().nullable(),
1291
+ topic: topicSchema.nullable(),
1292
+ tags: z19.array(tagSchema),
1293
+ scheduleCount: z19.number().int(),
1294
+ createdAt: z19.string()
1295
+ });
1296
+ var promptScheduleRefSchema = z19.object({
1297
+ id: z19.string(),
1298
+ name: z19.string(),
1299
+ cadence: cadenceSchema,
1300
+ daysPerWeek: z19.number().int().nullable(),
1301
+ enabled: z19.boolean()
1302
+ });
1303
+ var promptDetailSchema = promptSummarySchema.extend({
1304
+ schedules: z19.array(promptScheduleRefSchema)
1305
+ });
1306
+ var promptListResponseSchema = listResponseSchema(promptSummarySchema);
1307
+ var listPromptsQuerySchema = listQuerySchema.extend({
1308
+ topic: z19.string().min(1).optional(),
1309
+ tag: z19.string().min(1).optional(),
1310
+ q: z19.string().min(1).optional()
1311
+ });
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([])
1317
+ });
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()
1323
+ });
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()
1333
+ });
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()
1338
+ });
1339
+
1340
+ // ../packages/api-schemas/src/repos.ts
1341
+ import { z as z20 } from "zod";
705
1342
  var REPO_SIZE_BUCKETS = [
706
1343
  "small",
707
1344
  "medium",
708
1345
  "large",
709
1346
  "xlarge"
710
1347
  ];
711
- var repoSizeBucketSchema = z13.enum(REPO_SIZE_BUCKETS);
712
- var repoSchema = z13.object({
713
- url: z13.string(),
714
- name: z13.string(),
715
- isSystem: z13.boolean(),
716
- languages: z13.array(z13.string()),
717
- frameworks: z13.array(z13.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()),
718
1355
  /** Faceted labels (complexity:L2, buildable:yes, stack:nextjs, …). */
719
- tags: z13.array(z13.string()),
720
- primaryLanguage: z13.string(),
721
- sizeKb: z13.number(),
1356
+ tags: z20.array(z20.string()),
1357
+ primaryLanguage: z20.string(),
1358
+ sizeKb: z20.number(),
722
1359
  sizeBucket: repoSizeBucketSchema.nullable(),
723
- stars: z13.number()
1360
+ stars: z20.number()
724
1361
  });
725
1362
  var repoListResponseSchema = listResponseSchema(repoSchema);
726
- var addRepoBodySchema = z13.object({
727
- url: z13.string().min(1, "url is required"),
1363
+ var addRepoBodySchema = z20.object({
1364
+ url: z20.string().min(1, "url is required"),
728
1365
  /**
729
1366
  * Reserved (accepted, not yet persisted): the catalog keys repos by URL only
730
1367
  * — `fact_repo` has no ref column and metadata sync always reads the default
731
1368
  * branch. Kept in the wire format so `gauge repos add --ref` is stable once
732
1369
  * the catalog learns refs.
733
1370
  */
734
- ref: z13.string().min(1).optional(),
1371
+ ref: z20.string().min(1).optional(),
735
1372
  /** Display name; defaults to the `owner/repo` label of the URL. */
736
- name: z13.string().min(1).optional(),
1373
+ name: z20.string().min(1).optional(),
737
1374
  /** Manual override; defaults to frameworks detected from the repo's manifests. */
738
- frameworks: z13.array(z13.string()).optional(),
739
- tags: z13.array(z13.string()).optional()
1375
+ frameworks: z20.array(z20.string()).optional(),
1376
+ tags: z20.array(z20.string()).optional()
740
1377
  });
741
- var updateRepoBodySchema = z13.object({
742
- url: z13.string().min(1, "url is required"),
743
- name: z13.string().min(1).optional(),
744
- frameworks: z13.array(z13.string()).optional(),
745
- tags: z13.array(z13.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()
746
1383
  });
747
- var resyncRepoBodySchema = z13.object({
748
- url: z13.string().min(1, "url is required")
1384
+ var resyncRepoBodySchema = z20.object({
1385
+ url: z20.string().min(1, "url is required")
749
1386
  });
750
- var deleteRepoQuerySchema = z13.object({
751
- url: z13.string().min(1, "url is required")
1387
+ var deleteRepoQuerySchema = z20.object({
1388
+ url: z20.string().min(1, "url is required")
752
1389
  });
753
- var repoSyncResultSchema = z13.object({
1390
+ var repoSyncResultSchema = z20.object({
754
1391
  repo: repoSchema,
755
- synced: z13.boolean()
1392
+ synced: z20.boolean()
756
1393
  });
757
1394
 
758
1395
  // ../packages/api-schemas/src/runs.ts
759
- import { z as z14 } from "zod";
1396
+ import { z as z21 } from "zod";
760
1397
  var RUN_STATUSES = [
761
1398
  "QUEUED",
762
1399
  "CLAIMED",
@@ -767,102 +1404,178 @@ var RUN_STATUSES = [
767
1404
  "TIMED_OUT",
768
1405
  "CANCELED"
769
1406
  ];
770
- var runStatusSchema = z14.enum(RUN_STATUSES);
1407
+ var runStatusSchema = z21.enum(RUN_STATUSES);
771
1408
  var AGENTS2 = ["CLAUDE_CODE", "CODEX_CLI", "CURSOR"];
772
- var agentSchema2 = z14.enum(AGENTS2);
773
- var runStatusFilterSchema = z14.string().transform(
1409
+ var agentSchema2 = z21.enum(AGENTS2);
1410
+ var runStatusFilterSchema = z21.string().transform(
774
1411
  (raw) => raw.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean)
775
- ).pipe(z14.array(runStatusSchema).min(1));
1412
+ ).pipe(z21.array(runStatusSchema).min(1));
776
1413
  var runListQuerySchema = listQuerySchema.extend({
777
1414
  status: runStatusFilterSchema.optional(),
778
- batch: z14.string().optional(),
779
- prompt: z14.string().optional(),
780
- experiment: z14.string().optional(),
781
- since: z14.string().optional()
1415
+ batch: z21.string().optional(),
1416
+ prompt: z21.string().optional(),
1417
+ experiment: z21.string().optional(),
1418
+ since: z21.string().optional()
782
1419
  });
783
- var runListItemSchema = z14.object({
784
- id: z14.string(),
1420
+ var runListItemSchema = z21.object({
1421
+ id: z21.string(),
785
1422
  status: runStatusSchema,
786
1423
  agent: agentSchema2,
787
- model: z14.string(),
788
- promptId: z14.string(),
1424
+ model: z21.string(),
1425
+ promptId: z21.string(),
789
1426
  /** First ~80 chars of the batch's prompt snapshot, whitespace-collapsed. */
790
- promptSnippet: z14.string(),
791
- batchId: z14.string(),
792
- experiment: z14.string().nullable(),
793
- turns: z14.number().int().nullable(),
794
- usdCost: z14.number().nullable(),
795
- durationMs: z14.number().int().nullable(),
796
- exitReason: z14.string().nullable(),
797
- createdAt: z14.string(),
798
- startedAt: z14.string().nullable(),
799
- finishedAt: z14.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()
800
1445
  });
801
1446
  var runListResponseSchema = listResponseSchema(runListItemSchema);
802
1447
  var runDetailSchema = runListItemSchema.omit({ promptSnippet: true }).extend({
803
- promptText: z14.string(),
804
- attempt: z14.number().int(),
805
- cancelRequested: z14.boolean(),
806
- failureReason: z14.string().nullable(),
807
- repoUrl: z14.string().nullable(),
808
- repoRef: z14.string().nullable(),
809
- scenario: z14.string(),
810
- funding: z14.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(),
811
1456
  /** Raw harness usage write-back (token counts etc.); shape may evolve. */
812
- usage: z14.unknown().nullable(),
1457
+ usage: z21.unknown().nullable(),
813
1458
  /** Artifact pointer: a working-tree diff exists at GET /runs/{id}/diff. */
814
- hasDiff: z14.boolean(),
815
- claimedAt: z14.string().nullable()
1459
+ hasDiff: z21.boolean(),
1460
+ claimedAt: z21.string().nullable()
816
1461
  });
817
- var cancelRunResponseSchema = z14.object({
818
- id: z14.string(),
1462
+ var cancelRunResponseSchema = z21.object({
1463
+ id: z21.string(),
819
1464
  status: runStatusSchema,
820
- cancelRequested: z14.boolean(),
821
- note: z14.string().optional()
822
- });
823
- var forkRunBodySchema = z14.object({
824
- prompt: z14.string().trim().min(1).max(2e4),
825
- turn: z14.number().int().min(0).optional()
826
- });
827
- var forkRunResponseSchema = z14.object({
828
- runId: z14.string(),
829
- batchId: z14.string(),
830
- parentRunId: z14.string(),
831
- checkpointId: z14.string(),
832
- turn: z14.number().int().min(0)
833
- });
834
- var runEventSchema = z14.looseObject({
835
- run_id: z14.string(),
836
- seq: z14.number(),
837
- turn: z14.number(),
838
- ts: z14.string(),
839
- type: z14.string()
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()
1472
+ });
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)
1479
+ });
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())
1505
+ });
1506
+ var RUN_INSIGHT_STATUSES = [
1507
+ "PENDING",
1508
+ "RUNNING",
1509
+ "COMPLETE",
1510
+ "FAILED",
1511
+ "SKIPPED"
1512
+ ];
1513
+ var runInsightStatusSchema = z21.enum(RUN_INSIGHT_STATUSES);
1514
+ var insightPassSchema = z21.object({
1515
+ status: runInsightStatusSchema,
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(),
1542
+ decision: insightPassSchema,
1543
+ implementation: insightPassSchema,
1544
+ decisions: z21.array(runDecisionSchema),
1545
+ implementations: z21.array(runImplementationSchema)
1546
+ });
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()
840
1553
  });
841
1554
 
842
- // ../packages/api-schemas/src/tokens.ts
843
- import { z as z15 } from "zod";
844
- var apiTokenSchema = z15.object({
845
- id: z15.string(),
846
- name: z15.string(),
1555
+ // ../packages/api-schemas/src/tokens.ts
1556
+ import { z as z22 } from "zod";
1557
+ var apiTokenSchema = z22.object({
1558
+ id: z22.string(),
1559
+ name: z22.string(),
847
1560
  /** Last 4 chars of the plaintext, for recognizability (non-secret). */
848
- last4: z15.string(),
849
- expiresAt: z15.iso.datetime().nullable(),
850
- lastUsedAt: z15.iso.datetime().nullable(),
851
- createdAt: z15.iso.datetime(),
852
- revokedAt: z15.iso.datetime().nullable()
853
- });
854
- var createTokenRequestSchema = z15.object({
855
- name: z15.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),
856
1569
  /** ISO-8601 datetime; omit for no expiry. */
857
- expiresAt: z15.iso.datetime({ offset: true }).optional()
1570
+ expiresAt: z22.iso.datetime({ offset: true }).optional()
858
1571
  });
859
1572
  var createTokenResponseSchema = apiTokenSchema.extend({
860
- token: z15.string()
1573
+ token: z22.string()
861
1574
  });
862
1575
  var listTokensResponseSchema = listResponseSchema(apiTokenSchema);
863
1576
 
864
1577
  // src/commands/apply.ts
865
- import { z as z16 } from "zod";
1578
+ import { z as z23 } from "zod";
866
1579
 
867
1580
  // src/version.ts
868
1581
  import { createRequire } from "module";
@@ -1197,13 +1910,11 @@ var EXAMPLE_SPEC = {
1197
1910
  prompts: [
1198
1911
  {
1199
1912
  key: "add-healthcheck",
1200
- text: "Add a /health endpoint that returns 200 OK.",
1201
- scenario: "GREENFIELD"
1913
+ text: "Add a /health endpoint that returns 200 OK."
1202
1914
  },
1203
1915
  {
1204
1916
  key: "migrate-to-vitest",
1205
1917
  text: "Migrate the test suite from Jest to Vitest.",
1206
- scenario: "MIGRATION",
1207
1918
  schedules: [
1208
1919
  {
1209
1920
  repoUrl: "https://github.com/acme/api",
@@ -1312,7 +2023,7 @@ function register(program2) {
1312
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(
1313
2024
  async (opts, command) => {
1314
2025
  if (opts.schema) {
1315
- printJson(z16.toJSONSchema(batteries_exports.batterySpecSchema));
2026
+ printJson(z23.toJSONSchema(batteries_exports.batterySpecSchema));
1316
2027
  return;
1317
2028
  }
1318
2029
  if (opts.example) {
@@ -1349,12 +2060,17 @@ function register(program2) {
1349
2060
  // src/commands/auth.ts
1350
2061
  var auth_exports = {};
1351
2062
  __export(auth_exports, {
2063
+ deviceLogin: () => deviceLogin,
2064
+ parseLoopbackCallback: () => parseLoopbackCallback,
2065
+ readStdin: () => readStdin,
1352
2066
  register: () => register2
1353
2067
  });
1354
2068
  import { spawn } from "child_process";
1355
- import { randomBytes } from "crypto";
2069
+ import { createHash, randomBytes } from "crypto";
1356
2070
  import { createServer } from "http";
1357
2071
  import { hostname } from "os";
2072
+ import { createInterface } from "readline";
2073
+ import { setTimeout as sleep } from "timers/promises";
1358
2074
 
1359
2075
  // src/lib/paginate.ts
1360
2076
  async function fetchAllPages(client, path, query = {}) {
@@ -1375,7 +2091,6 @@ async function fetchAllPages(client, path, query = {}) {
1375
2091
  // src/commands/auth.ts
1376
2092
  var LOGIN_TIMEOUT_MS = 2 * 60 * 1e3;
1377
2093
  var TOKEN_PREFIX = "gauge_";
1378
- var MAX_CALLBACK_BODY_BYTES = 16 * 1024;
1379
2094
  function tokenSource() {
1380
2095
  if (process.env.GAUGE_API_TOKEN?.trim()) return "env";
1381
2096
  return resolveToken() ? "file" : "none";
@@ -1383,6 +2098,13 @@ function tokenSource() {
1383
2098
  async function fetchMe(client) {
1384
2099
  return client.get("/api/v1/me");
1385
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
+ }
1386
2108
  function printIdentity(me) {
1387
2109
  const orgs = me.orgs.map((o) => o.slug).join(", ") || "(none)";
1388
2110
  const su = me.user.isSuperuser ? " (superuser)" : "";
@@ -1404,63 +2126,33 @@ function openBrowser(url) {
1404
2126
  }
1405
2127
  async function browserLogin() {
1406
2128
  const state = randomBytes(16).toString("base64url");
2129
+ const codeVerifier = randomBytes(32).toString("base64url");
2130
+ const codeChallenge = createHash("sha256").update(codeVerifier).digest("base64url");
1407
2131
  const server = createServer();
1408
- const tokenPromise = new Promise((resolve, reject) => {
2132
+ const codePromise = new Promise((resolve, reject) => {
1409
2133
  server.on("request", (req, res) => {
1410
2134
  const url = new URL(req.url ?? "/", "http://127.0.0.1");
1411
2135
  if (url.pathname !== "/callback") {
1412
2136
  res.writeHead(404).end();
1413
2137
  return;
1414
2138
  }
1415
- if (req.method === "OPTIONS") {
1416
- res.writeHead(204, {
1417
- "access-control-allow-origin": "*",
1418
- "access-control-allow-methods": "POST",
1419
- "access-control-allow-headers": "content-type",
1420
- "access-control-allow-private-network": "true"
1421
- }).end();
2139
+ if (req.method !== "GET") {
2140
+ res.writeHead(405, { allow: "GET" }).end();
1422
2141
  return;
1423
2142
  }
1424
- if (req.method !== "POST") {
1425
- 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.");
1426
2149
  return;
1427
2150
  }
1428
- let body = "";
1429
- let overflowed = false;
1430
- req.on("data", (chunk) => {
1431
- if (overflowed) return;
1432
- body += chunk;
1433
- if (body.length > MAX_CALLBACK_BODY_BYTES) {
1434
- overflowed = true;
1435
- body = "";
1436
- res.writeHead(413, {
1437
- "content-type": "text/plain; charset=utf-8",
1438
- "access-control-allow-origin": "*"
1439
- });
1440
- res.end("Callback body too large.");
1441
- }
1442
- });
1443
- req.on("end", () => {
1444
- if (overflowed) return;
1445
- const params = new URLSearchParams(body);
1446
- const token = params.get("token");
1447
- if (params.get("state") !== state || !token) {
1448
- res.writeHead(400, {
1449
- "content-type": "text/plain; charset=utf-8",
1450
- "access-control-allow-origin": "*"
1451
- });
1452
- res.end(
1453
- "Invalid callback (state mismatch). Retry `gauge auth login`."
1454
- );
1455
- return;
1456
- }
1457
- res.writeHead(200, {
1458
- "content-type": "text/plain; charset=utf-8",
1459
- "access-control-allow-origin": "*"
1460
- });
1461
- res.end("Authorized \u2014 return to your terminal.");
1462
- resolve(token);
2151
+ res.writeHead(200, {
2152
+ "content-type": "text/plain; charset=utf-8"
1463
2153
  });
2154
+ res.end("Authorized. Return to your terminal.");
2155
+ resolve(code);
1464
2156
  });
1465
2157
  server.on(
1466
2158
  "error",
@@ -1480,27 +2172,46 @@ async function browserLogin() {
1480
2172
  authorizeUrl.searchParams.set("port", String(address.port));
1481
2173
  authorizeUrl.searchParams.set("state", state);
1482
2174
  authorizeUrl.searchParams.set("name", hostname() || "this device");
2175
+ authorizeUrl.searchParams.set("code_challenge", codeChallenge);
2176
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
1483
2177
  console.log("Opening your browser to authorize the Gauge CLI\u2026");
1484
2178
  console.log(`If it doesn't open, visit:
1485
2179
 
1486
2180
  ${authorizeUrl}
1487
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
+ );
1488
2186
  openBrowser(authorizeUrl.toString());
1489
2187
  let timer;
1490
2188
  try {
1491
- const token = await Promise.race([
1492
- tokenPromise,
2189
+ const code = await Promise.race([
2190
+ codePromise,
1493
2191
  new Promise((_, reject) => {
1494
2192
  timer = setTimeout(() => {
1495
2193
  reject(
1496
2194
  new CliError(
1497
2195
  "network",
1498
- "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."
1499
2197
  )
1500
2198
  );
1501
2199
  }, LOGIN_TIMEOUT_MS);
1502
2200
  })
1503
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;
1504
2215
  const me = await fetchMe(new ApiClient({ token }));
1505
2216
  saveToken(token);
1506
2217
  console.log(`Token saved to ${credentialsPath()}`);
@@ -1511,14 +2222,140 @@ async function browserLogin() {
1511
2222
  server.closeAllConnections();
1512
2223
  }
1513
2224
  }
1514
- async function readStdin() {
2225
+ var DEVICE_ENDPOINT = "/api/v1/device";
2226
+ async function bootstrapPost(path, body) {
2227
+ const base = resolveBaseUrl().replace(/\/+$/, "");
2228
+ let res;
2229
+ try {
2230
+ res = await fetch(`${base}${path}`, {
2231
+ method: "POST",
2232
+ headers: {
2233
+ "Content-Type": "application/json",
2234
+ Accept: "application/json",
2235
+ "User-Agent": USER_AGENT
2236
+ },
2237
+ body: JSON.stringify(body)
2238
+ });
2239
+ } catch (e) {
2240
+ throw new CliError(
2241
+ "network",
2242
+ `Request to ${base} failed: ${e instanceof Error ? e.message : String(e)}`
2243
+ );
2244
+ }
2245
+ const text = await res.text();
2246
+ if (!res.ok) {
2247
+ try {
2248
+ const parsed = errorEnvelopeSchema.safeParse(JSON.parse(text));
2249
+ if (parsed.success) {
2250
+ throw new CliError(parsed.data.error.code, parsed.data.error.message);
2251
+ }
2252
+ } catch (e) {
2253
+ if (e instanceof CliError) throw e;
2254
+ }
2255
+ throw new CliError(
2256
+ "internal",
2257
+ `Authentication request failed: HTTP ${res.status} ${res.statusText}`.trim()
2258
+ );
2259
+ }
2260
+ return JSON.parse(text);
2261
+ }
2262
+ async function deviceLogin(opts) {
2263
+ const start = await bootstrapPost(
2264
+ `${DEVICE_ENDPOINT}/authorize`,
2265
+ { deviceName: hostname() || "this device", email: opts.email }
2266
+ );
2267
+ console.log("To sign in, open this URL in a browser:\n");
2268
+ console.log(` ${start.verificationUriComplete}
2269
+ `);
2270
+ console.log(`and confirm this code: ${start.userCode}
2271
+ `);
2272
+ if (start.emailSent && opts.email) {
2273
+ console.log(`We also emailed a sign-in link to ${opts.email}.`);
2274
+ }
2275
+ console.log("Waiting for you to approve in the browser\u2026");
2276
+ openBrowser(start.verificationUriComplete);
2277
+ const deadline = Date.now() + start.expiresIn * 1e3;
2278
+ const MAX_TRANSIENT = 5;
2279
+ let interval = start.interval;
2280
+ let transient = 0;
2281
+ while (Date.now() < deadline) {
2282
+ await sleep(interval * 1e3);
2283
+ let raw;
2284
+ try {
2285
+ raw = await bootstrapPost(`${DEVICE_ENDPOINT}/token`, {
2286
+ deviceCode: start.deviceCode
2287
+ });
2288
+ } catch (e) {
2289
+ if (e instanceof CliError && (e.code === "network" || e.code === "internal") && ++transient <= MAX_TRANSIENT) {
2290
+ continue;
2291
+ }
2292
+ throw e;
2293
+ }
2294
+ transient = 0;
2295
+ const parsed = deviceTokenResultSchema.safeParse(raw);
2296
+ if (!parsed.success) {
2297
+ throw new CliError(
2298
+ "internal",
2299
+ "Unexpected response from the device token endpoint."
2300
+ );
2301
+ }
2302
+ const result = parsed.data;
2303
+ switch (result.status) {
2304
+ case "pending":
2305
+ continue;
2306
+ case "slow_down":
2307
+ interval = result.interval;
2308
+ continue;
2309
+ case "denied":
2310
+ throw new CliError(
2311
+ "unauthorized",
2312
+ "Authorization was denied in the browser."
2313
+ );
2314
+ case "expired":
2315
+ throw new CliError(
2316
+ "unauthorized",
2317
+ "The sign-in request expired before it was approved. Re-run it to try again."
2318
+ );
2319
+ case "approved": {
2320
+ const token = result.accessToken;
2321
+ try {
2322
+ const me = await fetchMe(new ApiClient({ token }));
2323
+ return { token, me };
2324
+ } catch (e) {
2325
+ throw new CliError(
2326
+ "network",
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.`
2328
+ );
2329
+ }
2330
+ }
2331
+ default:
2332
+ throw new CliError(
2333
+ "internal",
2334
+ `Unexpected device authorization status: ${result.status}`
2335
+ );
2336
+ }
2337
+ }
2338
+ throw new CliError(
2339
+ "network",
2340
+ "Timed out waiting for browser approval. Re-run to try again."
2341
+ );
2342
+ }
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
+ }
1515
2352
  let data = "";
1516
- for await (const chunk of process.stdin) data += chunk;
2353
+ for await (const chunk of input) data += chunk;
1517
2354
  return data;
1518
2355
  }
1519
2356
  async function withTokenLogin() {
1520
2357
  if (process.stdin.isTTY) {
1521
- console.error("Paste your API token, then press Enter and Ctrl-D:");
2358
+ console.error("Paste your API token, then press Enter:");
1522
2359
  }
1523
2360
  const token = (await readStdin()).trim();
1524
2361
  if (!token.startsWith(TOKEN_PREFIX)) {
@@ -1578,10 +2415,35 @@ async function whoami(output) {
1578
2415
  }
1579
2416
  function register2(program2) {
1580
2417
  const auth = program2.command("auth").description("Authenticate the CLI (personal access tokens)");
1581
- auth.command("login").description("Log in via the browser (localhost callback flow)").option("--with-token", "read a token from stdin (headless machines)").action(async (opts) => {
1582
- if (opts.withToken) await withTokenLogin();
1583
- else await browserLogin();
1584
- });
2418
+ auth.command("login").description("Log in via your browser (localhost callback flow)").option("--with-token", "read a token from stdin (headless machines)").option(
2419
+ "--device",
2420
+ "use a device code instead (no local network access required)"
2421
+ ).option(
2422
+ "--email <email>",
2423
+ "with --device: also email a sign-in link to this address"
2424
+ ).action(
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
+ }
2435
+ if (opts.device) {
2436
+ const { token, me } = await deviceLogin({ email: opts.email });
2437
+ saveToken(token);
2438
+ console.log(`Token saved to ${credentialsPath()}`);
2439
+ printIdentity(me);
2440
+ } else if (opts.withToken) {
2441
+ await withTokenLogin();
2442
+ } else {
2443
+ await browserLogin();
2444
+ }
2445
+ }
2446
+ );
1585
2447
  auth.command("logout").description("Remove the stored token").action(() => {
1586
2448
  clearToken();
1587
2449
  console.log(`Removed ${credentialsPath()}`);
@@ -2057,15 +2919,95 @@ function register7(program2) {
2057
2919
  });
2058
2920
  }
2059
2921
 
2060
- // src/commands/orgs.ts
2061
- var orgs_exports = {};
2062
- __export(orgs_exports, {
2922
+ // src/commands/onboard.ts
2923
+ var onboard_exports = {};
2924
+ __export(onboard_exports, {
2063
2925
  register: () => register8
2064
2926
  });
2927
+ function orgNameFromEmail(email) {
2928
+ const domain = email?.split("@")[1] ?? "";
2929
+ const base = domain.split(".")[0] ?? "";
2930
+ if (!base) return "My Workspace";
2931
+ return base.charAt(0).toUpperCase() + base.slice(1);
2932
+ }
2933
+ function register8(program2) {
2934
+ program2.command("onboard").description(
2935
+ "Self-serve onboarding: sign in (device flow) and create your first workspace"
2936
+ ).option("--email <email>", "email a sign-in link (device-flow convenience)").option("--org-name <name>", "workspace name (default: from your email)").option("--website <url>", "company site (logo source)").option("--new", "create a new workspace even if you already belong to one").action(
2937
+ async (opts, command) => {
2938
+ const output = resolveOutput(command);
2939
+ let client;
2940
+ let me;
2941
+ if (resolveToken()) {
2942
+ client = new ApiClient();
2943
+ me = await client.get("/api/v1/me");
2944
+ if (output !== "json") {
2945
+ console.log(`Already signed in as ${me.user.email ?? me.user.id}.`);
2946
+ }
2947
+ } else {
2948
+ const login = await deviceLogin({ email: opts.email });
2949
+ saveToken(login.token);
2950
+ me = login.me;
2951
+ client = new ApiClient({ token: login.token });
2952
+ if (output !== "json") {
2953
+ console.log(
2954
+ `
2955
+ Signed in as ${me.user.email ?? me.user.id} \u2014 token saved to ${credentialsPath()}.`
2956
+ );
2957
+ }
2958
+ }
2959
+ const wantNewOrg = opts.new === true || opts.orgName !== void 0 || me.orgs.length === 0;
2960
+ let orgSlug;
2961
+ let createdOrg = null;
2962
+ if (wantNewOrg) {
2963
+ const name = opts.orgName?.trim() || orgNameFromEmail(me.user.email);
2964
+ createdOrg = await client.post("/api/v1/orgs", {
2965
+ name,
2966
+ website: opts.website
2967
+ });
2968
+ orgSlug = createdOrg.slug;
2969
+ } else {
2970
+ orgSlug = readConfig().defaultOrg ?? me.orgs[0]?.slug ?? "";
2971
+ if (!orgSlug) {
2972
+ throw new CliError(
2973
+ "internal",
2974
+ "No workspace available; re-run with --org-name to create one."
2975
+ );
2976
+ }
2977
+ }
2978
+ updateConfig({ defaultOrg: orgSlug });
2979
+ if (output === "json") {
2980
+ printJson({
2981
+ user: me.user,
2982
+ org: createdOrg ?? { slug: orgSlug },
2983
+ defaultOrg: orgSlug
2984
+ });
2985
+ return;
2986
+ }
2987
+ console.log(
2988
+ createdOrg ? `
2989
+ Created workspace ${createdOrg.name} (${orgSlug}).` : `
2990
+ Using workspace ${orgSlug}.`
2991
+ );
2992
+ console.log(`Default org set to ${orgSlug}. You're ready:`);
2993
+ console.log(
2994
+ " gauge apply --example > battery.json # scaffold a run"
2995
+ );
2996
+ console.log(" gauge apply -f battery.json # launch it");
2997
+ console.log(" gauge runs list # watch results");
2998
+ }
2999
+ );
3000
+ }
3001
+
3002
+ // src/commands/orgs.ts
3003
+ var orgs_exports2 = {};
3004
+ __export(orgs_exports2, {
3005
+ register: () => register9
3006
+ });
2065
3007
  function isDefault(org, defaultOrg) {
2066
3008
  return defaultOrg !== void 0 && (org.slug === defaultOrg || org.publicId === defaultOrg);
2067
3009
  }
2068
- function register8(program2) {
3010
+ function register9(program2) {
2069
3011
  const orgs = program2.command("orgs").description("Organizations");
2070
3012
  orgs.command("list").description("List orgs you belong to").action(async (_opts, command) => {
2071
3013
  const output = resolveOutput(command);
@@ -2090,6 +3032,23 @@ function register8(program2) {
2090
3032
  "table"
2091
3033
  );
2092
3034
  });
3035
+ orgs.command("create <name>").description("Create a new LOCAL workspace and set it as the default org").option("--website <url>", "company site (used as the logo source)").option("--no-use", "don't set the new org as the default").action(
3036
+ async (name, opts, command) => {
3037
+ const created = await createClient().post(
3038
+ "/api/v1/orgs",
3039
+ { name, website: opts.website }
3040
+ );
3041
+ if (opts.use !== false) updateConfig({ defaultOrg: created.slug });
3042
+ if (resolveOutput(command) === "json") {
3043
+ printJson(created);
3044
+ return;
3045
+ }
3046
+ console.log(`Created workspace ${created.name} (${created.slug})`);
3047
+ if (opts.use !== false) {
3048
+ console.log(`Default org set to ${created.slug}`);
3049
+ }
3050
+ }
3051
+ );
2093
3052
  orgs.command("use <org>").description("Set the default org (slug or public id) in local config").action(async (org, _opts, command) => {
2094
3053
  const me = await createClient().get("/api/v1/me");
2095
3054
  const match = me.orgs.find((o) => o.slug === org || o.publicId === org);
@@ -2120,9 +3079,11 @@ function register8(program2) {
2120
3079
  var prompts_exports2 = {};
2121
3080
  __export(prompts_exports2, {
2122
3081
  parseAgents: () => parseAgents,
3082
+ parseSamples: () => parseSamples,
2123
3083
  promptsPath: () => promptsPath,
2124
3084
  readPromptText: () => readPromptText,
2125
- register: () => register9,
3085
+ readWebFixture: () => readWebFixture,
3086
+ register: () => register10,
2126
3087
  resolveOrCreateTopicId: () => resolveOrCreateTopicId
2127
3088
  });
2128
3089
  import { readFileSync as readFileSync4 } from "fs";
@@ -2167,6 +3128,38 @@ function readPromptText(opts) {
2167
3128
  if (!text) throw new CliError("usage", "prompt file is empty");
2168
3129
  return text;
2169
3130
  }
3131
+ function readWebFixture(path) {
3132
+ let raw;
3133
+ try {
3134
+ raw = readFileSync4(path, "utf8");
3135
+ } catch (error) {
3136
+ throw new CliError(
3137
+ "usage",
3138
+ "cannot read web fixture " + path + ": " + (error instanceof Error ? error.message : String(error))
3139
+ );
3140
+ }
3141
+ let parsed;
3142
+ try {
3143
+ parsed = JSON.parse(raw);
3144
+ } catch (error) {
3145
+ throw new CliError(
3146
+ "invalid_request",
3147
+ "web fixture is not valid JSON: " + (error instanceof Error ? error.message : String(error))
3148
+ );
3149
+ }
3150
+ const result = web_fixtures_exports.webFixtureSchema.safeParse(parsed);
3151
+ if (!result.success) {
3152
+ const details = result.error.issues.map(
3153
+ (issue) => ` ${issue.path.join(".") || "(fixture)"}: ${issue.message}`
3154
+ ).join("\n");
3155
+ throw new CliError(
3156
+ "invalid_request",
3157
+ `not a valid web fixture:
3158
+ ${details}`
3159
+ );
3160
+ }
3161
+ return result.data;
3162
+ }
2170
3163
  async function resolveOrCreateTopicId(client, org, name) {
2171
3164
  const path = `/api/v1/orgs/${encodeURIComponent(org)}/topics`;
2172
3165
  let cursor;
@@ -2197,19 +3190,20 @@ function toRow2(p) {
2197
3190
  topic: p.topic?.name ?? "",
2198
3191
  tags: p.tags.map((t) => t.name).join(", "),
2199
3192
  schedules: p.scheduleCount,
2200
- branded: p.isBranded ? "yes" : "",
2201
- scenario: p.scenario
3193
+ branded: p.isBranded ? "yes" : ""
2202
3194
  };
2203
3195
  }
2204
- var BLOCK_WARNINGS = {
2205
- insufficient_credits: "warning: prompt created, but the first run was blocked: out of credits",
2206
- needs_provider_key: "warning: prompt created, but the first run was blocked: no provider key for the selected agents"
2207
- };
2208
- var RUN_BLOCK_WARNINGS = {
2209
- insufficient_credits: "warning: some schedules were skipped or truncated: out of credits",
2210
- needs_provider_key: "warning: some schedules were skipped: no provider key for the selected agents"
2211
- };
2212
- function register9(program2) {
3196
+ var DEFAULT_RUN_AGENTS = ["CLAUDE_CODE", "CODEX_CLI"];
3197
+ function parseSamples(raw, max) {
3198
+ const n = Number(raw);
3199
+ if (!Number.isInteger(n) || n < 1 || max !== void 0 && n > max)
3200
+ throw new CliError(
3201
+ "usage",
3202
+ max === void 0 ? "--samples must be an integer >= 1" : `--samples must be an integer 1-${max}`
3203
+ );
3204
+ return n;
3205
+ }
3206
+ function register10(program2) {
2213
3207
  const group = program2.command("prompts").description("Manage prompts");
2214
3208
  group.command("list").description("List prompts").option("--topic <topic>", "filter by topic (id or name)").option("--tag <tag>", "filter by tag (id or name)").option("-q, --query <text>", "text search").action(
2215
3209
  async (opts, cmd) => {
@@ -2223,7 +3217,7 @@ function register9(program2) {
2223
3217
  else printItems(items.map(toRow2), "table");
2224
3218
  }
2225
3219
  );
2226
- group.command("get <id>").description("Show a prompt (schedules, topic, tags)").action(async (id, _opts, cmd) => {
3220
+ group.command("get <id>").description("Show a prompt (scheduled-via, topic, tags)").action(async (id, _opts, cmd) => {
2227
3221
  const org = resolveOrg(cmd);
2228
3222
  const prompt = await createClient().get(
2229
3223
  `${promptsPath(org)}/${encodeURIComponent(id)}`
@@ -2233,7 +3227,6 @@ function register9(program2) {
2233
3227
  return;
2234
3228
  }
2235
3229
  console.log(`id: ${prompt.id}`);
2236
- console.log(`scenario: ${prompt.scenario}`);
2237
3230
  console.log(`branded: ${prompt.isBranded}`);
2238
3231
  console.log(`topic: ${prompt.topic?.name ?? "-"}`);
2239
3232
  console.log(
@@ -2242,23 +3235,22 @@ function register9(program2) {
2242
3235
  console.log(`created: ${prompt.createdAt}`);
2243
3236
  console.log(`text: ${prompt.text}`);
2244
3237
  if (prompt.schedules.length) {
2245
- console.log("schedules:");
3238
+ console.log("scheduled via:");
2246
3239
  printItems(
2247
3240
  prompt.schedules.map((s) => ({
2248
3241
  id: s.id,
2249
- repo: s.repoUrl ?? "(default scaffold)",
2250
- ref: s.repoRef ?? "",
3242
+ name: s.name,
2251
3243
  cadence: s.cadence,
2252
3244
  days: s.daysPerWeek ?? "",
2253
- agents: s.agents.join(", ")
3245
+ enabled: s.enabled ? "yes" : "no"
2254
3246
  })),
2255
3247
  "table"
2256
3248
  );
2257
3249
  } else {
2258
- console.log("schedules: (none)");
3250
+ console.log("scheduled via: (none)");
2259
3251
  }
2260
3252
  });
2261
- 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(
2262
3254
  "--tag <name>",
2263
3255
  "tag name (repeatable; created if new)",
2264
3256
  collect2,
@@ -2266,18 +3258,10 @@ function register9(program2) {
2266
3258
  ).action(
2267
3259
  async (opts, cmd) => {
2268
3260
  const org = resolveOrg(cmd);
2269
- const scenario = opts.scenario.trim().toUpperCase();
2270
- if (scenario !== "GREENFIELD" && scenario !== "MIGRATION") {
2271
- throw new CliError(
2272
- "usage",
2273
- `invalid --scenario "${opts.scenario}" (expected: greenfield | migration)`
2274
- );
2275
- }
2276
3261
  const created = await createClient().post(
2277
3262
  promptsPath(org),
2278
3263
  {
2279
3264
  text: readPromptText(opts),
2280
- scenario,
2281
3265
  isBranded: opts.branded ?? false,
2282
3266
  topic: opts.topic,
2283
3267
  tags: opts.tag
@@ -2286,12 +3270,11 @@ function register9(program2) {
2286
3270
  if (resolveOutput(cmd) === "json") printJson(created);
2287
3271
  else {
2288
3272
  console.log(`Created prompt ${created.id}`);
3273
+ const firstTag = created.tags[0];
2289
3274
  console.log(
2290
- `No schedules yet \u2014 add one with \`gauge schedules add --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>\`)`)
2291
3276
  );
2292
3277
  }
2293
- if (created.firstRunBlocked)
2294
- console.error(BLOCK_WARNINGS[created.firstRunBlocked]);
2295
3278
  }
2296
3279
  );
2297
3280
  group.command("edit <id>").description("Update a prompt").option("--text <text>", "new prompt text").option("--file <path>", 'read new text from a file ("-" for stdin)').option("--branded <bool>", "true | false").option("--topic <name>", "set the topic (created if new)").option("--clear-topic", "clear the topic").option(
@@ -2337,19 +3320,27 @@ function register9(program2) {
2337
3320
  );
2338
3321
  if (resolveOutput(cmd) !== "json") console.log(`Deleted prompt ${id}`);
2339
3322
  });
2340
- group.command("run <id>").description("Run a prompt now (ORG funding, credit-gated)").option(
3323
+ group.command("run <id>").description(
3324
+ "Run a prompt now \u2014 an ad-hoc agents x repo x samples spec (ORG funding, credit-gated)"
3325
+ ).option(
2341
3326
  "--agent <agents>",
2342
- "comma-separated agents, e.g. claude-code,codex"
2343
- ).option("--schedule <ids>", "comma-separated schedule ids").action(
3327
+ "comma-separated agents, e.g. claude-code,codex (default: claude-code,codex)"
3328
+ ).option("--repo <url>", "base repo to run against (default: the scaffold)").option("--ref <ref>", "branch, tag, or commit (with --repo)").option("--samples <n>", "samples per agent, 1-10 (default: 1)").option(
3329
+ "--web-fixture <path>",
3330
+ "web fixture JSON; pages are injected transparently into native WebFetch (misses pass through live)"
3331
+ ).action(
2344
3332
  async (id, opts, cmd) => {
2345
3333
  const org = resolveOrg(cmd);
2346
- const body = {};
2347
- if (opts.agent !== void 0) body.agents = parseAgents(opts.agent);
2348
- if (opts.schedule !== void 0) {
2349
- const ids = opts.schedule.split(",").map((s) => s.trim()).filter(Boolean);
2350
- if (ids.length === 0)
2351
- throw new CliError("usage", "no schedule ids given");
2352
- body.scheduleIds = ids;
3334
+ if (opts.ref !== void 0 && opts.repo === void 0)
3335
+ throw new CliError("usage", "--ref requires --repo");
3336
+ const body = {
3337
+ agents: opts.agent !== void 0 ? parseAgents(opts.agent) : DEFAULT_RUN_AGENTS,
3338
+ samplesPerCycle: opts.samples !== void 0 ? parseSamples(opts.samples, 10) : 1
3339
+ };
3340
+ if (opts.repo !== void 0) body.repoUrl = opts.repo;
3341
+ if (opts.ref !== void 0) body.repoRef = opts.ref;
3342
+ if (opts.webFixture !== void 0) {
3343
+ body.webFixture = readWebFixture(opts.webFixture);
2353
3344
  }
2354
3345
  const result = await createClient().post(
2355
3346
  `${promptsPath(org)}/${encodeURIComponent(id)}/run`,
@@ -2360,16 +3351,13 @@ function register9(program2) {
2360
3351
  return;
2361
3352
  }
2362
3353
  if (result.runIds.length === 0) {
2363
- console.log(
2364
- "No runs enqueued (the prompt has no matching schedules)"
2365
- );
3354
+ console.log("No runs enqueued");
2366
3355
  return;
2367
3356
  }
2368
3357
  console.log(
2369
3358
  `Enqueued ${result.runIds.length} run(s) in ${result.batchIds.length} batch(es)`
2370
3359
  );
2371
3360
  for (const runId of result.runIds) console.log(runId);
2372
- if (result.blocked) console.error(RUN_BLOCK_WARNINGS[result.blocked]);
2373
3361
  console.error("Tip: `gauge runs watch <id>` streams a run live");
2374
3362
  }
2375
3363
  );
@@ -2378,7 +3366,7 @@ function register9(program2) {
2378
3366
  // src/commands/query.ts
2379
3367
  var query_exports2 = {};
2380
3368
  __export(query_exports2, {
2381
- register: () => register10
3369
+ register: () => register11
2382
3370
  });
2383
3371
  var collect3 = (value, prev = []) => [
2384
3372
  ...prev,
@@ -2571,7 +3559,7 @@ async function showMetadata(command, mode, dataset) {
2571
3559
  console.error(`dataset: ${ds.name} \u2014 ${ds.grain}`);
2572
3560
  printItems(rows, "table");
2573
3561
  }
2574
- function register10(program2) {
3562
+ function register11(program2) {
2575
3563
  const group = program2.command("query").description(
2576
3564
  "Flexible reports over your event warehouse (run a report, or discover the catalog)"
2577
3565
  );
@@ -2607,7 +3595,7 @@ function register10(program2) {
2607
3595
  // src/commands/repos.ts
2608
3596
  var repos_exports2 = {};
2609
3597
  __export(repos_exports2, {
2610
- register: () => register11
3598
+ register: () => register12
2611
3599
  });
2612
3600
  function reposPath(org) {
2613
3601
  return `/api/v1/orgs/${encodeURIComponent(org)}/repos`;
@@ -2630,7 +3618,7 @@ function toRow3(repo) {
2630
3618
  function syncWarning(repo) {
2631
3619
  return `warning: GitHub metadata sync failed; retry with \`gauge repos resync ${repo.url}\``;
2632
3620
  }
2633
- function register11(program2) {
3621
+ function register12(program2) {
2634
3622
  const repos = program2.command("repos").description("Manage repositories");
2635
3623
  repos.command("list").description("List repositories (yours + read-only Gauge-provided ones)").action(async (_opts, command) => {
2636
3624
  const org = resolveOrg(command);
@@ -2694,7 +3682,7 @@ function register11(program2) {
2694
3682
  // src/commands/runs.ts
2695
3683
  var runs_exports2 = {};
2696
3684
  __export(runs_exports2, {
2697
- register: () => register12
3685
+ register: () => register13
2698
3686
  });
2699
3687
  function runPath(id) {
2700
3688
  return `/api/v1/runs/${encodeURIComponent(id)}`;
@@ -2757,6 +3745,66 @@ function detailLines(run) {
2757
3745
  ["Finished", run.finishedAt ?? "\u2014"]
2758
3746
  ];
2759
3747
  }
3748
+ function passLine(label, pass) {
3749
+ const bits = [pass.status];
3750
+ if (pass.model) bits.push(pass.model);
3751
+ const cost = fmtUsd(pass.usdCost);
3752
+ if (cost) bits.push(cost);
3753
+ if (pass.error) bits.push(`error: ${compact(pass.error, 60)}`);
3754
+ return `${label.padEnd(20)} ${bits.join(" ")}`;
3755
+ }
3756
+ function decisionVia(detail) {
3757
+ const d = detail;
3758
+ if (typeof d?.source === "string") return d.source;
3759
+ const raw = d?.influences;
3760
+ if (!Array.isArray(raw)) return "";
3761
+ const types = [];
3762
+ for (const inf of raw) {
3763
+ const type = inf?.type;
3764
+ if (typeof type === "string" && !types.includes(type)) types.push(type);
3765
+ }
3766
+ return types.join(", ");
3767
+ }
3768
+ function printInsight(insight) {
3769
+ console.log(passLine("Decision pass", insight.decision));
3770
+ console.log(passLine("Implementation pass", insight.implementation));
3771
+ console.log(`
3772
+ Decisions (${insight.decisions.length})`);
3773
+ if (insight.decisions.length === 0) {
3774
+ console.log(insight.decision.status === "SKIPPED" ? "(skipped)" : "(none)");
3775
+ } else {
3776
+ printItems(
3777
+ insight.decisions.map((d) => ({
3778
+ "#": d.index,
3779
+ arena: d.category === "other" && d.categoryRaw ? d.categoryRaw : d.category,
3780
+ chosen: d.chosenPackage ?? d.chosenName,
3781
+ reversed: d.reversed ? "yes" : "",
3782
+ via: decisionVia(d.detail)
3783
+ })),
3784
+ "table"
3785
+ );
3786
+ }
3787
+ console.log(`
3788
+ Implementation quality (${insight.implementations.length})`);
3789
+ if (insight.implementations.length === 0) {
3790
+ console.log(
3791
+ insight.implementation.status === "SKIPPED" ? "(skipped)" : "(none)"
3792
+ );
3793
+ } else {
3794
+ printItems(
3795
+ insight.implementations.map((it) => ({
3796
+ verdict: it.verdict,
3797
+ brand: it.brandName,
3798
+ package: it.package ?? "",
3799
+ docs: it.docConsulted ? "docs consulted" : ""
3800
+ })),
3801
+ "table"
3802
+ );
3803
+ }
3804
+ if (insight.decisions.length > 0 || insight.implementations.length > 0) {
3805
+ console.error("\n(full detail: rerun with -o json)");
3806
+ }
3807
+ }
2760
3808
  function parseEvent(data) {
2761
3809
  try {
2762
3810
  const parsed = runEventSchema.safeParse(JSON.parse(data));
@@ -2872,7 +3920,7 @@ async function streamRun(id, json, opts) {
2872
3920
  if (drainTimer) clearTimeout(drainTimer);
2873
3921
  }
2874
3922
  }
2875
- function register12(program2) {
3923
+ function register13(program2) {
2876
3924
  const runs = program2.command("runs").description("Inspect and manage runs");
2877
3925
  runs.command("list").description("List runs (newest first)").option("--status <status>", "filter by status, e.g. running,queued").option("--batch <id>", "filter by batch").option("--prompt <id>", "filter by prompt").option("--experiment <experiment>", "filter by experiment label").option("--since <window>", "e.g. 24h, 7d, or an ISO date").option("--limit <n>", "page size (1-200)", "50").option("--cursor <cursor>", "resume from a previous page's nextCursor").action(
2878
3926
  async (opts, command) => {
@@ -2914,6 +3962,18 @@ function register12(program2) {
2914
3962
  console.log(`${label.padEnd(width)} ${value}`);
2915
3963
  }
2916
3964
  });
3965
+ runs.command("insight <id>").description(
3966
+ "Show the run's LLM analysis (decisions + implementation quality)"
3967
+ ).action(async (id, _opts, command) => {
3968
+ const insight = await createClient().get(
3969
+ `${runPath(id)}/insight`
3970
+ );
3971
+ if (resolveOutput(command) === "json") {
3972
+ printJson(insight);
3973
+ return;
3974
+ }
3975
+ printInsight(insight);
3976
+ });
2917
3977
  runs.command("watch <id>").description(
2918
3978
  "Stream normalized trace events live (SSE; exits when the run finishes)"
2919
3979
  ).action(async (id, _opts, command) => {
@@ -2932,6 +3992,10 @@ function register12(program2) {
2932
3992
  });
2933
3993
  runs.command("diff <id>").description("Print the run's working-tree diff to stdout").action(async (id) => {
2934
3994
  const diff = await createClient().get(`${runPath(id)}/diff`);
3995
+ if (!diff) {
3996
+ console.error("(no diff)");
3997
+ return;
3998
+ }
2935
3999
  process.stdout.write(diff);
2936
4000
  });
2937
4001
  runs.command("fork <id>").description("Fork a finished run from its latest conversation checkpoint").requiredOption("--prompt <text>", "continuation prompt for the child run").action(async (id, opts, command) => {
@@ -2966,7 +4030,7 @@ function register12(program2) {
2966
4030
  // src/commands/schedules.ts
2967
4031
  var schedules_exports2 = {};
2968
4032
  __export(schedules_exports2, {
2969
- register: () => register13
4033
+ register: () => register14
2970
4034
  });
2971
4035
  var CADENCE_CHOICES = [
2972
4036
  "none",
@@ -2991,67 +4055,139 @@ function parseDays(raw) {
2991
4055
  throw new CliError("usage", "--days-per-week must be an integer 1-7");
2992
4056
  return n;
2993
4057
  }
4058
+ function collect4(value, previous) {
4059
+ return [...previous, value];
4060
+ }
4061
+ function reposLabel(repos) {
4062
+ if (repos.length === 0) return "(default scaffold)";
4063
+ if (repos.length === 1) {
4064
+ const r = repos[0];
4065
+ if (r.repoUrl === null) return "(default scaffold)";
4066
+ return r.repoRef ? `${r.repoUrl}@${r.repoRef}` : r.repoUrl;
4067
+ }
4068
+ return `${repos.length} repos`;
4069
+ }
4070
+ function reposFromOpts(repo, ref) {
4071
+ return [{ repoUrl: repo, repoRef: ref ?? null }];
4072
+ }
2994
4073
  function toRow5(s) {
2995
4074
  return {
2996
4075
  id: s.id,
2997
- repo: s.repoUrl ?? "(default scaffold)",
2998
- ref: s.repoRef ?? "",
4076
+ name: s.name,
2999
4077
  cadence: s.cadence,
3000
4078
  days: s.daysPerWeek ?? "",
3001
4079
  agents: s.agents.join(", "),
4080
+ repos: reposLabel(s.repos),
4081
+ tags: s.tagCount,
4082
+ enabled: s.enabled ? "yes" : "no",
3002
4083
  experiment: s.experiment ?? ""
3003
4084
  };
3004
4085
  }
3005
- function register13(program2) {
3006
- const group = program2.command("schedules").description("Manage prompt schedules");
3007
- group.command("list").description("List schedules for a prompt").requiredOption("--prompt <id>", "prompt id").action(async (opts, cmd) => {
4086
+ function toRefRow(s) {
4087
+ return {
4088
+ id: s.id,
4089
+ name: s.name,
4090
+ cadence: s.cadence,
4091
+ days: s.daysPerWeek ?? "",
4092
+ enabled: s.enabled ? "yes" : "no"
4093
+ };
4094
+ }
4095
+ var RUN_BLOCK_WARNINGS = {
4096
+ insufficient_credits: "warning: some targets were skipped or truncated: out of credits",
4097
+ needs_provider_key: "warning: some targets were skipped: no provider key for the selected agents"
4098
+ };
4099
+ function register14(program2) {
4100
+ const group = program2.command("schedules").description("Manage org schedules (named prompt sets on a cadence)");
4101
+ group.command("list").description(
4102
+ "List schedules for the org, or (with --prompt) the schedules a prompt is in"
4103
+ ).option("--prompt <id>", "only schedules that contain this prompt").action(async (opts, cmd) => {
3008
4104
  const org = resolveOrg(cmd);
3009
- const res = await createClient().get(
3010
- `${promptsPath(org)}/${encodeURIComponent(opts.prompt)}/schedules`
4105
+ const client = createClient();
4106
+ const json = resolveOutput(cmd) === "json";
4107
+ if (opts.prompt !== void 0) {
4108
+ const res2 = await client.get(
4109
+ `${promptsPath(org)}/${encodeURIComponent(opts.prompt)}/schedules`
4110
+ );
4111
+ if (json) printJson(res2.items);
4112
+ else printItems(res2.items.map(toRefRow), "table");
4113
+ return;
4114
+ }
4115
+ const res = await client.get(
4116
+ `/api/v1/orgs/${encodeURIComponent(org)}/schedules`
3011
4117
  );
3012
- if (resolveOutput(cmd) === "json") printJson(res.items);
4118
+ if (json) printJson(res.items);
3013
4119
  else printItems(res.items.map(toRow5), "table");
3014
4120
  });
3015
- group.command("add").description(
3016
- "Add a schedule (a repo target + cadence + agents) to a prompt"
3017
- ).requiredOption("--prompt <id>", "prompt id").requiredOption(
4121
+ group.command("create").description(
4122
+ "Create an org schedule: a named tag set + agents + cadence + repo"
4123
+ ).requiredOption("--name <name>", "schedule name").requiredOption(
3018
4124
  "--agent <agents>",
3019
4125
  "comma-separated agents, e.g. claude-code,codex"
3020
- ).option("--repo <url>", "repository URL (default: the Gauge scaffold)").option("--ref <ref>", "branch, tag, or commit").option("--cadence <cadence>", CADENCE_CHOICES.join(" | "), "none").option("--days-per-week <n>", "1-7 (with --cadence days-per-week)").action(
4126
+ ).option(
4127
+ "--tag <id>",
4128
+ "membership tag id \u2014 the schedule runs the union of its tags (repeatable)",
4129
+ collect4,
4130
+ []
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(
3021
4132
  async (opts, cmd) => {
3022
4133
  const org = resolveOrg(cmd);
4134
+ if (opts.ref !== void 0 && opts.repo === void 0)
4135
+ throw new CliError("usage", "--ref requires --repo");
3023
4136
  const body = {
4137
+ name: opts.name,
3024
4138
  agents: parseAgents(opts.agent),
3025
4139
  cadence: parseCadence(opts.cadence),
3026
- repoUrl: opts.repo,
3027
- repoRef: opts.ref
4140
+ samplesPerCycle: opts.samples !== void 0 ? parseSamples(opts.samples) : 1,
4141
+ repos: opts.repo !== void 0 ? reposFromOpts(opts.repo, opts.ref) : [],
4142
+ tagIds: opts.tag,
4143
+ enabled: !opts.disabled
3028
4144
  };
3029
4145
  if (opts.daysPerWeek !== void 0)
3030
4146
  body.daysPerWeek = parseDays(opts.daysPerWeek);
4147
+ if (opts.model !== void 0) body.model = opts.model;
3031
4148
  const schedule = await createClient().post(
3032
- `${promptsPath(org)}/${encodeURIComponent(opts.prompt)}/schedules`,
4149
+ `/api/v1/orgs/${encodeURIComponent(org)}/schedules`,
3033
4150
  body
3034
4151
  );
3035
4152
  if (resolveOutput(cmd) === "json") printJson(schedule);
3036
- else console.log(`Added schedule ${schedule.id}`);
4153
+ else console.log(`Created schedule ${schedule.id}`);
3037
4154
  }
3038
4155
  );
3039
- group.command("edit <id>").description("Update a schedule").option("--agent <agents>", "comma-separated agents").option("--repo <url>", "repository URL").option("--clear-repo", "reset to the default scaffold").option("--ref <ref>", "branch, tag, or commit").option("--clear-ref", "reset to the repo's default branch").option("--cadence <cadence>", CADENCE_CHOICES.join(" | ")).option("--days-per-week <n>", "1-7 (with cadence days-per-week)").action(
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)",
4159
+ collect4,
4160
+ []
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(
3040
4162
  async (id, opts, cmd) => {
3041
4163
  const body = {};
4164
+ if (opts.name !== void 0) body.name = opts.name;
3042
4165
  if (opts.agent !== void 0) body.agents = parseAgents(opts.agent);
3043
- if (opts.repo !== void 0 && opts.clearRepo)
3044
- throw new CliError("usage", "--repo and --clear-repo conflict");
3045
- if (opts.clearRepo) body.repoUrl = null;
3046
- else if (opts.repo !== void 0) body.repoUrl = opts.repo;
3047
- if (opts.ref !== void 0 && opts.clearRef)
3048
- throw new CliError("usage", "--ref and --clear-ref conflict");
3049
- if (opts.clearRef) body.repoRef = null;
3050
- else if (opts.ref !== void 0) body.repoRef = opts.ref;
3051
4166
  if (opts.cadence !== void 0)
3052
4167
  body.cadence = parseCadence(opts.cadence);
3053
4168
  if (opts.daysPerWeek !== void 0)
3054
4169
  body.daysPerWeek = parseDays(opts.daysPerWeek);
4170
+ if (opts.samples !== void 0)
4171
+ body.samplesPerCycle = parseSamples(opts.samples);
4172
+ if (opts.model !== void 0 && opts.clearModel)
4173
+ throw new CliError("usage", "--model and --clear-model conflict");
4174
+ if (opts.clearModel) body.model = null;
4175
+ else if (opts.model !== void 0) body.model = opts.model;
4176
+ if (opts.ref !== void 0 && opts.repo === void 0)
4177
+ throw new CliError("usage", "--ref requires --repo");
4178
+ if (opts.repo !== void 0 && opts.clearRepos)
4179
+ throw new CliError("usage", "--repo and --clear-repos conflict");
4180
+ if (opts.clearRepos) body.repos = [];
4181
+ else if (opts.repo !== void 0)
4182
+ body.repos = reposFromOpts(opts.repo, opts.ref);
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;
4187
+ if (opts.enable && opts.disable)
4188
+ throw new CliError("usage", "--enable and --disable conflict");
4189
+ if (opts.enable) body.enabled = true;
4190
+ else if (opts.disable) body.enabled = false;
3055
4191
  if (Object.keys(body).length === 0)
3056
4192
  throw new CliError("usage", "nothing to change");
3057
4193
  const schedule = await createClient().patch(
@@ -3062,6 +4198,34 @@ function register13(program2) {
3062
4198
  else console.log(`Updated schedule ${schedule.id}`);
3063
4199
  }
3064
4200
  );
4201
+ group.command("run <id>").description(
4202
+ "Run a schedule now \u2014 forced expansion of its whole member set (ORG funding, credit-gated)"
4203
+ ).action(async (id, _opts, cmd) => {
4204
+ const result = await createClient().post(
4205
+ `/api/v1/schedules/${encodeURIComponent(id)}/run`,
4206
+ {}
4207
+ );
4208
+ if (resolveOutput(cmd) === "json") {
4209
+ printJson(result);
4210
+ return;
4211
+ }
4212
+ if (result.runIds.length === 0) {
4213
+ console.log(
4214
+ "No runs enqueued (the schedule's tags resolve to no prompts)"
4215
+ );
4216
+ return;
4217
+ }
4218
+ console.log(
4219
+ `Enqueued ${result.runIds.length} run(s) in ${result.batchIds.length} batch(es)`
4220
+ );
4221
+ for (const runId of result.runIds) console.log(runId);
4222
+ if (result.blocked) console.error(RUN_BLOCK_WARNINGS[result.blocked]);
4223
+ for (const nr of result.notReady ?? [])
4224
+ console.error(
4225
+ `warning: skipped ${nr.repoUrl} \u2014 baseline snapshot ${nr.status}`
4226
+ );
4227
+ console.error("Tip: `gauge runs watch <id>` streams a run live");
4228
+ });
3065
4229
  group.command("rm <id>").description("Delete a schedule").action(async (id, _opts, cmd) => {
3066
4230
  await createClient().delete(
3067
4231
  `/api/v1/schedules/${encodeURIComponent(id)}`
@@ -3073,7 +4237,7 @@ function register13(program2) {
3073
4237
  // src/commands/stats.ts
3074
4238
  var stats_exports2 = {};
3075
4239
  __export(stats_exports2, {
3076
- register: () => register14
4240
+ register: () => register15
3077
4241
  });
3078
4242
  function addFilterOptions(cmd) {
3079
4243
  return cmd.option("--prompt <id>", "filter to a single prompt").option("--topic <ids>", "comma-separated topic ids").option("--tag <ids>", "comma-separated tag ids").option("--repo <urls>", "comma-separated base repo urls").option("--language <langs>", "comma-separated repo languages").option("--framework <names>", "comma-separated repo frameworks").option("--size <buckets>", "comma-separated codebase-size buckets").option("--branded", "only branded prompts").option("--unbranded", "only non-branded prompts").option("--limit <n>", "max rows (default 50)").option("--full", "return all rows (up to 1000)");
@@ -3157,7 +4321,7 @@ var domainRow = (r) => ({
3157
4321
  rate: pct2(r.rate),
3158
4322
  requests: r.requests
3159
4323
  });
3160
- function register14(program2) {
4324
+ function register15(program2) {
3161
4325
  const group = program2.command("stats").description("Read-only analytics over your runs");
3162
4326
  addFilterOptions(
3163
4327
  group.command("rankings").description("Brands ranked by install rate")
@@ -3189,12 +4353,12 @@ function register14(program2) {
3189
4353
  // src/commands/tags.ts
3190
4354
  var tags_exports2 = {};
3191
4355
  __export(tags_exports2, {
3192
- register: () => register15
4356
+ register: () => register16
3193
4357
  });
3194
4358
  function tagsPath(org) {
3195
4359
  return `/api/v1/orgs/${encodeURIComponent(org)}/tags`;
3196
4360
  }
3197
- function register15(program2) {
4361
+ function register16(program2) {
3198
4362
  const group = program2.command("tags").description("Manage org tags");
3199
4363
  group.command("list").description("List tags").action(async (_opts, cmd) => {
3200
4364
  const org = resolveOrg(cmd);
@@ -3237,12 +4401,12 @@ function register15(program2) {
3237
4401
  // src/commands/topics.ts
3238
4402
  var topics_exports2 = {};
3239
4403
  __export(topics_exports2, {
3240
- register: () => register16
4404
+ register: () => register17
3241
4405
  });
3242
4406
  function topicsPath(org) {
3243
4407
  return `/api/v1/orgs/${encodeURIComponent(org)}/topics`;
3244
4408
  }
3245
- function register16(program2) {
4409
+ function register17(program2) {
3246
4410
  const group = program2.command("topics").description("Manage org topics");
3247
4411
  group.command("list").description("List topics").action(async (_opts, cmd) => {
3248
4412
  const org = resolveOrg(cmd);
@@ -3263,9 +4427,9 @@ function register16(program2) {
3263
4427
  // src/commands/usage.ts
3264
4428
  var usage_exports = {};
3265
4429
  __export(usage_exports, {
3266
- register: () => register17
4430
+ register: () => register18
3267
4431
  });
3268
- function register17(program2) {
4432
+ function register18(program2) {
3269
4433
  program2.command("usage").description("List credit ledger entries").option("--since <window>", 'e.g. "30d", "24h", or an ISO date').option("--limit <n>", "page size (1-200)", parseLimit, 50).option("--cursor <cursor>", "resume from a previous page's nextCursor").action(
3270
4434
  async (opts, cmd) => {
3271
4435
  const org = resolveOrg(cmd);
@@ -3321,7 +4485,8 @@ program.name("gauge").description(
3321
4485
  );
3322
4486
  for (const group of [
3323
4487
  auth_exports,
3324
- orgs_exports,
4488
+ onboard_exports,
4489
+ orgs_exports2,
3325
4490
  prompts_exports2,
3326
4491
  schedules_exports2,
3327
4492
  repos_exports2,