@gravity-rail/cli 0.15.0 → 0.17.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
@@ -59,6 +59,19 @@ var COMMON_ARGS = [
59
59
  { name: "id", description: "Entity ID" },
60
60
  { name: "uuid", description: "Entity UUID" }
61
61
  ];
62
+ var ORG_UUID_ARG = {
63
+ name: "org-uuid",
64
+ aliases: ["org"],
65
+ description: "Organization UUID or ID",
66
+ required: true
67
+ };
68
+ function requireOrgRef(args) {
69
+ const val = args["org-uuid"] ?? args.org;
70
+ if (typeof val !== "string" || !val) {
71
+ throw new CLIError("Missing required argument: --org-uuid");
72
+ }
73
+ return val;
74
+ }
62
75
  function parseArgs(defs, argv) {
63
76
  const allDefs = [...defs, ...COMMON_ARGS];
64
77
  const result2 = {};
@@ -838,8 +851,8 @@ var CommandRegistry = class {
838
851
  const key = cmd.path.join(" ");
839
852
  this.commands.set(key, cmd);
840
853
  }
841
- registerCommands(commands3) {
842
- for (const cmd of commands3) {
854
+ registerCommands(commands4) {
855
+ for (const cmd of commands4) {
843
856
  this.registerCommand(cmd);
844
857
  }
845
858
  }
@@ -1215,6 +1228,43 @@ var agentTasksDomain = {
1215
1228
 
1216
1229
  // src/domains/agents.ts
1217
1230
  var COLUMNS = [COL.id(), COL.uuid(), COL.name(), COL.status(), COL.created()];
1231
+ var AGENT_FIELD_REFERENCE = `
1232
+ Field reference for --data JSON (create/update):
1233
+
1234
+ Required on create
1235
+ name (string) Display name
1236
+ chatModelId (string) Text chat model ID (see \`gr ai-models chat\`)
1237
+ e.g. "aws:bedrock:claude-4-5-haiku"
1238
+
1239
+ Optional
1240
+ description (string) Short summary shown in listings
1241
+ systemPrompt (string) Base instructions / identity
1242
+ chatModelConfig (object|null) Chat model overrides (temperature, thinking, \u2026)
1243
+ realtimeModelId (string|null) Voice/realtime model (see \`gr ai-models realtime\`)
1244
+ e.g. "xai:realtime:voice-agent-2" (Grok Voice Think Fast 2)
1245
+ Native models auto-fill tts=native + default voice when
1246
+ realtimeModelConfig is omitted.
1247
+ realtimeModelConfig (object|null) Realtime config. Native example:
1248
+ {"ttsModel":"native","voiceModel":"xai:voice:eve"}
1249
+ Composable (custom:realtime:composable) needs
1250
+ voiceModel + ttsModel + inferenceModel.
1251
+ memberRoleId (number) Role id (omit to use the default Agent role)
1252
+ email / phone / externalId Optional contact fields
1253
+ labelIds (number[]) Member label ids
1254
+ codeInterpreterEnabled (bool)
1255
+ maxDailyActions (number|null)
1256
+
1257
+ Attach an agent\u2019s models/identity to a workflow (draft), then publish:
1258
+ gr workflows update --id <wf> -d '{"copyFromAgentId": <agentId>}'
1259
+ gr workflows publish --id <wf>
1260
+
1261
+ One-shot workflow voice WITHOUT creating an agent (preferred for "use Grok Voice 2"):
1262
+ gr workflows update --id <wf> -d '{"realtimeModelId":"xai:realtime:voice-agent-2"}'
1263
+ gr workflows publish --id <wf>
1264
+
1265
+ List models:
1266
+ gr ai-models chat | realtime | voice
1267
+ `;
1218
1268
  var agentsDomain = {
1219
1269
  name: "agents",
1220
1270
  description: "Manage agents",
@@ -1231,9 +1281,16 @@ var agentsDomain = {
1231
1281
  unarchiveMethod: "unarchiveAgent",
1232
1282
  columns: COLUMNS,
1233
1283
  paginationSupport: "full",
1234
- updateHelp: "Update an agent. Body schema (JSON via --data/--file/stdin), all fields optional:\n name string display name\n description string short summary shown in listings\n systemPrompt string base instructions for the agent\n model string AI model slug (see `gr ai-models list`)\n temperature number sampling temperature (0-2)\n avatarFileId number workspace file ID for the avatar\n config object AgentConfig overrides (advanced)\nWorkflow abilities are managed with `gr abilities`.",
1284
+ createHelp: `Create an agent
1285
+ ${AGENT_FIELD_REFERENCE}`,
1286
+ updateHelp: `Update an agent. All fields optional.
1287
+ ${AGENT_FIELD_REFERENCE}`,
1288
+ createExamples: [
1289
+ `gr agents create -d '{"name":"Support","chatModelId":"aws:bedrock:claude-4-5-haiku","realtimeModelId":"xai:realtime:voice-agent-2"}'`,
1290
+ "gr agents create --file agent.json"
1291
+ ],
1235
1292
  updateExamples: [
1236
- `gr agents update --id 42 --data '{"name":"Scheduler","temperature":0.4}'`,
1293
+ `gr agents update --id 42 -d '{"realtimeModelId":"xai:realtime:voice-agent-2"}'`,
1237
1294
  "gr agents update --id 42 --file agent.json"
1238
1295
  ]
1239
1296
  })
@@ -1307,6 +1364,42 @@ var FEEDBACK_COLUMNS = [
1307
1364
  },
1308
1365
  COL.created()
1309
1366
  ];
1367
+ async function respondWithValue(ctx, workspace, args) {
1368
+ const chatId = requireIdOrUuidFrom(args, "chat-id", "id");
1369
+ const chat = await requireAuth(ctx).apiClient.getChat(workspace, chatId);
1370
+ const interrupt = chat?.interrupt;
1371
+ if (!interrupt || !interrupt.interruptId) {
1372
+ throw new Error("No pending interrupt on this chat.");
1373
+ }
1374
+ const raw = args.value;
1375
+ if (typeof raw !== "string" || !raw.length) {
1376
+ throw new Error(
1377
+ `A --value is required. For a form pass the field map as JSON, e.g. --value '{"channels":"sms,voice","days":"2"}'; for a choice list pass the chosen value.`
1378
+ );
1379
+ }
1380
+ const url = `${ctx.envConfig.apiUrl}/api/v2/w/${workspace}/chats/${chat.id}/inference/hitl`;
1381
+ const response = await fetch(url, {
1382
+ method: "POST",
1383
+ headers: {
1384
+ Authorization: `Bearer ${requireAuth(ctx).accessToken}`,
1385
+ "Content-Type": "application/json"
1386
+ },
1387
+ body: JSON.stringify({ chosenValue: raw, interruptId: interrupt.interruptId })
1388
+ });
1389
+ if (!response.ok) {
1390
+ throw new Error(
1391
+ `Resume failed (${response.status}): ${(await response.text()).slice(0, 400)}`
1392
+ );
1393
+ }
1394
+ outputSingle(
1395
+ {
1396
+ status: "resumed",
1397
+ chatId: chat.id,
1398
+ next: `gr chats inspect --id ${chat.id} -w ${workspace}`
1399
+ },
1400
+ ctx
1401
+ );
1402
+ }
1310
1403
  async function respondToInterrupt(ctx, workspace, args, decisionType) {
1311
1404
  const chatId = requireIdOrUuidFrom(args, "chat-id", "id");
1312
1405
  const chat = await requireAuth(ctx).apiClient.getChat(workspace, chatId);
@@ -1339,6 +1432,27 @@ async function respondToInterrupt(ctx, workspace, args, decisionType) {
1339
1432
  if (streamError) throw new Error(`Inference error: ${streamError}`);
1340
1433
  outputSingle({ role: "assistant", content: buffered }, ctx, MESSAGE_COLUMNS2);
1341
1434
  }
1435
+ function isDevProfile(env) {
1436
+ return env === "dev" || env === "development" || env === "local";
1437
+ }
1438
+ function isLocalApiOrigin(apiUrl) {
1439
+ if (!apiUrl) return false;
1440
+ try {
1441
+ const host = new URL(apiUrl).hostname.replace(/^\[|\]$/g, "");
1442
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host.endsWith(".gravityrail.test");
1443
+ } catch {
1444
+ return false;
1445
+ }
1446
+ }
1447
+ async function shouldRedactChatContent(ctx, apiClient, workspace) {
1448
+ if (isDevProfile(ctx.env) && isLocalApiOrigin(ctx.envConfig?.apiUrl)) return false;
1449
+ try {
1450
+ const ws = await apiClient.getWorkspace(workspace);
1451
+ return ws.phiPostureDecision !== "allow_non_phi";
1452
+ } catch {
1453
+ return true;
1454
+ }
1455
+ }
1342
1456
  var chatsDomain = {
1343
1457
  name: "chats",
1344
1458
  description: "Manage chats",
@@ -1535,6 +1649,28 @@ var chatsDomain = {
1535
1649
  await respondToInterrupt(ctx, workspace, args, decisionType);
1536
1650
  }
1537
1651
  },
1652
+ {
1653
+ path: ["chats", "interrupt", "respond"],
1654
+ description: "Answer a chat's pending UI interrupt (form or choice list) with a value, and stream the continued reply.",
1655
+ mutates: true,
1656
+ requiresWorkspace: true,
1657
+ args: [
1658
+ {
1659
+ name: "chat-id",
1660
+ aliases: ["id"],
1661
+ description: "Chat ID (numeric id preferred; uuid accepted)",
1662
+ required: true
1663
+ },
1664
+ {
1665
+ name: "value",
1666
+ description: `The answer. For a form, the field map as JSON (e.g. '{"channels":"sms,voice","days":"2"}'); for a choice list, the chosen value.`,
1667
+ required: true
1668
+ }
1669
+ ],
1670
+ handler: async ({ ctx, workspace, args }) => {
1671
+ await respondWithValue(ctx, workspace, args);
1672
+ }
1673
+ },
1538
1674
  {
1539
1675
  path: ["chats", "interrupt", "deny"],
1540
1676
  description: "Reject a chat's pending approval request with a reason.",
@@ -1565,7 +1701,17 @@ var chatsDomain = {
1565
1701
  description: "Chat ID (numeric id preferred; uuid accepted)",
1566
1702
  required: true
1567
1703
  },
1568
- { name: "stream", description: "Stream the AI response via AG-UI", isFlag: true }
1704
+ { name: "stream", description: "Stream the AI response via AG-UI", isFlag: true },
1705
+ {
1706
+ // Read by the handler below since this command was written, but
1707
+ // never declared — so `--auto-approve` parsed as nothing and the
1708
+ // turn stopped on every tool call anyway. Driving a manager turn
1709
+ // from the CLI meant approving each exec by hand, which is why
1710
+ // multi-turn QA was impractical.
1711
+ name: "auto-approve",
1712
+ description: "Approve tool calls automatically for this turn (development QA). Capability round-trips (screenshots, browser, forms) still prompt.",
1713
+ isFlag: true
1714
+ }
1569
1715
  ],
1570
1716
  handler: async ({ ctx, workspace, args, data }) => {
1571
1717
  const content = typeof data === "string" ? data : data?.content;
@@ -1600,7 +1746,11 @@ var chatsDomain = {
1600
1746
  );
1601
1747
  process.stdout.write("\n");
1602
1748
  if (!streamed.trim()) {
1603
- await printPendingApproval(ctx, workspace, chatId);
1749
+ if (!await printPendingApproval(ctx, workspace, chatId)) {
1750
+ throw new Error(
1751
+ `No response was produced for chat ${chatId}, and no approval is pending. The inference stream ended without emitting anything \u2014 usually the turn never started.`
1752
+ );
1753
+ }
1604
1754
  }
1605
1755
  } else {
1606
1756
  const aguiClient = new AGUIClient({
@@ -1630,6 +1780,9 @@ var chatsDomain = {
1630
1780
  chatId
1631
1781
  );
1632
1782
  if (await printPendingApproval(ctx, workspace, chatId, chat)) return;
1783
+ throw new Error(
1784
+ `No response was produced for chat ${chatId}, and no approval is pending. The inference stream ended without emitting anything \u2014 usually the turn never started. Check the API log for "Inference stream timed out for key inference:${workspace}:${chatId}" and the temporal-worker log for an "inference-${workspace}-${chatId}" workflow.`
1785
+ );
1633
1786
  }
1634
1787
  outputSingle(
1635
1788
  {
@@ -1772,6 +1925,8 @@ var chatsDomain = {
1772
1925
  authed.apiClient.getChat(workspace, chatId),
1773
1926
  authed.apiClient.getChatMessages(workspace, chatId)
1774
1927
  ]);
1928
+ const redact = await shouldRedactChatContent(ctx, authed.apiClient, workspace);
1929
+ const hide = (value) => redact ? "[REDACTED]" : value;
1775
1930
  const result2 = {
1776
1931
  chat: {
1777
1932
  id: chat.id,
@@ -1787,7 +1942,7 @@ var chatsDomain = {
1787
1942
  // field projections (#20262). Always an array so the key
1788
1943
  // survives JSON serialization even when the API omits it.
1789
1944
  participants: (chat.participants ?? []).map((p) => ({
1790
- name: "[REDACTED]",
1945
+ name: hide(p.name),
1791
1946
  role: p.role,
1792
1947
  memberId: p.memberId ?? null,
1793
1948
  memberType: p.memberType ?? null
@@ -1795,11 +1950,13 @@ var chatsDomain = {
1795
1950
  },
1796
1951
  // Deliberate allow-list — never spread the API message. PHI
1797
1952
  // lives in content and (if ever added) sttMetadata.words
1798
- // (#21973); both must stay out of inspect output.
1953
+ // (#21973), so nothing beyond these three keys is emitted; the
1954
+ // content itself is gated on posture (see
1955
+ // shouldRedactChatContent), not blanket-hidden.
1799
1956
  messages: messages.map((m) => ({
1800
1957
  id: m.id,
1801
1958
  role: m.role,
1802
- content: "[REDACTED]"
1959
+ content: hide(m.content)
1803
1960
  }))
1804
1961
  };
1805
1962
  const assignmentId = chat.assignmentId;
@@ -1817,7 +1974,7 @@ var chatsDomain = {
1817
1974
  dataRecords: assignment.dataRecords?.map((dr) => ({
1818
1975
  id: dr.id,
1819
1976
  dataTypeId: dr.dataTypeId,
1820
- fieldValues: "[REDACTED]"
1977
+ fieldValues: hide(dr.fieldValues)
1821
1978
  }))
1822
1979
  };
1823
1980
  }
@@ -2205,8 +2362,26 @@ Core
2205
2362
  name (string) Display name
2206
2363
  description (string, optional)
2207
2364
  defaultPhoneNumberId (number|null) Outbound caller ID (workspace phone id)
2365
+ defaultInboxId (number|null) Default inbox for inbound messaging
2208
2366
  permissions (object, optional) Workflow-level permission flags
2209
2367
 
2368
+ Assistant / models (live on the DRAFT revision \u2014 publish to go live)
2369
+ assistantName (string) Display name for the workflow assistant
2370
+ assistantIdentity (string) Persona / identity instructions
2371
+ chatModelId (string) Text chat model (see \`gr ai-models chat\`)
2372
+ chatModelConfig (object|null) Chat model overrides
2373
+ realtimeModelId (string|null) Voice/realtime model (see \`gr ai-models realtime\`)
2374
+ One-shot voice example:
2375
+ {"realtimeModelId":"xai:realtime:voice-agent-2"}
2376
+ Native models auto-fill tts=native + default voice
2377
+ (xAI \u2192 xai:voice:eve). Optional explicit config:
2378
+ {"realtimeModelId":"xai:realtime:voice-agent-2",
2379
+ "realtimeModelConfig":{"ttsModel":"native",
2380
+ "voiceModel":"xai:voice:ara"}}
2381
+ realtimeModelConfig (object|null) Realtime config; omit for provider defaults
2382
+ copyFromAgentId (number) Copy full assistant settings from an agent
2383
+ copyFromWorkflowRevisionId (number) Copy assistant settings from a revision
2384
+
2210
2385
  Member role access (memberRoleAccess)
2211
2386
  Array of objects, NOT bare role ids:
2212
2387
  [{"memberRoleId": 6, "accessMode": 1}]
@@ -2232,6 +2407,9 @@ Use the dedicated commands:
2232
2407
  workflows revisions edit Branch a published revision back into the draft
2233
2408
  workflows revisions diff Compare two revisions
2234
2409
  workflows revisions update Edit a revision's label / publish notes
2410
+
2411
+ After changing assistant/realtime fields, publish so live traffic picks them up:
2412
+ gr workflows publish --id <workflowId>
2235
2413
  `;
2236
2414
 
2237
2415
  // src/domains/workflows.ts
@@ -3142,8 +3320,6 @@ Provisioning started. Watch it come up with:
3142
3320
  "inboxes",
3143
3321
  "routines",
3144
3322
  "memberFilters",
3145
- "milestones",
3146
- "milestoneGoals",
3147
3323
  "customToolkits",
3148
3324
  "customTools",
3149
3325
  "pages",
@@ -3224,8 +3400,6 @@ Provisioning started. Watch it come up with:
3224
3400
  "inboxes",
3225
3401
  "routines",
3226
3402
  "memberFilters",
3227
- "milestones",
3228
- "milestoneGoals",
3229
3403
  "customToolkits",
3230
3404
  "customTools",
3231
3405
  "pages",
@@ -5617,8 +5791,156 @@ var journeysDomain = {
5617
5791
  ]
5618
5792
  };
5619
5793
 
5620
- // src/domains/personas.ts
5794
+ // src/domains/metrics.ts
5621
5795
  var COLUMNS11 = [
5796
+ COL.id(),
5797
+ COL.name(),
5798
+ { header: "SLUG", getValue: (item) => item.slug ?? "" },
5799
+ { header: "TYPE", getValue: (item) => item.metricType ?? "" },
5800
+ { header: "SOURCE", getValue: (item) => item.source ?? "" },
5801
+ { header: "UNIT", getValue: (item) => item.unit ?? "" },
5802
+ {
5803
+ header: "ENABLED",
5804
+ getValue: (item) => item.enabled ? "yes" : "no"
5805
+ },
5806
+ COL.created()
5807
+ ];
5808
+ var OBS_COLUMNS = [
5809
+ COL.id(),
5810
+ { header: "VALUE", getValue: (item) => String(item.value ?? "") },
5811
+ { header: "OBSERVED_AT", getValue: (item) => item.observedAt ?? "" },
5812
+ {
5813
+ header: "CHAT_ID",
5814
+ getValue: (item) => item.chatId != null ? String(item.chatId) : ""
5815
+ },
5816
+ {
5817
+ header: "MEMBER_ID",
5818
+ getValue: (item) => item.memberId != null ? String(item.memberId) : ""
5819
+ }
5820
+ ];
5821
+ var metricsDomain = {
5822
+ name: "metrics",
5823
+ description: "Customer-defined outcome metrics (CEL expression or LLM rubric) with time-series readout",
5824
+ commands: [
5825
+ ...crudCommands({
5826
+ prefix: ["metrics"],
5827
+ entityName: "metric",
5828
+ listMethod: "listMetrics",
5829
+ getMethod: "getMetric",
5830
+ createMethod: "createMetric",
5831
+ updateMethod: "updateMetric",
5832
+ deleteMethod: "deleteMetric",
5833
+ columns: COLUMNS11,
5834
+ paginationSupport: "full",
5835
+ createExamples: [
5836
+ `yarn gr metrics create -w $WID --allow-write --data '{"name":"SMS Channel Rate","metricType":"expression","celExpression":"chat.channel == \\"phone-sms\\"","unit":"rate"}'`,
5837
+ `yarn gr metrics create -w $WID --allow-write --data '{"name":"Qualified Engagement","metricType":"rubric","evaluationPrompt":"Did the user show buying intent?","unit":"rate"}'`
5838
+ ],
5839
+ createHelp: "Create a metric definition. metricType is expression (CEL) or rubric (LLM). MVP source is chat only."
5840
+ }),
5841
+ {
5842
+ path: ["metrics", "observations"],
5843
+ description: "List raw observations for a metric in a date range (may include PHI reason)",
5844
+ args: [
5845
+ { name: "id", required: true, description: "Metric ID" },
5846
+ {
5847
+ name: "start",
5848
+ required: true,
5849
+ description: "ISO-8601 inclusive lower bound on observed_at"
5850
+ },
5851
+ {
5852
+ name: "end",
5853
+ required: true,
5854
+ description: "ISO-8601 exclusive upper bound on observed_at"
5855
+ },
5856
+ { name: "page", description: "Page number (default 1)" },
5857
+ { name: "page-size", description: "Page size (default 100)" }
5858
+ ],
5859
+ requiresWorkspace: true,
5860
+ examples: [
5861
+ "yarn gr metrics observations --id 1 --start 2026-07-01T00:00:00Z --end 2026-08-01T00:00:00Z"
5862
+ ],
5863
+ handler: async (hctx) => {
5864
+ const client = requireAuth(hctx.ctx).apiClient;
5865
+ const id = requireNumber(hctx.args, "id");
5866
+ const start = requireString(hctx.args, "start");
5867
+ const end = requireString(hctx.args, "end");
5868
+ const page = hctx.args["page"] != null ? Number(hctx.args["page"]) : void 0;
5869
+ const pageSize = hctx.args["page-size"] != null ? Number(hctx.args["page-size"]) : void 0;
5870
+ const result2 = await client.listMetricObservations(hctx.workspace, id, {
5871
+ start,
5872
+ end,
5873
+ page,
5874
+ pageSize
5875
+ });
5876
+ outputData(result2.items ?? result2, hctx.ctx, OBS_COLUMNS);
5877
+ }
5878
+ },
5879
+ {
5880
+ path: ["metrics", "series"],
5881
+ description: "Time-bucketed aggregation for a metric (numeric only)",
5882
+ args: [
5883
+ { name: "id", required: true, description: "Metric ID" },
5884
+ {
5885
+ name: "start",
5886
+ required: true,
5887
+ description: "ISO-8601 inclusive lower bound on observed_at"
5888
+ },
5889
+ {
5890
+ name: "end",
5891
+ required: true,
5892
+ description: "ISO-8601 exclusive upper bound on observed_at"
5893
+ },
5894
+ { name: "bucket", description: "day | week (default day)" },
5895
+ {
5896
+ name: "aggregation",
5897
+ description: "avg | sum | count | rate (default avg)"
5898
+ }
5899
+ ],
5900
+ requiresWorkspace: true,
5901
+ examples: [
5902
+ "yarn gr metrics series --id 1 --start 2026-07-01T00:00:00Z --end 2026-08-01T00:00:00Z --bucket day"
5903
+ ],
5904
+ handler: async (hctx) => {
5905
+ const client = requireAuth(hctx.ctx).apiClient;
5906
+ const id = requireNumber(hctx.args, "id");
5907
+ const result2 = await client.getMetricSeries(hctx.workspace, id, {
5908
+ start: requireString(hctx.args, "start"),
5909
+ end: requireString(hctx.args, "end"),
5910
+ bucket: hctx.args["bucket"] ?? "day",
5911
+ aggregation: hctx.args["aggregation"] ?? "avg"
5912
+ });
5913
+ outputSingle(result2, hctx.ctx);
5914
+ }
5915
+ },
5916
+ {
5917
+ path: ["metrics", "compute-for-chat"],
5918
+ description: "On-demand evaluate enabled chat-source metrics for one chat (writes observations + dual-write feedback)",
5919
+ args: [
5920
+ {
5921
+ name: "chat-id",
5922
+ required: true,
5923
+ description: "Chat ID to evaluate"
5924
+ }
5925
+ ],
5926
+ requiresWorkspace: true,
5927
+ mutates: true,
5928
+ examples: ["yarn gr metrics compute-for-chat --chat-id 42 --allow-write"],
5929
+ handler: async (hctx) => {
5930
+ const client = requireAuth(hctx.ctx).apiClient;
5931
+ const chatId = requireNumber(hctx.args, "chat-id");
5932
+ if (chatId < 1) {
5933
+ throw new CLIError("--chat-id must be a positive number");
5934
+ }
5935
+ const result2 = await client.computeChatMetrics(hctx.workspace, { chatId });
5936
+ outputSingle(result2, hctx.ctx);
5937
+ }
5938
+ }
5939
+ ]
5940
+ };
5941
+
5942
+ // src/domains/personas.ts
5943
+ var COLUMNS12 = [
5622
5944
  COL.id(),
5623
5945
  COL.name(),
5624
5946
  { header: "AGE", getValue: (item) => item.age != null ? String(item.age) : "" },
@@ -5648,7 +5970,7 @@ var personasDomain = {
5648
5970
  createMethod: "createPersona",
5649
5971
  updateMethod: "updatePersona",
5650
5972
  deleteMethod: "deletePersona",
5651
- columns: COLUMNS11,
5973
+ columns: COLUMNS12,
5652
5974
  paginationSupport: "full"
5653
5975
  })
5654
5976
  ]
@@ -5708,11 +6030,11 @@ function shuffleInPlace(items) {
5708
6030
  }
5709
6031
  return items;
5710
6032
  }
5711
- function buildModelEvalBatchJobs(scenarios, models, rounds, warmup) {
6033
+ function buildModelEvalBatchJobs(scenarios, models, rounds, warmup, realtimeModels = []) {
5712
6034
  if (scenarios.length === 0) {
5713
6035
  throw new CLIError("At least one scenario is required");
5714
6036
  }
5715
- if (models.length === 0) {
6037
+ if (models.length === 0 && realtimeModels.length === 0) {
5716
6038
  throw new CLIError("At least one model is required");
5717
6039
  }
5718
6040
  if (rounds < 1) {
@@ -5733,12 +6055,60 @@ function buildModelEvalBatchJobs(scenarios, models, rounds, warmup) {
5733
6055
  modelId
5734
6056
  });
5735
6057
  }
6058
+ for (const modelId of realtimeModels) {
6059
+ roundJobs.push({
6060
+ round,
6061
+ warmup: warm,
6062
+ scenarioId: scenario.id,
6063
+ scenarioSlug: scenario.slug,
6064
+ scenarioName: scenario.name,
6065
+ modelId,
6066
+ realtime: true
6067
+ });
6068
+ }
5736
6069
  }
5737
6070
  shuffleInPlace(roundJobs);
5738
6071
  jobs.push(...roundJobs);
5739
6072
  }
5740
6073
  return jobs;
5741
6074
  }
6075
+ var REALTIME_AUDIO_USD_PER_MIN = {
6076
+ "xai:realtime:voice-agent": 0.05,
6077
+ // Grok Voice Think Fast 1
6078
+ "xai:realtime:voice-agent-2": 0.08
6079
+ // Grok Voice Think Fast 2
6080
+ };
6081
+ var DEFAULT_REALTIME_AUDIO_USD_PER_MIN = 0.08;
6082
+ var EST_AUDIO_MIN_PER_RUN = 3;
6083
+ var EST_TEXT_USD_PER_RUN = 0.012;
6084
+ function realtimeAudioUsdPerMin(modelId) {
6085
+ return REALTIME_AUDIO_USD_PER_MIN[modelId] ?? DEFAULT_REALTIME_AUDIO_USD_PER_MIN;
6086
+ }
6087
+ function estimateRealtimeRunCostUsd(modelId) {
6088
+ return EST_AUDIO_MIN_PER_RUN * realtimeAudioUsdPerMin(modelId) + EST_TEXT_USD_PER_RUN;
6089
+ }
6090
+ function projectRealtimeBatchCostUsd(jobs) {
6091
+ return jobs.filter((j) => j.realtime).reduce((sum, j) => sum + estimateRealtimeRunCostUsd(j.modelId), 0);
6092
+ }
6093
+ function actualRealtimeRowCostUsd(row, modelId) {
6094
+ const summary = row.timing_summary;
6095
+ const audioMs = summary ? summary["audio_output_ms_total"] : void 0;
6096
+ if (typeof audioMs === "number" && Number.isFinite(audioMs) && audioMs >= 0) {
6097
+ return audioMs / 6e4 * realtimeAudioUsdPerMin(modelId) + EST_TEXT_USD_PER_RUN;
6098
+ }
6099
+ return estimateRealtimeRunCostUsd(modelId);
6100
+ }
6101
+ function parseMaxBudgetUsd(raw, flagName) {
6102
+ if (raw === void 0 || raw === null || raw === "") {
6103
+ return void 0;
6104
+ }
6105
+ const value = Number(raw);
6106
+ if (!Number.isFinite(value) || value <= 0) {
6107
+ throw new CLIError(`${flagName} must be a positive number of USD`);
6108
+ }
6109
+ return value;
6110
+ }
6111
+ var REALTIME_MAX_CONCURRENCY = 4;
5742
6112
  function summarizeCriterionResults(run) {
5743
6113
  if (!run.criterionResults?.length) return void 0;
5744
6114
  return run.criterionResults.map((c) => ({
@@ -5747,7 +6117,7 @@ function summarizeCriterionResults(run) {
5747
6117
  score: c.score ?? null
5748
6118
  }));
5749
6119
  }
5750
- function runToBatchRow(job, workflowId, run, error) {
6120
+ function runToBatchRow(job, workflowId, run, error, batchLabel) {
5751
6121
  return {
5752
6122
  ts: (/* @__PURE__ */ new Date()).toISOString(),
5753
6123
  round: job.round,
@@ -5757,6 +6127,8 @@ function runToBatchRow(job, workflowId, run, error) {
5757
6127
  scenario_slug: job.scenarioSlug,
5758
6128
  scenario_name: job.scenarioName,
5759
6129
  model_id: job.modelId,
6130
+ ...job.realtime ? { realtime_model_id: job.modelId } : {},
6131
+ ...batchLabel ? { batch_label: batchLabel } : {},
5760
6132
  run_id: run?.id,
5761
6133
  error,
5762
6134
  failure_reason: run?.failureReason ?? null,
@@ -5811,7 +6183,10 @@ async function executeModelEvalJob(api, options, job, waitTimeoutMs, pollMs, sle
5811
6183
  const started = await api.startTestChatRun(options.workspace, options.workflowId, {
5812
6184
  scenarioId: job.scenarioId,
5813
6185
  driver: DriverMode.AUTO,
5814
- assistantChatModelId: job.modelId
6186
+ ...job.realtime ? {
6187
+ assistantRealtimeModelId: job.modelId,
6188
+ ...options.realtimeConfig ? { assistantRealtimeModelConfig: options.realtimeConfig } : {}
6189
+ } : { assistantChatModelId: job.modelId }
5815
6190
  });
5816
6191
  let run = await waitForRunTerminal(
5817
6192
  api,
@@ -5832,10 +6207,10 @@ async function executeModelEvalJob(api, options, job, waitTimeoutMs, pollMs, sle
5832
6207
  sleep2
5833
6208
  );
5834
6209
  }
5835
- return runToBatchRow(job, options.workflowId, run);
6210
+ return runToBatchRow(job, options.workflowId, run, void 0, options.batchLabel);
5836
6211
  } catch (e) {
5837
6212
  const message = e instanceof Error ? e.message : String(e);
5838
- return runToBatchRow(job, options.workflowId, null, message);
6213
+ return runToBatchRow(job, options.workflowId, null, message, options.batchLabel);
5839
6214
  }
5840
6215
  }
5841
6216
  function createSpacingGate(spacingSec, sleep2) {
@@ -5853,56 +6228,99 @@ function createSpacingGate(spacingSec, sleep2) {
5853
6228
  }
5854
6229
  async function executeModelEvalBatch(api, options) {
5855
6230
  const sleep2 = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
5856
- const concurrency = options.concurrency ?? 1;
5857
6231
  const jobs = buildModelEvalBatchJobs(
5858
6232
  options.scenarios,
5859
6233
  options.models,
5860
6234
  options.rounds,
5861
- options.warmup
6235
+ options.warmup,
6236
+ options.realtimeModels ?? []
5862
6237
  );
5863
6238
  const waitTimeoutMs = options.waitTimeoutSec * 1e3;
5864
6239
  const pollMs = options.pollIntervalSec * 1e3;
5865
6240
  const rows = [];
5866
6241
  let stopBatch = false;
6242
+ let budgetStopped = false;
6243
+ let actualSpendUsd = 0;
5867
6244
  const awaitSpacing = createSpacingGate(options.spacingSec, sleep2);
6245
+ const emitProgress = (line) => {
6246
+ if (options.onProgress) {
6247
+ options.onProgress(line);
6248
+ } else {
6249
+ process.stdout.write(`${line}
6250
+ `);
6251
+ }
6252
+ };
6253
+ const realtimeJobCount = jobs.filter((j) => j.realtime).length;
6254
+ let concurrency = options.concurrency ?? 1;
6255
+ if (realtimeJobCount > 0 && concurrency > REALTIME_MAX_CONCURRENCY) {
6256
+ emitProgress(
6257
+ `concurrency clamped ${concurrency} -> ${REALTIME_MAX_CONCURRENCY} (realtime models share the provider session pool)`
6258
+ );
6259
+ concurrency = REALTIME_MAX_CONCURRENCY;
6260
+ }
6261
+ if (realtimeJobCount > 0) {
6262
+ const projectedUsd = projectRealtimeBatchCostUsd(jobs);
6263
+ const cap = options.maxBudgetUsd;
6264
+ emitProgress(
6265
+ `realtime budget: projected ~$${projectedUsd.toFixed(2)} for ${realtimeJobCount} realtime run(s)${cap != null ? ` (cap $${cap.toFixed(2)})` : ""}`
6266
+ );
6267
+ if (cap != null && projectedUsd > cap) {
6268
+ throw new CLIError(
6269
+ `Batch aborted before dispatch: projected realtime cost $${projectedUsd.toFixed(2)} exceeds --max-budget-usd $${cap.toFixed(2)}. Reduce rounds/scenarios/models or raise the cap.`
6270
+ );
6271
+ }
6272
+ }
5868
6273
  const recordRow = (job, row) => {
5869
6274
  rows.push(row);
5870
6275
  if (options.outPath) {
5871
6276
  appendFileSync(options.outPath, `${JSON.stringify(row)}
5872
6277
  `);
5873
6278
  }
5874
- const progress = formatBatchProgressLine(job, row);
5875
- if (options.onProgress) {
5876
- options.onProgress(progress);
5877
- } else {
5878
- process.stdout.write(`${progress}
5879
- `);
5880
- }
6279
+ emitProgress(formatBatchProgressLine(job, row));
5881
6280
  };
6281
+ const makeSkippedRow = (job) => ({
6282
+ ...runToBatchRow(
6283
+ job,
6284
+ options.workflowId,
6285
+ null,
6286
+ budgetStopped ? "batch stopped: realtime budget cap reached" : "batch aborted before start",
6287
+ options.batchLabel
6288
+ ),
6289
+ batch_skipped: true
6290
+ });
5882
6291
  const runOne = async (job) => {
5883
6292
  await awaitSpacing();
5884
6293
  if (stopBatch) {
5885
- return {
5886
- ...runToBatchRow(job, options.workflowId, null, "batch aborted before start"),
5887
- batch_skipped: true
5888
- };
6294
+ return makeSkippedRow(job);
5889
6295
  }
5890
6296
  const row = await executeModelEvalJob(api, options, job, waitTimeoutMs, pollMs, sleep2);
5891
6297
  if (isConfigurationBlockerFailure(row.failure_reason)) {
5892
6298
  stopBatch = true;
5893
6299
  }
6300
+ if (job.realtime && !row.batch_skipped) {
6301
+ actualSpendUsd += actualRealtimeRowCostUsd(row, job.modelId);
6302
+ if (options.maxBudgetUsd != null && actualSpendUsd >= options.maxBudgetUsd && !stopBatch) {
6303
+ stopBatch = true;
6304
+ budgetStopped = true;
6305
+ emitProgress(
6306
+ `realtime budget: actual spend ~$${actualSpendUsd.toFixed(2)} reached cap $${options.maxBudgetUsd.toFixed(2)} \u2014 stopping dispatch`
6307
+ );
6308
+ }
6309
+ }
5894
6310
  return row;
5895
6311
  };
5896
6312
  if (concurrency <= 1) {
5897
- for (const job of jobs) {
6313
+ let stoppedAt = jobs.length;
6314
+ for (const [index, job] of jobs.entries()) {
5898
6315
  if (stopBatch) {
6316
+ stoppedAt = index;
5899
6317
  break;
5900
6318
  }
5901
6319
  const row = await runOne(job);
5902
6320
  recordRow(job, row);
5903
- if (stopBatch) {
5904
- break;
5905
- }
6321
+ }
6322
+ for (const job of jobs.slice(stoppedAt)) {
6323
+ recordRow(job, makeSkippedRow(job));
5906
6324
  }
5907
6325
  } else {
5908
6326
  const results = new Array(jobs.length);
@@ -5918,6 +6336,9 @@ async function executeModelEvalBatch(api, options) {
5918
6336
  return;
5919
6337
  }
5920
6338
  const job = jobs[index];
6339
+ if (job === void 0) {
6340
+ return;
6341
+ }
5921
6342
  const row = await runOne(job);
5922
6343
  results[index] = row;
5923
6344
  recordRow(job, row);
@@ -5926,20 +6347,19 @@ async function executeModelEvalBatch(api, options) {
5926
6347
  const workers = Array.from({ length: Math.min(concurrency, jobs.length) }, () => worker());
5927
6348
  await Promise.all(workers);
5928
6349
  if (stopBatch) {
5929
- for (let index = 0; index < jobs.length; index++) {
6350
+ jobs.forEach((job, index) => {
5930
6351
  if (results[index] !== void 0) {
5931
- continue;
6352
+ return;
5932
6353
  }
5933
- const job = jobs[index];
5934
- const skipped = {
5935
- ...runToBatchRow(job, options.workflowId, null, "batch aborted before start"),
5936
- batch_skipped: true
5937
- };
6354
+ const skipped = makeSkippedRow(job);
5938
6355
  results[index] = skipped;
5939
6356
  recordRow(job, skipped);
5940
- }
6357
+ });
5941
6358
  }
5942
6359
  }
6360
+ if (realtimeJobCount > 0) {
6361
+ emitProgress(`realtime budget: total actual spend ~$${actualSpendUsd.toFixed(2)}`);
6362
+ }
5943
6363
  const blockerRow = rows.find((r) => isConfigurationBlockerFailure(r.failure_reason));
5944
6364
  if (blockerRow) {
5945
6365
  throw new CLIError(
@@ -6241,9 +6661,29 @@ var qualificationsDomain = {
6241
6661
  { name: "workflow-id", description: "Workflow ID", required: true },
6242
6662
  {
6243
6663
  name: "models",
6244
- description: "Comma-separated assistant chat model IDs",
6664
+ description: "Comma-separated assistant chat model IDs (optional with --realtime-models)",
6245
6665
  alias: "m",
6246
- required: true
6666
+ required: false
6667
+ },
6668
+ {
6669
+ name: "realtime-models",
6670
+ description: "Comma-separated native realtime model IDs (each forwarded as assistantRealtimeModelId)",
6671
+ required: false
6672
+ },
6673
+ {
6674
+ name: "realtime-config",
6675
+ description: "JSON object forwarded as assistantRealtimeModelConfig on realtime jobs",
6676
+ required: false
6677
+ },
6678
+ {
6679
+ name: "batch-label",
6680
+ description: "Label recorded on every JSONL row for cross-batch comparison",
6681
+ required: false
6682
+ },
6683
+ {
6684
+ name: "max-budget-usd",
6685
+ description: "Dispatch cap in USD on realtime spend: abort if pre-flight projection exceeds it, stop dispatching when actuals cross it (in-flight runs still finish and bill)",
6686
+ required: false
6247
6687
  },
6248
6688
  {
6249
6689
  name: "scenario-ids",
@@ -6283,7 +6723,31 @@ var qualificationsDomain = {
6283
6723
  { name: "out", description: "Append JSONL rows to this file" }
6284
6724
  ],
6285
6725
  handler: async ({ ctx, workspace, args }) => {
6286
- const models = parseCommaSeparatedList(requireString(args, "models"), "--models");
6726
+ const models = args.models ? parseCommaSeparatedList(String(args.models), "--models") : [];
6727
+ const realtimeModels = args["realtime-models"] ? parseCommaSeparatedList(String(args["realtime-models"]), "--realtime-models") : [];
6728
+ if (models.length === 0 && realtimeModels.length === 0) {
6729
+ throw new CLIError("Specify --models and/or --realtime-models");
6730
+ }
6731
+ let realtimeConfig;
6732
+ if (args["realtime-config"]) {
6733
+ if (realtimeModels.length === 0) {
6734
+ throw new CLIError("--realtime-config requires --realtime-models");
6735
+ }
6736
+ let parsed;
6737
+ try {
6738
+ parsed = JSON.parse(String(args["realtime-config"]));
6739
+ } catch {
6740
+ throw new CLIError("--realtime-config is not valid JSON");
6741
+ }
6742
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
6743
+ throw new CLIError(
6744
+ "--realtime-config must be a JSON object (not an array or null)"
6745
+ );
6746
+ }
6747
+ realtimeConfig = parsed;
6748
+ }
6749
+ const batchLabel = args["batch-label"] ? String(args["batch-label"]) : void 0;
6750
+ const maxBudgetUsd = parseMaxBudgetUsd(args["max-budget-usd"], "--max-budget-usd");
6287
6751
  const allScenarios = Boolean(args["all-scenarios"]);
6288
6752
  const scenarioIdsRaw = args["scenario-ids"];
6289
6753
  if (allScenarios && scenarioIdsRaw) {
@@ -6324,6 +6788,10 @@ var qualificationsDomain = {
6324
6788
  workspace,
6325
6789
  workflowId,
6326
6790
  models,
6791
+ realtimeModels,
6792
+ realtimeConfig,
6793
+ batchLabel,
6794
+ maxBudgetUsd,
6327
6795
  scenarios,
6328
6796
  rounds,
6329
6797
  warmup,
@@ -6638,7 +7106,7 @@ Relations (relationMatch): ${relations.join(", ")}`);
6638
7106
 
6639
7107
  // src/domains/sites.ts
6640
7108
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
6641
- var COLUMNS12 = [
7109
+ var COLUMNS13 = [
6642
7110
  COL.id(),
6643
7111
  COL.name(),
6644
7112
  { header: "SLUG", getValue: (item) => item.slug ?? "" },
@@ -6692,7 +7160,7 @@ var sitesDomain = {
6692
7160
  createMethod: "createSite",
6693
7161
  updateMethod: "updateSite",
6694
7162
  deleteMethod: "deleteSite",
6695
- columns: COLUMNS12
7163
+ columns: COLUMNS13
6696
7164
  }),
6697
7165
  // Pages sub-resource
6698
7166
  {
@@ -7363,7 +7831,7 @@ var abilitiesDomain = {
7363
7831
  };
7364
7832
 
7365
7833
  // src/domains/access-grants.ts
7366
- var COLUMNS13 = [
7834
+ var COLUMNS14 = [
7367
7835
  COL.id(),
7368
7836
  COL.status(),
7369
7837
  { header: "GRANTOR", getValue: (item) => String(item.grantorMemberId ?? "") },
@@ -7380,7 +7848,7 @@ var accessGrantsDomain = {
7380
7848
  requiresWorkspace: true,
7381
7849
  handler: async ({ ctx, workspace }) => {
7382
7850
  const result2 = await requireAuth(ctx).apiClient.getAccessGrants(workspace);
7383
- outputData(listResult(result2, false), ctx, COLUMNS13);
7851
+ outputData(listResult(result2, false), ctx, COLUMNS14);
7384
7852
  }
7385
7853
  },
7386
7854
  {
@@ -7393,7 +7861,7 @@ var accessGrantsDomain = {
7393
7861
  workspace,
7394
7862
  requireString(args, "id")
7395
7863
  );
7396
- outputSingle(result2, ctx, COLUMNS13);
7864
+ outputSingle(result2, ctx, COLUMNS14);
7397
7865
  }
7398
7866
  },
7399
7867
  {
@@ -7406,7 +7874,7 @@ var accessGrantsDomain = {
7406
7874
  workspace,
7407
7875
  data
7408
7876
  );
7409
- outputSingle(result2, ctx, COLUMNS13);
7877
+ outputSingle(result2, ctx, COLUMNS14);
7410
7878
  }
7411
7879
  },
7412
7880
  {
@@ -7417,7 +7885,7 @@ var accessGrantsDomain = {
7417
7885
  const result2 = await requireAuth(ctx).apiClient.getMyReceivedGrants(workspace, {
7418
7886
  pageSize: 200
7419
7887
  });
7420
- outputData(listResult(result2, false), ctx, COLUMNS13);
7888
+ outputData(listResult(result2, false), ctx, COLUMNS14);
7421
7889
  }
7422
7890
  },
7423
7891
  {
@@ -7428,7 +7896,7 @@ var accessGrantsDomain = {
7428
7896
  const result2 = await requireAuth(ctx).apiClient.getMyGivenGrants(workspace, {
7429
7897
  pageSize: 200
7430
7898
  });
7431
- outputData(listResult(result2, false), ctx, COLUMNS13);
7899
+ outputData(listResult(result2, false), ctx, COLUMNS14);
7432
7900
  }
7433
7901
  },
7434
7902
  {
@@ -7443,7 +7911,7 @@ var accessGrantsDomain = {
7443
7911
  requireString(args, "id"),
7444
7912
  data ?? {}
7445
7913
  );
7446
- outputSingle(result2, ctx, COLUMNS13);
7914
+ outputSingle(result2, ctx, COLUMNS14);
7447
7915
  }
7448
7916
  },
7449
7917
  {
@@ -7458,7 +7926,7 @@ var accessGrantsDomain = {
7458
7926
  requireString(args, "id"),
7459
7927
  data ?? {}
7460
7928
  );
7461
- outputSingle(result2, ctx, COLUMNS13);
7929
+ outputSingle(result2, ctx, COLUMNS14);
7462
7930
  }
7463
7931
  },
7464
7932
  {
@@ -7471,7 +7939,7 @@ var accessGrantsDomain = {
7471
7939
  workspace,
7472
7940
  requireNumber(args, "member-id")
7473
7941
  );
7474
- outputData(listResult(result2, false), ctx, COLUMNS13);
7942
+ outputData(listResult(result2, false), ctx, COLUMNS14);
7475
7943
  }
7476
7944
  },
7477
7945
  {
@@ -7496,14 +7964,14 @@ var accessGrantsDomain = {
7496
7964
  pageSize: 200
7497
7965
  }
7498
7966
  );
7499
- outputData(listResult(result2, false), ctx, COLUMNS13);
7967
+ outputData(listResult(result2, false), ctx, COLUMNS14);
7500
7968
  }
7501
7969
  }
7502
7970
  ]
7503
7971
  };
7504
7972
 
7505
7973
  // src/domains/ai-models.ts
7506
- var COLUMNS14 = [
7974
+ var COLUMNS15 = [
7507
7975
  { header: "ID", getValue: (item) => String(item.id ?? item.modelId ?? "") },
7508
7976
  { header: "NAME", getValue: (item) => item.name ?? item.displayName ?? "" },
7509
7977
  { header: "PROVIDER", getValue: (item) => item.provider ?? "" },
@@ -7511,7 +7979,7 @@ var COLUMNS14 = [
7511
7979
  ];
7512
7980
  var aiModelsDomain = {
7513
7981
  name: "ai-models",
7514
- description: "List available AI models",
7982
+ description: `List available AI models (chat, realtime/voice stacks, speaker voices). Use realtime ids as workflow/agent realtimeModelId; voice ids go in realtimeModelConfig.voiceModel. One-shot workflow voice: gr workflows update -d '{"realtimeModelId":"xai:realtime:voice-agent-2"}' then publish.`,
7515
7983
  commands: [
7516
7984
  {
7517
7985
  path: ["ai-models", "list"],
@@ -7519,41 +7987,41 @@ var aiModelsDomain = {
7519
7987
  requiresWorkspace: false,
7520
7988
  handler: async ({ ctx }) => {
7521
7989
  const result2 = await requireAuth(ctx).apiClient.getAllModels();
7522
- outputData(result2, ctx, COLUMNS14);
7990
+ outputData(result2, ctx, COLUMNS15);
7523
7991
  }
7524
7992
  },
7525
7993
  {
7526
7994
  path: ["ai-models", "chat"],
7527
- description: "List chat models",
7995
+ description: "List chat models (use as chatModelId on agents/workflows)",
7528
7996
  requiresWorkspace: false,
7529
7997
  handler: async ({ ctx }) => {
7530
7998
  const result2 = await requireAuth(ctx).apiClient.getChatModels();
7531
- outputData(result2, ctx, COLUMNS14);
7999
+ outputData(result2, ctx, COLUMNS15);
7532
8000
  }
7533
8001
  },
7534
8002
  {
7535
8003
  path: ["ai-models", "realtime"],
7536
- description: "List realtime models",
8004
+ description: "List realtime/voice stacks (use as realtimeModelId). e.g. xai:realtime:voice-agent-2 = Grok Voice Think Fast 2",
7537
8005
  requiresWorkspace: false,
7538
8006
  handler: async ({ ctx }) => {
7539
8007
  const result2 = await requireAuth(ctx).apiClient.getRealtimeModels();
7540
- outputData(result2, ctx, COLUMNS14);
8008
+ outputData(result2, ctx, COLUMNS15);
7541
8009
  }
7542
8010
  },
7543
8011
  {
7544
8012
  path: ["ai-models", "voice"],
7545
- description: "List voice models",
8013
+ description: "List speaker voices (use as realtimeModelConfig.voiceModel). Match provider to the realtime model (xai:voice:* with xAI realtime)",
7546
8014
  requiresWorkspace: false,
7547
8015
  handler: async ({ ctx }) => {
7548
8016
  const result2 = await requireAuth(ctx).apiClient.getVoiceModels();
7549
- outputData(result2, ctx, COLUMNS14);
8017
+ outputData(result2, ctx, COLUMNS15);
7550
8018
  }
7551
8019
  }
7552
8020
  ]
7553
8021
  };
7554
8022
 
7555
8023
  // src/domains/api-keys.ts
7556
- var COLUMNS15 = [
8024
+ var COLUMNS16 = [
7557
8025
  COL.id(),
7558
8026
  COL.name(),
7559
8027
  { header: "PREFIX", getValue: (item) => item.prefix ?? "" },
@@ -7576,7 +8044,7 @@ var apiKeysDomain = {
7576
8044
  requiresWorkspace: true,
7577
8045
  handler: async ({ ctx, workspace }) => {
7578
8046
  const result2 = await requireAuth(ctx).apiClient.getApiKeys(workspace);
7579
- outputData(result2, ctx, COLUMNS15);
8047
+ outputData(result2, ctx, COLUMNS16);
7580
8048
  }
7581
8049
  },
7582
8050
  {
@@ -7611,7 +8079,7 @@ var apiKeysDomain = {
7611
8079
  requiresWorkspace: false,
7612
8080
  handler: async ({ ctx }) => {
7613
8081
  const result2 = await requireAuth(ctx).apiClient.getGlobalApiKeys();
7614
- outputData(result2, ctx, COLUMNS15);
8082
+ outputData(result2, ctx, COLUMNS16);
7615
8083
  }
7616
8084
  },
7617
8085
  {
@@ -8261,7 +8729,7 @@ var conciergeDomain = {
8261
8729
  };
8262
8730
 
8263
8731
  // src/domains/custom-toolkits.ts
8264
- var COLUMNS16 = [COL.id(), COL.name(), COL.description(), COL.enabled()];
8732
+ var COLUMNS17 = [COL.id(), COL.name(), COL.description(), COL.enabled()];
8265
8733
  var TOOL_COLUMNS2 = [COL.id(), COL.name(), COL.description()];
8266
8734
  var customToolkitsDomain = {
8267
8735
  name: "custom-toolkits",
@@ -8275,7 +8743,7 @@ var customToolkitsDomain = {
8275
8743
  createMethod: "createCustomToolkit",
8276
8744
  updateMethod: "updateCustomToolkit",
8277
8745
  deleteMethod: "deleteCustomToolkit",
8278
- columns: COLUMNS16
8746
+ columns: COLUMNS17
8279
8747
  }),
8280
8748
  {
8281
8749
  path: ["custom-toolkits", "enable"],
@@ -8288,7 +8756,7 @@ var customToolkitsDomain = {
8288
8756
  workspace,
8289
8757
  requireNumber(args, "id")
8290
8758
  );
8291
- outputSingle(result2, ctx, COLUMNS16);
8759
+ outputSingle(result2, ctx, COLUMNS17);
8292
8760
  }
8293
8761
  },
8294
8762
  {
@@ -8302,7 +8770,7 @@ var customToolkitsDomain = {
8302
8770
  workspace,
8303
8771
  requireNumber(args, "id")
8304
8772
  );
8305
- outputSingle(result2, ctx, COLUMNS16);
8773
+ outputSingle(result2, ctx, COLUMNS17);
8306
8774
  }
8307
8775
  },
8308
8776
  // Tools — nested resource requiring toolkitId
@@ -8414,7 +8882,7 @@ var docsDomain = {
8414
8882
  };
8415
8883
 
8416
8884
  // src/domains/features.ts
8417
- var COLUMNS17 = [
8885
+ var COLUMNS18 = [
8418
8886
  { header: "SLUG", getValue: (item) => item.slug ?? "" },
8419
8887
  COL.name(),
8420
8888
  COL.description()
@@ -8429,7 +8897,7 @@ var featuresDomain = {
8429
8897
  requiresWorkspace: false,
8430
8898
  handler: async ({ ctx }) => {
8431
8899
  const result2 = await requireAuth(ctx).apiClient.getFeatureRegistry();
8432
- outputData(result2, ctx, COLUMNS17);
8900
+ outputData(result2, ctx, COLUMNS18);
8433
8901
  }
8434
8902
  },
8435
8903
  {
@@ -8441,7 +8909,7 @@ var featuresDomain = {
8441
8909
  const result2 = await requireAuth(ctx).apiClient.getFeatureBySlug(
8442
8910
  requireString(args, "slug")
8443
8911
  );
8444
- outputSingle(result2, ctx, COLUMNS17);
8912
+ outputSingle(result2, ctx, COLUMNS18);
8445
8913
  }
8446
8914
  },
8447
8915
  {
@@ -8450,14 +8918,14 @@ var featuresDomain = {
8450
8918
  requiresWorkspace: true,
8451
8919
  handler: async ({ ctx }) => {
8452
8920
  const result2 = await requireAuth(ctx).apiClient.getAvailableWorkspaceFeatures();
8453
- outputData(result2, ctx, COLUMNS17);
8921
+ outputData(result2, ctx, COLUMNS18);
8454
8922
  }
8455
8923
  }
8456
8924
  ]
8457
8925
  };
8458
8926
 
8459
8927
  // src/domains/inboxes.ts
8460
- var COLUMNS18 = [
8928
+ var COLUMNS19 = [
8461
8929
  COL.id(),
8462
8930
  COL.name(),
8463
8931
  { header: "EMAIL", getValue: (item) => item.emailAddress ?? "" },
@@ -8482,7 +8950,7 @@ var inboxesDomain = {
8482
8950
  createMethod: "createInbox",
8483
8951
  updateMethod: "updateInbox",
8484
8952
  deleteMethod: "deleteInbox",
8485
- columns: COLUMNS18
8953
+ columns: COLUMNS19
8486
8954
  }),
8487
8955
  {
8488
8956
  path: ["inboxes", "emails", "list"],
@@ -8567,7 +9035,7 @@ var inboxesDomain = {
8567
9035
  };
8568
9036
 
8569
9037
  // src/domains/mcp-servers.ts
8570
- var COLUMNS19 = [
9038
+ var COLUMNS20 = [
8571
9039
  COL.id(),
8572
9040
  COL.name(),
8573
9041
  { header: "URL", getValue: (item) => item.url ?? "" },
@@ -8585,7 +9053,7 @@ var mcpServersDomain = {
8585
9053
  createMethod: "createMcpServer",
8586
9054
  updateMethod: "updateMcpServer",
8587
9055
  deleteMethod: "deleteMcpServer",
8588
- columns: COLUMNS19
9056
+ columns: COLUMNS20
8589
9057
  }),
8590
9058
  {
8591
9059
  path: ["mcp-servers", "enable"],
@@ -8598,7 +9066,7 @@ var mcpServersDomain = {
8598
9066
  workspace,
8599
9067
  requireNumber(args, "id")
8600
9068
  );
8601
- outputSingle(result2, ctx, COLUMNS19);
9069
+ outputSingle(result2, ctx, COLUMNS20);
8602
9070
  }
8603
9071
  },
8604
9072
  {
@@ -8612,7 +9080,7 @@ var mcpServersDomain = {
8612
9080
  workspace,
8613
9081
  requireNumber(args, "id")
8614
9082
  );
8615
- outputSingle(result2, ctx, COLUMNS19);
9083
+ outputSingle(result2, ctx, COLUMNS20);
8616
9084
  }
8617
9085
  },
8618
9086
  {
@@ -8632,7 +9100,7 @@ var mcpServersDomain = {
8632
9100
  };
8633
9101
 
8634
9102
  // src/domains/member-memories.ts
8635
- var COLUMNS20 = [
9103
+ var COLUMNS21 = [
8636
9104
  { header: "KEY", getValue: (item) => item.key ?? "" },
8637
9105
  { header: "TYPE", getValue: (item) => item.type ?? "basic" },
8638
9106
  { header: "DESCRIPTION", getValue: (item) => truncate(item.description ?? "", 60) },
@@ -8666,7 +9134,7 @@ var memberMemoriesDomain = {
8666
9134
  type,
8667
9135
  query
8668
9136
  });
8669
- outputData(listResult(result2, false), ctx, COLUMNS20);
9137
+ outputData(listResult(result2, false), ctx, COLUMNS21);
8670
9138
  }
8671
9139
  },
8672
9140
  {
@@ -8685,7 +9153,7 @@ var memberMemoriesDomain = {
8685
9153
  memberId,
8686
9154
  key
8687
9155
  );
8688
- outputData(result2, ctx, COLUMNS20);
9156
+ outputData(result2, ctx, COLUMNS21);
8689
9157
  }
8690
9158
  },
8691
9159
  {
@@ -8716,7 +9184,7 @@ var memberMemoriesDomain = {
8716
9184
  ...priority !== void 0 && { priority }
8717
9185
  }
8718
9186
  );
8719
- outputData(result2, ctx, COLUMNS20);
9187
+ outputData(result2, ctx, COLUMNS21);
8720
9188
  }
8721
9189
  },
8722
9190
  {
@@ -8749,33 +9217,56 @@ var memberMemoriesDomain = {
8749
9217
  ]
8750
9218
  };
8751
9219
 
8752
- // src/domains/milestones.ts
8753
- var COLUMNS21 = [
9220
+ // src/domains/intervention-requests.ts
9221
+ var COLUMNS22 = [
8754
9222
  COL.id(),
8755
- COL.name(),
8756
- COL.status(),
8757
- { header: "DUE DATE", getValue: (item) => item.dueDate ?? "" }
9223
+ { header: "KIND", getValue: (item) => item.kind ?? "" },
9224
+ { header: "CHAT", getValue: (item) => item.chatId ?? "" },
9225
+ {
9226
+ header: "STATUS",
9227
+ getValue: (item) => item.resolvedAt ? item.resolution ?? "resolved" : "open"
9228
+ },
9229
+ // Zero is the interesting value: the intervention was requested and nobody
9230
+ // was told, which is what `--unrouted` filters for.
9231
+ { header: "NOTIFIED", getValue: (item) => item.notifiedCount ?? 0 },
9232
+ { header: "REASON", getValue: (item) => item.reasonCode ?? "" },
9233
+ { header: "CREATED", getValue: (item) => item.createdAt ?? "" }
8758
9234
  ];
8759
- var milestonesDomain = {
8760
- name: "milestones",
8761
- description: "Manage milestones",
9235
+ var interventionRequestsDomain = {
9236
+ name: "interventions",
9237
+ description: "Inspect intervention requests \u2014 escalations and other asks for a person",
8762
9238
  commands: [
8763
- ...crudCommands({
8764
- prefix: ["milestones"],
8765
- entityName: "milestone",
8766
- listMethod: "getMilestones",
8767
- getMethod: "getMilestone",
8768
- createMethod: "createMilestone",
8769
- updateMethod: "updateMilestone",
8770
- deleteMethod: "deleteMilestone",
8771
- columns: COLUMNS21,
8772
- paginationSupport: "full"
8773
- })
9239
+ {
9240
+ path: ["interventions", "list"],
9241
+ description: "List intervention requests (escalations etc). Newest first. Read-only.",
9242
+ requiresWorkspace: true,
9243
+ args: [
9244
+ { name: "kind", description: "escalation | contributor_input | approval" },
9245
+ { name: "open", description: "Only unresolved requests", isFlag: true },
9246
+ { name: "chat-id", description: "Only requests for this chat" },
9247
+ {
9248
+ name: "unrouted",
9249
+ description: "Only requests that notified NOBODY \u2014 escalations that reached no one",
9250
+ isFlag: true
9251
+ },
9252
+ { name: "limit", description: "Max rows (default 50, max 200)" }
9253
+ ],
9254
+ handler: async ({ ctx, workspace, args, requireAuth: requireAuth2, outputData: outputData2 }) => {
9255
+ const result2 = await requireAuth2(ctx).apiClient.getInterventionRequests(workspace, {
9256
+ kind: args["kind"],
9257
+ openOnly: Boolean(args["open"]),
9258
+ chatId: args["chat-id"] ? Number(args["chat-id"]) : void 0,
9259
+ unroutedOnly: Boolean(args["unrouted"]),
9260
+ limit: args["limit"] ? Number(args["limit"]) : void 0
9261
+ });
9262
+ outputData2(result2, ctx, COLUMNS22);
9263
+ }
9264
+ }
8774
9265
  ]
8775
9266
  };
8776
9267
 
8777
9268
  // src/domains/notification-rules.ts
8778
- var COLUMNS22 = [
9269
+ var COLUMNS23 = [
8779
9270
  COL.id(),
8780
9271
  COL.name(),
8781
9272
  { header: "TYPE", getValue: (item) => item.noticeType ?? "" },
@@ -8792,7 +9283,7 @@ var notificationRulesDomain = {
8792
9283
  createMethod: "createNotificationRule",
8793
9284
  updateMethod: "updateNotificationRule",
8794
9285
  deleteMethod: "deleteNotificationRule",
8795
- columns: COLUMNS22
9286
+ columns: COLUMNS23
8796
9287
  })
8797
9288
  ]
8798
9289
  };
@@ -8852,7 +9343,7 @@ var oauthDomain = {
8852
9343
  };
8853
9344
 
8854
9345
  // src/domains/operator-groups.ts
8855
- var COLUMNS23 = [COL.id(), COL.name(), COL.description()];
9346
+ var COLUMNS24 = [COL.id(), COL.name(), COL.description()];
8856
9347
  var operatorGroupsDomain = {
8857
9348
  name: "operator-groups",
8858
9349
  description: "Manage operator groups",
@@ -8865,7 +9356,7 @@ var operatorGroupsDomain = {
8865
9356
  createMethod: "createOperatorGroup",
8866
9357
  updateMethod: "updateOperatorGroup",
8867
9358
  deleteMethod: "deleteOperatorGroup",
8868
- columns: COLUMNS23
9359
+ columns: COLUMNS24
8869
9360
  }),
8870
9361
  {
8871
9362
  path: ["operator-groups", "add-member"],
@@ -8943,13 +9434,6 @@ var ORG_DOMAIN_COLUMNS = [
8943
9434
  maxWidth: 80
8944
9435
  }
8945
9436
  ];
8946
- function requireOrgId(args) {
8947
- const val = args["org-uuid"] ?? args.org;
8948
- if (typeof val !== "string" || !val) {
8949
- throw new CLIError("Missing required argument: --org-uuid");
8950
- }
8951
- return val;
8952
- }
8953
9437
  function requireDomainUuid(args) {
8954
9438
  const val = args["domain-uuid"] ?? args.uuid;
8955
9439
  if (typeof val !== "string" || !val) {
@@ -8964,7 +9448,7 @@ function requireDomain(args) {
8964
9448
  }
8965
9449
  return val;
8966
9450
  }
8967
- var ORG_UUID_ARG = {
9451
+ var ORG_UUID_ARG2 = {
8968
9452
  name: "org-uuid",
8969
9453
  aliases: ["org"],
8970
9454
  description: "Organization UUID or ID",
@@ -8985,13 +9469,13 @@ function emailVerifyCommand(path4, description) {
8985
9469
  description,
8986
9470
  mutates: true,
8987
9471
  requiresWorkspace: false,
8988
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9472
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
8989
9473
  examples: [
8990
9474
  `yarn gr ${path4.join(" ")} --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID --allow-write`
8991
9475
  ],
8992
9476
  handler: async (hctx) => {
8993
9477
  const result2 = await requireAuth(hctx.ctx).apiClient.verifyOrgDomainEmail(
8994
- requireOrgId(hctx.args),
9478
+ requireOrgRef(hctx.args),
8995
9479
  requireDomainUuid(hctx.args)
8996
9480
  );
8997
9481
  outputSingle(result2, hctx.ctx);
@@ -9004,13 +9488,13 @@ function siteVerifyCommand(path4, description) {
9004
9488
  description,
9005
9489
  mutates: true,
9006
9490
  requiresWorkspace: false,
9007
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9491
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9008
9492
  examples: [
9009
9493
  `yarn gr ${path4.join(" ")} --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID --allow-write`
9010
9494
  ],
9011
9495
  handler: async (hctx) => {
9012
9496
  const result2 = await requireAuth(hctx.ctx).apiClient.verifyOrgDomainSite(
9013
- requireOrgId(hctx.args),
9497
+ requireOrgRef(hctx.args),
9014
9498
  requireDomainUuid(hctx.args)
9015
9499
  );
9016
9500
  outputSingle(result2, hctx.ctx);
@@ -9024,7 +9508,7 @@ function registerDomainCommand(path4) {
9024
9508
  mutates: true,
9025
9509
  requiresWorkspace: false,
9026
9510
  args: [
9027
- ORG_UUID_ARG,
9511
+ ORG_UUID_ARG2,
9028
9512
  { name: "domain", description: "Domain to register, e.g. example.com", required: true }
9029
9513
  ],
9030
9514
  examples: [
@@ -9032,7 +9516,7 @@ function registerDomainCommand(path4) {
9032
9516
  ],
9033
9517
  handler: async (hctx) => {
9034
9518
  const result2 = await requireAuth(hctx.ctx).apiClient.registerOrgDomain(
9035
- requireOrgId(hctx.args),
9519
+ requireOrgRef(hctx.args),
9036
9520
  requireDomain(hctx.args)
9037
9521
  );
9038
9522
  outputSingle(result2, hctx.ctx, ORG_DOMAIN_COLUMNS);
@@ -9044,11 +9528,11 @@ var domainCommands = [
9044
9528
  path: ["org", "domains", "list"],
9045
9529
  description: "List domains registered to an organization",
9046
9530
  requiresWorkspace: false,
9047
- args: [ORG_UUID_ARG],
9531
+ args: [ORG_UUID_ARG2],
9048
9532
  examples: ["yarn gr org domains list --org-uuid $ORG_UUID"],
9049
9533
  handler: async (hctx) => {
9050
9534
  const result2 = await requireAuth(hctx.ctx).apiClient.listOrgDomains(
9051
- requireOrgId(hctx.args)
9535
+ requireOrgRef(hctx.args)
9052
9536
  );
9053
9537
  outputData(result2, hctx.ctx, ORG_DOMAIN_COLUMNS);
9054
9538
  }
@@ -9057,11 +9541,11 @@ var domainCommands = [
9057
9541
  path: ["org", "domains", "get"],
9058
9542
  description: "Get a registered organization domain",
9059
9543
  requiresWorkspace: false,
9060
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9544
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9061
9545
  examples: ["yarn gr org domains get --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID"],
9062
9546
  handler: async (hctx) => {
9063
9547
  const result2 = await requireAuth(hctx.ctx).apiClient.getOrgDomain(
9064
- requireOrgId(hctx.args),
9548
+ requireOrgRef(hctx.args),
9065
9549
  requireDomainUuid(hctx.args)
9066
9550
  );
9067
9551
  outputSingle(result2, hctx.ctx, ORG_DOMAIN_COLUMNS);
@@ -9074,13 +9558,13 @@ var domainCommands = [
9074
9558
  description: "Verify domain ownership by checking the _gravity-verify TXT record",
9075
9559
  mutates: true,
9076
9560
  requiresWorkspace: false,
9077
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9561
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9078
9562
  examples: [
9079
9563
  "yarn gr org domains verify-ownership --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID --allow-write"
9080
9564
  ],
9081
9565
  handler: async (hctx) => {
9082
9566
  const result2 = await requireAuth(hctx.ctx).apiClient.verifyOrgDomainOwnership(
9083
- requireOrgId(hctx.args),
9567
+ requireOrgRef(hctx.args),
9084
9568
  requireDomainUuid(hctx.args)
9085
9569
  );
9086
9570
  outputSingle(result2, hctx.ctx);
@@ -9091,13 +9575,16 @@ var domainCommands = [
9091
9575
  description: "Delete a registered organization domain",
9092
9576
  mutates: true,
9093
9577
  requiresWorkspace: false,
9094
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9578
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9095
9579
  examples: [
9096
9580
  "yarn gr org domains delete --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID --allow-write"
9097
9581
  ],
9098
9582
  handler: async (hctx) => {
9099
9583
  const domainUuid = requireDomainUuid(hctx.args);
9100
- await requireAuth(hctx.ctx).apiClient.deleteOrgDomain(requireOrgId(hctx.args), domainUuid);
9584
+ await requireAuth(hctx.ctx).apiClient.deleteOrgDomain(
9585
+ requireOrgRef(hctx.args),
9586
+ domainUuid
9587
+ );
9101
9588
  process.stdout.write(`Deleted org domain ${domainUuid}
9102
9589
  `);
9103
9590
  }
@@ -9107,13 +9594,13 @@ var domainCommands = [
9107
9594
  description: "Enable email DNS records on a verified organization domain",
9108
9595
  mutates: true,
9109
9596
  requiresWorkspace: false,
9110
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9597
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9111
9598
  examples: [
9112
9599
  "yarn gr org domains email enable --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID --allow-write"
9113
9600
  ],
9114
9601
  handler: async (hctx) => {
9115
9602
  const result2 = await requireAuth(hctx.ctx).apiClient.enableOrgDomainEmail(
9116
- requireOrgId(hctx.args),
9603
+ requireOrgRef(hctx.args),
9117
9604
  requireDomainUuid(hctx.args)
9118
9605
  );
9119
9606
  outputSingle(result2, hctx.ctx);
@@ -9123,11 +9610,11 @@ var domainCommands = [
9123
9610
  path: ["org", "domains", "email", "get"],
9124
9611
  description: "Get email DNS setup and status for an organization domain",
9125
9612
  requiresWorkspace: false,
9126
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9613
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9127
9614
  examples: ["yarn gr org domains email get --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID"],
9128
9615
  handler: async (hctx) => {
9129
9616
  const result2 = await requireAuth(hctx.ctx).apiClient.getOrgDomainEmail(
9130
- requireOrgId(hctx.args),
9617
+ requireOrgRef(hctx.args),
9131
9618
  requireDomainUuid(hctx.args)
9132
9619
  );
9133
9620
  outputSingle(result2, hctx.ctx);
@@ -9147,7 +9634,7 @@ var domainCommands = [
9147
9634
  mutates: true,
9148
9635
  requiresWorkspace: false,
9149
9636
  args: [
9150
- ORG_UUID_ARG,
9637
+ ORG_UUID_ARG2,
9151
9638
  DOMAIN_UUID_ARG,
9152
9639
  {
9153
9640
  name: "confirm",
@@ -9161,7 +9648,7 @@ var domainCommands = [
9161
9648
  handler: async (hctx) => {
9162
9649
  const domainUuid = requireDomainUuid(hctx.args);
9163
9650
  const result2 = await requireAuth(hctx.ctx).apiClient.disableOrgDomainEmail(
9164
- requireOrgId(hctx.args),
9651
+ requireOrgRef(hctx.args),
9165
9652
  domainUuid,
9166
9653
  hctx.args.confirm === true
9167
9654
  );
@@ -9184,13 +9671,13 @@ var domainCommands = [
9184
9671
  description: "Enable custom site CNAME verification on a verified organization domain",
9185
9672
  mutates: true,
9186
9673
  requiresWorkspace: false,
9187
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9674
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9188
9675
  examples: [
9189
9676
  "yarn gr org domains site enable --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID --allow-write"
9190
9677
  ],
9191
9678
  handler: async (hctx) => {
9192
9679
  const result2 = await requireAuth(hctx.ctx).apiClient.enableOrgDomainSite(
9193
- requireOrgId(hctx.args),
9680
+ requireOrgRef(hctx.args),
9194
9681
  requireDomainUuid(hctx.args)
9195
9682
  );
9196
9683
  outputSingle(result2, hctx.ctx);
@@ -9200,11 +9687,11 @@ var domainCommands = [
9200
9687
  path: ["org", "domains", "site", "get"],
9201
9688
  description: "Get custom site CNAME setup and status for an organization domain",
9202
9689
  requiresWorkspace: false,
9203
- args: [ORG_UUID_ARG, DOMAIN_UUID_ARG],
9690
+ args: [ORG_UUID_ARG2, DOMAIN_UUID_ARG],
9204
9691
  examples: ["yarn gr org domains site get --org-uuid $ORG_UUID --domain-uuid $DOMAIN_UUID"],
9205
9692
  handler: async (hctx) => {
9206
9693
  const result2 = await requireAuth(hctx.ctx).apiClient.getOrgDomainSite(
9207
- requireOrgId(hctx.args),
9694
+ requireOrgRef(hctx.args),
9208
9695
  requireDomainUuid(hctx.args)
9209
9696
  );
9210
9697
  outputSingle(result2, hctx.ctx);
@@ -9224,7 +9711,7 @@ var domainCommands = [
9224
9711
  mutates: true,
9225
9712
  requiresWorkspace: false,
9226
9713
  args: [
9227
- ORG_UUID_ARG,
9714
+ ORG_UUID_ARG2,
9228
9715
  DOMAIN_UUID_ARG,
9229
9716
  {
9230
9717
  name: "confirm",
@@ -9238,7 +9725,7 @@ var domainCommands = [
9238
9725
  handler: async (hctx) => {
9239
9726
  const domainUuid = requireDomainUuid(hctx.args);
9240
9727
  const result2 = await requireAuth(hctx.ctx).apiClient.disableOrgDomainSite(
9241
- requireOrgId(hctx.args),
9728
+ requireOrgRef(hctx.args),
9242
9729
  domainUuid,
9243
9730
  hctx.args.confirm === true
9244
9731
  );
@@ -9273,6 +9760,226 @@ var orgDomain = {
9273
9760
  ]
9274
9761
  };
9275
9762
 
9763
+ // src/domains/org-legal-entities.ts
9764
+ var LEGAL_ENTITY_COLUMNS = [
9765
+ { header: "UUID", getValue: (e) => e.uuid ?? "" },
9766
+ { header: "LEGAL NAME", getValue: (e) => e.legalName ?? "" },
9767
+ { header: "PRIMARY", getValue: (e) => e.isPrimary ? "yes" : "" },
9768
+ { header: "ID TYPE", getValue: (e) => e.registrationIdentifierType ?? "" },
9769
+ { header: "PROFILE SID", getValue: (e) => e.customerProfileSid ?? "" },
9770
+ // The CACHED status hint. `org business-profile get` reads Twilio live.
9771
+ { header: "PROFILE STATUS (cached)", getValue: (e) => e.customerProfileStatus ?? "" }
9772
+ ];
9773
+ var LEGAL_ENTITY_UUID_ARG = {
9774
+ name: "legal-entity-uuid",
9775
+ aliases: ["legal-entity", "entity-uuid"],
9776
+ description: "Legal entity UUID (omit to use the org primary entity)",
9777
+ required: false
9778
+ };
9779
+ var TRUST_PRODUCT_ENTITY_UUID_ARG = { ...LEGAL_ENTITY_UUID_ARG, required: true };
9780
+ var TRUST_PRODUCT_COLUMNS = [
9781
+ { header: "PRODUCT", getValue: (p) => p.product ?? "" },
9782
+ { header: "STATUS", getValue: (p) => p.status ?? "(none)" },
9783
+ { header: "TRUST PRODUCT SID", getValue: (p) => p.trustProductSid ?? "(none)" },
9784
+ // CNAM only; blank for the other two rather than absent, so the column lines up.
9785
+ { header: "DISPLAY NAME", getValue: (p) => p.displayName ?? "" }
9786
+ ];
9787
+ function optionalEntityUuid(args) {
9788
+ const val = args["legal-entity-uuid"] ?? args["legal-entity"] ?? args["entity-uuid"];
9789
+ return typeof val === "string" && val ? val : void 0;
9790
+ }
9791
+ function requireEntityUuid(args) {
9792
+ const val = optionalEntityUuid(args);
9793
+ if (!val) {
9794
+ throw new CLIError("Missing required argument: --legal-entity-uuid");
9795
+ }
9796
+ return val;
9797
+ }
9798
+ function requireBody(data) {
9799
+ if (data && typeof data === "object" && !Array.isArray(data)) return data;
9800
+ throw new CLIError(
9801
+ `Missing or invalid --data. Pass a JSON object, e.g. --data '{"key":"value"}' (or --file body.json). Arrays are not accepted.`
9802
+ );
9803
+ }
9804
+ function submittability(profile) {
9805
+ if (profile.evaluationStatus === "compliant") return "yes";
9806
+ if (profile.evaluationStatus === "noncompliant") return "no (noncompliant)";
9807
+ if (profile.status && profile.status !== "draft") return `n/a (${profile.status})`;
9808
+ return "no (never evaluated)";
9809
+ }
9810
+ var commands2 = [
9811
+ {
9812
+ path: ["org", "legal-entities", "list"],
9813
+ description: "List an org's legal entities (one Twilio Customer Profile each). Requires org admin \u2014 staff join via `gr admin organizations join --role platform_support`.",
9814
+ requiresWorkspace: false,
9815
+ args: [ORG_UUID_ARG],
9816
+ examples: ["yarn gr org legal-entities list --org-uuid $ORG_UUID"],
9817
+ handler: async (hctx) => {
9818
+ const result2 = await requireAuth(hctx.ctx).apiClient.listLegalEntities(
9819
+ requireOrgRef(hctx.args)
9820
+ );
9821
+ outputData(result2.legalEntities ?? [], hctx.ctx, LEGAL_ENTITY_COLUMNS);
9822
+ }
9823
+ },
9824
+ {
9825
+ path: ["org", "legal-entities", "get"],
9826
+ description: "Get one legal entity",
9827
+ requiresWorkspace: false,
9828
+ args: [ORG_UUID_ARG, { ...LEGAL_ENTITY_UUID_ARG, required: true }],
9829
+ examples: [
9830
+ "yarn gr org legal-entities get --org-uuid $ORG_UUID --legal-entity-uuid $ENTITY_UUID"
9831
+ ],
9832
+ handler: async (hctx) => {
9833
+ const result2 = await requireAuth(hctx.ctx).apiClient.getLegalEntity(
9834
+ requireOrgRef(hctx.args),
9835
+ requireEntityUuid(hctx.args)
9836
+ );
9837
+ outputSingle(result2, hctx.ctx);
9838
+ }
9839
+ },
9840
+ {
9841
+ path: ["org", "legal-entities", "create"],
9842
+ description: "Create a legal entity (its business profile is filled in separately)",
9843
+ mutates: true,
9844
+ requiresWorkspace: false,
9845
+ args: [ORG_UUID_ARG],
9846
+ examples: [
9847
+ `yarn gr org legal-entities create --org-uuid $ORG_UUID --data '{"legalName":"Acme Health"}' --allow-write`
9848
+ ],
9849
+ handler: async (hctx) => {
9850
+ const result2 = await requireAuth(hctx.ctx).apiClient.createLegalEntity(
9851
+ requireOrgRef(hctx.args),
9852
+ requireBody(hctx.data)
9853
+ );
9854
+ outputSingle(result2, hctx.ctx);
9855
+ }
9856
+ },
9857
+ {
9858
+ path: ["org", "business-profile", "get"],
9859
+ description: "Read a legal entity's business profile LIVE from Twilio. SUBMITTABLE is derived from evaluationStatus, not status.",
9860
+ requiresWorkspace: false,
9861
+ args: [ORG_UUID_ARG, LEGAL_ENTITY_UUID_ARG],
9862
+ examples: ["yarn gr org business-profile get --org-uuid $ORG_UUID"],
9863
+ handler: async (hctx) => {
9864
+ const profile = await requireAuth(hctx.ctx).apiClient.getBusinessProfile(
9865
+ requireOrgRef(hctx.args),
9866
+ optionalEntityUuid(hctx.args)
9867
+ );
9868
+ outputSingle(
9869
+ hctx.ctx.outputFormat === "json" ? profile : {
9870
+ status: profile.status ?? "(none)",
9871
+ evaluationStatus: profile.evaluationStatus ?? "(not evaluated)",
9872
+ SUBMITTABLE: submittability(profile),
9873
+ customerProfileSid: profile.customerProfileSid ?? "(none)",
9874
+ legalName: profile.businessInfo?.legalName ?? "(missing)",
9875
+ authorizedReps: (profile.authorizedReps ?? []).length,
9876
+ hasAddress: profile.address ? "yes" : "no",
9877
+ failureReasons: (profile.failureReasons ?? []).join("; ") || "(none)",
9878
+ profileRecoveryFailed: profile.profileRecoveryFailed ? "YES" : "no"
9879
+ },
9880
+ hctx.ctx
9881
+ );
9882
+ }
9883
+ },
9884
+ {
9885
+ path: ["org", "business-profile", "update"],
9886
+ description: "Upsert the business profile (idempotent via cached SIDs). Returns the fresh compliance evaluation.",
9887
+ mutates: true,
9888
+ requiresWorkspace: false,
9889
+ args: [ORG_UUID_ARG, LEGAL_ENTITY_UUID_ARG],
9890
+ examples: [
9891
+ "yarn gr org business-profile update --org-uuid $ORG_UUID --file profile.json --allow-write"
9892
+ ],
9893
+ handler: async (hctx) => {
9894
+ const result2 = await requireAuth(hctx.ctx).apiClient.updateBusinessProfile(
9895
+ requireOrgRef(hctx.args),
9896
+ requireBody(hctx.data),
9897
+ optionalEntityUuid(hctx.args)
9898
+ );
9899
+ outputSingle(result2, hctx.ctx);
9900
+ }
9901
+ },
9902
+ {
9903
+ path: ["org", "business-profile", "submit"],
9904
+ description: "Submit the business profile to Twilio for review. Free \u2014 the paid step is brand registration, which is separate. 412 if not currently compliant, 409 if a review is already in flight.",
9905
+ mutates: true,
9906
+ requiresWorkspace: false,
9907
+ args: [ORG_UUID_ARG, LEGAL_ENTITY_UUID_ARG],
9908
+ examples: ["yarn gr org business-profile submit --org-uuid $ORG_UUID --allow-write"],
9909
+ handler: async (hctx) => {
9910
+ const result2 = await requireAuth(hctx.ctx).apiClient.submitBusinessProfile(
9911
+ requireOrgRef(hctx.args),
9912
+ optionalEntityUuid(hctx.args)
9913
+ );
9914
+ outputSingle(result2, hctx.ctx);
9915
+ }
9916
+ },
9917
+ {
9918
+ path: ["org", "business-profile", "cancel"],
9919
+ description: "Cancel an in-flight Twilio review, resetting the profile to draft so it can be edited and resubmitted",
9920
+ mutates: true,
9921
+ requiresWorkspace: false,
9922
+ args: [ORG_UUID_ARG, LEGAL_ENTITY_UUID_ARG],
9923
+ examples: ["yarn gr org business-profile cancel --org-uuid $ORG_UUID --allow-write"],
9924
+ handler: async (hctx) => {
9925
+ const result2 = await requireAuth(hctx.ctx).apiClient.cancelBusinessProfile(
9926
+ requireOrgRef(hctx.args),
9927
+ optionalEntityUuid(hctx.args)
9928
+ );
9929
+ outputSingle(result2, hctx.ctx);
9930
+ }
9931
+ },
9932
+ {
9933
+ path: ["org", "trust-products", "list"],
9934
+ description: "Read an entity's CACHED voice trust product state (CNAM / SHAKEN-STIR / Voice Integrity) from trust_hub_state. No Twilio calls \u2014 run `sync` to reconcile.",
9935
+ requiresWorkspace: false,
9936
+ args: [ORG_UUID_ARG, TRUST_PRODUCT_ENTITY_UUID_ARG],
9937
+ examples: [
9938
+ "yarn gr org trust-products list --org-uuid $ORG_UUID --legal-entity-uuid $ENTITY_UUID --env prod"
9939
+ ],
9940
+ handler: async (hctx) => {
9941
+ const result2 = await requireAuth(hctx.ctx).apiClient.getVoiceTrustProducts(
9942
+ requireOrgRef(hctx.args),
9943
+ requireEntityUuid(hctx.args)
9944
+ );
9945
+ outputData(result2.products, hctx.ctx, TRUST_PRODUCT_COLUMNS);
9946
+ }
9947
+ },
9948
+ {
9949
+ path: ["org", "trust-products", "sync"],
9950
+ description: "Reconcile voice trust products against Twilio: claim products staged outside the app and refresh non-terminal statuses. This is the prerequisite for `admin phone-numbers migrate`, whose preflight reads the cached state. 409 if another Trust Hub operation holds the org lock \u2014 retry shortly.",
9951
+ // Writes trust_hub_state and calls Twilio. Read-only in business terms
9952
+ // (it discovers, it does not create or submit), but it mutates our cache,
9953
+ // so it takes --allow-write like every other state-changing verb.
9954
+ mutates: true,
9955
+ requiresWorkspace: false,
9956
+ args: [ORG_UUID_ARG, TRUST_PRODUCT_ENTITY_UUID_ARG],
9957
+ examples: [
9958
+ "yarn gr org trust-products sync --org-uuid $ORG_UUID --legal-entity-uuid $ENTITY_UUID --env prod --allow-write"
9959
+ ],
9960
+ handler: async (hctx) => {
9961
+ const result2 = await requireAuth(hctx.ctx).apiClient.syncVoiceTrustProducts(
9962
+ requireOrgRef(hctx.args),
9963
+ requireEntityUuid(hctx.args)
9964
+ );
9965
+ if (hctx.ctx.outputFormat !== "table") {
9966
+ outputSingle(result2, hctx.ctx);
9967
+ return;
9968
+ }
9969
+ const discovered = result2.discovered ?? [];
9970
+ console.log(
9971
+ discovered.length > 0 ? `Discovered ${discovered.length} product(s): ${discovered.join(", ")}` : "No new products discovered \u2014 already up to date."
9972
+ );
9973
+ outputData(result2.products, hctx.ctx, TRUST_PRODUCT_COLUMNS);
9974
+ }
9975
+ }
9976
+ ];
9977
+ var orgLegalEntitiesDomain = {
9978
+ name: "org",
9979
+ description: "Legal entities and business profiles (Twilio Customer Profiles)",
9980
+ commands: commands2
9981
+ };
9982
+
9276
9983
  // src/domains/org-phone-numbers.ts
9277
9984
  import { OrgApi } from "@gravity-rail/sdk";
9278
9985
  function getOrgApi(hctx) {
@@ -9294,14 +10001,7 @@ var AVAILABLE_PHONE_COLUMNS = [
9294
10001
  { header: "Region", getValue: (p) => p.region ?? "" },
9295
10002
  { header: "Type", getValue: (p) => p.phoneNumberType ?? "" }
9296
10003
  ];
9297
- function requireOrgUuid(args) {
9298
- const val = args["org-uuid"] ?? args["org"];
9299
- if (typeof val !== "string" || !val) {
9300
- throw new CLIError("Missing required argument: --org-uuid");
9301
- }
9302
- return val;
9303
- }
9304
- var commands2 = [
10004
+ var commands3 = [
9305
10005
  {
9306
10006
  path: ["org", "phone-numbers", "list"],
9307
10007
  description: "List all phone numbers owned by an organization",
@@ -9311,7 +10011,7 @@ var commands2 = [
9311
10011
  requiresWorkspace: false,
9312
10012
  columns: PROVIDER_PHONE_COLUMNS,
9313
10013
  handler: async (hctx) => {
9314
- const orgUuid = requireOrgUuid(hctx.args);
10014
+ const orgUuid = requireOrgRef(hctx.args);
9315
10015
  const result2 = await getOrgApi(hctx).listPhoneNumbers(orgUuid);
9316
10016
  outputData(result2, hctx.ctx, PROVIDER_PHONE_COLUMNS);
9317
10017
  }
@@ -9334,7 +10034,7 @@ var commands2 = [
9334
10034
  requiresWorkspace: false,
9335
10035
  columns: AVAILABLE_PHONE_COLUMNS,
9336
10036
  handler: async (hctx) => {
9337
- const orgUuid = requireOrgUuid(hctx.args);
10037
+ const orgUuid = requireOrgRef(hctx.args);
9338
10038
  const result2 = await getOrgApi(hctx).searchPhoneNumbers(orgUuid, {
9339
10039
  country: hctx.args.country ?? "US",
9340
10040
  numberType: hctx.args["number-type"] ?? "local",
@@ -9370,7 +10070,7 @@ var commands2 = [
9370
10070
  requiresWorkspace: false,
9371
10071
  columns: PROVIDER_PHONE_COLUMNS,
9372
10072
  handler: async (hctx) => {
9373
- const orgUuid = requireOrgUuid(hctx.args);
10073
+ const orgUuid = requireOrgRef(hctx.args);
9374
10074
  const phoneNumber = hctx.args["phone-number"];
9375
10075
  if (!phoneNumber) throw new CLIError("Missing required argument: --phone-number");
9376
10076
  const numberType = hctx.args["number-type"] ?? "local";
@@ -9399,7 +10099,7 @@ var commands2 = [
9399
10099
  requiresWorkspace: false,
9400
10100
  columns: PROVIDER_PHONE_COLUMNS,
9401
10101
  handler: async (hctx) => {
9402
- const orgUuid = requireOrgUuid(hctx.args);
10102
+ const orgUuid = requireOrgRef(hctx.args);
9403
10103
  const providerPhoneUuid = hctx.args["provider-phone-uuid"];
9404
10104
  const workspaceUuid = hctx.args["workspace-uuid"];
9405
10105
  if (!providerPhoneUuid)
@@ -9431,7 +10131,7 @@ Create a workspace phone linked to this provider number (sets Twilio webhooks):
9431
10131
  requiresWorkspace: false,
9432
10132
  columns: PROVIDER_PHONE_COLUMNS,
9433
10133
  handler: async (hctx) => {
9434
- const orgUuid = requireOrgUuid(hctx.args);
10134
+ const orgUuid = requireOrgRef(hctx.args);
9435
10135
  const providerPhoneUuid = hctx.args["provider-phone-uuid"];
9436
10136
  const newWorkspaceUuid = hctx.args["new-workspace-uuid"];
9437
10137
  if (!providerPhoneUuid)
@@ -9457,7 +10157,7 @@ Create a workspace phone linked to this provider number (sets Twilio webhooks):
9457
10157
  requiresWorkspace: false,
9458
10158
  columns: PROVIDER_PHONE_COLUMNS,
9459
10159
  handler: async (hctx) => {
9460
- const orgUuid = requireOrgUuid(hctx.args);
10160
+ const orgUuid = requireOrgRef(hctx.args);
9461
10161
  const providerPhoneUuid = hctx.args["provider-phone-uuid"];
9462
10162
  if (!providerPhoneUuid)
9463
10163
  throw new CLIError("Missing required argument: --provider-phone-uuid");
@@ -9475,7 +10175,7 @@ Create a workspace phone linked to this provider number (sets Twilio webhooks):
9475
10175
  ],
9476
10176
  requiresWorkspace: false,
9477
10177
  handler: async (hctx) => {
9478
- const orgUuid = requireOrgUuid(hctx.args);
10178
+ const orgUuid = requireOrgRef(hctx.args);
9479
10179
  const providerPhoneUuid = hctx.args["provider-phone-uuid"];
9480
10180
  if (!providerPhoneUuid)
9481
10181
  throw new CLIError("Missing required argument: --provider-phone-uuid");
@@ -9487,7 +10187,7 @@ Create a workspace phone linked to this provider number (sets Twilio webhooks):
9487
10187
  var orgPhoneNumbersDomain = {
9488
10188
  name: "org",
9489
10189
  description: "Organization management",
9490
- commands: commands2
10190
+ commands: commands3
9491
10191
  };
9492
10192
 
9493
10193
  // src/lib/phone-numbers/defaults.ts
@@ -12498,7 +13198,7 @@ function requireCallerRole(args, flag) {
12498
13198
  }
12499
13199
  return role;
12500
13200
  }
12501
- var COLUMNS24 = [
13201
+ var COLUMNS25 = [
12502
13202
  COL.id(),
12503
13203
  { header: "NUMBER", getValue: (item) => item.phoneNumber ?? item.number ?? "" },
12504
13204
  { header: "LABEL", getValue: (item) => item.label ?? item.name ?? "" },
@@ -12525,7 +13225,7 @@ var phoneNumbersDomain = {
12525
13225
  entityName: "phone number",
12526
13226
  listMethod: "getPhoneNumbers",
12527
13227
  archiveMethod: "archivePhoneNumber",
12528
- columns: COLUMNS24
13228
+ columns: COLUMNS25
12529
13229
  }),
12530
13230
  {
12531
13231
  path: ["phone-numbers", "get"],
@@ -12575,7 +13275,7 @@ ${PHONE_NUMBER_FIELD_REFERENCE}`,
12575
13275
  );
12576
13276
  const record = asPhoneRecord(result2);
12577
13277
  const warnings = collectPhoneNumberWarnings(record);
12578
- outputData([record], ctx, COLUMNS24);
13278
+ outputData([record], ctx, COLUMNS25);
12579
13279
  if (warnings.length > 0) {
12580
13280
  process.stderr.write("\nWarnings after create:\n");
12581
13281
  for (const w of warnings) {
@@ -12607,7 +13307,7 @@ ${PHONE_NUMBER_FIELD_REFERENCE}`,
12607
13307
  id,
12608
13308
  data
12609
13309
  );
12610
- outputData([result2], ctx, COLUMNS24);
13310
+ outputData([result2], ctx, COLUMNS25);
12611
13311
  } catch (err) {
12612
13312
  return enrichPhoneNumberApiError(err);
12613
13313
  }
@@ -12895,7 +13595,7 @@ ${formatRoutingSimulation(sim, phone)}
12895
13595
  requiresWorkspace: true,
12896
13596
  handler: async ({ ctx, workspace }) => {
12897
13597
  const result2 = await requireAuth(ctx).apiClient.getAvailablePhoneNumbers(workspace);
12898
- outputData(result2, ctx, COLUMNS24);
13598
+ outputData(result2, ctx, COLUMNS25);
12899
13599
  }
12900
13600
  },
12901
13601
  {
@@ -12920,7 +13620,7 @@ ${formatRoutingSimulation(sim, phone)}
12920
13620
  const id = requireNumberFrom(args, "phone-number-id", "id");
12921
13621
  const providerPhoneUuid = requireString(args, "provider-phone-uuid");
12922
13622
  const result2 = await auth.apiClient.linkPhoneNumber(workspace, id, providerPhoneUuid);
12923
- outputData([result2], auth, COLUMNS24);
13623
+ outputData([result2], auth, COLUMNS25);
12924
13624
  }
12925
13625
  },
12926
13626
  {
@@ -12933,7 +13633,7 @@ ${formatRoutingSimulation(sim, phone)}
12933
13633
  workspace,
12934
13634
  data
12935
13635
  );
12936
- outputData([result2], ctx, COLUMNS24);
13636
+ outputData([result2], ctx, COLUMNS25);
12937
13637
  }
12938
13638
  },
12939
13639
  {
@@ -13080,7 +13780,7 @@ function normalizePronunciationUpdatePayload(data) {
13080
13780
  }
13081
13781
 
13082
13782
  // src/domains/pronunciations.ts
13083
- var COLUMNS25 = [
13783
+ var COLUMNS26 = [
13084
13784
  COL.id(),
13085
13785
  { header: "TERM", getValue: (item) => item.term ?? "" },
13086
13786
  { header: "RESPELLING", getValue: (item) => item.respelling ?? "" },
@@ -13102,7 +13802,7 @@ var pronunciationsDomain = {
13102
13802
  const auth = requireAuth(ctx);
13103
13803
  const orgUuid = await resolveOrgUuidFromWorkspace(auth.apiClient, workspace);
13104
13804
  const result2 = await auth.apiClient.getPronunciationEntries(orgUuid);
13105
- outputData(result2, ctx, COLUMNS25);
13805
+ outputData(result2, ctx, COLUMNS26);
13106
13806
  }
13107
13807
  },
13108
13808
  {
@@ -13116,7 +13816,7 @@ var pronunciationsDomain = {
13116
13816
  const orgUuid = await resolveOrgUuidFromWorkspace(auth.apiClient, workspace);
13117
13817
  const payload = normalizePronunciationCreatePayload(data);
13118
13818
  const result2 = await auth.apiClient.createPronunciationEntry(orgUuid, payload);
13119
- outputSingle(result2, ctx, COLUMNS25);
13819
+ outputSingle(result2, ctx, COLUMNS26);
13120
13820
  }
13121
13821
  },
13122
13822
  {
@@ -13134,7 +13834,7 @@ var pronunciationsDomain = {
13134
13834
  requireNumber(args, "id"),
13135
13835
  payload
13136
13836
  );
13137
- outputSingle(result2, ctx, COLUMNS25);
13837
+ outputSingle(result2, ctx, COLUMNS26);
13138
13838
  }
13139
13839
  },
13140
13840
  {
@@ -13158,7 +13858,7 @@ var pronunciationsDomain = {
13158
13858
  requiresWorkspace: true,
13159
13859
  handler: async ({ ctx }) => {
13160
13860
  const result2 = await requireAuth(ctx).apiClient.getMyPronunciations();
13161
- outputData(result2, ctx, COLUMNS25);
13861
+ outputData(result2, ctx, COLUMNS26);
13162
13862
  }
13163
13863
  },
13164
13864
  {
@@ -13169,7 +13869,7 @@ var pronunciationsDomain = {
13169
13869
  handler: async ({ ctx, data }) => {
13170
13870
  const payload = normalizePronunciationCreatePayload(data);
13171
13871
  const result2 = await requireAuth(ctx).apiClient.createMyPronunciation(payload);
13172
- outputSingle(result2, ctx, COLUMNS25);
13872
+ outputSingle(result2, ctx, COLUMNS26);
13173
13873
  }
13174
13874
  },
13175
13875
  {
@@ -13467,7 +14167,7 @@ ${ROUTINE_FIELD_REFERENCE}`,
13467
14167
  };
13468
14168
 
13469
14169
  // src/domains/subscriptions.ts
13470
- var COLUMNS26 = [
14170
+ var COLUMNS27 = [
13471
14171
  COL.id(),
13472
14172
  COL.status(),
13473
14173
  { header: "PLAN", getValue: (item) => item.planName ?? item.plan ?? "" },
@@ -13483,7 +14183,7 @@ var subscriptionsDomain = {
13483
14183
  requiresWorkspace: false,
13484
14184
  handler: async ({ ctx }) => {
13485
14185
  const result2 = await requireAuth(ctx).apiClient.getSubscriptions();
13486
- outputData(result2, ctx, COLUMNS26);
14186
+ outputData(result2, ctx, COLUMNS27);
13487
14187
  }
13488
14188
  },
13489
14189
  {
@@ -13492,7 +14192,7 @@ var subscriptionsDomain = {
13492
14192
  requiresWorkspace: true,
13493
14193
  handler: async ({ ctx, workspace }) => {
13494
14194
  const result2 = await requireAuth(ctx).apiClient.getWorkspaceSubscriptions(workspace);
13495
- outputData(result2, ctx, COLUMNS26);
14195
+ outputData(result2, ctx, COLUMNS27);
13496
14196
  }
13497
14197
  },
13498
14198
  {
@@ -13505,7 +14205,7 @@ var subscriptionsDomain = {
13505
14205
  const result2 = await requireAuth(ctx).apiClient.cancelSubscription(
13506
14206
  requireNumber(args, "id")
13507
14207
  );
13508
- outputSingle(result2, ctx, COLUMNS26);
14208
+ outputSingle(result2, ctx, COLUMNS27);
13509
14209
  }
13510
14210
  },
13511
14211
  {
@@ -13517,7 +14217,7 @@ var subscriptionsDomain = {
13517
14217
  const result2 = await requireAuth(ctx).apiClient.reactivateSubscription(
13518
14218
  requireNumber(args, "id")
13519
14219
  );
13520
- outputSingle(result2, ctx, COLUMNS26);
14220
+ outputSingle(result2, ctx, COLUMNS27);
13521
14221
  }
13522
14222
  },
13523
14223
  {
@@ -13531,7 +14231,7 @@ var subscriptionsDomain = {
13531
14231
  requireNumber(args, "id"),
13532
14232
  data
13533
14233
  );
13534
- outputSingle(result2, ctx, COLUMNS26);
14234
+ outputSingle(result2, ctx, COLUMNS27);
13535
14235
  }
13536
14236
  }
13537
14237
  ]
@@ -13785,7 +14485,7 @@ var supportDomain = {
13785
14485
  };
13786
14486
 
13787
14487
  // src/domains/supervisors.ts
13788
- var COLUMNS27 = [
14488
+ var COLUMNS28 = [
13789
14489
  COL.id(),
13790
14490
  COL.name(),
13791
14491
  { header: "TYPE", getValue: (item) => item.type ?? "" },
@@ -13803,7 +14503,7 @@ var supervisorsDomain = {
13803
14503
  createMethod: "createSupervisor",
13804
14504
  updateMethod: "updateSupervisor",
13805
14505
  deleteMethod: "deleteSupervisor",
13806
- columns: COLUMNS27
14506
+ columns: COLUMNS28
13807
14507
  })
13808
14508
  ]
13809
14509
  };
@@ -14147,7 +14847,7 @@ var widgetDomainsDomain = {
14147
14847
  }
14148
14848
  ],
14149
14849
  examples: [
14150
- "gr widget-domains enable -w $WID --domain <uuid> --widgets chat,operator --allow-write",
14850
+ "gr widget-domains enable -w $WID --domain <uuid> --widgets chat,operator-tools --allow-write",
14151
14851
  "gr widget-domains enable -w $WID --domain <uuid> --widgets chat --allow-subdomains --port 4444 --allow-write"
14152
14852
  ],
14153
14853
  handler: async ({ ctx, workspace, args }) => {
@@ -14191,7 +14891,7 @@ var widgetDomainsDomain = {
14191
14891
  };
14192
14892
 
14193
14893
  // src/domains/integrations/app-connections.ts
14194
- var COLUMNS28 = [
14894
+ var COLUMNS29 = [
14195
14895
  COL.id(),
14196
14896
  COL.name(),
14197
14897
  { header: "TYPE", getValue: (item) => item.type ?? "" },
@@ -14232,7 +14932,7 @@ var appConnectionsDomain = {
14232
14932
  requiresWorkspace: true,
14233
14933
  handler: async ({ ctx, workspace }) => {
14234
14934
  const result2 = await requireAuth(ctx).apiClient.listAvailableAppConnections(workspace);
14235
- outputData(result2, ctx, COLUMNS28);
14935
+ outputData(result2, ctx, COLUMNS29);
14236
14936
  }
14237
14937
  },
14238
14938
  {
@@ -14241,7 +14941,7 @@ var appConnectionsDomain = {
14241
14941
  requiresWorkspace: true,
14242
14942
  handler: async ({ ctx, workspace }) => {
14243
14943
  const result2 = await requireAuth(ctx).apiClient.listAppConnections(workspace);
14244
- outputData(result2, ctx, COLUMNS28);
14944
+ outputData(result2, ctx, COLUMNS29);
14245
14945
  }
14246
14946
  },
14247
14947
  {
@@ -14265,7 +14965,7 @@ var appConnectionsDomain = {
14265
14965
  const result2 = await requireAuth(ctx).apiClient.enablePlatformApp(workspace, {
14266
14966
  slug: requireString(args, "slug")
14267
14967
  });
14268
- outputSingle(result2, ctx, COLUMNS28);
14968
+ outputSingle(result2, ctx, COLUMNS29);
14269
14969
  }
14270
14970
  },
14271
14971
  {
@@ -14278,7 +14978,7 @@ var appConnectionsDomain = {
14278
14978
  workspace,
14279
14979
  requireString(args, "id")
14280
14980
  );
14281
- outputSingle(result2, ctx, COLUMNS28);
14981
+ outputSingle(result2, ctx, COLUMNS29);
14282
14982
  }
14283
14983
  },
14284
14984
  {
@@ -14293,7 +14993,7 @@ var appConnectionsDomain = {
14293
14993
  requireString(args, "id"),
14294
14994
  data
14295
14995
  );
14296
- outputSingle(result2, ctx, COLUMNS28);
14996
+ outputSingle(result2, ctx, COLUMNS29);
14297
14997
  }
14298
14998
  },
14299
14999
  {
@@ -14635,7 +15335,7 @@ var confluenceDomain = {
14635
15335
  };
14636
15336
 
14637
15337
  // src/domains/integrations/discord-bots.ts
14638
- var COLUMNS29 = [COL.id(), COL.name(), COL.status()];
15338
+ var COLUMNS30 = [COL.id(), COL.name(), COL.status()];
14639
15339
  var discordBotsDomain = {
14640
15340
  name: "discord-bots",
14641
15341
  description: "Manage Discord bot integrations",
@@ -14648,7 +15348,7 @@ var discordBotsDomain = {
14648
15348
  createMethod: "createDiscordBot",
14649
15349
  updateMethod: "updateDiscordBot",
14650
15350
  deleteMethod: "deleteDiscordBot",
14651
- columns: COLUMNS29,
15351
+ columns: COLUMNS30,
14652
15352
  paginationSupport: "full"
14653
15353
  }),
14654
15354
  {
@@ -14708,7 +15408,7 @@ var discordBotsDomain = {
14708
15408
  };
14709
15409
 
14710
15410
  // src/domains/integrations/fhir-connections.ts
14711
- var COLUMNS30 = [
15411
+ var COLUMNS31 = [
14712
15412
  COL.id(),
14713
15413
  COL.name(),
14714
15414
  { header: "URL", getValue: (item) => item.baseUrl ?? "" },
@@ -14726,7 +15426,7 @@ var fhirConnectionsDomain = {
14726
15426
  createMethod: "createFhirConnection",
14727
15427
  updateMethod: "updateFhirConnection",
14728
15428
  deleteMethod: "deleteFhirConnection",
14729
- columns: COLUMNS30,
15429
+ columns: COLUMNS31,
14730
15430
  paginationSupport: "full"
14731
15431
  }),
14732
15432
  {
@@ -14746,7 +15446,7 @@ var fhirConnectionsDomain = {
14746
15446
  };
14747
15447
 
14748
15448
  // src/domains/integrations/patientsync.ts
14749
- var COLUMNS31 = [
15449
+ var COLUMNS32 = [
14750
15450
  { header: "CONFIGURED", getValue: (i) => String(i.configured ?? false) },
14751
15451
  { header: "ENABLED", getValue: (i) => String(i.enabled ?? false) },
14752
15452
  { header: "HAS_KEY", getValue: (i) => String(i.hasApiKey ?? false) },
@@ -14775,7 +15475,7 @@ var patientSyncDomain = {
14775
15475
  workspace,
14776
15476
  data
14777
15477
  );
14778
- outputSingle(result2, ctx, COLUMNS31);
15478
+ outputSingle(result2, ctx, COLUMNS32);
14779
15479
  }
14780
15480
  },
14781
15481
  {
@@ -14784,7 +15484,7 @@ var patientSyncDomain = {
14784
15484
  requiresWorkspace: true,
14785
15485
  handler: async ({ ctx, workspace }) => {
14786
15486
  const result2 = await requireAuth(ctx).apiClient.getPatientSyncStatus(workspace);
14787
- outputSingle(result2, ctx, COLUMNS31);
15487
+ outputSingle(result2, ctx, COLUMNS32);
14788
15488
  }
14789
15489
  },
14790
15490
  {
@@ -15833,7 +16533,7 @@ var salesforceDomain = {
15833
16533
  };
15834
16534
 
15835
16535
  // src/domains/integrations/slack-apps.ts
15836
- var COLUMNS32 = [COL.id(), COL.name(), COL.status()];
16536
+ var COLUMNS33 = [COL.id(), COL.name(), COL.status()];
15837
16537
  function addSlackUrls(data, apiUrl, workspaceUuid) {
15838
16538
  const base = `${apiUrl}/api/v2/w/${workspaceUuid}/app-connections/slack`;
15839
16539
  return {
@@ -15856,7 +16556,7 @@ var slackAppsDomain = {
15856
16556
  entityName: "Slack app",
15857
16557
  listMethod: "getSlackApps",
15858
16558
  deleteMethod: "deleteSlackApp",
15859
- columns: COLUMNS32,
16559
+ columns: COLUMNS33,
15860
16560
  paginationSupport: "full"
15861
16561
  }),
15862
16562
  {
@@ -15942,7 +16642,7 @@ var slackAppsDomain = {
15942
16642
  };
15943
16643
 
15944
16644
  // src/domains/integrations/teams-apps.ts
15945
- var COLUMNS33 = [COL.id(), COL.name(), COL.status()];
16645
+ var COLUMNS34 = [COL.id(), COL.name(), COL.status()];
15946
16646
  function addTeamsUrls(data, apiUrl, workspaceUuid) {
15947
16647
  const base = `${apiUrl}/api/v2/w/${workspaceUuid}/app-connections/teams`;
15948
16648
  return {
@@ -15963,7 +16663,7 @@ var teamsAppsDomain = {
15963
16663
  entityName: "Teams app",
15964
16664
  listMethod: "getTeamsApps",
15965
16665
  deleteMethod: "deleteTeamsApp",
15966
- columns: COLUMNS33,
16666
+ columns: COLUMNS34,
15967
16667
  paginationSupport: "full"
15968
16668
  }),
15969
16669
  {
@@ -16069,6 +16769,7 @@ function registerPublicDomains(registry) {
16069
16769
  registry.register(qualificationsDomain);
16070
16770
  registry.register(queriesDomain);
16071
16771
  registry.register(personasDomain);
16772
+ registry.register(metricsDomain);
16072
16773
  registry.register(journeysDomain);
16073
16774
  registry.register(abilitiesDomain);
16074
16775
  registry.register(phoneNumbersDomain);
@@ -16076,10 +16777,10 @@ function registerPublicDomains(registry) {
16076
16777
  registry.register(inboxesDomain);
16077
16778
  registry.register(operatorGroupsDomain);
16078
16779
  registry.register(accessGrantsDomain);
16780
+ registry.register(interventionRequestsDomain);
16079
16781
  registry.register(notificationRulesDomain);
16080
16782
  registry.register(supervisorsDomain);
16081
16783
  registry.register(promptsDomain);
16082
- registry.register(milestonesDomain);
16083
16784
  registry.register(customToolkitsDomain);
16084
16785
  registry.register(mcpServersDomain);
16085
16786
  registry.register(apiKeysDomain);
@@ -16091,6 +16792,7 @@ function registerPublicDomains(registry) {
16091
16792
  registry.register(featuresDomain);
16092
16793
  registry.register(pronunciationsDomain);
16093
16794
  registry.register(orgDomain);
16795
+ registry.register(orgLegalEntitiesDomain);
16094
16796
  registry.register(orgPhoneNumbersDomain);
16095
16797
  registry.register(authManageDomain);
16096
16798
  registry.register(appsDomain);
@@ -19228,7 +19930,7 @@ async function authImportDevCommand(ctx, args) {
19228
19930
  }
19229
19931
 
19230
19932
  // src/commands/organizations.ts
19231
- var COLUMNS34 = [
19933
+ var COLUMNS35 = [
19232
19934
  { header: "NAME", getValue: (o) => o.organizationName || "", maxWidth: 35 },
19233
19935
  { header: "SLUG", getValue: (o) => o.organizationSlug || "", maxWidth: 25 },
19234
19936
  { header: "UUID", getValue: (o) => o.organizationUuid },
@@ -19236,7 +19938,7 @@ var COLUMNS34 = [
19236
19938
  ];
19237
19939
  async function organizationsListCommand(ctx) {
19238
19940
  const organizations = await ctx.apiClient.getMyOrganizations();
19239
- outputData(organizations, ctx, COLUMNS34);
19941
+ outputData(organizations, ctx, COLUMNS35);
19240
19942
  }
19241
19943
 
19242
19944
  // src/commands/whoami.ts