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