@seclai/cli 1.5.0 → 1.6.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/CHANGELOG.md +15 -8
- package/README.md +12 -9
- package/dist/cli.js +235 -336
- package/package.json +3 -1
- package/dist/cli.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command4 } from "commander";
|
|
5
5
|
import { realpathSync } from "fs";
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
7
7
|
|
|
@@ -75,12 +75,25 @@ function getCliVersion() {
|
|
|
75
75
|
}
|
|
76
76
|
function createClient(opts) {
|
|
77
77
|
const seclaiOpts = {};
|
|
78
|
+
const identityFlags = [
|
|
79
|
+
["apiKey", "--api-key", "Pass a key, or omit the flag to use SECLAI_API_KEY or SSO."],
|
|
80
|
+
["profile", "--profile", "Pass a profile name, or omit the flag to use the default profile."],
|
|
81
|
+
["accountId", "--account-id", "Pass an account ID, or omit the flag to use the default org."],
|
|
82
|
+
["configDir", "--config-dir", "Pass a directory, or omit the flag to use ~/.seclai."]
|
|
83
|
+
];
|
|
84
|
+
for (const [key, flag, hint] of identityFlags) {
|
|
85
|
+
const value = opts[key];
|
|
86
|
+
if (typeof value === "string" && value.trim().length === 0) {
|
|
87
|
+
throw new Error(`${flag} was given an empty value. ${hint}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
78
90
|
if (opts.apiKey !== void 0) seclaiOpts.apiKey = opts.apiKey;
|
|
79
91
|
if (opts.profile !== void 0) seclaiOpts.profile = opts.profile;
|
|
80
92
|
if (opts.configDir !== void 0) seclaiOpts.configDir = opts.configDir;
|
|
81
93
|
if (opts.accountId !== void 0) seclaiOpts.accountId = opts.accountId;
|
|
82
94
|
const envVersion = process2.env.SECLAI_API_VERSION;
|
|
83
|
-
const
|
|
95
|
+
const blank = (v) => v === void 0 || v.trim().length === 0;
|
|
96
|
+
const version = blank(opts.apiVersion) ? opts.apiVersion !== void 0 ? void 0 : blank(envVersion) ? void 0 : envVersion : opts.apiVersion;
|
|
84
97
|
if (version !== void 0) seclaiOpts.apiVersion = version;
|
|
85
98
|
if (opts.allowUnknownApiVersion) seclaiOpts.allowUnknownApiVersion = true;
|
|
86
99
|
const envUrl = process2.env.SECLAI_API_URL;
|
|
@@ -92,8 +105,9 @@ function printJson(rt, value) {
|
|
|
92
105
|
rt.writeOut(`${JSON.stringify(value, null, indent)}
|
|
93
106
|
`);
|
|
94
107
|
}
|
|
95
|
-
function warnDeprecated(rt, message) {
|
|
96
|
-
|
|
108
|
+
function warnDeprecated(rt, message, fate = "rejected") {
|
|
109
|
+
const suffix = fate === "kept" ? "" : fate === "removed" ? " This will be removed in a future release." : " This will be rejected in a future release.";
|
|
110
|
+
rt.writeErr(`warning: ${message}${suffix}
|
|
97
111
|
`);
|
|
98
112
|
}
|
|
99
113
|
function printError(rt, err) {
|
|
@@ -123,8 +137,13 @@ function printError(rt, err) {
|
|
|
123
137
|
if (err instanceof SeclaiConfigurationError) {
|
|
124
138
|
rt.writeErr(`${err.name}: ${err.message}
|
|
125
139
|
`);
|
|
126
|
-
|
|
140
|
+
if (/api version/i.test(err.message)) {
|
|
141
|
+
rt.writeErr(`hint: Pass --allow-unknown-api-version to send it anyway.
|
|
142
|
+
`);
|
|
143
|
+
} else {
|
|
144
|
+
rt.writeErr(`hint: Set the SECLAI_API_KEY environment variable or pass --api-key.
|
|
127
145
|
`);
|
|
146
|
+
}
|
|
128
147
|
return;
|
|
129
148
|
}
|
|
130
149
|
if (err instanceof Error) {
|
|
@@ -144,18 +163,30 @@ async function run(rt, main) {
|
|
|
144
163
|
}
|
|
145
164
|
}
|
|
146
165
|
function parseNumber(value) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
throw new InvalidArgumentError("Expected a number.");
|
|
166
|
+
if (!/^\d+$/.test(value.trim())) {
|
|
167
|
+
throw new InvalidArgumentError("Expected a non-negative whole number.");
|
|
150
168
|
}
|
|
151
|
-
return
|
|
169
|
+
return Number(value.trim());
|
|
152
170
|
}
|
|
153
|
-
function withLimitOption(cmd) {
|
|
154
|
-
return cmd.option("--limit <n>",
|
|
171
|
+
function withLimitOption(cmd, description = "Page size.") {
|
|
172
|
+
return cmd.option("--limit <n>", description, parseNumber);
|
|
155
173
|
}
|
|
156
174
|
function withOffsetListOptions(cmd) {
|
|
157
175
|
return withLimitOption(cmd).option("--offset <n>", "Number of items to skip.", parseNumber);
|
|
158
176
|
}
|
|
177
|
+
function toPagedEnvelope(res, ...legacyKeys) {
|
|
178
|
+
if (Array.isArray(res)) return { data: res };
|
|
179
|
+
if (res === null || typeof res !== "object") return res;
|
|
180
|
+
const obj = res;
|
|
181
|
+
if (Array.isArray(obj.data)) return obj;
|
|
182
|
+
for (const key of legacyKeys) {
|
|
183
|
+
if (Array.isArray(obj[key])) {
|
|
184
|
+
const { [key]: rows, ...rest } = obj;
|
|
185
|
+
return { data: rows, ...rest };
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return res;
|
|
189
|
+
}
|
|
159
190
|
function offsetListOpts(opts) {
|
|
160
191
|
const o = {};
|
|
161
192
|
if (opts.limit !== void 0) o.limit = opts.limit;
|
|
@@ -339,7 +370,10 @@ function register(program, rt) {
|
|
|
339
370
|
await run(rt, async () => {
|
|
340
371
|
warnDeprecated(
|
|
341
372
|
rt,
|
|
342
|
-
`'agents runs delete' is deprecated and cancels the run rather than deleting it \u2014 the API has no delete-a-run operation. Use 'agents runs cancel', which also prints the cancelled run instead of {"ok": true}
|
|
373
|
+
`'agents runs delete' is deprecated and cancels the run rather than deleting it \u2014 the API has no delete-a-run operation. Use 'agents runs cancel', which also prints the cancelled run instead of {"ok": true}.`,
|
|
374
|
+
// Kept, not scheduled for removal — the whole point of the alias is
|
|
375
|
+
// that existing scripts keep working.
|
|
376
|
+
"kept"
|
|
343
377
|
);
|
|
344
378
|
const client = createClient(program.opts());
|
|
345
379
|
await client.cancelAgentRun(runId);
|
|
@@ -487,10 +521,14 @@ function register(program, rt) {
|
|
|
487
521
|
printJson(rt, { ok: true });
|
|
488
522
|
});
|
|
489
523
|
});
|
|
490
|
-
runs.command("eval-results").description("List evaluation results for a run.").argument("<agentId>", "Agent ID.").argument("<runId>", "Run ID.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).
|
|
524
|
+
runs.command("eval-results").description("List evaluation results for a run.").argument("<agentId>", "Agent ID.").argument("<runId>", "Run ID.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option(
|
|
525
|
+
"--paged",
|
|
526
|
+
"Wrap the results in {data: [...]}, the shape this endpoint moves to from --api-version 2026-07-27."
|
|
527
|
+
).action(async (agentId, runId, opts) => {
|
|
491
528
|
await run(rt, async () => {
|
|
492
529
|
const client = createClient(program.opts());
|
|
493
|
-
|
|
530
|
+
const res = await client.listRunEvaluationResults(agentId, runId, listOpts(opts));
|
|
531
|
+
printJson(rt, opts.paged ? toPagedEnvelope(res) : res);
|
|
494
532
|
});
|
|
495
533
|
});
|
|
496
534
|
}
|
|
@@ -498,7 +536,7 @@ function register(program, rt) {
|
|
|
498
536
|
// src/commands/sources.ts
|
|
499
537
|
function register2(program, rt) {
|
|
500
538
|
const sources = program.command("sources").alias("source").description("Manage content sources.");
|
|
501
|
-
sources.command("list").description("List sources.").option("--page <n>", "Page number.",
|
|
539
|
+
sources.command("list").description("List sources.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option("--sort <field>", "Sort field.").option("--order <asc|desc>", "Sort direction.").option("--account-id <id>", "Filter by account ID.").action(async (opts) => {
|
|
502
540
|
await run(rt, async () => {
|
|
503
541
|
const globalOpts = program.opts();
|
|
504
542
|
const client = createClient(globalOpts);
|
|
@@ -551,7 +589,7 @@ function register2(program, rt) {
|
|
|
551
589
|
});
|
|
552
590
|
});
|
|
553
591
|
const exports_ = sources.command("exports").description("Manage source exports.");
|
|
554
|
-
exports_.command("list").description("List exports for a source.").argument("<sourceId>", "Source ID.").option("--page <n>", "Page number.",
|
|
592
|
+
exports_.command("list").description("List exports for a source.").argument("<sourceId>", "Source ID.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).action(async (sourceId, opts) => {
|
|
555
593
|
await run(rt, async () => {
|
|
556
594
|
const client = createClient(program.opts());
|
|
557
595
|
printJson(rt, await client.listSourceExports(sourceId, listOpts(opts)));
|
|
@@ -622,7 +660,7 @@ function register2(program, rt) {
|
|
|
622
660
|
// src/commands/contents.ts
|
|
623
661
|
function register3(program, rt) {
|
|
624
662
|
const contents = program.command("contents").description("Manage indexed content and embeddings.");
|
|
625
|
-
contents.command("get").description("Get content version details.").argument("<contentVersionId>", "Content version ID.").option("--start <n>", "Text start offset (0-based).",
|
|
663
|
+
contents.command("get").description("Get content version details.").argument("<contentVersionId>", "Content version ID.").option("--start <n>", "Text start offset (0-based).", parseNumber).option("--end <n>", "Text end offset (exclusive).", parseNumber).action(async (contentVersionId, opts) => {
|
|
626
664
|
await run(rt, async () => {
|
|
627
665
|
const client = createClient(program.opts());
|
|
628
666
|
const o = {};
|
|
@@ -653,7 +691,7 @@ function register3(program, rt) {
|
|
|
653
691
|
printJson(rt, await client.replaceContentWithInlineText(contentVersionId, body));
|
|
654
692
|
});
|
|
655
693
|
});
|
|
656
|
-
contents.command("embeddings").description("List embeddings for a content version.").argument("<contentVersionId>", "Content version ID.").option("--page <n>", "Page number.",
|
|
694
|
+
contents.command("embeddings").description("List embeddings for a content version.").argument("<contentVersionId>", "Content version ID.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).action(async (contentVersionId, opts) => {
|
|
657
695
|
await run(rt, async () => {
|
|
658
696
|
const client = createClient(program.opts());
|
|
659
697
|
printJson(rt, await client.listContentEmbeddings(contentVersionId, listOpts(opts)));
|
|
@@ -664,7 +702,7 @@ function register3(program, rt) {
|
|
|
664
702
|
// src/commands/kb.ts
|
|
665
703
|
function register4(program, rt) {
|
|
666
704
|
const kb = program.command("kb").description("Manage knowledge bases.");
|
|
667
|
-
kb.command("list").description("List knowledge bases.").option("--page <n>", "Page number.",
|
|
705
|
+
kb.command("list").description("List knowledge bases.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option("--sort <field>", "Sort field.").option("--order <asc|desc>", "Sort direction.").action(async (opts) => {
|
|
668
706
|
await run(rt, async () => {
|
|
669
707
|
const client = createClient(program.opts());
|
|
670
708
|
printJson(rt, await client.listKnowledgeBases(listOpts(opts)));
|
|
@@ -702,7 +740,7 @@ function register4(program, rt) {
|
|
|
702
740
|
// src/commands/memory.ts
|
|
703
741
|
function register5(program, rt) {
|
|
704
742
|
const memory = program.command("memory").description("Manage memory banks.");
|
|
705
|
-
memory.command("list").description("List memory banks.").option("--page <n>", "Page number.",
|
|
743
|
+
memory.command("list").description("List memory banks.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option("--sort <field>", "Sort field.").option("--order <asc|desc>", "Sort direction.").action(async (opts) => {
|
|
706
744
|
await run(rt, async () => {
|
|
707
745
|
const client = createClient(program.opts());
|
|
708
746
|
printJson(rt, await client.listMemoryBanks(listOpts(opts)));
|
|
@@ -905,7 +943,7 @@ function register6(program, rt) {
|
|
|
905
943
|
// src/commands/solutions.ts
|
|
906
944
|
function register7(program, rt) {
|
|
907
945
|
const solutions = program.command("solutions").description("Manage solutions.");
|
|
908
|
-
solutions.command("list").description("List solutions.").option("--page <n>", "Page number.",
|
|
946
|
+
solutions.command("list").description("List solutions.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option("--sort <field>", "Sort field.").option("--order <asc|desc>", "Sort direction.").action(async (opts) => {
|
|
909
947
|
await run(rt, async () => {
|
|
910
948
|
const client = createClient(program.opts());
|
|
911
949
|
printJson(rt, await client.listSolutions(listOpts(opts)));
|
|
@@ -1083,20 +1121,11 @@ function register8(program, rt) {
|
|
|
1083
1121
|
// src/commands/alerts.ts
|
|
1084
1122
|
function register9(program, rt) {
|
|
1085
1123
|
const alerts = program.command("alerts").description("Manage alerts and alert configurations.");
|
|
1086
|
-
alerts.command("list").description("List alerts.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option("--status <status>", "Filter by status.").
|
|
1087
|
-
"--severity <severity>",
|
|
1088
|
-
"Deprecated and ignored \u2014 GET /alerts declares no severity filter. Filter with jq instead."
|
|
1089
|
-
).action(async (opts) => {
|
|
1124
|
+
alerts.command("list").description("List alerts.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option("--status <status>", "Filter by status.").action(async (opts) => {
|
|
1090
1125
|
await run(rt, async () => {
|
|
1091
1126
|
const client = createClient(program.opts());
|
|
1092
1127
|
const o = listOpts(opts);
|
|
1093
1128
|
if (opts.status) o.status = opts.status;
|
|
1094
|
-
if (opts.severity !== void 0) {
|
|
1095
|
-
warnDeprecated(
|
|
1096
|
-
rt,
|
|
1097
|
-
`'alerts list --severity' is ignored \u2014 the API has no severity filter, so it never filtered anything. Filter client-side, e.g. | jq '[.data[] | select(.severity == "high")]'.`
|
|
1098
|
-
);
|
|
1099
|
-
}
|
|
1100
1129
|
printJson(rt, await client.listAlerts(o));
|
|
1101
1130
|
});
|
|
1102
1131
|
});
|
|
@@ -1133,10 +1162,14 @@ function register9(program, rt) {
|
|
|
1133
1162
|
});
|
|
1134
1163
|
});
|
|
1135
1164
|
const configs = alerts.command("configs").description("Alert configurations.");
|
|
1136
|
-
configs.command("list").description("List alert configurations.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).
|
|
1165
|
+
configs.command("list").description("List alert configurations.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option(
|
|
1166
|
+
"--paged",
|
|
1167
|
+
"Wrap the results in {data: [...]}, the shape this endpoint moves to from --api-version 2026-07-27."
|
|
1168
|
+
).action(async (opts) => {
|
|
1137
1169
|
await run(rt, async () => {
|
|
1138
1170
|
const client = createClient(program.opts());
|
|
1139
|
-
|
|
1171
|
+
const res = await client.listAlertConfigs(listOpts(opts));
|
|
1172
|
+
printJson(rt, opts.paged ? toPagedEnvelope(res, "configs") : res);
|
|
1140
1173
|
});
|
|
1141
1174
|
});
|
|
1142
1175
|
configs.command("create").description("Create an alert configuration.").option("--json <json>", "Config body JSON.").option("--json-file <path>", "Config body JSON file.").action(async (opts) => {
|
|
@@ -1183,6 +1216,7 @@ function register9(program, rt) {
|
|
|
1183
1216
|
}
|
|
1184
1217
|
|
|
1185
1218
|
// src/commands/email.ts
|
|
1219
|
+
import { Argument, Option } from "commander";
|
|
1186
1220
|
function register10(program, rt) {
|
|
1187
1221
|
const email = program.command("email").description("Agent email: sending domains, inbound blocklist, inbound health, and opt-outs.");
|
|
1188
1222
|
const domains = email.command("domains").description("Agent-email sending domains.");
|
|
@@ -1192,7 +1226,9 @@ function register10(program, rt) {
|
|
|
1192
1226
|
printJson(rt, await client.listEmailDomains());
|
|
1193
1227
|
});
|
|
1194
1228
|
});
|
|
1195
|
-
domains.command("add").description("Add and provision a new agent-email domain. Returns the DNS records to publish.").
|
|
1229
|
+
domains.command("add").description("Add and provision a new agent-email domain. Returns the DNS records to publish.").addOption(
|
|
1230
|
+
new Option("--kind <kind>", "'vanity' (a subdomain of seclai.com) or 'custom' (your own domain).").choices(["vanity", "custom"]).makeOptionMandatory()
|
|
1231
|
+
).requiredOption("--value <domain>", "The domain to add.").option("--delegated", "The domain's DNS is delegated to Seclai, so records are published automatically.").action(async (opts) => {
|
|
1196
1232
|
await run(rt, async () => {
|
|
1197
1233
|
const client = createClient(program.opts());
|
|
1198
1234
|
const body = {
|
|
@@ -1252,7 +1288,9 @@ function register10(program, rt) {
|
|
|
1252
1288
|
printJson(rt, await client.listBlockedEmailSenders(offsetListOpts(opts)));
|
|
1253
1289
|
});
|
|
1254
1290
|
});
|
|
1255
|
-
blocked.command("add").description("Block an inbound sender address or domain.").requiredOption("--sender-email <email>", "Sender address, or the domain when --match-type is 'domain'.").
|
|
1291
|
+
blocked.command("add").description("Block an inbound sender address or domain.").requiredOption("--sender-email <email>", "Sender address, or the domain when --match-type is 'domain'.").addOption(
|
|
1292
|
+
new Option("--match-type <type>", "'address' or 'domain'.").choices(["address", "domain"]).default("address")
|
|
1293
|
+
).option("--note <text>", "Why the sender was blocked.").action(async (opts) => {
|
|
1256
1294
|
await run(rt, async () => {
|
|
1257
1295
|
const client = createClient(program.opts());
|
|
1258
1296
|
const body = {
|
|
@@ -1270,7 +1308,15 @@ function register10(program, rt) {
|
|
|
1270
1308
|
printJson(rt, { ok: true });
|
|
1271
1309
|
});
|
|
1272
1310
|
});
|
|
1273
|
-
blocked.command("auto-block-mode").description("Set whether a governance BLOCK on an authenticated sender auto-adds them to the blocklist.").
|
|
1311
|
+
blocked.command("auto-block-mode").description("Set whether a governance BLOCK on an authenticated sender auto-adds them to the blocklist.").addArgument(
|
|
1312
|
+
// A closed set the API will only ever 422 on. Failing the parse names the
|
|
1313
|
+
// accepted values; the server names nothing.
|
|
1314
|
+
new Argument("<mode>", "How governance BLOCK verdicts feed the blocklist.").choices([
|
|
1315
|
+
"disabled",
|
|
1316
|
+
"input",
|
|
1317
|
+
"input_and_output"
|
|
1318
|
+
])
|
|
1319
|
+
).action(async (mode) => {
|
|
1274
1320
|
await run(rt, async () => {
|
|
1275
1321
|
const client = createClient(program.opts());
|
|
1276
1322
|
printJson(rt, await client.setAutoBlockMode({ mode }));
|
|
@@ -1325,6 +1371,7 @@ function register10(program, rt) {
|
|
|
1325
1371
|
}
|
|
1326
1372
|
|
|
1327
1373
|
// src/commands/account.ts
|
|
1374
|
+
import { SeclaiApiVersion } from "@seclai/sdk";
|
|
1328
1375
|
function register11(program, rt) {
|
|
1329
1376
|
program.command("me").description("Show the authenticated user's account ID and organization memberships.").action(async () => {
|
|
1330
1377
|
await run(rt, async () => {
|
|
@@ -1343,8 +1390,11 @@ function register11(program, rt) {
|
|
|
1343
1390
|
});
|
|
1344
1391
|
version.command("set").description("Pin the account to a dated API version. Affects every client, not just this CLI.").argument("<date>", "API version as YYYY-MM-DD.").action(async (date) => {
|
|
1345
1392
|
await run(rt, async () => {
|
|
1346
|
-
|
|
1347
|
-
|
|
1393
|
+
const known = Object.values(SeclaiApiVersion);
|
|
1394
|
+
if (!known.includes(date) && !program.opts().allowUnknownApiVersion) {
|
|
1395
|
+
throw new Error(
|
|
1396
|
+
`Unknown API version "${date}". This release knows ${[...new Set(known)].sort().join(", ")}. Pass --allow-unknown-api-version to pin it anyway.`
|
|
1397
|
+
);
|
|
1348
1398
|
}
|
|
1349
1399
|
const client = createClient(program.opts());
|
|
1350
1400
|
printJson(rt, await client.updateApiVersion(date));
|
|
@@ -1386,10 +1436,14 @@ function register12(program, rt) {
|
|
|
1386
1436
|
});
|
|
1387
1437
|
});
|
|
1388
1438
|
const alerts = models.command("alerts").description("Model alerts.");
|
|
1389
|
-
alerts.command("list").description("List model alerts.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).
|
|
1439
|
+
alerts.command("list").description("List model alerts.").option("--page <n>", "Page number.", parseNumber).option("--limit <n>", "Page size.", parseNumber).option(
|
|
1440
|
+
"--paged",
|
|
1441
|
+
"Wrap the results in {data: [...]}, the shape this endpoint moves to from --api-version 2026-07-27."
|
|
1442
|
+
).action(async (opts) => {
|
|
1390
1443
|
await run(rt, async () => {
|
|
1391
1444
|
const client = createClient(program.opts());
|
|
1392
|
-
|
|
1445
|
+
const res = await client.listModelAlerts(listOpts(opts));
|
|
1446
|
+
printJson(rt, opts.paged ? toPagedEnvelope(res, "alerts") : res);
|
|
1393
1447
|
});
|
|
1394
1448
|
});
|
|
1395
1449
|
alerts.command("mark-read").description("Mark a model alert as read.").argument("<alertId>", "Alert ID.").action(async (alertId) => {
|
|
@@ -1460,19 +1514,19 @@ function register12(program, rt) {
|
|
|
1460
1514
|
}
|
|
1461
1515
|
|
|
1462
1516
|
// src/commands/search.ts
|
|
1463
|
-
import { Option } from "commander";
|
|
1517
|
+
import { Option as Option2 } from "commander";
|
|
1464
1518
|
function register13(program, rt) {
|
|
1465
1519
|
program.command("search").description("Search across Seclai resources.").requiredOption("--query <text>", "Search query text.").option("--limit <n>", "Max results.", parseNumber).option("--entity-type <type>", "Filter by entity type (e.g. agent, source, knowledge_base, memory_bank).").action(async (opts) => {
|
|
1466
1520
|
await run(rt, async () => {
|
|
1467
1521
|
const client = createClient(program.opts());
|
|
1468
1522
|
const o = { query: opts.query };
|
|
1469
1523
|
if (opts.limit !== void 0) o.limit = opts.limit;
|
|
1470
|
-
if (opts.entityType) o.entityType = opts.entityType;
|
|
1524
|
+
if (opts.entityType !== void 0) o.entityType = opts.entityType;
|
|
1471
1525
|
printJson(rt, await client.search(o));
|
|
1472
1526
|
});
|
|
1473
1527
|
});
|
|
1474
1528
|
const docs = program.command("docs").description("Seclai documentation.");
|
|
1475
|
-
docs.command("search").description("Search the Seclai documentation.").requiredOption("--query <text>", "Search query text.").addOption(new
|
|
1529
|
+
docs.command("search").description("Search the Seclai documentation.").requiredOption("--query <text>", "Search query text.").addOption(new Option2("--mode <mode>", "Search mode.").choices(["keyword", "semantic"])).option("--limit <n>", "Max results.", parseNumber).action(async (opts) => {
|
|
1476
1530
|
await run(rt, async () => {
|
|
1477
1531
|
const client = createClient(program.opts());
|
|
1478
1532
|
const o = { query: opts.query };
|
|
@@ -1608,6 +1662,7 @@ seclai agents runs list <agentId>
|
|
|
1608
1662
|
| \`models\` | Model catalog, generation tiers, model alerts, recommendations, playground experiments | [references/models.md](references/models.md) |
|
|
1609
1663
|
| \`auth\` \`configure\` \`api-version\` \`mcp\` \`skills\` \`completion\` | Authentication, profiles, API version pinning, editor integration | [references/setup.md](references/setup.md) |
|
|
1610
1664
|
| \`ai\` | Top-level AI assistant for knowledge bases, sources, solutions and memory | [references/ai-assistant.md](references/ai-assistant.md) |
|
|
1665
|
+
| \`search\` \`docs\` \`me\` | Search across resources, search the documentation, show the authenticated account | below, under [Search and account](#search-and-account) |
|
|
1611
1666
|
|
|
1612
1667
|
Cross-cutting topics: [streaming and event modes](references/streaming.md),
|
|
1613
1668
|
[file uploads](references/uploads.md).
|
|
@@ -1878,9 +1933,9 @@ seclai alerts subscribe <alertId>
|
|
|
1878
1933
|
seclai alerts unsubscribe <alertId>
|
|
1879
1934
|
\`\`\`
|
|
1880
1935
|
|
|
1881
|
-
\`GET /alerts\` declares no severity filter
|
|
1882
|
-
|
|
1883
|
-
client-side instead:
|
|
1936
|
+
\`GET /alerts\` declares no severity filter, so there is no \`--severity\` \u2014 it
|
|
1937
|
+
never filtered anything, and returned unfiltered rows that looked filtered.
|
|
1938
|
+
Filter client-side instead:
|
|
1884
1939
|
|
|
1885
1940
|
\`\`\`bash
|
|
1886
1941
|
seclai alerts list | jq '[.data[] | select(.severity == "high")]'
|
|
@@ -2635,302 +2690,156 @@ function register16(program, rt) {
|
|
|
2635
2690
|
}
|
|
2636
2691
|
|
|
2637
2692
|
// src/commands/completion.ts
|
|
2638
|
-
|
|
2693
|
+
function collectTree(program) {
|
|
2694
|
+
const tree = /* @__PURE__ */ new Map();
|
|
2695
|
+
const walk = (cmd, prefix) => {
|
|
2696
|
+
const children = [];
|
|
2697
|
+
for (const sub of cmd.commands) {
|
|
2698
|
+
const name = sub.name();
|
|
2699
|
+
if (name === "help") continue;
|
|
2700
|
+
children.push({ name, description: sub.description().replace(/\s+/g, " ").trim() });
|
|
2701
|
+
walk(sub, [...prefix, name]);
|
|
2702
|
+
}
|
|
2703
|
+
if (children.length > 0) tree.set(prefix.join(" "), children);
|
|
2704
|
+
};
|
|
2705
|
+
walk(program, []);
|
|
2706
|
+
return tree;
|
|
2707
|
+
}
|
|
2708
|
+
function globalOptions(program) {
|
|
2709
|
+
return program.options.filter((o) => o.long && o.long !== "--help").map((o) => ({
|
|
2710
|
+
flag: o.long,
|
|
2711
|
+
description: o.description.replace(/\s+/g, " ").trim()
|
|
2712
|
+
}));
|
|
2713
|
+
}
|
|
2714
|
+
var names = (children) => children.map((c) => c.name).join(" ");
|
|
2715
|
+
function renderBash(tree, options) {
|
|
2716
|
+
const cases = [...tree.entries()].map(([prefix, children]) => ` ${JSON.stringify(prefix)}) __seclai_reply "${names(children)}" ;;`).join("\n");
|
|
2717
|
+
return `#!/usr/bin/env bash
|
|
2639
2718
|
# seclai bash completion \u2014 add to ~/.bashrc:
|
|
2640
2719
|
# eval "$(seclai completion bash)"
|
|
2720
|
+
#
|
|
2721
|
+
# Generated from the command tree by \`seclai completion bash\`. Do not edit.
|
|
2722
|
+
|
|
2723
|
+
__seclai_reply() {
|
|
2724
|
+
COMPREPLY=( $(compgen -W "$1" -- "$__seclai_cur") )
|
|
2725
|
+
}
|
|
2641
2726
|
|
|
2642
2727
|
_seclai_completions() {
|
|
2643
|
-
local
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
#
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
migration) COMPREPLY=( $(compgen -W "get start cancel" -- "$cur") ); return ;;
|
|
2663
|
-
*) COMPREPLY=( $(compgen -W "list create get update delete upload upload-text exports migration" -- "$cur") ); return ;;
|
|
2664
|
-
esac ;;
|
|
2665
|
-
contents) COMPREPLY=( $(compgen -W "get delete upload replace replace-text embeddings" -- "$cur") ); return ;;
|
|
2666
|
-
kb) COMPREPLY=( $(compgen -W "list create get update delete" -- "$cur") ); return ;;
|
|
2667
|
-
memory)
|
|
2668
|
-
case "\${COMP_WORDS[2]}" in
|
|
2669
|
-
ai) COMPREPLY=( $(compgen -W "generate last accept" -- "$cur") ); return ;;
|
|
2670
|
-
*) COMPREPLY=( $(compgen -W "list create get update delete stats agents compact delete-source templates test-compaction test-compaction-standalone ai" -- "$cur") ); return ;;
|
|
2671
|
-
esac ;;
|
|
2672
|
-
evals)
|
|
2673
|
-
case "\${COMP_WORDS[2]}" in
|
|
2674
|
-
criteria) COMPREPLY=( $(compgen -W "list create get update delete summary" -- "$cur") ); return ;;
|
|
2675
|
-
results) COMPREPLY=( $(compgen -W "list create" -- "$cur") ); return ;;
|
|
2676
|
-
*) COMPREPLY=( $(compgen -W "criteria results compatible-runs test-draft agent-results agent-runs non-manual-summary" -- "$cur") ); return ;;
|
|
2677
|
-
esac ;;
|
|
2678
|
-
solutions)
|
|
2679
|
-
case "\${COMP_WORDS[2]}" in
|
|
2680
|
-
convos) COMPREPLY=( $(compgen -W "list add mark" -- "$cur") ); return ;;
|
|
2681
|
-
ai) COMPREPLY=( $(compgen -W "generate kb source accept decline" -- "$cur") ); return ;;
|
|
2682
|
-
*) COMPREPLY=( $(compgen -W "list create get update delete link unlink convos ai" -- "$cur") ); return ;;
|
|
2683
|
-
esac ;;
|
|
2684
|
-
governance)
|
|
2685
|
-
case "\${COMP_WORDS[2]}" in
|
|
2686
|
-
ai) COMPREPLY=( $(compgen -W "generate list accept decline" -- "$cur") ); return ;;
|
|
2687
|
-
*) COMPREPLY=( $(compgen -W "ai" -- "$cur") ); return ;;
|
|
2688
|
-
esac ;;
|
|
2689
|
-
alerts)
|
|
2690
|
-
case "\${COMP_WORDS[2]}" in
|
|
2691
|
-
configs) COMPREPLY=( $(compgen -W "list create get update delete" -- "$cur") ); return ;;
|
|
2692
|
-
prefs) COMPREPLY=( $(compgen -W "list update" -- "$cur") ); return ;;
|
|
2693
|
-
*) COMPREPLY=( $(compgen -W "list get status comment subscribe unsubscribe configs prefs" -- "$cur") ); return ;;
|
|
2694
|
-
esac ;;
|
|
2695
|
-
email)
|
|
2696
|
-
case "\${COMP_WORDS[2]}" in
|
|
2697
|
-
domains) COMPREPLY=( $(compgen -W "list add remove verify set-primary use-shared test-email dmarc" -- "$cur") ); return ;;
|
|
2698
|
-
blocked) COMPREPLY=( $(compgen -W "list add remove auto-block-mode" -- "$cur") ); return ;;
|
|
2699
|
-
inbound) COMPREPLY=( $(compgen -W "status rejections cancel-queued resume" -- "$cur") ); return ;;
|
|
2700
|
-
optouts) COMPREPLY=( $(compgen -W "list remove" -- "$cur") ); return ;;
|
|
2701
|
-
*) COMPREPLY=( $(compgen -W "domains blocked inbound optouts" -- "$cur") ); return ;;
|
|
2702
|
-
esac ;;
|
|
2703
|
-
models)
|
|
2704
|
-
case "\${COMP_WORDS[2]}" in
|
|
2705
|
-
alerts) COMPREPLY=( $(compgen -W "list mark-read mark-all-read unread-count" -- "$cur") ); return ;;
|
|
2706
|
-
experiments) COMPREPLY=( $(compgen -W "list create get cancel delete" -- "$cur") ); return ;;
|
|
2707
|
-
*) COMPREPLY=( $(compgen -W "list get tiers alerts recommendations experiments" -- "$cur") ); return ;;
|
|
2708
|
-
esac ;;
|
|
2709
|
-
docs) COMPREPLY=( $(compgen -W "search" -- "$cur") ); return ;;
|
|
2710
|
-
api-version) COMPREPLY=( $(compgen -W "get set clear" -- "$cur") ); return ;;
|
|
2711
|
-
auth) COMPREPLY=( $(compgen -W "login logout status refresh" -- "$cur") ); return ;;
|
|
2712
|
-
configure) COMPREPLY=( $(compgen -W "sso list" -- "$cur") ); return ;;
|
|
2713
|
-
ai) COMPREPLY=( $(compgen -W "feedback kb source solution memory memory-history accept decline memory-accept" -- "$cur") ); return ;;
|
|
2714
|
-
skills) COMPREPLY=( $(compgen -W "install" -- "$cur") ); return ;;
|
|
2715
|
-
mcp) COMPREPLY=( $(compgen -W "configure show" -- "$cur") ); return ;;
|
|
2716
|
-
completion) COMPREPLY=( $(compgen -W "bash zsh fish" -- "$cur") ); return ;;
|
|
2728
|
+
local __seclai_cur prefix i
|
|
2729
|
+
__seclai_cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
2730
|
+
|
|
2731
|
+
# Everything typed so far except the program name and the word being
|
|
2732
|
+
# completed, with flags dropped, joined by spaces.
|
|
2733
|
+
prefix=""
|
|
2734
|
+
for ((i = 1; i < COMP_CWORD; i++)); do
|
|
2735
|
+
case "\${COMP_WORDS[i]}" in
|
|
2736
|
+
-*) continue ;;
|
|
2737
|
+
esac
|
|
2738
|
+
if [ -z "$prefix" ]; then
|
|
2739
|
+
prefix="\${COMP_WORDS[i]}"
|
|
2740
|
+
else
|
|
2741
|
+
prefix="$prefix \${COMP_WORDS[i]}"
|
|
2742
|
+
fi
|
|
2743
|
+
done
|
|
2744
|
+
|
|
2745
|
+
case "$__seclai_cur" in
|
|
2746
|
+
-*) __seclai_reply "${options.map((o) => o.flag).join(" ")}"; return ;;
|
|
2717
2747
|
esac
|
|
2718
2748
|
|
|
2719
|
-
|
|
2749
|
+
case "$prefix" in
|
|
2750
|
+
${cases}
|
|
2751
|
+
*) COMPREPLY=() ;;
|
|
2752
|
+
esac
|
|
2720
2753
|
}
|
|
2721
2754
|
|
|
2722
2755
|
complete -F _seclai_completions seclai
|
|
2723
2756
|
`;
|
|
2724
|
-
|
|
2757
|
+
}
|
|
2758
|
+
function renderZsh(tree, options) {
|
|
2759
|
+
const cases = [...tree.entries()].map(([prefix, children]) => {
|
|
2760
|
+
const described = children.map((c) => `'${c.name}:${c.description.replace(/['`$]/g, "")}'`).join(" ");
|
|
2761
|
+
return ` ${JSON.stringify(prefix)}) sub=(${described}) ;;`;
|
|
2762
|
+
}).join("\n");
|
|
2763
|
+
const opts = options.map((o) => `'${o.flag}[${o.description.replace(/['\]`$]/g, "")}]'`).join(" ");
|
|
2764
|
+
return `#compdef seclai
|
|
2725
2765
|
# seclai zsh completion \u2014 add to ~/.zshrc:
|
|
2726
2766
|
# eval "$(seclai completion zsh)"
|
|
2767
|
+
#
|
|
2768
|
+
# Generated from the command tree by \`seclai completion zsh\`. Do not edit.
|
|
2727
2769
|
|
|
2728
2770
|
_seclai() {
|
|
2729
|
-
local
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
'
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
'ai:Top-level AI assistant'
|
|
2747
|
-
'skills:Install skill files for AI coding tools'
|
|
2748
|
-
'mcp:Configure the Seclai MCP server'
|
|
2749
|
-
'completion:Generate shell completion scripts'
|
|
2750
|
-
'auth:SSO authentication'
|
|
2751
|
-
'configure:Manage SSO profiles'
|
|
2752
|
-
'help:Display help for command'
|
|
2753
|
-
)
|
|
2754
|
-
|
|
2755
|
-
_arguments -C \\
|
|
2756
|
-
'--api-key[Seclai API key]:key' \\
|
|
2757
|
-
'--profile[SSO profile name]:name' \\
|
|
2758
|
-
'--account-id[Account ID (X-Account-Id header)]:id' \\
|
|
2759
|
-
'--config-dir[Config directory]:path' \\
|
|
2760
|
-
'--api-version[Dated API version (YYYY-MM-DD)]:date' \\
|
|
2761
|
-
'--allow-unknown-api-version[Permit an unrecognized --api-version]' \\
|
|
2762
|
-
'--compact[Output compact JSON]' \\
|
|
2763
|
-
'-V[Output version]' \\
|
|
2764
|
-
'-h[Display help]' \\
|
|
2765
|
-
'1:command:->cmd' \\
|
|
2766
|
-
'*::arg:->args'
|
|
2767
|
-
|
|
2768
|
-
case $state in
|
|
2769
|
-
cmd) _describe 'command' commands ;;
|
|
2770
|
-
args)
|
|
2771
|
-
case \${words[1]} in
|
|
2772
|
-
agents)
|
|
2773
|
-
local -a sub=(list create get update delete disable enable callers triggers run runs def export preview-import upload-input input-status attachment-references ai)
|
|
2774
|
-
_describe 'subcommand' sub ;;
|
|
2775
|
-
sources|source)
|
|
2776
|
-
local -a sub=(list create get update delete upload upload-text exports migration)
|
|
2777
|
-
_describe 'subcommand' sub ;;
|
|
2778
|
-
contents)
|
|
2779
|
-
local -a sub=(get delete upload replace replace-text embeddings)
|
|
2780
|
-
_describe 'subcommand' sub ;;
|
|
2781
|
-
kb)
|
|
2782
|
-
local -a sub=(list create get update delete)
|
|
2783
|
-
_describe 'subcommand' sub ;;
|
|
2784
|
-
memory)
|
|
2785
|
-
local -a sub=(list create get update delete stats agents compact delete-source templates test-compaction test-compaction-standalone ai)
|
|
2786
|
-
_describe 'subcommand' sub ;;
|
|
2787
|
-
evals)
|
|
2788
|
-
local -a sub=(criteria results compatible-runs test-draft agent-results agent-runs non-manual-summary)
|
|
2789
|
-
_describe 'subcommand' sub ;;
|
|
2790
|
-
solutions)
|
|
2791
|
-
local -a sub=(list create get update delete link unlink convos ai)
|
|
2792
|
-
_describe 'subcommand' sub ;;
|
|
2793
|
-
governance)
|
|
2794
|
-
local -a sub=(ai)
|
|
2795
|
-
_describe 'subcommand' sub ;;
|
|
2796
|
-
alerts)
|
|
2797
|
-
local -a sub=(list get status comment subscribe unsubscribe configs prefs)
|
|
2798
|
-
_describe 'subcommand' sub ;;
|
|
2799
|
-
email)
|
|
2800
|
-
local -a sub=(domains blocked inbound optouts)
|
|
2801
|
-
_describe 'subcommand' sub ;;
|
|
2802
|
-
models)
|
|
2803
|
-
local -a sub=(list get tiers alerts recommendations experiments)
|
|
2804
|
-
_describe 'subcommand' sub ;;
|
|
2805
|
-
docs)
|
|
2806
|
-
local -a sub=(search)
|
|
2807
|
-
_describe 'subcommand' sub ;;
|
|
2808
|
-
api-version)
|
|
2809
|
-
local -a sub=(get set clear)
|
|
2810
|
-
_describe 'subcommand' sub ;;
|
|
2811
|
-
auth)
|
|
2812
|
-
local -a sub=(login logout status refresh)
|
|
2813
|
-
_describe 'subcommand' sub ;;
|
|
2814
|
-
configure)
|
|
2815
|
-
local -a sub=(sso list)
|
|
2816
|
-
_describe 'subcommand' sub ;;
|
|
2817
|
-
ai)
|
|
2818
|
-
local -a sub=(feedback kb source solution memory memory-history accept decline memory-accept)
|
|
2819
|
-
_describe 'subcommand' sub ;;
|
|
2820
|
-
skills)
|
|
2821
|
-
local -a sub=(install)
|
|
2822
|
-
_describe 'subcommand' sub ;;
|
|
2823
|
-
mcp)
|
|
2824
|
-
local -a sub=(configure show)
|
|
2825
|
-
_describe 'subcommand' sub ;;
|
|
2826
|
-
completion)
|
|
2827
|
-
local -a sub=(bash zsh fish)
|
|
2828
|
-
_describe 'shell' sub ;;
|
|
2829
|
-
esac ;;
|
|
2771
|
+
local prefix cur
|
|
2772
|
+
local -a sub opts
|
|
2773
|
+
cur="\${words[CURRENT]}"
|
|
2774
|
+
|
|
2775
|
+
opts=(${opts})
|
|
2776
|
+
if [[ "$cur" == -* ]]; then
|
|
2777
|
+
_describe 'option' opts
|
|
2778
|
+
return
|
|
2779
|
+
fi
|
|
2780
|
+
|
|
2781
|
+
# Words typed so far, minus the program name, the word being completed, and
|
|
2782
|
+
# any flags.
|
|
2783
|
+
prefix="\${(j: :)\${(M)words[2,CURRENT-1]:#[^-]*}}"
|
|
2784
|
+
|
|
2785
|
+
case "$prefix" in
|
|
2786
|
+
${cases}
|
|
2787
|
+
*) return ;;
|
|
2830
2788
|
esac
|
|
2789
|
+
|
|
2790
|
+
_describe 'command' sub
|
|
2831
2791
|
}
|
|
2832
2792
|
|
|
2833
|
-
_seclai
|
|
2793
|
+
compdef _seclai seclai
|
|
2834
2794
|
`;
|
|
2835
|
-
|
|
2795
|
+
}
|
|
2796
|
+
function renderFish(tree, options) {
|
|
2797
|
+
const lines = [...tree.entries()].map(
|
|
2798
|
+
([prefix, children]) => children.map(
|
|
2799
|
+
(c) => `complete -c seclai -f -n "__seclai_at '${prefix}'" -a "${c.name}" -d "${c.description.replace(/["$`]/g, "")}"`
|
|
2800
|
+
).join("\n")
|
|
2801
|
+
).join("\n");
|
|
2802
|
+
const opts = options.map(
|
|
2803
|
+
(o) => `complete -c seclai -l ${o.flag.replace(/^--/, "")} -d "${o.description.replace(/["$`]/g, "")}"`
|
|
2804
|
+
).join("\n");
|
|
2805
|
+
return `# seclai fish completion \u2014 save to your completions directory:
|
|
2836
2806
|
# seclai completion fish > ~/.config/fish/completions/seclai.fish
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "skills" -d "Skill files"
|
|
2858
|
-
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "mcp" -d "MCP server config"
|
|
2859
|
-
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "completion" -d "Shell completions"
|
|
2860
|
-
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "auth" -d "SSO authentication"
|
|
2861
|
-
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "configure" -d "Manage SSO profiles"
|
|
2862
|
-
|
|
2863
|
-
# agents
|
|
2864
|
-
complete -c seclai -n "__fish_seen_subcommand_from agents; and not __fish_seen_subcommand_from list create get update delete disable enable callers triggers run runs def export preview-import upload-input input-status attachment-references ai" -f -a "list create get update delete disable enable callers triggers run runs def export preview-import upload-input input-status attachment-references ai"
|
|
2865
|
-
|
|
2866
|
-
# sources
|
|
2867
|
-
complete -c seclai -n "__fish_seen_subcommand_from sources; and not __fish_seen_subcommand_from list create get update delete upload upload-text exports migration" -f -a "list create get update delete upload upload-text exports migration"
|
|
2868
|
-
|
|
2869
|
-
# contents
|
|
2870
|
-
complete -c seclai -n "__fish_seen_subcommand_from contents; and not __fish_seen_subcommand_from get delete upload replace replace-text embeddings" -f -a "get delete upload replace replace-text embeddings"
|
|
2871
|
-
|
|
2872
|
-
# kb
|
|
2873
|
-
complete -c seclai -n "__fish_seen_subcommand_from kb; and not __fish_seen_subcommand_from list create get update delete" -f -a "list create get update delete"
|
|
2874
|
-
|
|
2875
|
-
# memory
|
|
2876
|
-
complete -c seclai -n "__fish_seen_subcommand_from memory; and not __fish_seen_subcommand_from list create get update delete stats agents compact delete-source templates test-compaction test-compaction-standalone ai" -f -a "list create get update delete stats agents compact delete-source templates test-compaction test-compaction-standalone ai"
|
|
2877
|
-
|
|
2878
|
-
# evals
|
|
2879
|
-
complete -c seclai -n "__fish_seen_subcommand_from evals; and not __fish_seen_subcommand_from criteria results compatible-runs test-draft agent-results agent-runs non-manual-summary" -f -a "criteria results compatible-runs test-draft agent-results agent-runs non-manual-summary"
|
|
2880
|
-
|
|
2881
|
-
# solutions
|
|
2882
|
-
complete -c seclai -n "__fish_seen_subcommand_from solutions; and not __fish_seen_subcommand_from list create get update delete link unlink convos ai" -f -a "list create get update delete link unlink convos ai"
|
|
2883
|
-
|
|
2884
|
-
# governance
|
|
2885
|
-
complete -c seclai -n "__fish_seen_subcommand_from governance; and not __fish_seen_subcommand_from ai" -f -a "ai"
|
|
2886
|
-
|
|
2887
|
-
# alerts
|
|
2888
|
-
complete -c seclai -n "__fish_seen_subcommand_from alerts; and not __fish_seen_subcommand_from list get status comment subscribe unsubscribe configs prefs" -f -a "list get status comment subscribe unsubscribe configs prefs"
|
|
2889
|
-
|
|
2890
|
-
# email
|
|
2891
|
-
complete -c seclai -n "__fish_seen_subcommand_from email; and not __fish_seen_subcommand_from domains blocked inbound optouts" -f -a "domains blocked inbound optouts"
|
|
2892
|
-
|
|
2893
|
-
# models
|
|
2894
|
-
complete -c seclai -n "__fish_seen_subcommand_from models; and not __fish_seen_subcommand_from list get tiers alerts recommendations experiments" -f -a "list get tiers alerts recommendations experiments"
|
|
2895
|
-
|
|
2896
|
-
# docs
|
|
2897
|
-
complete -c seclai -n "__fish_seen_subcommand_from docs; and not __fish_seen_subcommand_from search" -f -a "search"
|
|
2898
|
-
|
|
2899
|
-
# api-version
|
|
2900
|
-
complete -c seclai -n "__fish_seen_subcommand_from api-version; and not __fish_seen_subcommand_from get set clear" -f -a "get set clear"
|
|
2901
|
-
|
|
2902
|
-
# auth
|
|
2903
|
-
complete -c seclai -n "__fish_seen_subcommand_from auth; and not __fish_seen_subcommand_from login logout status refresh" -f -a "login logout status refresh"
|
|
2904
|
-
|
|
2905
|
-
# configure
|
|
2906
|
-
complete -c seclai -n "__fish_seen_subcommand_from configure; and not __fish_seen_subcommand_from sso list" -f -a "sso list"
|
|
2907
|
-
|
|
2908
|
-
# ai
|
|
2909
|
-
complete -c seclai -n "__fish_seen_subcommand_from ai; and not __fish_seen_subcommand_from feedback kb source solution memory memory-history accept decline memory-accept" -f -a "feedback kb source solution memory memory-history accept decline memory-accept"
|
|
2910
|
-
|
|
2911
|
-
# skills
|
|
2912
|
-
complete -c seclai -n "__fish_seen_subcommand_from skills; and not __fish_seen_subcommand_from install" -f -a "install"
|
|
2913
|
-
|
|
2914
|
-
# mcp
|
|
2915
|
-
complete -c seclai -n "__fish_seen_subcommand_from mcp; and not __fish_seen_subcommand_from configure show" -f -a "configure show"
|
|
2916
|
-
|
|
2917
|
-
# completion
|
|
2918
|
-
complete -c seclai -n "__fish_seen_subcommand_from completion; and not __fish_seen_subcommand_from bash zsh fish" -f -a "bash zsh fish"
|
|
2807
|
+
#
|
|
2808
|
+
# Generated from the command tree by \`seclai completion fish\`. Do not edit.
|
|
2809
|
+
|
|
2810
|
+
function __seclai_prefix
|
|
2811
|
+
set -l toks (commandline -opc)
|
|
2812
|
+
set -e toks[1]
|
|
2813
|
+
set -l out
|
|
2814
|
+
for t in $toks
|
|
2815
|
+
if not string match -q -- '-*' $t
|
|
2816
|
+
set -a out $t
|
|
2817
|
+
end
|
|
2818
|
+
end
|
|
2819
|
+
string join ' ' $out
|
|
2820
|
+
end
|
|
2821
|
+
|
|
2822
|
+
function __seclai_at
|
|
2823
|
+
test (__seclai_prefix) = "$argv[1]"
|
|
2824
|
+
end
|
|
2825
|
+
|
|
2826
|
+
${lines}
|
|
2919
2827
|
|
|
2920
2828
|
# Global options
|
|
2921
|
-
|
|
2922
|
-
complete -c seclai -l profile -d "SSO profile name"
|
|
2923
|
-
complete -c seclai -l account-id -d "Account ID (X-Account-Id header)"
|
|
2924
|
-
complete -c seclai -l config-dir -d "Config directory"
|
|
2925
|
-
complete -c seclai -l api-version -d "Dated API version (YYYY-MM-DD)"
|
|
2926
|
-
complete -c seclai -l allow-unknown-api-version -d "Permit an unrecognized --api-version"
|
|
2927
|
-
complete -c seclai -l compact -d "Output compact JSON"
|
|
2928
|
-
complete -c seclai -s V -l version -d "Output version"
|
|
2829
|
+
${opts}
|
|
2929
2830
|
`;
|
|
2930
|
-
|
|
2831
|
+
}
|
|
2832
|
+
function renderCompletion(shell, program) {
|
|
2833
|
+
const tree = collectTree(program);
|
|
2834
|
+
const options = globalOptions(program);
|
|
2835
|
+
if (shell === "bash") return renderBash(tree, options);
|
|
2836
|
+
if (shell === "zsh") return renderZsh(tree, options);
|
|
2837
|
+
if (shell === "fish") return renderFish(tree, options);
|
|
2838
|
+
return void 0;
|
|
2839
|
+
}
|
|
2931
2840
|
function register17(program, rt) {
|
|
2932
|
-
|
|
2933
|
-
const script =
|
|
2841
|
+
program.command("completion").description("Generate shell completion scripts.").argument("<shell>", "Shell type: bash, zsh, or fish.").action((shell) => {
|
|
2842
|
+
const script = renderCompletion(shell, program);
|
|
2934
2843
|
if (!script) {
|
|
2935
2844
|
rt.writeErr(`Unknown shell "${shell}". Use: bash, zsh, or fish.
|
|
2936
2845
|
`);
|
|
@@ -3389,15 +3298,8 @@ function escapeRegExp(s) {
|
|
|
3389
3298
|
}
|
|
3390
3299
|
|
|
3391
3300
|
// src/cli.ts
|
|
3392
|
-
var VALUED_GLOBAL_OPTIONS = [
|
|
3393
|
-
["apiKey", "--api-key", "reject", "Pass a key, or omit the flag to use SECLAI_API_KEY or SSO."],
|
|
3394
|
-
["profile", "--profile", "reject", "Pass a profile name, or omit the flag to use the default profile."],
|
|
3395
|
-
["accountId", "--account-id", "reject", "Pass an account ID, or omit the flag to use the default org."],
|
|
3396
|
-
["configDir", "--config-dir", "reject", "Pass a directory, or omit the flag to use ~/.seclai."],
|
|
3397
|
-
["apiVersion", "--api-version", "warn", "Pass a YYYY-MM-DD date, or omit the flag to use the account default."]
|
|
3398
|
-
];
|
|
3399
3301
|
function createProgram(rt = defaultRuntime()) {
|
|
3400
|
-
const program = new
|
|
3302
|
+
const program = new Command4();
|
|
3401
3303
|
const cliVersion = getCliVersion();
|
|
3402
3304
|
program.name("seclai").description(
|
|
3403
3305
|
`Seclai Command Line Interface (v${cliVersion})
|
|
@@ -3455,14 +3357,12 @@ Examples:
|
|
|
3455
3357
|
program.exitOverride();
|
|
3456
3358
|
program.hook("preAction", (thisCommand) => {
|
|
3457
3359
|
const globalOpts = thisCommand.opts();
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
delete globalOpts[key];
|
|
3465
|
-
warnDeprecated(rt, `${flag} was given an empty value and is being ignored. ${hint}`);
|
|
3360
|
+
if (typeof globalOpts.apiVersion === "string" && globalOpts.apiVersion.trim().length === 0) {
|
|
3361
|
+
warnDeprecated(
|
|
3362
|
+
rt,
|
|
3363
|
+
"--api-version was given an empty value and is being ignored. Pass a YYYY-MM-DD date, or omit the flag to use the account default.",
|
|
3364
|
+
"rejected"
|
|
3365
|
+
);
|
|
3466
3366
|
}
|
|
3467
3367
|
rt.compact = Boolean(globalOpts.compact);
|
|
3468
3368
|
});
|
|
@@ -3531,4 +3431,3 @@ export {
|
|
|
3531
3431
|
createProgram,
|
|
3532
3432
|
runCli
|
|
3533
3433
|
};
|
|
3534
|
-
//# sourceMappingURL=cli.js.map
|