@withgauge/cli 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +11 -2
  2. package/dist/index.js +552 -178
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -18,13 +18,22 @@ Requires Node.js ≥ 22.12.
18
18
  gauge prompts list # your prompts
19
19
  gauge runs list --status running # recent & active runs
20
20
  gauge runs watch <run-id> # follow a run as the agent works
21
+ gauge runs fork <run-id> --prompt "Try a different approach"
21
22
  gauge repos list # your repository catalog
22
23
  gauge stats rankings -o json # brand rankings (share of voice) as JSON
24
+ gauge query fields --dataset installs # discover a dataset's dimensions/metrics
25
+ gauge query -d ecosystem -m installs,install_rate -o json # a flexible report
23
26
  ```
24
27
 
25
28
  Run `gauge --help` (or `gauge <command> --help`) for the full command set:
26
- prompts, schedules, repos, runs, stats, brands, tags, topics, provider keys,
27
- billing, and more.
29
+ prompts, schedules, repos, runs, stats, query, brands, tags, topics, provider
30
+ keys, billing, and more.
31
+
32
+ `gauge query` builds flexible reports over your event warehouse (a GA4
33
+ `run_report` analog): pick a `--dataset`, group by `--dimensions`, and aggregate
34
+ `--metrics`, or pass a whole spec with `--json` (the agent-friendly surface).
35
+ `gauge query datasets` / `gauge query fields --dataset <name>` list what you can
36
+ ask for.
28
37
 
29
38
  To launch runs declaratively, `gauge apply -f <spec>.json`. Discover the spec
30
39
  format without leaving the terminal: `gauge apply --example` prints a starter
package/dist/index.js CHANGED
@@ -528,63 +528,235 @@ var runPromptResponseSchema = z10.object({
528
528
  blocked: z10.enum(["insufficient_credits", "needs_provider_key"]).optional()
529
529
  });
530
530
 
531
- // ../packages/api-schemas/src/repos.ts
531
+ // ../packages/api-schemas/src/query.ts
532
+ import { z as z12 } from "zod";
533
+
534
+ // ../packages/api-schemas/src/stats.ts
532
535
  import { z as z11 } from "zod";
536
+ var BRAND_KINDS2 = ["OWNED", "COMPETITOR", "OTHER"];
537
+ var brandKindSchema2 = z11.enum(BRAND_KINDS2);
538
+ var brandRankingSchema = z11.object({
539
+ rank: z11.number().int(),
540
+ brandId: z11.string(),
541
+ brandName: z11.string(),
542
+ kind: brandKindSchema2,
543
+ installs: z11.number().int(),
544
+ installRate: z11.number(),
545
+ mentionRate: z11.number(),
546
+ /** Movement between the two most recent batch windows; null if not ranked in both. */
547
+ deltaRank: z11.number().int().nullable()
548
+ });
549
+ var packageRateSchema = z11.object({
550
+ ecosystem: z11.string(),
551
+ name: z11.string(),
552
+ brandName: z11.string().optional(),
553
+ kind: brandKindSchema2.optional(),
554
+ installs: z11.number().int(),
555
+ rate: z11.number()
556
+ });
557
+ var brandRateSchema = z11.object({
558
+ brandId: z11.string(),
559
+ brandName: z11.string(),
560
+ kind: brandKindSchema2,
561
+ installs: z11.number().int(),
562
+ rate: z11.number()
563
+ });
564
+ var brandFunnelRowSchema = z11.object({
565
+ brandId: z11.string(),
566
+ brandName: z11.string(),
567
+ kind: brandKindSchema2,
568
+ mentionRate: z11.number(),
569
+ installRate: z11.number()
570
+ });
571
+ var domainRateSchema = z11.object({
572
+ domain: z11.string(),
573
+ runs: z11.number().int(),
574
+ rate: z11.number(),
575
+ requests: z11.number().int(),
576
+ brandName: z11.string().optional(),
577
+ owned: z11.boolean().optional()
578
+ });
579
+ var statsFreshnessSchema = z11.object({
580
+ /** Newest run-ingest time across the org (ISO), or null if nothing ingested. */
581
+ watermark: z11.string().nullable(),
582
+ /** Runs that succeeded recently but haven't landed in the warehouse yet. */
583
+ pending: z11.number().int(),
584
+ /** False when the freshness read itself failed (distinguish from genuine zero). */
585
+ available: z11.boolean()
586
+ });
587
+ var statsResponseSchema = (item) => z11.object({ items: z11.array(item), freshness: statsFreshnessSchema });
588
+ var rankingsResponseSchema = statsResponseSchema(brandRankingSchema);
589
+ var installsResponseSchema = statsResponseSchema(packageRateSchema);
590
+ var brandsResponseSchema = statsResponseSchema(brandRateSchema);
591
+ var funnelResponseSchema = statsResponseSchema(brandFunnelRowSchema);
592
+ var domainsResponseSchema = statsResponseSchema(domainRateSchema);
593
+
594
+ // ../packages/api-schemas/src/query.ts
595
+ var DATASETS = [
596
+ "runs",
597
+ "installs",
598
+ "mentions",
599
+ "web",
600
+ "network",
601
+ "files",
602
+ "tokens"
603
+ ];
604
+ var datasetSchema = z12.enum(DATASETS);
605
+ var WHERE_OPS = [
606
+ "eq",
607
+ "neq",
608
+ "in",
609
+ "notIn",
610
+ "contains",
611
+ "gt",
612
+ "gte",
613
+ "lt",
614
+ "lte"
615
+ ];
616
+ var whereOpSchema = z12.enum(WHERE_OPS);
617
+ var GRANULARITIES = ["day", "week", "month"];
618
+ var granularitySchema = z12.enum(GRANULARITIES);
619
+ var DEFAULT_QUERY_LIMIT = 50;
620
+ var MAX_QUERY_LIMIT = 1e3;
621
+ var scalar = z12.union([z12.string(), z12.number(), z12.boolean()]);
622
+ var whereClauseSchema = z12.object({
623
+ dimension: z12.string().min(1),
624
+ op: whereOpSchema,
625
+ value: z12.union([scalar, z12.array(scalar)])
626
+ });
627
+ var queryFiltersSchema = z12.object({
628
+ prompt: z12.string(),
629
+ topic: z12.array(z12.string()),
630
+ tag: z12.array(z12.string()),
631
+ repo: z12.array(z12.string()),
632
+ language: z12.array(z12.string()),
633
+ framework: z12.array(z12.string()),
634
+ size: z12.array(z12.string()),
635
+ agent: z12.array(z12.string()),
636
+ model: z12.array(z12.string()),
637
+ scenario: z12.array(z12.string()),
638
+ experiment: z12.array(z12.string()),
639
+ branded: z12.boolean()
640
+ }).partial();
641
+ var dateRangeSchema = z12.object({
642
+ since: z12.string(),
643
+ until: z12.string(),
644
+ lastDays: z12.number().int().positive()
645
+ }).partial();
646
+ var orderBySchema = z12.object({
647
+ /** A selected dimension or metric name. */
648
+ key: z12.string().min(1),
649
+ dir: z12.enum(["asc", "desc"]).default("desc")
650
+ });
651
+ var querySpecSchema = z12.object({
652
+ dataset: datasetSchema.default("runs"),
653
+ dimensions: z12.array(z12.string()).default([]),
654
+ metrics: z12.array(z12.string()).min(1, "at least one metric is required"),
655
+ filters: queryFiltersSchema.default({}),
656
+ where: z12.array(whereClauseSchema).default([]),
657
+ dateRange: dateRangeSchema.optional(),
658
+ orderBy: z12.array(orderBySchema).default([]),
659
+ limit: z12.number().int().min(1).max(MAX_QUERY_LIMIT).default(DEFAULT_QUERY_LIMIT),
660
+ granularity: granularitySchema.default("day"),
661
+ /** When true, the response echoes the compiled SQL (params bound, not inlined). */
662
+ explain: z12.boolean().default(false)
663
+ });
664
+ var columnKindSchema = z12.enum(["dimension", "metric"]);
665
+ var queryColumnSchema = z12.object({
666
+ key: z12.string(),
667
+ kind: columnKindSchema
668
+ });
669
+ var queryRowSchema = z12.record(
670
+ z12.string(),
671
+ z12.union([z12.string(), z12.number(), z12.boolean(), z12.null()])
672
+ );
673
+ var queryResponseSchema = z12.object({
674
+ columns: z12.array(queryColumnSchema),
675
+ rows: z12.array(queryRowSchema),
676
+ /** Present only when the request set explain=true. */
677
+ sql: z12.string().optional(),
678
+ freshness: statsFreshnessSchema
679
+ });
680
+ var fieldTypeSchema = z12.enum([
681
+ "string",
682
+ "number",
683
+ "rate",
684
+ "date",
685
+ "boolean"
686
+ ]);
687
+ var fieldSchema = z12.object({
688
+ name: z12.string(),
689
+ type: fieldTypeSchema,
690
+ /** One-line human/agent hint. */
691
+ description: z12.string().optional()
692
+ });
693
+ var datasetMetaSchema = z12.object({
694
+ name: datasetSchema,
695
+ grain: z12.string(),
696
+ dimensions: z12.array(fieldSchema),
697
+ metrics: z12.array(fieldSchema)
698
+ });
699
+ var metadataResponseSchema = z12.object({
700
+ datasets: z12.array(datasetMetaSchema)
701
+ });
702
+
703
+ // ../packages/api-schemas/src/repos.ts
704
+ import { z as z13 } from "zod";
533
705
  var REPO_SIZE_BUCKETS = [
534
706
  "small",
535
707
  "medium",
536
708
  "large",
537
709
  "xlarge"
538
710
  ];
539
- var repoSizeBucketSchema = z11.enum(REPO_SIZE_BUCKETS);
540
- var repoSchema = z11.object({
541
- url: z11.string(),
542
- name: z11.string(),
543
- isSystem: z11.boolean(),
544
- languages: z11.array(z11.string()),
545
- frameworks: z11.array(z11.string()),
711
+ var repoSizeBucketSchema = z13.enum(REPO_SIZE_BUCKETS);
712
+ var repoSchema = z13.object({
713
+ url: z13.string(),
714
+ name: z13.string(),
715
+ isSystem: z13.boolean(),
716
+ languages: z13.array(z13.string()),
717
+ frameworks: z13.array(z13.string()),
546
718
  /** Faceted labels (complexity:L2, buildable:yes, stack:nextjs, …). */
547
- tags: z11.array(z11.string()),
548
- primaryLanguage: z11.string(),
549
- sizeKb: z11.number(),
719
+ tags: z13.array(z13.string()),
720
+ primaryLanguage: z13.string(),
721
+ sizeKb: z13.number(),
550
722
  sizeBucket: repoSizeBucketSchema.nullable(),
551
- stars: z11.number()
723
+ stars: z13.number()
552
724
  });
553
725
  var repoListResponseSchema = listResponseSchema(repoSchema);
554
- var addRepoBodySchema = z11.object({
555
- url: z11.string().min(1, "url is required"),
726
+ var addRepoBodySchema = z13.object({
727
+ url: z13.string().min(1, "url is required"),
556
728
  /**
557
729
  * Reserved (accepted, not yet persisted): the catalog keys repos by URL only
558
730
  * — `fact_repo` has no ref column and metadata sync always reads the default
559
731
  * branch. Kept in the wire format so `gauge repos add --ref` is stable once
560
732
  * the catalog learns refs.
561
733
  */
562
- ref: z11.string().min(1).optional(),
734
+ ref: z13.string().min(1).optional(),
563
735
  /** Display name; defaults to the `owner/repo` label of the URL. */
564
- name: z11.string().min(1).optional(),
736
+ name: z13.string().min(1).optional(),
565
737
  /** Manual override; defaults to frameworks detected from the repo's manifests. */
566
- frameworks: z11.array(z11.string()).optional(),
567
- tags: z11.array(z11.string()).optional()
738
+ frameworks: z13.array(z13.string()).optional(),
739
+ tags: z13.array(z13.string()).optional()
568
740
  });
569
- var updateRepoBodySchema = z11.object({
570
- url: z11.string().min(1, "url is required"),
571
- name: z11.string().min(1).optional(),
572
- frameworks: z11.array(z11.string()).optional(),
573
- tags: z11.array(z11.string()).optional()
741
+ var updateRepoBodySchema = z13.object({
742
+ url: z13.string().min(1, "url is required"),
743
+ name: z13.string().min(1).optional(),
744
+ frameworks: z13.array(z13.string()).optional(),
745
+ tags: z13.array(z13.string()).optional()
574
746
  });
575
- var resyncRepoBodySchema = z11.object({
576
- url: z11.string().min(1, "url is required")
747
+ var resyncRepoBodySchema = z13.object({
748
+ url: z13.string().min(1, "url is required")
577
749
  });
578
- var deleteRepoQuerySchema = z11.object({
579
- url: z11.string().min(1, "url is required")
750
+ var deleteRepoQuerySchema = z13.object({
751
+ url: z13.string().min(1, "url is required")
580
752
  });
581
- var repoSyncResultSchema = z11.object({
753
+ var repoSyncResultSchema = z13.object({
582
754
  repo: repoSchema,
583
- synced: z11.boolean()
755
+ synced: z13.boolean()
584
756
  });
585
757
 
586
758
  // ../packages/api-schemas/src/runs.ts
587
- import { z as z12 } from "zod";
759
+ import { z as z14 } from "zod";
588
760
  var RUN_STATUSES = [
589
761
  "QUEUED",
590
762
  "CLAIMED",
@@ -595,152 +767,102 @@ var RUN_STATUSES = [
595
767
  "TIMED_OUT",
596
768
  "CANCELED"
597
769
  ];
598
- var runStatusSchema = z12.enum(RUN_STATUSES);
770
+ var runStatusSchema = z14.enum(RUN_STATUSES);
599
771
  var AGENTS2 = ["CLAUDE_CODE", "CODEX_CLI", "CURSOR"];
600
- var agentSchema2 = z12.enum(AGENTS2);
601
- var runStatusFilterSchema = z12.string().transform(
772
+ var agentSchema2 = z14.enum(AGENTS2);
773
+ var runStatusFilterSchema = z14.string().transform(
602
774
  (raw) => raw.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean)
603
- ).pipe(z12.array(runStatusSchema).min(1));
775
+ ).pipe(z14.array(runStatusSchema).min(1));
604
776
  var runListQuerySchema = listQuerySchema.extend({
605
777
  status: runStatusFilterSchema.optional(),
606
- batch: z12.string().optional(),
607
- prompt: z12.string().optional(),
608
- experiment: z12.string().optional(),
609
- since: z12.string().optional()
778
+ batch: z14.string().optional(),
779
+ prompt: z14.string().optional(),
780
+ experiment: z14.string().optional(),
781
+ since: z14.string().optional()
610
782
  });
611
- var runListItemSchema = z12.object({
612
- id: z12.string(),
783
+ var runListItemSchema = z14.object({
784
+ id: z14.string(),
613
785
  status: runStatusSchema,
614
786
  agent: agentSchema2,
615
- model: z12.string(),
616
- promptId: z12.string(),
787
+ model: z14.string(),
788
+ promptId: z14.string(),
617
789
  /** First ~80 chars of the batch's prompt snapshot, whitespace-collapsed. */
618
- promptSnippet: z12.string(),
619
- batchId: z12.string(),
620
- experiment: z12.string().nullable(),
621
- turns: z12.number().int().nullable(),
622
- usdCost: z12.number().nullable(),
623
- durationMs: z12.number().int().nullable(),
624
- exitReason: z12.string().nullable(),
625
- createdAt: z12.string(),
626
- startedAt: z12.string().nullable(),
627
- finishedAt: z12.string().nullable()
790
+ promptSnippet: z14.string(),
791
+ batchId: z14.string(),
792
+ experiment: z14.string().nullable(),
793
+ turns: z14.number().int().nullable(),
794
+ usdCost: z14.number().nullable(),
795
+ durationMs: z14.number().int().nullable(),
796
+ exitReason: z14.string().nullable(),
797
+ createdAt: z14.string(),
798
+ startedAt: z14.string().nullable(),
799
+ finishedAt: z14.string().nullable()
628
800
  });
629
801
  var runListResponseSchema = listResponseSchema(runListItemSchema);
630
802
  var runDetailSchema = runListItemSchema.omit({ promptSnippet: true }).extend({
631
- promptText: z12.string(),
632
- attempt: z12.number().int(),
633
- cancelRequested: z12.boolean(),
634
- failureReason: z12.string().nullable(),
635
- repoUrl: z12.string().nullable(),
636
- repoRef: z12.string().nullable(),
637
- scenario: z12.string(),
638
- funding: z12.string(),
803
+ promptText: z14.string(),
804
+ attempt: z14.number().int(),
805
+ cancelRequested: z14.boolean(),
806
+ failureReason: z14.string().nullable(),
807
+ repoUrl: z14.string().nullable(),
808
+ repoRef: z14.string().nullable(),
809
+ scenario: z14.string(),
810
+ funding: z14.string(),
639
811
  /** Raw harness usage write-back (token counts etc.); shape may evolve. */
640
- usage: z12.unknown().nullable(),
812
+ usage: z14.unknown().nullable(),
641
813
  /** Artifact pointer: a working-tree diff exists at GET /runs/{id}/diff. */
642
- hasDiff: z12.boolean(),
643
- claimedAt: z12.string().nullable()
814
+ hasDiff: z14.boolean(),
815
+ claimedAt: z14.string().nullable()
644
816
  });
645
- var cancelRunResponseSchema = z12.object({
646
- id: z12.string(),
817
+ var cancelRunResponseSchema = z14.object({
818
+ id: z14.string(),
647
819
  status: runStatusSchema,
648
- cancelRequested: z12.boolean(),
649
- note: z12.string().optional()
650
- });
651
- var runEventSchema = z12.looseObject({
652
- run_id: z12.string(),
653
- seq: z12.number(),
654
- turn: z12.number(),
655
- ts: z12.string(),
656
- type: z12.string()
657
- });
658
-
659
- // ../packages/api-schemas/src/stats.ts
660
- import { z as z13 } from "zod";
661
- var BRAND_KINDS2 = ["OWNED", "COMPETITOR", "OTHER"];
662
- var brandKindSchema2 = z13.enum(BRAND_KINDS2);
663
- var brandRankingSchema = z13.object({
664
- rank: z13.number().int(),
665
- brandId: z13.string(),
666
- brandName: z13.string(),
667
- kind: brandKindSchema2,
668
- installs: z13.number().int(),
669
- installRate: z13.number(),
670
- mentionRate: z13.number(),
671
- /** Movement between the two most recent batch windows; null if not ranked in both. */
672
- deltaRank: z13.number().int().nullable()
673
- });
674
- var packageRateSchema = z13.object({
675
- ecosystem: z13.string(),
676
- name: z13.string(),
677
- brandName: z13.string().optional(),
678
- kind: brandKindSchema2.optional(),
679
- installs: z13.number().int(),
680
- rate: z13.number()
681
- });
682
- var brandRateSchema = z13.object({
683
- brandId: z13.string(),
684
- brandName: z13.string(),
685
- kind: brandKindSchema2,
686
- installs: z13.number().int(),
687
- rate: z13.number()
688
- });
689
- var brandFunnelRowSchema = z13.object({
690
- brandId: z13.string(),
691
- brandName: z13.string(),
692
- kind: brandKindSchema2,
693
- mentionRate: z13.number(),
694
- installRate: z13.number()
695
- });
696
- var domainRateSchema = z13.object({
697
- domain: z13.string(),
698
- runs: z13.number().int(),
699
- rate: z13.number(),
700
- requests: z13.number().int(),
701
- deniedRequests: z13.number().int(),
702
- brandName: z13.string().optional(),
703
- owned: z13.boolean().optional()
704
- });
705
- var statsFreshnessSchema = z13.object({
706
- /** Newest run-ingest time across the org (ISO), or null if nothing ingested. */
707
- watermark: z13.string().nullable(),
708
- /** Runs that succeeded recently but haven't landed in the warehouse yet. */
709
- pending: z13.number().int(),
710
- /** False when the freshness read itself failed (distinguish from genuine zero). */
711
- available: z13.boolean()
820
+ cancelRequested: z14.boolean(),
821
+ note: z14.string().optional()
822
+ });
823
+ var forkRunBodySchema = z14.object({
824
+ prompt: z14.string().trim().min(1).max(2e4),
825
+ turn: z14.number().int().min(0).optional()
826
+ });
827
+ var forkRunResponseSchema = z14.object({
828
+ runId: z14.string(),
829
+ batchId: z14.string(),
830
+ parentRunId: z14.string(),
831
+ checkpointId: z14.string(),
832
+ turn: z14.number().int().min(0)
833
+ });
834
+ var runEventSchema = z14.looseObject({
835
+ run_id: z14.string(),
836
+ seq: z14.number(),
837
+ turn: z14.number(),
838
+ ts: z14.string(),
839
+ type: z14.string()
712
840
  });
713
- var statsResponseSchema = (item) => z13.object({ items: z13.array(item), freshness: statsFreshnessSchema });
714
- var rankingsResponseSchema = statsResponseSchema(brandRankingSchema);
715
- var installsResponseSchema = statsResponseSchema(packageRateSchema);
716
- var brandsResponseSchema = statsResponseSchema(brandRateSchema);
717
- var funnelResponseSchema = statsResponseSchema(brandFunnelRowSchema);
718
- var domainsResponseSchema = statsResponseSchema(domainRateSchema);
719
841
 
720
842
  // ../packages/api-schemas/src/tokens.ts
721
- import { z as z14 } from "zod";
722
- var apiTokenSchema = z14.object({
723
- id: z14.string(),
724
- name: z14.string(),
843
+ import { z as z15 } from "zod";
844
+ var apiTokenSchema = z15.object({
845
+ id: z15.string(),
846
+ name: z15.string(),
725
847
  /** Last 4 chars of the plaintext, for recognizability (non-secret). */
726
- last4: z14.string(),
727
- expiresAt: z14.iso.datetime().nullable(),
728
- lastUsedAt: z14.iso.datetime().nullable(),
729
- createdAt: z14.iso.datetime(),
730
- revokedAt: z14.iso.datetime().nullable()
731
- });
732
- var createTokenRequestSchema = z14.object({
733
- name: z14.string().min(1).max(100),
848
+ last4: z15.string(),
849
+ expiresAt: z15.iso.datetime().nullable(),
850
+ lastUsedAt: z15.iso.datetime().nullable(),
851
+ createdAt: z15.iso.datetime(),
852
+ revokedAt: z15.iso.datetime().nullable()
853
+ });
854
+ var createTokenRequestSchema = z15.object({
855
+ name: z15.string().min(1).max(100),
734
856
  /** ISO-8601 datetime; omit for no expiry. */
735
- expiresAt: z14.iso.datetime({ offset: true }).optional()
857
+ expiresAt: z15.iso.datetime({ offset: true }).optional()
736
858
  });
737
859
  var createTokenResponseSchema = apiTokenSchema.extend({
738
- token: z14.string()
860
+ token: z15.string()
739
861
  });
740
862
  var listTokensResponseSchema = listResponseSchema(apiTokenSchema);
741
863
 
742
864
  // src/commands/apply.ts
743
- import { z as z15 } from "zod";
865
+ import { z as z16 } from "zod";
744
866
 
745
867
  // src/version.ts
746
868
  import { createRequire } from "module";
@@ -1082,7 +1204,16 @@ var EXAMPLE_SPEC = {
1082
1204
  key: "migrate-to-vitest",
1083
1205
  text: "Migrate the test suite from Jest to Vitest.",
1084
1206
  scenario: "MIGRATION",
1085
- schedules: [{ repoUrl: "https://github.com/acme/api", repoRef: "main" }]
1207
+ schedules: [
1208
+ {
1209
+ repoUrl: "https://github.com/acme/api",
1210
+ repoRef: "main",
1211
+ // Optional: pin a specific model id. Must be one the schedule's
1212
+ // agent(s) can actually serve, or the run falls back to the agent
1213
+ // default. Omit (or use null) to always use the agent default.
1214
+ model: "claude-opus-4-8"
1215
+ }
1216
+ ]
1086
1217
  }
1087
1218
  ]
1088
1219
  };
@@ -1181,7 +1312,7 @@ function register(program2) {
1181
1312
  ).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(
1182
1313
  async (opts, command) => {
1183
1314
  if (opts.schema) {
1184
- printJson(z15.toJSONSchema(batteries_exports.batterySpecSchema));
1315
+ printJson(z16.toJSONSchema(batteries_exports.batterySpecSchema));
1185
1316
  return;
1186
1317
  }
1187
1318
  if (opts.example) {
@@ -2244,10 +2375,239 @@ function register9(program2) {
2244
2375
  );
2245
2376
  }
2246
2377
 
2378
+ // src/commands/query.ts
2379
+ var query_exports2 = {};
2380
+ __export(query_exports2, {
2381
+ register: () => register10
2382
+ });
2383
+ var collect3 = (value, prev = []) => [
2384
+ ...prev,
2385
+ value
2386
+ ];
2387
+ var csv = (raw) => raw.split(",").map((s) => s.trim()).filter(Boolean);
2388
+ function parseWhere(expr) {
2389
+ const inMatch = expr.match(/^\s*(\w+)\s+(in|contains)\s+(.*)$/i);
2390
+ if (inMatch) {
2391
+ const [, dimension2, opRaw, rest2] = inMatch;
2392
+ const op = opRaw.toLowerCase();
2393
+ if (op === "in") {
2394
+ return { dimension: dimension2, op: "in", value: csv(rest2) };
2395
+ }
2396
+ return { dimension: dimension2, op: "contains", value: rest2.trim() };
2397
+ }
2398
+ const opMatch = expr.match(/^\s*(\w+)\s*(!=|>=|<=|=|>|<)\s*(.*)$/);
2399
+ if (!opMatch) {
2400
+ throw new CliError(
2401
+ "usage",
2402
+ `Could not parse --where "${expr}". Use e.g. "action=install", "ecosystem in npm,pypi", or "name contains supa".`
2403
+ );
2404
+ }
2405
+ const [, dimension, sym, rest] = opMatch;
2406
+ const opFor = {
2407
+ "=": "eq",
2408
+ "!=": "neq",
2409
+ ">": "gt",
2410
+ ">=": "gte",
2411
+ "<": "lt",
2412
+ "<=": "lte"
2413
+ };
2414
+ return { dimension, op: opFor[sym], value: rest.trim() };
2415
+ }
2416
+ function parseOrderBy(raw) {
2417
+ const [key, dir] = raw.split(":");
2418
+ return { key: key.trim(), dir: dir?.trim() === "asc" ? "asc" : "desc" };
2419
+ }
2420
+ async function readStdin2() {
2421
+ const chunks = [];
2422
+ for await (const chunk of process.stdin) chunks.push(chunk);
2423
+ return Buffer.concat(chunks).toString("utf8");
2424
+ }
2425
+ async function buildSpec(opts) {
2426
+ let spec = { metrics: [] };
2427
+ if (opts.json) {
2428
+ const raw = opts.json === "-" ? await readStdin2() : opts.json;
2429
+ try {
2430
+ spec = JSON.parse(raw);
2431
+ } catch (e) {
2432
+ throw new CliError(
2433
+ "usage",
2434
+ `--json is not valid JSON: ${e.message}`
2435
+ );
2436
+ }
2437
+ }
2438
+ if (opts.dataset) spec.dataset = opts.dataset;
2439
+ if (opts.dimensions !== void 0) spec.dimensions = csv(opts.dimensions);
2440
+ if (opts.metrics !== void 0) spec.metrics = csv(opts.metrics);
2441
+ if (opts.where?.length) spec.where = opts.where.map(parseWhere);
2442
+ if (opts.orderBy?.length) spec.orderBy = opts.orderBy.map(parseOrderBy);
2443
+ if (opts.limit !== void 0) spec.limit = Number(opts.limit);
2444
+ if (opts.granularity)
2445
+ spec.granularity = opts.granularity;
2446
+ if (opts.explain) spec.explain = true;
2447
+ const date = {
2448
+ ...spec.dateRange ?? {}
2449
+ };
2450
+ if (opts.since) {
2451
+ date.since = opts.since;
2452
+ delete date.lastDays;
2453
+ } else if (opts.lastDays) {
2454
+ date.lastDays = Number(opts.lastDays);
2455
+ delete date.since;
2456
+ }
2457
+ if (opts.until) date.until = opts.until;
2458
+ if (Object.keys(date).length) spec.dateRange = date;
2459
+ if (opts.branded && opts.unbranded) {
2460
+ throw new CliError("usage", "Pass at most one of --branded / --unbranded.");
2461
+ }
2462
+ const filters = {
2463
+ ...spec.filters ?? {}
2464
+ };
2465
+ if (opts.prompt) filters.prompt = opts.prompt;
2466
+ if (opts.topic) filters.topic = csv(opts.topic);
2467
+ if (opts.tag) filters.tag = csv(opts.tag);
2468
+ if (opts.repo) filters.repo = csv(opts.repo);
2469
+ if (opts.language) filters.language = csv(opts.language);
2470
+ if (opts.framework) filters.framework = csv(opts.framework);
2471
+ if (opts.size) filters.size = csv(opts.size);
2472
+ if (opts.agent) filters.agent = csv(opts.agent);
2473
+ if (opts.model) filters.model = csv(opts.model);
2474
+ if (opts.scenario) filters.scenario = csv(opts.scenario);
2475
+ if (opts.experiment) filters.experiment = csv(opts.experiment);
2476
+ if (opts.branded) filters.branded = true;
2477
+ if (opts.unbranded) filters.branded = false;
2478
+ if (Object.keys(filters).length) spec.filters = filters;
2479
+ if (!spec.metrics || spec.metrics.length === 0) {
2480
+ throw new CliError(
2481
+ "usage",
2482
+ "At least one metric is required. Pass --metrics <a,b> (or a `metrics` array in --json). See `gauge query fields --dataset <name>`."
2483
+ );
2484
+ }
2485
+ return spec;
2486
+ }
2487
+ var pct = (n) => `${(n * 100).toFixed(1)}%`;
2488
+ function noteFreshness(f) {
2489
+ if (!f.available) {
2490
+ console.error(
2491
+ "warning: analytics store is temporarily unavailable; results may be incomplete."
2492
+ );
2493
+ } else if (f.pending > 0) {
2494
+ console.error(
2495
+ `note: ${f.pending} recent run(s) still ingesting; results may not reflect them yet.`
2496
+ );
2497
+ }
2498
+ }
2499
+ async function runQuery(command, opts) {
2500
+ const org = resolveOrg(command);
2501
+ const output = resolveOutput(command);
2502
+ const spec = await buildSpec(opts);
2503
+ const res = await createClient().post(
2504
+ `/api/v1/orgs/${encodeURIComponent(org)}/query`,
2505
+ spec
2506
+ );
2507
+ if (output === "json") {
2508
+ printJson(res);
2509
+ return;
2510
+ }
2511
+ if (res.sql) console.error(`
2512
+ ${res.sql}
2513
+ `);
2514
+ const rateKeys = new Set(
2515
+ res.columns.filter((c) => c.kind === "metric" && c.key.endsWith("_rate")).map((c) => c.key)
2516
+ );
2517
+ const rows = res.rows.map((row) => {
2518
+ const out = {};
2519
+ for (const col of res.columns) {
2520
+ const v = row[col.key];
2521
+ out[col.key] = rateKeys.has(col.key) && typeof v === "number" ? pct(v) : v;
2522
+ }
2523
+ return out;
2524
+ });
2525
+ printItems(
2526
+ rows,
2527
+ "table",
2528
+ res.columns.map((c) => ({ key: c.key }))
2529
+ );
2530
+ noteFreshness(res.freshness);
2531
+ }
2532
+ async function showMetadata(command, mode, dataset) {
2533
+ const org = resolveOrg(command);
2534
+ const output = resolveOutput(command);
2535
+ const meta = await createClient().get(
2536
+ `/api/v1/orgs/${encodeURIComponent(org)}/query/metadata`
2537
+ );
2538
+ if (mode === "datasets") {
2539
+ if (output === "json")
2540
+ return printJson(
2541
+ meta.datasets.map((d) => ({ name: d.name, grain: d.grain }))
2542
+ );
2543
+ printItems(
2544
+ meta.datasets.map((d) => ({ dataset: d.name, grain: d.grain })),
2545
+ "table"
2546
+ );
2547
+ return;
2548
+ }
2549
+ const ds = meta.datasets.find((d) => d.name === dataset);
2550
+ if (!ds) {
2551
+ throw new CliError(
2552
+ "usage",
2553
+ `Unknown dataset "${dataset}". Valid: ${meta.datasets.map((d) => d.name).join(", ")}.`
2554
+ );
2555
+ }
2556
+ if (output === "json") return printJson(ds);
2557
+ const rows = [
2558
+ ...ds.dimensions.map((f) => ({
2559
+ field: f.name,
2560
+ kind: "dimension",
2561
+ type: f.type,
2562
+ about: f.description ?? ""
2563
+ })),
2564
+ ...ds.metrics.map((f) => ({
2565
+ field: f.name,
2566
+ kind: "metric",
2567
+ type: f.type,
2568
+ about: f.description ?? ""
2569
+ }))
2570
+ ];
2571
+ console.error(`dataset: ${ds.name} \u2014 ${ds.grain}`);
2572
+ printItems(rows, "table");
2573
+ }
2574
+ function register10(program2) {
2575
+ const group = program2.command("query").description(
2576
+ "Flexible reports over your event warehouse (run a report, or discover the catalog)"
2577
+ );
2578
+ group.command("run", { isDefault: true }).description("Run a report (default command)").option(
2579
+ "--json <spec>",
2580
+ "full query spec as JSON (or '-' to read stdin); flags override its keys"
2581
+ ).option(
2582
+ "--dataset <name>",
2583
+ "runs | installs | mentions | web | network | files | tokens (default runs)"
2584
+ ).option("-d, --dimensions <names>", "comma-separated GROUP BY dimensions").option("-m, --metrics <names>", "comma-separated metrics (at least one)").option(
2585
+ "--where <expr>",
2586
+ 'predicate, e.g. "action=install" (repeatable)',
2587
+ collect3
2588
+ ).option("--since <val>", "date range start \u2014 ISO date or window (30d, 24h)").option("--until <val>", "date range end \u2014 ISO date or window").option("--last-days <n>", "shorthand for --since <n> days ago").option(
2589
+ "--order-by <key:dir>",
2590
+ "sort by a selected key, e.g. installs:desc (repeatable)",
2591
+ collect3
2592
+ ).option("--limit <n>", "max rows (default 50, max 1000)").option(
2593
+ "--granularity <g>",
2594
+ "date bucket: day | week | month (default day)"
2595
+ ).option("--explain", "print the compiled SQL to stderr").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("--agent <names>", "comma-separated agent names").option("--model <models>", "comma-separated models").option(
2596
+ "--scenario <types>",
2597
+ "comma-separated scenario types (greenfield|migration)"
2598
+ ).option("--experiment <labels>", "comma-separated experiment labels").option("--branded", "only branded prompts").option("--unbranded", "only non-branded prompts").action((opts, command) => runQuery(command, opts));
2599
+ group.command("datasets").description("List the datasets you can query").action(
2600
+ (_opts, command) => showMetadata(command, "datasets")
2601
+ );
2602
+ group.command("fields").description("List the dimensions and metrics for a dataset").requiredOption("--dataset <name>", "dataset to describe").action(
2603
+ (opts, command) => showMetadata(command, "fields", opts.dataset)
2604
+ );
2605
+ }
2606
+
2247
2607
  // src/commands/repos.ts
2248
2608
  var repos_exports2 = {};
2249
2609
  __export(repos_exports2, {
2250
- register: () => register10
2610
+ register: () => register11
2251
2611
  });
2252
2612
  function reposPath(org) {
2253
2613
  return `/api/v1/orgs/${encodeURIComponent(org)}/repos`;
@@ -2270,7 +2630,7 @@ function toRow3(repo) {
2270
2630
  function syncWarning(repo) {
2271
2631
  return `warning: GitHub metadata sync failed; retry with \`gauge repos resync ${repo.url}\``;
