@gravity-rail/cli 0.40.0 → 0.43.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/lib.js CHANGED
@@ -3153,10 +3153,14 @@ Assistant / models (live on the DRAFT revision \u2014 publish to go live)
3153
3153
  chatModelId (string) Text chat model (see \`gr ai-models chat\`)
3154
3154
  chatModelConfig (object|null) Chat model overrides
3155
3155
  realtimeModelId (string|null) Voice/realtime model (see \`gr ai-models realtime\`)
3156
+ create: omit \u2192 xai:realtime:voice-agent-2 with
3157
+ voice xai:voice:cosmo; null = voice off
3158
+ update: null = voice off
3156
3159
  One-shot voice example:
3157
3160
  {"realtimeModelId":"xai:realtime:voice-agent-2"}
3158
- Native models auto-fill tts=native + default voice
3159
- (xAI \u2192 xai:voice:eve). Optional explicit config:
3161
+ A native model named WITHOUT a config gets
3162
+ tts=native + the provider fallback voice
3163
+ (xAI \u2192 xai:voice:eve, not cosmo). Explicit config:
3160
3164
  {"realtimeModelId":"xai:realtime:voice-agent-2",
3161
3165
  "realtimeModelConfig":{"ttsModel":"native",
3162
3166
  "voiceModel":"xai:voice:ara"}}
@@ -7510,6 +7514,23 @@ async function readBindings(hctx) {
7510
7514
  }
7511
7515
  return payload;
7512
7516
  }
7517
+ var CREATE_INBOX_ARG = {
7518
+ name: "create-inbox",
7519
+ description: "Comma-separated Inbox slot keys to fill by creating an Inbox (one per installation, named for the Bundle; needs inboxes:write)"
7520
+ };
7521
+ async function readSlotTargets(hctx) {
7522
+ const bindings = await readBindings(hctx);
7523
+ const keys = (optionalString(hctx.args, "create-inbox") ?? "").split(",").map((key) => key.trim()).filter(Boolean);
7524
+ if (keys.length === 0) return bindings;
7525
+ const merged = { ...bindings };
7526
+ for (const key of keys) {
7527
+ if (merged[key]) {
7528
+ throw new CLIError(`--create-inbox "${key}" is also set in --bindings; choose one`);
7529
+ }
7530
+ merged[key] = { kind: "new_inbox" };
7531
+ }
7532
+ return merged;
7533
+ }
7513
7534
  async function guardConflict(run, hint2) {
7514
7535
  try {
7515
7536
  return await run();
@@ -7583,18 +7604,20 @@ var installationCommands = [
7583
7604
  {
7584
7605
  name: "bindings",
7585
7606
  description: "Path to a JSON object mapping slot keys to targets"
7586
- }
7607
+ },
7608
+ CREATE_INBOX_ARG
7587
7609
  ],
7588
7610
  examples: [
7589
7611
  "gr bundles install -w $WID --bundle <bundle-uuid> --allow-write",
7590
- "gr bundles install -w $WID --bundle <bundle-uuid> --bindings bindings.json --allow-write"
7612
+ "gr bundles install -w $WID --bundle <bundle-uuid> --bindings bindings.json --allow-write",
7613
+ "gr bundles install -w $WID --bundle <bundle-uuid> --create-inbox program.inbox --allow-write"
7591
7614
  ],
7592
7615
  handler: async (hctx) => {
7593
7616
  const bundle = requireBundleUuid(hctx);
7594
7617
  const summary = await getBundleSummary(hctx, bundle);
7595
7618
  const version = summary.publishedVersion;
7596
7619
  if (version == null) throw new CLIError("Publish the Bundle before installing it");
7597
- const bindings = await readBindings(hctx);
7620
+ const bindings = await readSlotTargets(hctx);
7598
7621
  const result2 = await guardConflict(
7599
7622
  () => client(hctx).installBundle(hctx.workspace, bundle, {
7600
7623
  version,
@@ -7709,6 +7732,7 @@ var installationCommands = [
7709
7732
  name: "bindings",
7710
7733
  description: "Path to a JSON object mapping new slot keys to targets"
7711
7734
  },
7735
+ CREATE_INBOX_ARG,
7712
7736
  { name: "preview", description: "Show what would change and write nothing", isFlag: true }
7713
7737
  ],
7714
7738
  examples: [
@@ -7725,7 +7749,7 @@ var installationCommands = [
7725
7749
  );
7726
7750
  return;
7727
7751
  }
7728
- const bindings = await readBindings(hctx);
7752
+ const bindings = await readSlotTargets(hctx);
7729
7753
  const result2 = await guardConflict(
7730
7754
  () => client(hctx).upgradeInstallation(hctx.workspace, uuid, {
7731
7755
  toVersion: to,
@@ -7767,17 +7791,17 @@ var installationCommands = [
7767
7791
  INSTALLATION_ARG,
7768
7792
  {
7769
7793
  name: "bindings",
7770
- description: "Path to a JSON object mapping slot keys to targets",
7771
- required: true
7772
- }
7794
+ description: "Path to a JSON object mapping slot keys to targets"
7795
+ },
7796
+ CREATE_INBOX_ARG
7773
7797
  ],
7774
7798
  examples: [
7775
7799
  "gr bundles bind -w $WID --installation <installation-uuid> --bindings bindings.json --allow-write"
7776
7800
  ],
7777
7801
  handler: async (hctx) => {
7778
- const bindings = await readBindings(hctx);
7802
+ const bindings = await readSlotTargets(hctx);
7779
7803
  if (!bindings || Object.keys(bindings).length === 0) {
7780
- throw new CLIError("--bindings must name at least one slot");
7804
+ throw new CLIError("--bindings or --create-inbox must name at least one slot");
7781
7805
  }
7782
7806
  const result2 = await guardConflict(
7783
7807
  () => client(hctx).bindInstallationSlots(hctx.workspace, installationUuid(hctx), {
@@ -7862,6 +7886,18 @@ function parseDraftItems(payload) {
7862
7886
  });
7863
7887
  return items;
7864
7888
  }
7889
+ function parseDraftLinks(payload) {
7890
+ const links = payload.links;
7891
+ if (links === void 0) return void 0;
7892
+ if (!Array.isArray(links)) throw new CLIError('"links" must be an array');
7893
+ links.forEach((link, index) => {
7894
+ const record2 = link;
7895
+ if (typeof record2 !== "object" || record2 === null || typeof record2.label !== "string" || typeof record2.url !== "string") {
7896
+ throw new CLIError(`links[${index}] needs string "label" and "url"`);
7897
+ }
7898
+ });
7899
+ return links;
7900
+ }
7865
7901
  async function currentGeneration(hctx, uuid) {
7866
7902
  const expected2 = optionalNumber(hctx.args, "expected-generation");
7867
7903
  if (expected2 !== void 0) {
@@ -7937,6 +7973,14 @@ Draft generation: ${version.draftGeneration}
7937
7973
  hctx.ctx,
7938
7974
  ITEM_COLUMNS
7939
7975
  );
7976
+ if (version.links?.length) {
7977
+ process.stdout.write(
7978
+ `
7979
+ Links:
7980
+ ${version.links.map((link) => ` ${link.label}: ${link.url}`).join("\n")}
7981
+ `
7982
+ );
7983
+ }
7940
7984
  if (version.releaseNotes) {
7941
7985
  process.stdout.write(`
7942
7986
  Release notes:
@@ -8106,7 +8150,7 @@ var bundlesDomain = {
8106
8150
  },
8107
8151
  {
8108
8152
  path: ["bundles", "draft", "set"],
8109
- description: 'Replace draft items from {"items": [...]}; use --expected-generation from draft get to protect edits.',
8153
+ description: 'Replace draft items from {"items": [...]}; an optional "links": [{"label", "url"}] replaces the draft links. Use --expected-generation from draft get to protect edits.',
8110
8154
  requiresWorkspace: true,
8111
8155
  mutates: true,
8112
8156
  args: [BUNDLE_ARG, GENERATION_ARG],
@@ -8115,11 +8159,13 @@ var bundlesDomain = {
8115
8159
  ],
8116
8160
  handler: async (hctx) => {
8117
8161
  const items = parseDraftItems(hctx.data);
8162
+ const links = parseDraftLinks(hctx.data);
8118
8163
  const uuid = bundleUuid(hctx);
8119
8164
  const expectedGeneration = await currentGeneration(hctx, uuid);
8120
8165
  const result2 = await client2(hctx).replaceBundleDraft(hctx.workspace, uuid, {
8121
8166
  expectedGeneration,
8122
- items
8167
+ items,
8168
+ ...links ? { links } : {}
8123
8169
  });
8124
8170
  writeVersionDetail(hctx, result2);
8125
8171
  }
@@ -8168,28 +8214,30 @@ var bundlesDomain = {
8168
8214
  },
8169
8215
  {
8170
8216
  path: ["bundles", "grant"],
8171
- description: "Share a published Bundle within its organization with full source visibility",
8217
+ description: "Share a published Bundle with its organization, or with everyone as a superuser",
8172
8218
  requiresWorkspace: true,
8173
8219
  mutates: true,
8174
8220
  args: [
8175
8221
  BUNDLE_ARG,
8176
8222
  ...sharingArgs.filter((arg) => arg.name !== "disclosure").map(
8177
- (arg) => arg.name === "to" ? { ...arg, description: "organization (publishing organization only)" } : arg.name === "uuid" ? { ...arg, description: "Publishing organization UUID", required: true } : arg
8223
+ (arg) => arg.name === "to" ? {
8224
+ ...arg,
8225
+ description: "organization (publishing organization only) | global (everyone; superuser only)"
8226
+ } : arg.name === "uuid" ? {
8227
+ ...arg,
8228
+ description: "Publishing organization UUID (omit with --to global)"
8229
+ } : arg
8178
8230
  )
8179
8231
  ],
8180
8232
  examples: [
8181
- "gr bundles grant -w $WID --allow-write --bundle <bundle-uuid> --to organization --uuid <org-uuid>"
8233
+ "gr bundles grant -w $WID --allow-write --bundle <bundle-uuid> --to organization --uuid <org-uuid>",
8234
+ "gr bundles grant -w $WID --allow-write --bundle <bundle-uuid> --to global"
8182
8235
  ],
8183
8236
  handler: async (hctx) => {
8184
- if (requireString(hctx.args, "to") === "global") {
8185
- throw new CLIError(
8186
- "Bundle sharing is organization-only; official solution approval uses the staff catalog command"
8187
- );
8188
- }
8189
8237
  const request = sharingRequest(hctx.args, "full");
8190
- if (request.granteeType !== "organization") {
8238
+ if (request.granteeType === "workspace") {
8191
8239
  throw new CLIError(
8192
- "Share Bundles with their organization, then install per workspace"
8240
+ "Share Bundles with their organization or with everyone, then install per workspace"
8193
8241
  );
8194
8242
  }
8195
8243
  const bundleRequest = {
@@ -9343,7 +9391,6 @@ var metricsDomain = {
9343
9391
  var COLUMNS12 = [
9344
9392
  COL.id(),
9345
9393
  COL.name(),
9346
- { header: "AGE", getValue: (item) => item.age != null ? String(item.age) : "" },
9347
9394
  {
9348
9395
  header: "HAS_PHONE",
9349
9396
  getValue: (item) => item.hasPhone ? "yes" : "no"
@@ -19442,6 +19489,14 @@ var supervisorsDomain = {
19442
19489
  function runOutcome(run) {
19443
19490
  return run.outcome ?? run.status ?? "";
19444
19491
  }
19492
+ function replayedPages(run) {
19493
+ return typeof run.replayedPages === "number" ? run.replayedPages : 0;
19494
+ }
19495
+ function countSummary(run) {
19496
+ const replayed = replayedPages(run);
19497
+ const replay = replayed > 0 ? `, replayed pages: ${replayed}` : "";
19498
+ return `${run.synced} synced, ${run.failed} failed, ${run.skipped} skipped (${run.total} total${replay})`;
19499
+ }
19445
19500
  var RUN_COLUMNS2 = [
19446
19501
  { header: "RUN ID", getValue: (item) => item.runId ?? "" },
19447
19502
  { header: "OUTCOME", getValue: (item) => runOutcome(item) },
@@ -19451,6 +19506,7 @@ var RUN_COLUMNS2 = [
19451
19506
  { header: "SYNCED", getValue: (item) => String(item.synced ?? 0) },
19452
19507
  { header: "FAILED", getValue: (item) => String(item.failed ?? 0) },
19453
19508
  { header: "SKIPPED", getValue: (item) => String(item.skipped ?? 0) },
19509
+ { header: "REPLAYED PAGES", getValue: (item) => String(replayedPages(item)) },
19454
19510
  { header: "DRY RUN", getValue: (item) => item.dryRun ? "yes" : "no" },
19455
19511
  { header: "STARTED", getValue: (item) => item.startedAt ?? "" }
19456
19512
  ];
@@ -19489,9 +19545,7 @@ async function streamSyncRun(response, verbose) {
19489
19545
  lastRun = data;
19490
19546
  if (verbose) {
19491
19547
  const s = data;
19492
- process.stderr.write(
19493
- `\r ${runOutcome(s)} \u2014 ${s.synced} synced, ${s.failed} failed, ${s.skipped} skipped (${s.total} total)`
19494
- );
19548
+ process.stderr.write(`\r ${runOutcome(s)} \u2014 ${countSummary(s)}`);
19495
19549
  }
19496
19550
  } else if (data.type === "sync_item") {
19497
19551
  if (verbose) {