@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.
- package/dist/index.js +1690 -525
- 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
|
|
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/
|
|
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
|
|
357
|
-
var
|
|
358
|
-
var
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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
|
|
364
|
-
|
|
365
|
-
|
|
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
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
|
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
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
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
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
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
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
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/
|
|
467
|
-
import { z as
|
|
468
|
-
var
|
|
469
|
-
|
|
470
|
-
|
|
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
|
|
473
|
-
|
|
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/
|
|
478
|
-
|
|
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
|
|
561
|
+
import { z as z8 } from "zod";
|
|
533
562
|
|
|
534
563
|
// ../packages/api-schemas/src/stats.ts
|
|
535
|
-
import { z as
|
|
564
|
+
import { z as z7 } from "zod";
|
|
536
565
|
var BRAND_KINDS2 = ["OWNED", "COMPETITOR", "OTHER"];
|
|
537
|
-
var brandKindSchema2 =
|
|
538
|
-
var brandRankingSchema =
|
|
539
|
-
rank:
|
|
540
|
-
brandId:
|
|
541
|
-
brandName:
|
|
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:
|
|
544
|
-
installRate:
|
|
545
|
-
mentionRate:
|
|
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:
|
|
576
|
+
deltaRank: z7.number().int().nullable()
|
|
548
577
|
});
|
|
549
|
-
var packageRateSchema =
|
|
550
|
-
ecosystem:
|
|
551
|
-
name:
|
|
552
|
-
brandName:
|
|
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:
|
|
555
|
-
rate:
|
|
583
|
+
installs: z7.number().int(),
|
|
584
|
+
rate: z7.number()
|
|
556
585
|
});
|
|
557
|
-
var brandRateSchema =
|
|
558
|
-
brandId:
|
|
559
|
-
brandName:
|
|
586
|
+
var brandRateSchema = z7.object({
|
|
587
|
+
brandId: z7.string(),
|
|
588
|
+
brandName: z7.string(),
|
|
560
589
|
kind: brandKindSchema2,
|
|
561
|
-
installs:
|
|
562
|
-
rate:
|
|
590
|
+
installs: z7.number().int(),
|
|
591
|
+
rate: z7.number()
|
|
563
592
|
});
|
|
564
|
-
var brandFunnelRowSchema =
|
|
565
|
-
brandId:
|
|
566
|
-
brandName:
|
|
593
|
+
var brandFunnelRowSchema = z7.object({
|
|
594
|
+
brandId: z7.string(),
|
|
595
|
+
brandName: z7.string(),
|
|
567
596
|
kind: brandKindSchema2,
|
|
568
|
-
mentionRate:
|
|
569
|
-
installRate:
|
|
570
|
-
});
|
|
571
|
-
var domainRateSchema =
|
|
572
|
-
domain:
|
|
573
|
-
runs:
|
|
574
|
-
rate:
|
|
575
|
-
requests:
|
|
576
|
-
brandName:
|
|
577
|
-
owned:
|
|
578
|
-
});
|
|
579
|
-
var statsFreshnessSchema =
|
|
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:
|
|
610
|
+
watermark: z7.string().nullable(),
|
|
582
611
|
/** Runs that succeeded recently but haven't landed in the warehouse yet. */
|
|
583
|
-
pending:
|
|
612
|
+
pending: z7.number().int(),
|
|
584
613
|
/** False when the freshness read itself failed (distinguish from genuine zero). */
|
|
585
|
-
available:
|
|
614
|
+
available: z7.boolean()
|
|
586
615
|
});
|
|
587
|
-
var statsResponseSchema = (item) =>
|
|
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 =
|
|
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 =
|
|
647
|
+
var whereOpSchema = z8.enum(WHERE_OPS);
|
|
617
648
|
var GRANULARITIES = ["day", "week", "month"];
|
|
618
|
-
var granularitySchema =
|
|
649
|
+
var granularitySchema = z8.enum(GRANULARITIES);
|
|
619
650
|
var DEFAULT_QUERY_LIMIT = 50;
|
|
620
651
|
var MAX_QUERY_LIMIT = 1e3;
|
|
621
|
-
var scalar =
|
|
622
|
-
var whereClauseSchema =
|
|
623
|
-
dimension:
|
|
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:
|
|
626
|
-
});
|
|
627
|
-
var queryFiltersSchema =
|
|
628
|
-
prompt:
|
|
629
|
-
topic:
|
|
630
|
-
tag:
|
|
631
|
-
repo:
|
|
632
|
-
language:
|
|
633
|
-
framework:
|
|
634
|
-
size:
|
|
635
|
-
agent:
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
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 =
|
|
642
|
-
since:
|
|
643
|
-
until:
|
|
644
|
-
lastDays:
|
|
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 =
|
|
679
|
+
var orderBySchema = z8.object({
|
|
647
680
|
/** A selected dimension or metric name. */
|
|
648
|
-
key:
|
|
649
|
-
dir:
|
|
681
|
+
key: z8.string().min(1),
|
|
682
|
+
dir: z8.enum(["asc", "desc"]).default("desc")
|
|
650
683
|
});
|
|
651
|
-
var querySpecSchema =
|
|
684
|
+
var querySpecSchema = z8.object({
|
|
652
685
|
dataset: datasetSchema.default("runs"),
|
|
653
|
-
dimensions:
|
|
654
|
-
metrics:
|
|
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:
|
|
689
|
+
where: z8.array(whereClauseSchema).default([]),
|
|
657
690
|
dateRange: dateRangeSchema.optional(),
|
|
658
|
-
orderBy:
|
|
659
|
-
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:
|
|
695
|
+
explain: z8.boolean().default(false)
|
|
663
696
|
});
|
|
664
|
-
var columnKindSchema =
|
|
665
|
-
var queryColumnSchema =
|
|
666
|
-
key:
|
|
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 =
|
|
670
|
-
|
|
671
|
-
|
|
702
|
+
var queryRowSchema = z8.record(
|
|
703
|
+
z8.string(),
|
|
704
|
+
z8.union([z8.string(), z8.number(), z8.boolean(), z8.null()])
|
|
672
705
|
);
|
|
673
|
-
var queryResponseSchema =
|
|
674
|
-
columns:
|
|
675
|
-
rows:
|
|
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:
|
|
710
|
+
sql: z8.string().optional(),
|
|
678
711
|
freshness: statsFreshnessSchema
|
|
679
712
|
});
|
|
680
|
-
var fieldTypeSchema =
|
|
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 =
|
|
688
|
-
name:
|
|
720
|
+
var fieldSchema = z8.object({
|
|
721
|
+
name: z8.string(),
|
|
689
722
|
type: fieldTypeSchema,
|
|
690
723
|
/** One-line human/agent hint. */
|
|
691
|
-
description:
|
|
724
|
+
description: z8.string().optional()
|
|
692
725
|
});
|
|
693
|
-
var datasetMetaSchema =
|
|
726
|
+
var datasetMetaSchema = z8.object({
|
|
694
727
|
name: datasetSchema,
|
|
695
|
-
grain:
|
|
696
|
-
dimensions:
|
|
697
|
-
metrics:
|
|
728
|
+
grain: z8.string(),
|
|
729
|
+
dimensions: z8.array(fieldSchema),
|
|
730
|
+
metrics: z8.array(fieldSchema)
|
|
698
731
|
});
|
|
699
|
-
var metadataResponseSchema =
|
|
700
|
-
datasets:
|
|
732
|
+
var metadataResponseSchema = z8.object({
|
|
733
|
+
datasets: z8.array(datasetMetaSchema)
|
|
701
734
|
});
|
|
702
735
|
|
|
703
|
-
// ../packages/api-schemas/src/
|
|
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 =
|
|
712
|
-
var repoSchema =
|
|
713
|
-
url:
|
|
714
|
-
name:
|
|
715
|
-
isSystem:
|
|
716
|
-
languages:
|
|
717
|
-
frameworks:
|
|
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:
|
|
720
|
-
primaryLanguage:
|
|
721
|
-
sizeKb:
|
|
1356
|
+
tags: z20.array(z20.string()),
|
|
1357
|
+
primaryLanguage: z20.string(),
|
|
1358
|
+
sizeKb: z20.number(),
|
|
722
1359
|
sizeBucket: repoSizeBucketSchema.nullable(),
|
|
723
|
-
stars:
|
|
1360
|
+
stars: z20.number()
|
|
724
1361
|
});
|
|
725
1362
|
var repoListResponseSchema = listResponseSchema(repoSchema);
|
|
726
|
-
var addRepoBodySchema =
|
|
727
|
-
url:
|
|
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:
|
|
1371
|
+
ref: z20.string().min(1).optional(),
|
|
735
1372
|
/** Display name; defaults to the `owner/repo` label of the URL. */
|
|
736
|
-
name:
|
|
1373
|
+
name: z20.string().min(1).optional(),
|
|
737
1374
|
/** Manual override; defaults to frameworks detected from the repo's manifests. */
|
|
738
|
-
frameworks:
|
|
739
|
-
tags:
|
|
1375
|
+
frameworks: z20.array(z20.string()).optional(),
|
|
1376
|
+
tags: z20.array(z20.string()).optional()
|
|
740
1377
|
});
|
|
741
|
-
var updateRepoBodySchema =
|
|
742
|
-
url:
|
|
743
|
-
name:
|
|
744
|
-
frameworks:
|
|
745
|
-
tags:
|
|
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 =
|
|
748
|
-
url:
|
|
1384
|
+
var resyncRepoBodySchema = z20.object({
|
|
1385
|
+
url: z20.string().min(1, "url is required")
|
|
749
1386
|
});
|
|
750
|
-
var deleteRepoQuerySchema =
|
|
751
|
-
url:
|
|
1387
|
+
var deleteRepoQuerySchema = z20.object({
|
|
1388
|
+
url: z20.string().min(1, "url is required")
|
|
752
1389
|
});
|
|
753
|
-
var repoSyncResultSchema =
|
|
1390
|
+
var repoSyncResultSchema = z20.object({
|
|
754
1391
|
repo: repoSchema,
|
|
755
|
-
synced:
|
|
1392
|
+
synced: z20.boolean()
|
|
756
1393
|
});
|
|
757
1394
|
|
|
758
1395
|
// ../packages/api-schemas/src/runs.ts
|
|
759
|
-
import { z as
|
|
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 =
|
|
1407
|
+
var runStatusSchema = z21.enum(RUN_STATUSES);
|
|
771
1408
|
var AGENTS2 = ["CLAUDE_CODE", "CODEX_CLI", "CURSOR"];
|
|
772
|
-
var agentSchema2 =
|
|
773
|
-
var runStatusFilterSchema =
|
|
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(
|
|
1412
|
+
).pipe(z21.array(runStatusSchema).min(1));
|
|
776
1413
|
var runListQuerySchema = listQuerySchema.extend({
|
|
777
1414
|
status: runStatusFilterSchema.optional(),
|
|
778
|
-
batch:
|
|
779
|
-
prompt:
|
|
780
|
-
experiment:
|
|
781
|
-
since:
|
|
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 =
|
|
784
|
-
id:
|
|
1420
|
+
var runListItemSchema = z21.object({
|
|
1421
|
+
id: z21.string(),
|
|
785
1422
|
status: runStatusSchema,
|
|
786
1423
|
agent: agentSchema2,
|
|
787
|
-
model:
|
|
788
|
-
promptId:
|
|
1424
|
+
model: z21.string(),
|
|
1425
|
+
promptId: z21.string(),
|
|
789
1426
|
/** First ~80 chars of the batch's prompt snapshot, whitespace-collapsed. */
|
|
790
|
-
promptSnippet:
|
|
791
|
-
batchId:
|
|
792
|
-
experiment:
|
|
793
|
-
turns:
|
|
794
|
-
usdCost:
|
|
795
|
-
durationMs:
|
|
796
|
-
exitReason:
|
|
797
|
-
createdAt:
|
|
798
|
-
startedAt:
|
|
799
|
-
finishedAt:
|
|
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:
|
|
804
|
-
attempt:
|
|
805
|
-
cancelRequested:
|
|
806
|
-
failureReason:
|
|
807
|
-
repoUrl:
|
|
808
|
-
repoRef:
|
|
809
|
-
scenario:
|
|
810
|
-
funding:
|
|
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:
|
|
1457
|
+
usage: z21.unknown().nullable(),
|
|
813
1458
|
/** Artifact pointer: a working-tree diff exists at GET /runs/{id}/diff. */
|
|
814
|
-
hasDiff:
|
|
815
|
-
claimedAt:
|
|
1459
|
+
hasDiff: z21.boolean(),
|
|
1460
|
+
claimedAt: z21.string().nullable()
|
|
816
1461
|
});
|
|
817
|
-
var cancelRunResponseSchema =
|
|
818
|
-
id:
|
|
1462
|
+
var cancelRunResponseSchema = z21.object({
|
|
1463
|
+
id: z21.string(),
|
|
819
1464
|
status: runStatusSchema,
|
|
820
|
-
cancelRequested:
|
|
821
|
-
note:
|
|
822
|
-
});
|
|
823
|
-
var forkRunBodySchema =
|
|
824
|
-
prompt:
|
|
825
|
-
turn:
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
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
|
|
844
|
-
var apiTokenSchema =
|
|
845
|
-
id:
|
|
846
|
-
name:
|
|
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:
|
|
849
|
-
expiresAt:
|
|
850
|
-
lastUsedAt:
|
|
851
|
-
createdAt:
|
|
852
|
-
revokedAt:
|
|
853
|
-
});
|
|
854
|
-
var createTokenRequestSchema =
|
|
855
|
-
name:
|
|
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:
|
|
1570
|
+
expiresAt: z22.iso.datetime({ offset: true }).optional()
|
|
858
1571
|
});
|
|
859
1572
|
var createTokenResponseSchema = apiTokenSchema.extend({
|
|
860
|
-
token:
|
|
1573
|
+
token: z22.string()
|
|
861
1574
|
});
|
|
862
1575
|
var listTokensResponseSchema = listResponseSchema(apiTokenSchema);
|
|
863
1576
|
|
|
864
1577
|
// src/commands/apply.ts
|
|
865
|
-
import { z as
|
|
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(
|
|
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
|
|
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
|
|
1416
|
-
res.writeHead(
|
|
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
|
-
|
|
1425
|
-
|
|
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
|
-
|
|
1429
|
-
|
|
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
|
|
1492
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
1582
|
-
|
|
1583
|
-
|
|
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/
|
|
2061
|
-
var
|
|
2062
|
-
__export(
|
|
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
|
|
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
|
-
|
|
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
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
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 (
|
|
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("
|
|
3238
|
+
console.log("scheduled via:");
|
|
2246
3239
|
printItems(
|
|
2247
3240
|
prompt.schedules.map((s) => ({
|
|
2248
3241
|
id: s.id,
|
|
2249
|
-
|
|
2250
|
-
ref: s.repoRef ?? "",
|
|
3242
|
+
name: s.name,
|
|
2251
3243
|
cadence: s.cadence,
|
|
2252
3244
|
days: s.daysPerWeek ?? "",
|
|
2253
|
-
|
|
3245
|
+
enabled: s.enabled ? "yes" : "no"
|
|
2254
3246
|
})),
|
|
2255
3247
|
"table"
|
|
2256
3248
|
);
|
|
2257
3249
|
} else {
|
|
2258
|
-
console.log("
|
|
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("--
|
|
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
|
-
`
|
|
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(
|
|
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("--
|
|
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
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
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: () =>
|
|
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
|
|
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: () =>
|
|
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
|
|
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: () =>
|
|
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
|
|
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: () =>
|
|
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
|
-
|
|
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
|
|
3006
|
-
|
|
3007
|
-
|
|
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
|
|
3010
|
-
|
|
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 (
|
|
4118
|
+
if (json) printJson(res.items);
|
|
3013
4119
|
else printItems(res.items.map(toRow5), "table");
|
|
3014
4120
|
});
|
|
3015
|
-
group.command("
|
|
3016
|
-
"
|
|
3017
|
-
).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(
|
|
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
|
-
|
|
3027
|
-
|
|
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
|
-
|
|
4149
|
+
`/api/v1/orgs/${encodeURIComponent(org)}/schedules`,
|
|
3033
4150
|
body
|
|
3034
4151
|
);
|
|
3035
4152
|
if (resolveOutput(cmd) === "json") printJson(schedule);
|
|
3036
|
-
else console.log(`
|
|
4153
|
+
else console.log(`Created schedule ${schedule.id}`);
|
|
3037
4154
|
}
|
|
3038
4155
|
);
|
|
3039
|
-
group.command("edit <id>").description("Update a schedule
|
|
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: () =>
|
|
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
|
|
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: () =>
|
|
4356
|
+
register: () => register16
|
|
3193
4357
|
});
|
|
3194
4358
|
function tagsPath(org) {
|
|
3195
4359
|
return `/api/v1/orgs/${encodeURIComponent(org)}/tags`;
|
|
3196
4360
|
}
|
|
3197
|
-
function
|
|
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: () =>
|
|
4404
|
+
register: () => register17
|
|
3241
4405
|
});
|
|
3242
4406
|
function topicsPath(org) {
|
|
3243
4407
|
return `/api/v1/orgs/${encodeURIComponent(org)}/topics`;
|
|
3244
4408
|
}
|
|
3245
|
-
function
|
|
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: () =>
|
|
4430
|
+
register: () => register18
|
|
3267
4431
|
});
|
|
3268
|
-
function
|
|
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
|
-
|
|
4488
|
+
onboard_exports,
|
|
4489
|
+
orgs_exports2,
|
|
3325
4490
|
prompts_exports2,
|
|
3326
4491
|
schedules_exports2,
|
|
3327
4492
|
repos_exports2,
|