@stndrds/cli 1.0.0-alpha.295 → 1.0.0-alpha.296
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/bin.mjs +115 -70
- package/package.json +3 -3
package/dist/bin.mjs
CHANGED
|
@@ -16,62 +16,11 @@ function createClient(config) {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// src/commands/
|
|
20
|
-
import
|
|
21
|
-
|
|
22
|
-
// src/commands/common.ts
|
|
23
|
-
function getGlobalOptions(cmd) {
|
|
24
|
-
return cmd.optsWithGlobals();
|
|
25
|
-
}
|
|
26
|
-
function getFormat(cmd) {
|
|
27
|
-
return getGlobalOptions(cmd).format;
|
|
28
|
-
}
|
|
29
|
-
function parseCsvList(value) {
|
|
30
|
-
return value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
31
|
-
}
|
|
32
|
-
function getClientFromCommand(cmd) {
|
|
33
|
-
const root = getGlobalOptions(cmd);
|
|
34
|
-
if (!(root.apiUrl && root.apiKey)) {
|
|
35
|
-
throw new Error('No Standards instance configured. Run "standards login" or pass --api-key.');
|
|
36
|
-
}
|
|
37
|
-
return createClient({ apiUrl: root.apiUrl, apiKey: root.apiKey, tenantId: root.tenant });
|
|
38
|
-
}
|
|
39
|
-
function requireTenant(cmd, message) {
|
|
40
|
-
const { tenant } = getGlobalOptions(cmd);
|
|
41
|
-
if (!tenant) {
|
|
42
|
-
throw new Error(message);
|
|
43
|
-
}
|
|
44
|
-
return tenant;
|
|
45
|
-
}
|
|
46
|
-
function messageOf(error) {
|
|
47
|
-
return error instanceof Error ? error.message : String(error);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// src/commands/auth.ts
|
|
51
|
-
function registerAuthCommand(program) {
|
|
52
|
-
const auth = program.command("auth").description("Inspect CLI authentication");
|
|
53
|
-
auth.command("whoami").description("Show current configuration and validate API key").action(async (_opts, cmd) => {
|
|
54
|
-
const root = getGlobalOptions(cmd);
|
|
55
|
-
const client = getClientFromCommand(cmd);
|
|
56
|
-
const write = (msg) => process.stdout.write(`${msg}
|
|
57
|
-
`);
|
|
58
|
-
write(chalk.bold("Standards CLI Configuration"));
|
|
59
|
-
write(` API URL: ${root.apiUrl}`);
|
|
60
|
-
write(` API Key: ${root.apiKey ? `${root.apiKey.slice(0, 8)}...` : chalk.red("not set")}`);
|
|
61
|
-
write("");
|
|
62
|
-
const keys = await client.get("/api-keys");
|
|
63
|
-
write(chalk.green("\u2713 API key is valid"));
|
|
64
|
-
if (Array.isArray(keys) && keys.length > 0) {
|
|
65
|
-
const activeKeys = keys.filter(
|
|
66
|
-
(key) => typeof key === "object" && key !== null && !("revokedAt" in key && key.revokedAt)
|
|
67
|
-
);
|
|
68
|
-
write(` Active keys: ${activeKeys.length}`);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
}
|
|
19
|
+
// src/commands/ai.ts
|
|
20
|
+
import { ValidationError } from "@stndrds/schema";
|
|
72
21
|
|
|
73
22
|
// src/output.ts
|
|
74
|
-
import
|
|
23
|
+
import chalk from "chalk";
|
|
75
24
|
import Table from "cli-table3";
|
|
76
25
|
var MAX_CELL_WIDTH = 50;
|
|
77
26
|
function truncate(value, maxLength) {
|
|
@@ -100,7 +49,7 @@ function formatTable(items) {
|
|
|
100
49
|
if (items.length === 0) return "No results.";
|
|
101
50
|
const headers = Object.keys(items[0]);
|
|
102
51
|
const table = new Table({
|
|
103
|
-
head: headers.map((h) =>
|
|
52
|
+
head: headers.map((h) => chalk.bold(h)),
|
|
104
53
|
style: { head: [], border: [] }
|
|
105
54
|
});
|
|
106
55
|
for (const item of items) {
|
|
@@ -130,6 +79,90 @@ function formatOutput(data, format) {
|
|
|
130
79
|
`);
|
|
131
80
|
}
|
|
132
81
|
|
|
82
|
+
// src/commands/common.ts
|
|
83
|
+
function getGlobalOptions(cmd) {
|
|
84
|
+
return cmd.optsWithGlobals();
|
|
85
|
+
}
|
|
86
|
+
function getFormat(cmd) {
|
|
87
|
+
return getGlobalOptions(cmd).format;
|
|
88
|
+
}
|
|
89
|
+
function parseCsvList(value) {
|
|
90
|
+
return value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
91
|
+
}
|
|
92
|
+
function getClientFromCommand(cmd) {
|
|
93
|
+
const root = getGlobalOptions(cmd);
|
|
94
|
+
if (!(root.apiUrl && root.apiKey)) {
|
|
95
|
+
throw new Error('No Standards instance configured. Run "standards login" or pass --api-key.');
|
|
96
|
+
}
|
|
97
|
+
return createClient({ apiUrl: root.apiUrl, apiKey: root.apiKey, tenantId: root.tenant });
|
|
98
|
+
}
|
|
99
|
+
function requireTenant(cmd, message) {
|
|
100
|
+
const { tenant } = getGlobalOptions(cmd);
|
|
101
|
+
if (!tenant) {
|
|
102
|
+
throw new Error(message);
|
|
103
|
+
}
|
|
104
|
+
return tenant;
|
|
105
|
+
}
|
|
106
|
+
function messageOf(error) {
|
|
107
|
+
return error instanceof Error ? error.message : String(error);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/commands/ai.ts
|
|
111
|
+
var SCOPES = ["me", "workspace"];
|
|
112
|
+
var ISO_DAY = /^\d{4}-\d{2}-\d{2}$/u;
|
|
113
|
+
function parseDay(flag, value) {
|
|
114
|
+
if (!ISO_DAY.test(value)) {
|
|
115
|
+
throw new ValidationError(`${flag} must be a YYYY-MM-DD date`, []);
|
|
116
|
+
}
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
function parseScope(scope) {
|
|
120
|
+
if (SCOPES.includes(scope)) return scope;
|
|
121
|
+
throw new ValidationError(`--scope must be one of: ${SCOPES.join(", ")}`, []);
|
|
122
|
+
}
|
|
123
|
+
function registerAiCommand(program) {
|
|
124
|
+
const ai = program.command("ai").description("Inspect AI usage and credit state");
|
|
125
|
+
ai.command("usage").description("Aggregate the AI journal over an inclusive UTC day window").requiredOption("--from <day>", "first day of the window (YYYY-MM-DD)").requiredOption("--to <day>", "last day of the window, inclusive (YYYY-MM-DD)").option("--scope <scope>", "me or workspace", "me").action(async (opts, cmd) => {
|
|
126
|
+
const params = {
|
|
127
|
+
from: parseDay("--from", opts.from),
|
|
128
|
+
to: parseDay("--to", opts.to),
|
|
129
|
+
scope: parseScope(opts.scope ?? "me")
|
|
130
|
+
};
|
|
131
|
+
const client = getClientFromCommand(cmd);
|
|
132
|
+
const result = await client.get("/ai/usage", params);
|
|
133
|
+
formatOutput(result, getFormat(cmd));
|
|
134
|
+
});
|
|
135
|
+
ai.command("wallet").description("Show the tenant's billing mode and AI credit state").action(async (_opts, cmd) => {
|
|
136
|
+
const client = getClientFromCommand(cmd);
|
|
137
|
+
const result = await client.get("/ai/wallet");
|
|
138
|
+
formatOutput(result, getFormat(cmd));
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/commands/auth.ts
|
|
143
|
+
import chalk2 from "chalk";
|
|
144
|
+
function registerAuthCommand(program) {
|
|
145
|
+
const auth = program.command("auth").description("Inspect CLI authentication");
|
|
146
|
+
auth.command("whoami").description("Show current configuration and validate API key").action(async (_opts, cmd) => {
|
|
147
|
+
const root = getGlobalOptions(cmd);
|
|
148
|
+
const client = getClientFromCommand(cmd);
|
|
149
|
+
const write = (msg) => process.stdout.write(`${msg}
|
|
150
|
+
`);
|
|
151
|
+
write(chalk2.bold("Standards CLI Configuration"));
|
|
152
|
+
write(` API URL: ${root.apiUrl}`);
|
|
153
|
+
write(` API Key: ${root.apiKey ? `${root.apiKey.slice(0, 8)}...` : chalk2.red("not set")}`);
|
|
154
|
+
write("");
|
|
155
|
+
const keys = await client.get("/api-keys");
|
|
156
|
+
write(chalk2.green("\u2713 API key is valid"));
|
|
157
|
+
if (Array.isArray(keys) && keys.length > 0) {
|
|
158
|
+
const activeKeys = keys.filter(
|
|
159
|
+
(key) => typeof key === "object" && key !== null && !("revokedAt" in key && key.revokedAt)
|
|
160
|
+
);
|
|
161
|
+
write(` Active keys: ${activeKeys.length}`);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
133
166
|
// src/commands/bundles.ts
|
|
134
167
|
function registerBundlesCommand(program) {
|
|
135
168
|
const bundles = program.command("bundles").description("Manage system bundles assigned to the current tenant (admin)");
|
|
@@ -164,7 +197,7 @@ function registerBundlesCommand(program) {
|
|
|
164
197
|
}
|
|
165
198
|
|
|
166
199
|
// src/commands/connectors.ts
|
|
167
|
-
import { ValidationError } from "@stndrds/schema";
|
|
200
|
+
import { ValidationError as ValidationError2 } from "@stndrds/schema";
|
|
168
201
|
import chalk3 from "chalk";
|
|
169
202
|
var PROVIDER_IDS = {
|
|
170
203
|
gmail: true,
|
|
@@ -195,7 +228,7 @@ function registerConnectorsCommand(program) {
|
|
|
195
228
|
`connector provider (${PROVIDERS.join(", ")}); run "connectors providers" for the ones this deployment configured`
|
|
196
229
|
).option("--scope <scope>", "connection scope (tenant or actor)", "tenant").action(async (opts, cmd) => {
|
|
197
230
|
if (!PROVIDERS.includes(opts.provider)) {
|
|
198
|
-
throw new
|
|
231
|
+
throw new ValidationError2(`--provider must be one of: ${PROVIDERS.join(", ")}`, []);
|
|
199
232
|
}
|
|
200
233
|
const client = getClientFromCommand(cmd);
|
|
201
234
|
const result = await client.post("/connectors/auth/start", {
|
|
@@ -1202,19 +1235,19 @@ function registerKeysCommand(program) {
|
|
|
1202
1235
|
}
|
|
1203
1236
|
|
|
1204
1237
|
// src/commands/mcp.ts
|
|
1205
|
-
import { RESOURCE_VISIBILITIES, ValidationError as
|
|
1238
|
+
import { RESOURCE_VISIBILITIES, ValidationError as ValidationError3 } from "@stndrds/schema";
|
|
1206
1239
|
import chalk6 from "chalk";
|
|
1207
1240
|
var AUTH_TYPES = ["none", "header"];
|
|
1208
1241
|
function buildAuth(opts) {
|
|
1209
1242
|
const type = opts.authType ?? "none";
|
|
1210
1243
|
if (!AUTH_TYPES.includes(type)) {
|
|
1211
|
-
throw new
|
|
1244
|
+
throw new ValidationError3(`--auth-type must be one of: ${AUTH_TYPES.join(", ")}`, []);
|
|
1212
1245
|
}
|
|
1213
1246
|
if (type === "none") {
|
|
1214
1247
|
return { type: "none" };
|
|
1215
1248
|
}
|
|
1216
1249
|
if (!(opts.headerName && opts.secret)) {
|
|
1217
|
-
throw new
|
|
1250
|
+
throw new ValidationError3('--auth-type "header" requires both --header-name and --secret.', []);
|
|
1218
1251
|
}
|
|
1219
1252
|
return { type: "header", headerName: opts.headerName, secret: opts.secret };
|
|
1220
1253
|
}
|
|
@@ -1223,7 +1256,7 @@ function resolveVisibility(visibility) {
|
|
|
1223
1256
|
return "workspace";
|
|
1224
1257
|
}
|
|
1225
1258
|
if (!RESOURCE_VISIBILITIES.includes(visibility)) {
|
|
1226
|
-
throw new
|
|
1259
|
+
throw new ValidationError3(
|
|
1227
1260
|
`--visibility must be one of: ${RESOURCE_VISIBILITIES.join(", ")}`,
|
|
1228
1261
|
[]
|
|
1229
1262
|
);
|
|
@@ -1272,7 +1305,7 @@ function registerMcpCommand(program) {
|
|
|
1272
1305
|
});
|
|
1273
1306
|
mcp.command("disconnect").description("Disconnect (delete) an MCP server").argument("<id>", "MCP server ID").option("--yes", "disconnect without confirmation").action(async (id, opts, cmd) => {
|
|
1274
1307
|
if (!opts.yes) {
|
|
1275
|
-
throw new
|
|
1308
|
+
throw new ValidationError3(
|
|
1276
1309
|
'Disconnecting an MCP server is explicit. Re-run with "--yes" to confirm.',
|
|
1277
1310
|
[]
|
|
1278
1311
|
);
|
|
@@ -1289,17 +1322,17 @@ import { createHmac } from "crypto";
|
|
|
1289
1322
|
import {
|
|
1290
1323
|
FAKE_MEETING_BOT_SIGNATURE_HEADER,
|
|
1291
1324
|
RECORDING_OVERRIDES,
|
|
1292
|
-
ValidationError as
|
|
1325
|
+
ValidationError as ValidationError4
|
|
1293
1326
|
} from "@stndrds/schema";
|
|
1294
1327
|
var ORDERS = ["asc", "desc"];
|
|
1295
1328
|
function parseOrder(order) {
|
|
1296
1329
|
if (ORDERS.includes(order)) return order;
|
|
1297
|
-
throw new
|
|
1330
|
+
throw new ValidationError4(`--order must be one of: ${ORDERS.join(", ")}`, []);
|
|
1298
1331
|
}
|
|
1299
1332
|
function parseCount(flag, value) {
|
|
1300
1333
|
const parsed = Number(value);
|
|
1301
1334
|
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
1302
|
-
throw new
|
|
1335
|
+
throw new ValidationError4(`${flag} must be a non-negative integer`, []);
|
|
1303
1336
|
}
|
|
1304
1337
|
return parsed;
|
|
1305
1338
|
}
|
|
@@ -1321,7 +1354,7 @@ function parseOverride(opts) {
|
|
|
1321
1354
|
);
|
|
1322
1355
|
if (opts.auto) chosen.push(null);
|
|
1323
1356
|
if (chosen.length !== 1) {
|
|
1324
|
-
throw new
|
|
1357
|
+
throw new ValidationError4("record needs exactly one of --force, --skip or --auto", []);
|
|
1325
1358
|
}
|
|
1326
1359
|
return chosen[0] ?? null;
|
|
1327
1360
|
}
|
|
@@ -1406,15 +1439,15 @@ function registerMeetingsCommand(program) {
|
|
|
1406
1439
|
).action(async (id, opts, cmd) => {
|
|
1407
1440
|
const secret = process.env.MEETING_BOT_FAKE_SECRET;
|
|
1408
1441
|
if (!secret) {
|
|
1409
|
-
throw new
|
|
1442
|
+
throw new ValidationError4("MEETING_BOT_FAKE_SECRET is not set in this shell", []);
|
|
1410
1443
|
}
|
|
1411
1444
|
const lines = parseCount("--lines", opts.lines);
|
|
1412
|
-
if (lines < 1) throw new
|
|
1445
|
+
if (lines < 1) throw new ValidationError4("--lines must be at least 1", []);
|
|
1413
1446
|
const client = getClientFromCommand(cmd);
|
|
1414
1447
|
const meeting = await client.get(`/meetings/${id}`);
|
|
1415
1448
|
const { status, botId } = meeting.recording;
|
|
1416
1449
|
if (status !== "scheduled" && status !== "recording" || botId === null) {
|
|
1417
|
-
throw new
|
|
1450
|
+
throw new ValidationError4(`Meeting ${id} has no bot to complete (status: ${status})`, []);
|
|
1418
1451
|
}
|
|
1419
1452
|
const segments = buildSimulatedSegments(simulatedSpeakers(meeting), lines);
|
|
1420
1453
|
const startedAt = meeting.startsAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1443,7 +1476,7 @@ function registerMeetingsCommand(program) {
|
|
|
1443
1476
|
}
|
|
1444
1477
|
);
|
|
1445
1478
|
if (!response.ok) {
|
|
1446
|
-
throw new
|
|
1479
|
+
throw new ValidationError4(`webhook answered ${response.status}`, []);
|
|
1447
1480
|
}
|
|
1448
1481
|
formatOutput({ botId, segments: segments.length }, getFormat(cmd));
|
|
1449
1482
|
});
|
|
@@ -1595,6 +1628,16 @@ function registerPullCommand(program) {
|
|
|
1595
1628
|
});
|
|
1596
1629
|
}
|
|
1597
1630
|
|
|
1631
|
+
// src/commands/quotas.ts
|
|
1632
|
+
function registerQuotasCommand(program) {
|
|
1633
|
+
const quotas = program.command("quotas").description("Inspect the tenant's remaining capacity");
|
|
1634
|
+
quotas.command("list").description("List one state per quota key (limit is null when nothing is enforced)").action(async (_opts, cmd) => {
|
|
1635
|
+
const client = getClientFromCommand(cmd);
|
|
1636
|
+
const result = await client.get("/quotas");
|
|
1637
|
+
formatOutput(result, getFormat(cmd));
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1598
1641
|
// src/commands/records.ts
|
|
1599
1642
|
import { readFile as readFile3 } from "fs/promises";
|
|
1600
1643
|
import { basename } from "path";
|
|
@@ -1819,6 +1862,8 @@ function createProgram() {
|
|
|
1819
1862
|
registerMeetingsCommand(program);
|
|
1820
1863
|
registerSearchCommand(program);
|
|
1821
1864
|
registerEmbeddingsCommand(program);
|
|
1865
|
+
registerAiCommand(program);
|
|
1866
|
+
registerQuotasCommand(program);
|
|
1822
1867
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
1823
1868
|
const raw = program.opts();
|
|
1824
1869
|
const resolved = await resolveCliConfig({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stndrds/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.296",
|
|
4
4
|
"description": "CLI tool to interact with Standards API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"chalk": "^5.4.1",
|
|
16
16
|
"cli-table3": "^0.6.5",
|
|
17
17
|
"commander": "^13.1.0",
|
|
18
|
-
"@stndrds/client": "1.0.0-alpha.
|
|
19
|
-
"@stndrds/schema": "1.0.0-alpha.
|
|
18
|
+
"@stndrds/client": "1.0.0-alpha.296",
|
|
19
|
+
"@stndrds/schema": "1.0.0-alpha.296"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^25.6.0",
|