2272
2632
  }
2273
- function register10(program2) {
2633
+ function register11(program2) {
2274
2634
  const repos = program2.command("repos").description("Manage repositories");
2275
2635
  repos.command("list").description("List repositories (yours + read-only Gauge-provided ones)").action(async (_opts, command) => {
2276
2636
  const org = resolveOrg(command);
@@ -2334,7 +2694,7 @@ function register10(program2) {
2334
2694
  // src/commands/runs.ts
2335
2695
  var runs_exports2 = {};
2336
2696
  __export(runs_exports2, {
2337
- register: () => register11
2697
+ register: () => register12
2338
2698
  });
2339
2699
  function runPath(id) {
2340
2700
  return `/api/v1/runs/${encodeURIComponent(id)}`;
@@ -2512,7 +2872,7 @@ async function streamRun(id, json, opts) {
2512
2872
  if (drainTimer) clearTimeout(drainTimer);
2513
2873
  }
2514
2874
  }
2515
- function register11(program2) {
2875
+ function register12(program2) {
2516
2876
  const runs = program2.command("runs").description("Inspect and manage runs");
2517
2877
  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(
2518
2878
  async (opts, command) => {
@@ -2574,6 +2934,20 @@ function register11(program2) {
2574
2934
  const diff = await createClient().get(`${runPath(id)}/diff`);
2575
2935
  process.stdout.write(diff);
2576
2936
  });
2937
+ 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) => {
2938
+ const result = await createClient().post(
2939
+ `${runPath(id)}/fork`,
2940
+ { prompt: opts.prompt }
2941
+ );
2942
+ if (resolveOutput(command) === "json") {
2943
+ printJson(result);
2944
+ return;
2945
+ }
2946
+ console.log(
2947
+ `Forked run ${result.runId} from ${result.parentRunId} at turn ${result.turn}`
2948
+ );
2949
+ console.error(`Watch it with: gauge runs watch ${result.runId}`);
2950
+ });
2577
2951
  runs.command("cancel <id>").description("Request cancellation of a run").action(async (id, _opts, command) => {
2578
2952
  const result = await createClient().post(
2579
2953
  `${runPath(id)}/cancel`
@@ -2592,7 +2966,7 @@ function register11(program2) {
2592
2966
  // src/commands/schedules.ts
2593
2967
  var schedules_exports2 = {};
2594
2968
  __export(schedules_exports2, {
2595
- register: () => register12
2969
+ register: () => register13
2596
2970
  });
2597
2971
  var CADENCE_CHOICES = [
2598
2972
  "none",
@@ -2628,7 +3002,7 @@ function toRow5(s) {
2628
3002
  experiment: s.experiment ?? ""
2629
3003
  };
2630
3004
  }
2631
- function register12(program2) {
3005
+ function register13(program2) {
2632
3006
  const group = program2.command("schedules").description("Manage prompt schedules");
2633
3007
  group.command("list").description("List schedules for a prompt").requiredOption("--prompt <id>", "prompt id").action(async (opts, cmd) => {
2634
3008
  const org = resolveOrg(cmd);
@@ -2699,7 +3073,7 @@ function register12(program2) {
2699
3073
  // src/commands/stats.ts
2700
3074
  var stats_exports2 = {};
2701
3075
  __export(stats_exports2, {
2702
- register: () => register13
3076
+ register: () => register14
2703
3077
  });
2704
3078
  function addFilterOptions(cmd) {
2705
3079
  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)");
@@ -2720,9 +3094,9 @@ function filterQuery(opts) {
2720
3094
  limit: opts.full ? "1000" : opts.limit
2721
3095
  };
2722
3096
  }
2723
- var pct = (rate) => `${(rate * 100).toFixed(1)}%`;
3097
+ var pct2 = (rate) => `${(rate * 100).toFixed(1)}%`;
2724
3098
  var delta = (d) => d === null || d === 0 ? "\u2014" : d > 0 ? `+${d}` : String(d);
2725
- function noteFreshness(f) {
3099
+ function noteFreshness2(f) {
2726
3100
  if (!f.available) {
2727
3101
  console.error(
2728
3102
  "warning: analytics store is temporarily unavailable; results may be incomplete."
@@ -2745,15 +3119,15 @@ async function runStats(command, resource, opts, toRow6) {
2745
3119
  return;
2746
3120
  }
2747
3121
  printItems(res.items.map(toRow6), "table");
2748
- noteFreshness(res.freshness);
3122
+ noteFreshness2(res.freshness);
2749
3123
  }
2750
3124
  var rankingRow = (r) => ({
2751
3125
  rank: r.rank,
2752
3126
  brand: r.brandName,
2753
3127
  kind: r.kind,
2754
3128
  installs: r.installs,
2755
- "install%": pct(r.installRate),
2756
- "mention%": pct(r.mentionRate),
3129
+ "install%": pct2(r.installRate),
3130
+ "mention%": pct2(r.mentionRate),
2757
3131
  delta: delta(r.deltaRank)
2758
3132
  });
2759
3133
  var packageRow = (r) => ({
@@ -2762,29 +3136,28 @@ var packageRow = (r) => ({
2762
3136
  brand: r.brandName,
2763
3137
  kind: r.kind,
2764
3138
  installs: r.installs,
2765
- rate: pct(r.rate)
3139
+ rate: pct2(r.rate)
2766
3140
  });
2767
3141
  var brandRow = (r) => ({
2768
3142
  brand: r.brandName,
2769
3143
  kind: r.kind,
2770
3144
  installs: r.installs,
2771
- rate: pct(r.rate)
3145
+ rate: pct2(r.rate)
2772
3146
  });
2773
3147
  var funnelRow = (r) => ({
2774
3148
  brand: r.brandName,
2775
3149
  kind: r.kind,
2776
- "mention%": pct(r.mentionRate),
2777
- "install%": pct(r.installRate)
3150
+ "mention%": pct2(r.mentionRate),
3151
+ "install%": pct2(r.installRate)
2778
3152
  });
2779
3153
  var domainRow = (r) => ({
2780
3154
  domain: r.domain,
2781
3155
  brand: r.brandName,
2782
3156
  runs: r.runs,
2783
- rate: pct(r.rate),
2784
- requests: r.requests,
2785
- denied: r.deniedRequests
3157
+ rate: pct2(r.rate),
3158
+ requests: r.requests
2786
3159
  });
2787
- function register13(program2) {
3160
+ function register14(program2) {
2788
3161
  const group = program2.command("stats").description("Read-only analytics over your runs");
2789
3162
  addFilterOptions(
2790
3163
  group.command("rankings").description("Brands ranked by install rate")
@@ -2816,12 +3189,12 @@ function register13(program2) {
2816
3189
  // src/commands/tags.ts
2817
3190
  var tags_exports2 = {};
2818
3191
  __export(tags_exports2, {
2819
- register: () => register14
3192
+ register: () => register15
2820
3193
  });
2821
3194
  function tagsPath(org) {
2822
3195
  return `/api/v1/orgs/${encodeURIComponent(org)}/tags`;
2823
3196
  }
2824
- function register14(program2) {
3197
+ function register15(program2) {
2825
3198
  const group = program2.command("tags").description("Manage org tags");
2826
3199
  group.command("list").description("List tags").action(async (_opts, cmd) => {
2827
3200
  const org = resolveOrg(cmd);
@@ -2864,12 +3237,12 @@ function register14(program2) {
2864
3237
  // src/commands/topics.ts
2865
3238
  var topics_exports2 = {};
2866
3239
  __export(topics_exports2, {
2867
- register: () => register15
3240
+ register: () => register16
2868
3241
  });
2869
3242
  function topicsPath(org) {
2870
3243
  return `/api/v1/orgs/${encodeURIComponent(org)}/topics`;
2871
3244
  }
2872
- function register15(program2) {
3245
+ function register16(program2) {
2873
3246
  const group = program2.command("topics").description("Manage org topics");
2874
3247
  group.command("list").description("List topics").action(async (_opts, cmd) => {
2875
3248
  const org = resolveOrg(cmd);
@@ -2890,9 +3263,9 @@ function register15(program2) {
2890
3263
  // src/commands/usage.ts
2891
3264
  var usage_exports = {};
2892
3265
  __export(usage_exports, {
2893
- register: () => register16
3266
+ register: () => register17
2894
3267
  });
2895
- function register16(program2) {
3268
+ function register17(program2) {
2896
3269
  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(
2897
3270
  async (opts, cmd) => {
2898
3271
  const org = resolveOrg(cmd);
@@ -2962,6 +3335,7 @@ for (const group of [
2962
3335
  billing_exports2,
2963
3336
  usage_exports,
2964
3337
  stats_exports2,
3338
+ query_exports2,
2965
3339
  config_exports
2966
3340
  ]) {
2967
3341
  group.register(program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withgauge/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Gauge customer CLI — prompts, repos, runs & org settings over the Gauge API",
5
5
  "private": false,
6
6
  "author": "Gauge <support@withgauge.com> (https://withgauge.com)",