@carrierllc/mcp 0.2.20 → 0.3.1
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/{chunk-NHQDO2E7.js → chunk-TABEJ7SM.js} +2 -2
- package/dist/chunk-TABEJ7SM.js.map +1 -0
- package/dist/cli.js +594 -70
- package/dist/cli.js.map +1 -1
- package/dist/index.js +494 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-NHQDO2E7.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
clampUsagePeriod,
|
|
6
6
|
generateStorefrontLogo,
|
|
7
7
|
lastNDaysPeriod
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TABEJ7SM.js";
|
|
9
9
|
|
|
10
10
|
// src/cli/index.ts
|
|
11
11
|
import { Command } from "commander";
|
|
@@ -773,6 +773,22 @@ var DEFAULT_ERROR_HINTS = [
|
|
|
773
773
|
"Re-check the arguments: carrier <domain> <command> --help",
|
|
774
774
|
"Or open Claude and ask there with full tool routing"
|
|
775
775
|
];
|
|
776
|
+
var DEFAULT_MCP_TIMEOUT_MS = 45e3;
|
|
777
|
+
function mcpTimeoutMs() {
|
|
778
|
+
const parsed = Number(process.env.CARRIER_MCP_TIMEOUT_MS);
|
|
779
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_MCP_TIMEOUT_MS;
|
|
780
|
+
}
|
|
781
|
+
var McpTimeoutError = class extends Error {
|
|
782
|
+
constructor(timeoutMs) {
|
|
783
|
+
super(`timed out after ${Math.round(timeoutMs / 1e3)}s`);
|
|
784
|
+
this.timeoutMs = timeoutMs;
|
|
785
|
+
this.name = "McpTimeoutError";
|
|
786
|
+
}
|
|
787
|
+
timeoutMs;
|
|
788
|
+
};
|
|
789
|
+
function isTimeoutish(err) {
|
|
790
|
+
return err instanceof McpTimeoutError || err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError");
|
|
791
|
+
}
|
|
776
792
|
function parseRpcBody(raw) {
|
|
777
793
|
const trimmed = raw.trim();
|
|
778
794
|
if (!trimmed) return {};
|
|
@@ -801,79 +817,113 @@ async function callMcpTool(tool, args, opts = {}) {
|
|
|
801
817
|
"Content-Type": "application/json",
|
|
802
818
|
Accept: "application/json, text/event-stream"
|
|
803
819
|
};
|
|
820
|
+
const timeoutMs = mcpTimeoutMs();
|
|
821
|
+
const controller = new AbortController();
|
|
822
|
+
let deadlineTimer;
|
|
823
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
824
|
+
deadlineTimer = setTimeout(() => {
|
|
825
|
+
controller.abort();
|
|
826
|
+
reject(new McpTimeoutError(timeoutMs));
|
|
827
|
+
}, timeoutMs);
|
|
828
|
+
});
|
|
829
|
+
const signal = controller.signal;
|
|
804
830
|
try {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
831
|
+
return await Promise.race([
|
|
832
|
+
(async () => {
|
|
833
|
+
const initRes = await fetch(MCP_URL, {
|
|
834
|
+
method: "POST",
|
|
835
|
+
headers,
|
|
836
|
+
signal,
|
|
837
|
+
body: JSON.stringify({
|
|
838
|
+
jsonrpc: "2.0",
|
|
839
|
+
id: 1,
|
|
840
|
+
method: "initialize",
|
|
841
|
+
params: {
|
|
842
|
+
protocolVersion: "2024-11-05",
|
|
843
|
+
capabilities: {},
|
|
844
|
+
clientInfo: { name: "carrier-cli", version: CARRIER_VERSION }
|
|
845
|
+
}
|
|
846
|
+
})
|
|
847
|
+
});
|
|
848
|
+
if (initRes.status === 401 || initRes.status === 403) {
|
|
849
|
+
return {
|
|
850
|
+
ok: false,
|
|
851
|
+
text: withNextStep(`MCP returned ${initRes.status} (auth rejected).`, [
|
|
852
|
+
"Confirm CARRIER_API_KEY is a valid org key (ak_\u2026) from app.carrier.llc",
|
|
853
|
+
"Or complete OCS onboarding: https://app.carrier.llc/onboarding",
|
|
854
|
+
"Interactive: use Claude + OAuth instead of a headless key"
|
|
855
|
+
])
|
|
856
|
+
};
|
|
816
857
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
"
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
]
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
858
|
+
const sessionId = initRes.headers.get("mcp-session-id") ?? initRes.headers.get("Mcp-Session-Id");
|
|
859
|
+
await initRes.arrayBuffer().catch(() => void 0);
|
|
860
|
+
if (!sessionId) {
|
|
861
|
+
return {
|
|
862
|
+
ok: false,
|
|
863
|
+
text: withNextStep("MCP initialize did not return a session id.", [
|
|
864
|
+
"Check network access to https://mcp.carrier.llc/mcp",
|
|
865
|
+
"Retry later, or use Claude with the registered MCP (OAuth path)"
|
|
866
|
+
])
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
const sessionHeaders = { ...headers, "Mcp-Session-Id": sessionId };
|
|
870
|
+
await fetch(MCP_URL, {
|
|
871
|
+
method: "POST",
|
|
872
|
+
headers: sessionHeaders,
|
|
873
|
+
signal,
|
|
874
|
+
body: JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" })
|
|
875
|
+
}).catch(() => void 0);
|
|
876
|
+
const res = await fetch(MCP_URL, {
|
|
877
|
+
method: "POST",
|
|
878
|
+
headers: sessionHeaders,
|
|
879
|
+
signal,
|
|
880
|
+
body: JSON.stringify({
|
|
881
|
+
jsonrpc: "2.0",
|
|
882
|
+
id: 2,
|
|
883
|
+
method: "tools/call",
|
|
884
|
+
params: { name: tool, arguments: args }
|
|
885
|
+
})
|
|
886
|
+
});
|
|
887
|
+
if (!res.ok) {
|
|
888
|
+
const snippet = (await res.text().catch(() => "")).slice(0, 240);
|
|
889
|
+
return {
|
|
890
|
+
ok: false,
|
|
891
|
+
text: withNextStep(`MCP call failed (${res.status}). ${snippet}`, [
|
|
892
|
+
"Check network access to https://mcp.carrier.llc/mcp",
|
|
893
|
+
"Retry later, or use Claude with the registered MCP (OAuth path)"
|
|
894
|
+
])
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
const json = parseRpcBody(await res.text());
|
|
898
|
+
if (json.error?.message) {
|
|
899
|
+
return {
|
|
900
|
+
ok: false,
|
|
901
|
+
text: withNextStep(json.error.message, opts.errorHints ?? DEFAULT_ERROR_HINTS)
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
const parts = json.result?.content ?? [];
|
|
905
|
+
const text3 = parts.map((p4) => p4.text).filter(Boolean).join("\n").trim() || JSON.stringify(json.result ?? json, null, 2);
|
|
906
|
+
return { ok: !json.result?.isError, text: text3 };
|
|
907
|
+
})(),
|
|
908
|
+
deadline
|
|
909
|
+
]);
|
|
910
|
+
} catch (e) {
|
|
911
|
+
if (isTimeoutish(e)) {
|
|
912
|
+
const secs = Math.round(timeoutMs / 1e3);
|
|
868
913
|
return {
|
|
869
914
|
ok: false,
|
|
870
|
-
text: withNextStep(
|
|
915
|
+
text: withNextStep(
|
|
916
|
+
`MCP call to ${tool} timed out after ${secs}s (no response).`,
|
|
917
|
+
[
|
|
918
|
+
"The tool is likely returning more data than the MCP transport can deliver \u2014 see issue #663",
|
|
919
|
+
"Narrow the request (a specific --account-id / --iccid returns far less than a whole-fleet call)",
|
|
920
|
+
`Raise the deadline for one slow call: CARRIER_MCP_TIMEOUT_MS=${timeoutMs * 2} carrier \u2026`,
|
|
921
|
+
"Confirm the service is up: check network access to https://mcp.carrier.llc/mcp",
|
|
922
|
+
"Or open Claude and ask there with full tool routing"
|
|
923
|
+
]
|
|
924
|
+
)
|
|
871
925
|
};
|
|
872
926
|
}
|
|
873
|
-
const parts = json.result?.content ?? [];
|
|
874
|
-
const text3 = parts.map((p4) => p4.text).filter(Boolean).join("\n").trim() || JSON.stringify(json.result ?? json, null, 2);
|
|
875
|
-
return { ok: !json.result?.isError, text: text3 };
|
|
876
|
-
} catch (e) {
|
|
877
927
|
const msg = e instanceof Error ? e.message : String(e);
|
|
878
928
|
return {
|
|
879
929
|
ok: false,
|
|
@@ -882,6 +932,8 @@ async function callMcpTool(tool, args, opts = {}) {
|
|
|
882
932
|
"Use the interactive Claude path while offline from this machine"
|
|
883
933
|
])
|
|
884
934
|
};
|
|
935
|
+
} finally {
|
|
936
|
+
if (deadlineTimer !== void 0) clearTimeout(deadlineTimer);
|
|
885
937
|
}
|
|
886
938
|
}
|
|
887
939
|
async function carrierAsk(intent) {
|
|
@@ -1188,6 +1240,169 @@ var CLI_DOMAINS = [
|
|
|
1188
1240
|
}
|
|
1189
1241
|
],
|
|
1190
1242
|
write: true
|
|
1243
|
+
},
|
|
1244
|
+
{
|
|
1245
|
+
name: "sim-status show",
|
|
1246
|
+
tool: "get_sim_provider_status",
|
|
1247
|
+
summary: "SIM/eSIM status at the SIM provider level, distinct from OCS status.",
|
|
1248
|
+
options: [ICCID]
|
|
1249
|
+
},
|
|
1250
|
+
{
|
|
1251
|
+
name: "sim-status set",
|
|
1252
|
+
tool: "change_sim_status",
|
|
1253
|
+
summary: "Change the SIM/eSIM status at the SIM provider level. DELETED is irreversible.",
|
|
1254
|
+
options: [
|
|
1255
|
+
ICCID,
|
|
1256
|
+
{
|
|
1257
|
+
flags: "--status <status>",
|
|
1258
|
+
description: "New SIM status: ENABLED, DISABLED or DELETED (irreversible)",
|
|
1259
|
+
arg: "simStatus",
|
|
1260
|
+
type: "string",
|
|
1261
|
+
required: true
|
|
1262
|
+
}
|
|
1263
|
+
],
|
|
1264
|
+
write: true
|
|
1265
|
+
},
|
|
1266
|
+
{
|
|
1267
|
+
name: "phone-number set",
|
|
1268
|
+
tool: "affect_subscriber_phone_number",
|
|
1269
|
+
summary: "Assign a phone number (MSISDN) to a subscriber.",
|
|
1270
|
+
options: [
|
|
1271
|
+
ICCID,
|
|
1272
|
+
{
|
|
1273
|
+
flags: "--phone-number <e164>",
|
|
1274
|
+
description: "E.164 phone number to assign, e.g. +31612345678",
|
|
1275
|
+
arg: "phone_number",
|
|
1276
|
+
type: "string",
|
|
1277
|
+
required: true
|
|
1278
|
+
},
|
|
1279
|
+
{
|
|
1280
|
+
flags: "--phone-type <type>",
|
|
1281
|
+
description: "'fake' for test/dev MSISDNs, 'real' for production",
|
|
1282
|
+
arg: "phone_type",
|
|
1283
|
+
type: "string",
|
|
1284
|
+
required: true
|
|
1285
|
+
}
|
|
1286
|
+
],
|
|
1287
|
+
write: true
|
|
1288
|
+
},
|
|
1289
|
+
{
|
|
1290
|
+
name: "contact set",
|
|
1291
|
+
tool: "modify_subscriber_contact_info",
|
|
1292
|
+
summary: "Update contact details on a subscriber. Omitted fields stay unchanged.",
|
|
1293
|
+
options: [
|
|
1294
|
+
ICCID,
|
|
1295
|
+
{ flags: "--first-name <name>", description: "First name", arg: "firstName", type: "string" },
|
|
1296
|
+
{ flags: "--last-name <name>", description: "Last name", arg: "lastName", type: "string" },
|
|
1297
|
+
{ flags: "--company <name>", description: "Company name", arg: "company", type: "string" },
|
|
1298
|
+
{ flags: "--email <email>", description: "Email address", arg: "email", type: "string" },
|
|
1299
|
+
{ flags: "--phone-number <number>", description: "Phone number", arg: "phoneNumber", type: "string" }
|
|
1300
|
+
],
|
|
1301
|
+
write: true
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
name: "mobile-plan set",
|
|
1305
|
+
tool: "modify_subscriber_mobile_plan",
|
|
1306
|
+
summary: "Change the mobile pricing plan a subscriber is billed under.",
|
|
1307
|
+
options: [
|
|
1308
|
+
ICCID,
|
|
1309
|
+
{
|
|
1310
|
+
flags: "--plan-id <id>",
|
|
1311
|
+
description: "Mobile pricing plan ID",
|
|
1312
|
+
arg: "mobile_plan_id",
|
|
1313
|
+
type: "number",
|
|
1314
|
+
required: true
|
|
1315
|
+
}
|
|
1316
|
+
],
|
|
1317
|
+
write: true
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
name: "voip-plan set",
|
|
1321
|
+
tool: "modify_subscriber_voip_plan",
|
|
1322
|
+
summary: "Change the VoIP pricing plan assigned to a subscriber.",
|
|
1323
|
+
options: [
|
|
1324
|
+
ICCID,
|
|
1325
|
+
{
|
|
1326
|
+
flags: "--plan-id <id>",
|
|
1327
|
+
description: "VoIP pricing plan ID",
|
|
1328
|
+
arg: "voip_plan_id",
|
|
1329
|
+
type: "number",
|
|
1330
|
+
required: true
|
|
1331
|
+
}
|
|
1332
|
+
],
|
|
1333
|
+
write: true
|
|
1334
|
+
},
|
|
1335
|
+
{
|
|
1336
|
+
name: "traffic set",
|
|
1337
|
+
tool: "set_subscriber_traffic_restrictions",
|
|
1338
|
+
summary: "Enable or disable data, calls and SMS per traffic type. Omit a flag to leave it unchanged.",
|
|
1339
|
+
options: [
|
|
1340
|
+
ICCID,
|
|
1341
|
+
{ flags: "--data <bool>", description: "Allow data traffic (true or false)", arg: "dataAllowed", type: "boolean" },
|
|
1342
|
+
{ flags: "--moc <bool>", description: "Allow outbound calls (true or false)", arg: "mocAllowed", type: "boolean" },
|
|
1343
|
+
{ flags: "--mtc <bool>", description: "Allow inbound calls (true or false)", arg: "mtcAllowed", type: "boolean" },
|
|
1344
|
+
{ flags: "--sms <bool>", description: "Allow outbound SMS (true or false)", arg: "smsMoAllowed", type: "boolean" }
|
|
1345
|
+
],
|
|
1346
|
+
write: true
|
|
1347
|
+
},
|
|
1348
|
+
{
|
|
1349
|
+
name: "bitrate show",
|
|
1350
|
+
tool: "hlr_get_bitrate",
|
|
1351
|
+
summary: "Current HLR-level bandwidth cap for a subscriber.",
|
|
1352
|
+
options: [ICCID]
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
name: "bitrate set",
|
|
1356
|
+
tool: "hlr_set_bitrate",
|
|
1357
|
+
summary: "Set an HLR-level bandwidth cap. Pass a numeric bps value or an OCS level.",
|
|
1358
|
+
options: [
|
|
1359
|
+
ICCID,
|
|
1360
|
+
{
|
|
1361
|
+
flags: "--bitrate <bps>",
|
|
1362
|
+
description: "Max bitrate in bits per second (0 removes the limit)",
|
|
1363
|
+
arg: "bitrate",
|
|
1364
|
+
type: "number"
|
|
1365
|
+
},
|
|
1366
|
+
{
|
|
1367
|
+
flags: "--bitrate-string <level>",
|
|
1368
|
+
description: "OCS bitrate level, e.g. KB_256, KB_1024, UNLIMITED (instead of --bitrate)",
|
|
1369
|
+
arg: "bitrate_string",
|
|
1370
|
+
type: "string"
|
|
1371
|
+
}
|
|
1372
|
+
],
|
|
1373
|
+
write: true,
|
|
1374
|
+
requireOneOf: ["bitrate", "bitrate_string"]
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
name: "greenzone reset",
|
|
1378
|
+
tool: "reset_subscriber_gz_counter",
|
|
1379
|
+
summary: "Reset the Green Zone byte counter to zero. Irreversible.",
|
|
1380
|
+
options: [ICCID],
|
|
1381
|
+
write: true
|
|
1382
|
+
},
|
|
1383
|
+
{
|
|
1384
|
+
name: "cell-location",
|
|
1385
|
+
tool: "get_subscriber_location_by_cell_id",
|
|
1386
|
+
summary: "Resolve a raw cell tower tuple to coordinates (Bridge4IP GeoSense).",
|
|
1387
|
+
options: [
|
|
1388
|
+
{
|
|
1389
|
+
flags: "--radio-type <type>",
|
|
1390
|
+
description: "Radio type: 2G, 3G, 4G, 5G or NB-IoT",
|
|
1391
|
+
arg: "radio_type",
|
|
1392
|
+
type: "string",
|
|
1393
|
+
required: true
|
|
1394
|
+
},
|
|
1395
|
+
{ flags: "--mcc <mcc>", description: "Mobile Country Code", arg: "mcc", type: "number", required: true },
|
|
1396
|
+
{ flags: "--mnc <mnc>", description: "Mobile Network Code", arg: "mnc", type: "number", required: true },
|
|
1397
|
+
{ flags: "--lac <lac>", description: "Location Area Code", arg: "lac", type: "number", required: true },
|
|
1398
|
+
{ flags: "--cell-id <id>", description: "Cell tower ID (strongly recommended)", arg: "cell_id", type: "number" },
|
|
1399
|
+
{
|
|
1400
|
+
flags: "--signal-strength <dbm>",
|
|
1401
|
+
description: "Signal strength in dBm, e.g. -89 (improves accuracy)",
|
|
1402
|
+
arg: "signal_strength",
|
|
1403
|
+
type: "number"
|
|
1404
|
+
}
|
|
1405
|
+
]
|
|
1191
1406
|
}
|
|
1192
1407
|
]
|
|
1193
1408
|
},
|
|
@@ -1280,6 +1495,87 @@ var CLI_DOMAINS = [
|
|
|
1280
1495
|
],
|
|
1281
1496
|
write: true
|
|
1282
1497
|
},
|
|
1498
|
+
{
|
|
1499
|
+
name: "assign-recurring",
|
|
1500
|
+
tool: "assign_recurring_package",
|
|
1501
|
+
summary: "Assign an auto-renewing package from a recurring-enabled template.",
|
|
1502
|
+
options: [
|
|
1503
|
+
ICCID,
|
|
1504
|
+
{
|
|
1505
|
+
flags: "--template-id <id>",
|
|
1506
|
+
description: "Recurring package template ID from `carrier templates list`",
|
|
1507
|
+
arg: "packageTemplateId",
|
|
1508
|
+
type: "number",
|
|
1509
|
+
required: true
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
flags: "--activate-at-first-use",
|
|
1513
|
+
description: "Activate on first network usage (instead of --start-time)",
|
|
1514
|
+
arg: "activation_at_first_use",
|
|
1515
|
+
type: "boolean"
|
|
1516
|
+
},
|
|
1517
|
+
{
|
|
1518
|
+
flags: "--start-time <iso>",
|
|
1519
|
+
description: "Scheduled activation, ISO 8601 UTC (instead of --activate-at-first-use)",
|
|
1520
|
+
arg: "start_time_utc",
|
|
1521
|
+
type: "string"
|
|
1522
|
+
}
|
|
1523
|
+
],
|
|
1524
|
+
write: true
|
|
1525
|
+
},
|
|
1526
|
+
{
|
|
1527
|
+
name: "recurring set",
|
|
1528
|
+
tool: "stop_resume_recurring_package",
|
|
1529
|
+
summary: "Pause or restart the auto-renewal of a recurring package.",
|
|
1530
|
+
options: [
|
|
1531
|
+
ICCID,
|
|
1532
|
+
PACKAGE_ID,
|
|
1533
|
+
{
|
|
1534
|
+
flags: "--action <action>",
|
|
1535
|
+
description: "'stop' halts future renewals, 'resume' re-enables them",
|
|
1536
|
+
arg: "action",
|
|
1537
|
+
type: "string",
|
|
1538
|
+
required: true
|
|
1539
|
+
}
|
|
1540
|
+
],
|
|
1541
|
+
write: true
|
|
1542
|
+
},
|
|
1543
|
+
{
|
|
1544
|
+
name: "active-period set",
|
|
1545
|
+
tool: "modify_subscriber_package_active_period",
|
|
1546
|
+
summary: "Move the start and/or end of a package's active period.",
|
|
1547
|
+
options: [
|
|
1548
|
+
ICCID,
|
|
1549
|
+
{
|
|
1550
|
+
flags: "--package-id <id>",
|
|
1551
|
+
description: "Package ID from `carrier packages list`",
|
|
1552
|
+
arg: "package_id",
|
|
1553
|
+
type: "number",
|
|
1554
|
+
required: true
|
|
1555
|
+
},
|
|
1556
|
+
{
|
|
1557
|
+
flags: "--start <date>",
|
|
1558
|
+
description: "New start date, ISO 8601 (e.g. 2026-09-01)",
|
|
1559
|
+
arg: "start_date",
|
|
1560
|
+
type: "string"
|
|
1561
|
+
},
|
|
1562
|
+
{
|
|
1563
|
+
flags: "--end <date>",
|
|
1564
|
+
description: "New end date, ISO 8601 (e.g. 2026-09-30)",
|
|
1565
|
+
arg: "end_date",
|
|
1566
|
+
type: "string"
|
|
1567
|
+
}
|
|
1568
|
+
],
|
|
1569
|
+
write: true,
|
|
1570
|
+
requireOneOf: ["start_date", "end_date"]
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
name: "clean",
|
|
1574
|
+
tool: "clean_all_packages",
|
|
1575
|
+
summary: "Remove ALL packages from a subscriber. Irreversible.",
|
|
1576
|
+
options: [ICCID],
|
|
1577
|
+
write: true
|
|
1578
|
+
},
|
|
1283
1579
|
{
|
|
1284
1580
|
name: "delete",
|
|
1285
1581
|
tool: "delete_subscriber_package",
|
|
@@ -1402,6 +1698,28 @@ var CLI_DOMAINS = [
|
|
|
1402
1698
|
],
|
|
1403
1699
|
write: true
|
|
1404
1700
|
},
|
|
1701
|
+
{
|
|
1702
|
+
name: "network-profile set",
|
|
1703
|
+
tool: "change_network_profile_of_location_zone",
|
|
1704
|
+
summary: "Attach or change the network profile on an existing location zone.",
|
|
1705
|
+
options: [
|
|
1706
|
+
{
|
|
1707
|
+
flags: "--zone-id <id>",
|
|
1708
|
+
description: "Location zone ID from `carrier zones list`",
|
|
1709
|
+
arg: "location_zone_id",
|
|
1710
|
+
type: "number",
|
|
1711
|
+
required: true
|
|
1712
|
+
},
|
|
1713
|
+
{
|
|
1714
|
+
flags: "--network-profile-id <id>",
|
|
1715
|
+
description: "Network profile ID from `carrier network-profiles list`",
|
|
1716
|
+
arg: "network_profile_id",
|
|
1717
|
+
type: "number",
|
|
1718
|
+
required: true
|
|
1719
|
+
}
|
|
1720
|
+
],
|
|
1721
|
+
write: true
|
|
1722
|
+
},
|
|
1405
1723
|
{
|
|
1406
1724
|
name: "destinations",
|
|
1407
1725
|
tool: "list_destination_lists",
|
|
@@ -1458,6 +1776,193 @@ var CLI_DOMAINS = [
|
|
|
1458
1776
|
}
|
|
1459
1777
|
]
|
|
1460
1778
|
},
|
|
1779
|
+
{
|
|
1780
|
+
name: "accounts",
|
|
1781
|
+
summary: "Reseller accounts: balances and subscriber moves.",
|
|
1782
|
+
commands: [
|
|
1783
|
+
{
|
|
1784
|
+
name: "list",
|
|
1785
|
+
tool: "list_reseller_accounts",
|
|
1786
|
+
summary: "Accounts under a reseller with name, balance and type.",
|
|
1787
|
+
options: [RESELLER_ID]
|
|
1788
|
+
},
|
|
1789
|
+
{
|
|
1790
|
+
name: "balance set",
|
|
1791
|
+
tool: "modify_account_balance",
|
|
1792
|
+
summary: "Add to or replace an account's monetary balance.",
|
|
1793
|
+
options: [
|
|
1794
|
+
{ ...ACCOUNT_ID("Account ID from `carrier accounts list`"), required: true },
|
|
1795
|
+
{
|
|
1796
|
+
flags: "--amount <amount>",
|
|
1797
|
+
description: "Amount to add (adapt) or set to (set)",
|
|
1798
|
+
arg: "amount",
|
|
1799
|
+
type: "number",
|
|
1800
|
+
required: true
|
|
1801
|
+
},
|
|
1802
|
+
{
|
|
1803
|
+
flags: "--mode <mode>",
|
|
1804
|
+
description: "'adapt' adds or subtracts, 'set' replaces",
|
|
1805
|
+
arg: "mode",
|
|
1806
|
+
type: "string",
|
|
1807
|
+
required: true
|
|
1808
|
+
}
|
|
1809
|
+
],
|
|
1810
|
+
write: true
|
|
1811
|
+
},
|
|
1812
|
+
{
|
|
1813
|
+
name: "move-subscribers",
|
|
1814
|
+
tool: "move_subscriber_range_to_account",
|
|
1815
|
+
summary: "Move a contiguous ICCID range of subscribers to another account.",
|
|
1816
|
+
options: [
|
|
1817
|
+
{
|
|
1818
|
+
flags: "--iccid-from <iccid>",
|
|
1819
|
+
description: "Start ICCID of the range (inclusive)",
|
|
1820
|
+
arg: "iccidFrom",
|
|
1821
|
+
type: "string",
|
|
1822
|
+
required: true
|
|
1823
|
+
},
|
|
1824
|
+
{
|
|
1825
|
+
flags: "--iccid-to <iccid>",
|
|
1826
|
+
description: "End ICCID of the range (inclusive)",
|
|
1827
|
+
arg: "iccidTo",
|
|
1828
|
+
type: "string",
|
|
1829
|
+
required: true
|
|
1830
|
+
},
|
|
1831
|
+
{ ...ACCOUNT_ID("Target account ID from `carrier accounts list`"), required: true }
|
|
1832
|
+
],
|
|
1833
|
+
write: true
|
|
1834
|
+
}
|
|
1835
|
+
]
|
|
1836
|
+
},
|
|
1837
|
+
{
|
|
1838
|
+
name: "reseller",
|
|
1839
|
+
summary: "The reseller the token belongs to.",
|
|
1840
|
+
commands: [
|
|
1841
|
+
{
|
|
1842
|
+
name: "show",
|
|
1843
|
+
tool: "get_reseller_info",
|
|
1844
|
+
summary: "Full reseller record: balance, pricing plans, contact and traffic config.",
|
|
1845
|
+
options: [RESELLER_ID]
|
|
1846
|
+
}
|
|
1847
|
+
]
|
|
1848
|
+
},
|
|
1849
|
+
{
|
|
1850
|
+
name: "tariff",
|
|
1851
|
+
summary: "Wholesale tariffs: mobile and VoIP rates.",
|
|
1852
|
+
commands: [
|
|
1853
|
+
{
|
|
1854
|
+
name: "show",
|
|
1855
|
+
tool: "get_tariff",
|
|
1856
|
+
summary: "Per-country wholesale rates for data, voice and SMS.",
|
|
1857
|
+
options: [RESELLER_ID]
|
|
1858
|
+
},
|
|
1859
|
+
{
|
|
1860
|
+
name: "voip",
|
|
1861
|
+
tool: "list_subscriber_voip_tariff",
|
|
1862
|
+
summary: "VoIP tariff catalog for a reseller.",
|
|
1863
|
+
options: [
|
|
1864
|
+
{
|
|
1865
|
+
flags: "--reseller-id <id>",
|
|
1866
|
+
description: "Reseller ID (omit for the token owner's reseller)",
|
|
1867
|
+
arg: "reseller_id",
|
|
1868
|
+
type: "number"
|
|
1869
|
+
}
|
|
1870
|
+
]
|
|
1871
|
+
},
|
|
1872
|
+
{
|
|
1873
|
+
name: "voip-rules",
|
|
1874
|
+
tool: "list_voip_tariff_rule",
|
|
1875
|
+
summary: "Rate rules inside one VoIP plan.",
|
|
1876
|
+
options: [
|
|
1877
|
+
{
|
|
1878
|
+
flags: "--voip-plan-id <id>",
|
|
1879
|
+
description: "VoIP plan ID from `carrier tariff voip`",
|
|
1880
|
+
arg: "voip_plan_id",
|
|
1881
|
+
type: "number",
|
|
1882
|
+
required: true
|
|
1883
|
+
}
|
|
1884
|
+
]
|
|
1885
|
+
}
|
|
1886
|
+
]
|
|
1887
|
+
},
|
|
1888
|
+
{
|
|
1889
|
+
name: "sms",
|
|
1890
|
+
summary: "Mobile-terminated SMS to subscribers.",
|
|
1891
|
+
commands: [
|
|
1892
|
+
{
|
|
1893
|
+
name: "send",
|
|
1894
|
+
tool: "send_sms",
|
|
1895
|
+
summary: "Send an MT SMS to one subscriber.",
|
|
1896
|
+
options: [
|
|
1897
|
+
ICCID,
|
|
1898
|
+
{
|
|
1899
|
+
flags: "--msisdn <msisdn>",
|
|
1900
|
+
description: "Target MSISDN in E.164 format",
|
|
1901
|
+
arg: "msisdn",
|
|
1902
|
+
type: "string",
|
|
1903
|
+
required: true
|
|
1904
|
+
},
|
|
1905
|
+
{
|
|
1906
|
+
flags: "--message <text>",
|
|
1907
|
+
description: "SMS text (160 chars GSM-7; 70 with emoji or non-Latin scripts)",
|
|
1908
|
+
arg: "message",
|
|
1909
|
+
type: "string",
|
|
1910
|
+
required: true
|
|
1911
|
+
},
|
|
1912
|
+
{
|
|
1913
|
+
flags: "--sender <sender>",
|
|
1914
|
+
description: "Sender ID or number shown on the device",
|
|
1915
|
+
arg: "sender",
|
|
1916
|
+
type: "string"
|
|
1917
|
+
}
|
|
1918
|
+
],
|
|
1919
|
+
write: true
|
|
1920
|
+
}
|
|
1921
|
+
]
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
name: "sponsors",
|
|
1925
|
+
summary: "Sponsor networks backing the eSIM profiles.",
|
|
1926
|
+
commands: [
|
|
1927
|
+
{
|
|
1928
|
+
name: "list",
|
|
1929
|
+
tool: "list_sponsors",
|
|
1930
|
+
summary: "Sponsor carriers available to this reseller.",
|
|
1931
|
+
options: [RESELLER_ID]
|
|
1932
|
+
}
|
|
1933
|
+
]
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
name: "network-profiles",
|
|
1937
|
+
summary: "Roaming configuration profiles for zones and provisioning.",
|
|
1938
|
+
commands: [
|
|
1939
|
+
{
|
|
1940
|
+
name: "list",
|
|
1941
|
+
tool: "list_network_profiles",
|
|
1942
|
+
summary: "Network profiles available to this reseller.",
|
|
1943
|
+
options: []
|
|
1944
|
+
}
|
|
1945
|
+
]
|
|
1946
|
+
},
|
|
1947
|
+
{
|
|
1948
|
+
name: "webhooks",
|
|
1949
|
+
summary: "Bridge4IP webhook and relay flag status.",
|
|
1950
|
+
commands: [
|
|
1951
|
+
{
|
|
1952
|
+
name: "show",
|
|
1953
|
+
tool: "carrier_webhook_config",
|
|
1954
|
+
summary: "Current relay flags (LU, Gy, VoIP, calls+SMS) and notification webhooks.",
|
|
1955
|
+
options: [
|
|
1956
|
+
{
|
|
1957
|
+
flags: "--reseller-id <id>",
|
|
1958
|
+
description: "Reseller ID (omit for the token owner's reseller)",
|
|
1959
|
+
arg: "reseller_id",
|
|
1960
|
+
type: "number"
|
|
1961
|
+
}
|
|
1962
|
+
]
|
|
1963
|
+
}
|
|
1964
|
+
]
|
|
1965
|
+
},
|
|
1461
1966
|
{
|
|
1462
1967
|
name: "intelligence",
|
|
1463
1968
|
summary: "Composite reports over the fleet.",
|
|
@@ -1560,7 +2065,13 @@ function setArg(target, path, value) {
|
|
|
1560
2065
|
node[parts[parts.length - 1]] = value;
|
|
1561
2066
|
}
|
|
1562
2067
|
function coerce(opt, raw) {
|
|
1563
|
-
if (opt.type === "boolean")
|
|
2068
|
+
if (opt.type === "boolean") {
|
|
2069
|
+
if (raw === true) return { value: true };
|
|
2070
|
+
const text3 = String(raw).toLowerCase();
|
|
2071
|
+
if (text3 === "true") return { value: true };
|
|
2072
|
+
if (text3 === "false") return { value: false };
|
|
2073
|
+
return { error: `${opt.flags} expects true or false, got "${String(raw)}"` };
|
|
2074
|
+
}
|
|
1564
2075
|
if (opt.type === "number") {
|
|
1565
2076
|
const n = Number(raw);
|
|
1566
2077
|
if (!Number.isFinite(n)) return { error: `${opt.flags} expects a number, got "${String(raw)}"` };
|
|
@@ -2068,8 +2579,21 @@ program.command("ask").description(
|
|
|
2068
2579
|
});
|
|
2069
2580
|
for (const domain of CLI_DOMAINS) {
|
|
2070
2581
|
const group = program.command(domain.name).description(domain.summary);
|
|
2582
|
+
const subgroups = /* @__PURE__ */ new Map();
|
|
2071
2583
|
for (const cmd of domain.commands) {
|
|
2072
|
-
const
|
|
2584
|
+
const parts = cmd.name.split(" ");
|
|
2585
|
+
let parent = group;
|
|
2586
|
+
let prefix = "";
|
|
2587
|
+
for (const part of parts.slice(0, -1)) {
|
|
2588
|
+
prefix = prefix ? `${prefix} ${part}` : part;
|
|
2589
|
+
let nested = subgroups.get(prefix);
|
|
2590
|
+
if (!nested) {
|
|
2591
|
+
nested = parent.command(part).description(`${part} subcommands`);
|
|
2592
|
+
subgroups.set(prefix, nested);
|
|
2593
|
+
}
|
|
2594
|
+
parent = nested;
|
|
2595
|
+
}
|
|
2596
|
+
const sub = parent.command(parts[parts.length - 1]).description(cmd.write ? `${cmd.summary} Dry run unless --commit.` : cmd.summary);
|
|
2073
2597
|
for (const opt of cmd.options) sub.option(opt.flags, opt.description);
|
|
2074
2598
|
sub.option("--json", "Print the raw tool response on stdout and nothing else");
|
|
2075
2599
|
if (cmd.write) sub.option("--commit", "Apply the change instead of previewing it");
|