@seclai/cli 1.1.0 → 1.1.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/README.md +61 -1
- package/dist/cli.js +498 -150
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -302,8 +302,8 @@ function register(program, rt) {
|
|
|
302
302
|
agents.command("upload-input").description("Upload a file as agent input.").argument("<agentId>", "Agent ID.").requiredOption("--file <path>", "File to upload.").option("--file-name <name>", "Override filename.").option("--mime-type <type>", "MIME type.").action(async (agentId, opts) => {
|
|
303
303
|
await run(rt, async () => {
|
|
304
304
|
const client = createClient(program.opts());
|
|
305
|
-
const { readFile:
|
|
306
|
-
const bytes = new Uint8Array(await
|
|
305
|
+
const { readFile: readFile3 } = await import("fs/promises");
|
|
306
|
+
const bytes = new Uint8Array(await readFile3(opts.file));
|
|
307
307
|
const o = { file: bytes };
|
|
308
308
|
if (opts.fileName) o.fileName = opts.fileName;
|
|
309
309
|
if (opts.mimeType) o.mimeType = opts.mimeType;
|
|
@@ -1172,35 +1172,42 @@ The Seclai CLI (\`seclai\` / \`npx @seclai/cli\`) manages agents, knowledge base
|
|
|
1172
1172
|
|
|
1173
1173
|
All commands output JSON to stdout. Pipe into \`jq\` for filtering.
|
|
1174
1174
|
|
|
1175
|
+
## Quick start
|
|
1176
|
+
|
|
1177
|
+
\`\`\`bash
|
|
1178
|
+
# authenticate
|
|
1179
|
+
export SECLAI_API_KEY="sk-..."
|
|
1180
|
+
|
|
1181
|
+
# create an agent
|
|
1182
|
+
seclai agents create --json '{"name":"My Agent","description":"QA chatbot"}'
|
|
1183
|
+
|
|
1184
|
+
# configure steps via AI assistant
|
|
1185
|
+
seclai agents ai gen-steps <agentId> --user-input "Build a QA chatbot that uses a knowledge base"
|
|
1186
|
+
|
|
1187
|
+
# accept the generated plan
|
|
1188
|
+
seclai agents ai mark <agentId> <conversationId> --json '{"accepted":true}'
|
|
1189
|
+
|
|
1190
|
+
# run the agent
|
|
1191
|
+
seclai agents run <agentId> --json '{"input":"How do I reset my password?"}' --stream
|
|
1192
|
+
|
|
1193
|
+
# list runs
|
|
1194
|
+
seclai agents runs list <agentId>
|
|
1195
|
+
\`\`\`
|
|
1196
|
+
|
|
1175
1197
|
## Authentication
|
|
1176
1198
|
|
|
1177
1199
|
Set \`SECLAI_API_KEY\` env var or pass \`--api-key <key>\`.
|
|
1178
1200
|
Override the API URL with \`SECLAI_API_URL\` (default: https://api.seclai.com).
|
|
1179
1201
|
|
|
1180
|
-
##
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
| Source Exports | \`seclai sources exports list/create/get/cancel/delete/download/estimate\` | Export management |
|
|
1190
|
-
| Contents | \`seclai contents get/delete/upload/replace-text/embeddings\` | Indexed content |
|
|
1191
|
-
| Knowledge Bases | \`seclai kb list/create/get/update/delete\` | Knowledge bases |
|
|
1192
|
-
| Memory Banks | \`seclai memory list/create/get/update/delete/stats/agents/compact/templates\` | Memory banks |
|
|
1193
|
-
| Evaluations | \`seclai evals criteria list/create/get/update/delete/summary\` | Eval criteria |
|
|
1194
|
-
| Evaluations | \`seclai evals results list/create\` | Eval results |
|
|
1195
|
-
| Solutions | \`seclai solutions list/create/get/update/delete/link/unlink\` | Solutions |
|
|
1196
|
-
| Governance | \`seclai governance ai generate/list/accept/decline\` | Governance AI |
|
|
1197
|
-
| Alerts | \`seclai alerts list/get/status/comment/subscribe/unsubscribe\` | Alerts |
|
|
1198
|
-
| Alert Config | \`seclai alerts configs list/create/get/update/delete\` | Alert configs |
|
|
1199
|
-
| Models | \`seclai models alerts list/mark-read/mark-all-read/unread-count\` | Model alerts |
|
|
1200
|
-
| Search | \`seclai search --query "text"\` | Global search |
|
|
1201
|
-
| AI Assistant | \`seclai ai feedback/kb/source/solution/memory/accept/decline/memory-accept\` | AI assistant |
|
|
1202
|
-
|
|
1203
|
-
## Common Patterns
|
|
1202
|
+
## Global options
|
|
1203
|
+
|
|
1204
|
+
\`\`\`bash
|
|
1205
|
+
--api-key <key> # Seclai API key (or set SECLAI_API_KEY)
|
|
1206
|
+
--compact # Output compact single-line JSON
|
|
1207
|
+
-V, --version # Print version
|
|
1208
|
+
\`\`\`
|
|
1209
|
+
|
|
1210
|
+
## Common patterns
|
|
1204
1211
|
|
|
1205
1212
|
### JSON input
|
|
1206
1213
|
Most create/update commands accept \`--json '{"key":"value"}'\` or \`--json-file path.json\`.
|
|
@@ -1208,76 +1215,45 @@ Use \`--json -\` or \`--json-file -\` to read from stdin.
|
|
|
1208
1215
|
|
|
1209
1216
|
### AI assistant shorthand
|
|
1210
1217
|
AI generation commands accept \`--user-input <text>\` as shorthand for \`--json '{"user_input":"<text>"}'\`.
|
|
1211
|
-
\`\`\`bash
|
|
1212
|
-
seclai agents ai gen-steps <id> --user-input "Build a QA chatbot"
|
|
1213
|
-
seclai ai kb --user-input "Create a support knowledge base"
|
|
1214
|
-
\`\`\`
|
|
1215
|
-
|
|
1216
|
-
### Compact output
|
|
1217
|
-
Use \`--compact\` for single-line JSON output (useful for scripting):
|
|
1218
|
-
\`\`\`bash
|
|
1219
|
-
seclai agents list --compact | jq -c '.[]'
|
|
1220
|
-
\`\`\`
|
|
1221
1218
|
|
|
1222
1219
|
### Pagination
|
|
1223
1220
|
List commands support \`--page <n>\` and \`--limit <n>\`. Some also support \`--sort <field>\` and \`--order asc|desc\`.
|
|
1224
1221
|
|
|
1225
|
-
### Streaming agent runs
|
|
1226
|
-
\`\`\`bash
|
|
1227
|
-
# Wait for completion via SSE, print final result
|
|
1228
|
-
seclai agents run <id> --json '{"input":"Hello"}' --stream
|
|
1229
|
-
|
|
1230
|
-
# Stream individual SSE events as NDJSON
|
|
1231
|
-
seclai agents run <id> --json '{"input":"Hello"}' --events
|
|
1232
|
-
|
|
1233
|
-
# Filter event types
|
|
1234
|
-
seclai agents run <id> --json '{"input":"Hello"}' --events --event-filter "status,data"
|
|
1235
|
-
|
|
1236
|
-
# Poll-based waiting
|
|
1237
|
-
seclai agents run <id> --json '{"input":"Hello"}' --poll --poll-interval-ms 2000
|
|
1238
|
-
\`\`\`
|
|
1239
|
-
|
|
1240
1222
|
### File uploads
|
|
1241
|
-
|
|
1242
|
-
seclai sources upload <sourceId> --file ./doc.pdf --title "My Doc" --metadata '{"category":"docs"}'
|
|
1243
|
-
seclai contents upload <contentVersionId> --file ./updated.pdf
|
|
1244
|
-
\`\`\`
|
|
1223
|
+
Upload commands accept \`--file <path>\` (required), plus optional \`--title\`, \`--metadata '{"k":"v"}'\`, \`--metadata-file path.json\`, \`--file-name\`, \`--mime-type\`.
|
|
1245
1224
|
|
|
1246
|
-
##
|
|
1225
|
+
## Commands
|
|
1247
1226
|
|
|
1248
|
-
|
|
1249
|
-
- [Sources](references/sources.md) \u2014 content sources, uploads, exports, migrations
|
|
1250
|
-
- [Knowledge Bases & Memory Banks](references/kb-memory.md) \u2014 KB CRUD, memory banks, compaction
|
|
1251
|
-
- [Evaluations & Solutions](references/evals-solutions.md) \u2014 criteria, results, solutions, links
|
|
1252
|
-
- [Alerts, Governance & More](references/alerts-governance.md) \u2014 alerts, governance, models, search, AI
|
|
1253
|
-
`;
|
|
1254
|
-
var AGENTS_SKILL = `# Seclai CLI \u2014 Agents
|
|
1227
|
+
### Agents
|
|
1255
1228
|
|
|
1256
|
-
## CRUD
|
|
1257
1229
|
\`\`\`bash
|
|
1258
1230
|
seclai agents list [--page N] [--limit N]
|
|
1259
|
-
seclai agents create --json '{"name":"My Agent"
|
|
1231
|
+
seclai agents create --json '{"name":"My Agent","description":"..."}'
|
|
1260
1232
|
seclai agents get <agentId>
|
|
1261
|
-
seclai agents update <agentId> --json '{"name":"
|
|
1233
|
+
seclai agents update <agentId> --json '{"name":"Renamed"}'
|
|
1262
1234
|
seclai agents delete <agentId>
|
|
1263
1235
|
\`\`\`
|
|
1264
1236
|
|
|
1265
|
-
|
|
1237
|
+
### Running agents
|
|
1238
|
+
|
|
1266
1239
|
\`\`\`bash
|
|
1267
|
-
#
|
|
1240
|
+
# simple run \u2014 returns the final result
|
|
1268
1241
|
seclai agents run <agentId> --json '{"input":"Hello"}'
|
|
1269
1242
|
|
|
1270
|
-
#
|
|
1243
|
+
# stream \u2014 wait for completion via SSE, print final result
|
|
1271
1244
|
seclai agents run <agentId> --json '{"input":"Hello"}' --stream [--timeout-ms 60000]
|
|
1272
1245
|
|
|
1273
|
-
#
|
|
1274
|
-
|
|
1246
|
+
# events \u2014 stream individual SSE events as NDJSON lines
|
|
1247
|
+
# --output: full (entire event), data (event data only), status (status events only)
|
|
1248
|
+
# --event-filter: comma-separated event types to include, e.g. "status,data"
|
|
1249
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --events [--output full|data|status] [--event-filter "status,data"]
|
|
1275
1250
|
|
|
1276
|
-
#
|
|
1251
|
+
# poll \u2014 poll for completion
|
|
1277
1252
|
seclai agents run <agentId> --json '{"input":"Hello"}' --poll [--poll-interval-ms 2000] [--include-step-outputs]
|
|
1278
1253
|
\`\`\`
|
|
1279
1254
|
|
|
1280
|
-
|
|
1255
|
+
### Agent runs
|
|
1256
|
+
|
|
1281
1257
|
\`\`\`bash
|
|
1282
1258
|
seclai agents runs list <agentId> [--page N] [--limit N] [--status <status>]
|
|
1283
1259
|
seclai agents runs get <runId> [--include-step-outputs]
|
|
@@ -1287,185 +1263,202 @@ seclai agents runs search --json '{"query":"..."}'
|
|
|
1287
1263
|
seclai agents runs eval-results <agentId> <runId> [--page N] [--limit N]
|
|
1288
1264
|
\`\`\`
|
|
1289
1265
|
|
|
1290
|
-
|
|
1266
|
+
### Agent definitions
|
|
1267
|
+
|
|
1291
1268
|
\`\`\`bash
|
|
1292
1269
|
seclai agents def get <agentId>
|
|
1293
|
-
seclai agents def update <agentId> --json '{"steps":[...]}'
|
|
1270
|
+
seclai agents def update <agentId> --json '{"steps":[{"step_type":"llm","config":{...}}]}'
|
|
1294
1271
|
\`\`\`
|
|
1295
1272
|
|
|
1296
|
-
|
|
1273
|
+
### Agent input uploads
|
|
1274
|
+
|
|
1297
1275
|
\`\`\`bash
|
|
1298
1276
|
seclai agents upload-input <agentId> --file ./input.pdf [--file-name name] [--mime-type type]
|
|
1299
1277
|
seclai agents input-status <agentId> <uploadId>
|
|
1300
1278
|
\`\`\`
|
|
1301
1279
|
|
|
1302
|
-
|
|
1280
|
+
### Agent AI assistant
|
|
1281
|
+
|
|
1303
1282
|
\`\`\`bash
|
|
1304
|
-
seclai agents ai gen-steps <agentId> --user-input "Build a
|
|
1305
|
-
seclai agents ai step-config <agentId> --json '{"step_type":"
|
|
1283
|
+
seclai agents ai gen-steps <agentId> --user-input "Build a QA chatbot"
|
|
1284
|
+
seclai agents ai step-config <agentId> --json '{"step_type":"llm","user_input":"Configure the LLM step"}'
|
|
1306
1285
|
seclai agents ai history <agentId>
|
|
1307
1286
|
seclai agents ai mark <agentId> <conversationId> --json '{"accepted":true}'
|
|
1308
1287
|
\`\`\`
|
|
1309
|
-
`;
|
|
1310
|
-
var SOURCES_SKILL = `# Seclai CLI \u2014 Sources
|
|
1311
1288
|
|
|
1312
|
-
|
|
1289
|
+
### Sources
|
|
1290
|
+
|
|
1313
1291
|
\`\`\`bash
|
|
1314
1292
|
seclai sources list [--page N] [--limit N] [--sort field] [--order asc|desc] [--account-id id]
|
|
1315
|
-
seclai sources create --json '{"name":"
|
|
1293
|
+
seclai sources create --json '{"name":"Docs","description":"Product documentation"}'
|
|
1316
1294
|
seclai sources get <sourceId>
|
|
1317
|
-
seclai sources update <sourceId> --json '{"name":"Updated"}'
|
|
1295
|
+
seclai sources update <sourceId> --json '{"name":"Updated Docs"}'
|
|
1318
1296
|
seclai sources delete <sourceId>
|
|
1319
1297
|
\`\`\`
|
|
1320
1298
|
|
|
1321
|
-
|
|
1299
|
+
### Source uploads
|
|
1300
|
+
|
|
1322
1301
|
\`\`\`bash
|
|
1323
|
-
seclai sources upload <sourceId> --file ./doc.pdf [--title "
|
|
1324
|
-
seclai sources upload-text <sourceId> --json '{"text":"...","title":"
|
|
1302
|
+
seclai sources upload <sourceId> --file ./doc.pdf [--title "My Doc"] [--metadata '{"category":"docs"}'] [--file-name name] [--mime-type type]
|
|
1303
|
+
seclai sources upload-text <sourceId> --json '{"text":"Article content here...","title":"My Article"}'
|
|
1325
1304
|
\`\`\`
|
|
1326
1305
|
|
|
1327
|
-
|
|
1306
|
+
### Source exports
|
|
1307
|
+
|
|
1328
1308
|
\`\`\`bash
|
|
1329
1309
|
seclai sources exports list <sourceId> [--page N] [--limit N]
|
|
1330
|
-
seclai sources exports create <sourceId> --json '{"format":"
|
|
1310
|
+
seclai sources exports create <sourceId> --json '{"format":"jsonl"}'
|
|
1331
1311
|
seclai sources exports get <sourceId> <exportId>
|
|
1332
1312
|
seclai sources exports cancel <sourceId> <exportId>
|
|
1333
1313
|
seclai sources exports delete <sourceId> <exportId>
|
|
1334
1314
|
seclai sources exports download <sourceId> <exportId>
|
|
1335
|
-
seclai sources exports estimate <sourceId> --json '{"format":"
|
|
1315
|
+
seclai sources exports estimate <sourceId> --json '{"format":"jsonl"}'
|
|
1336
1316
|
\`\`\`
|
|
1337
1317
|
|
|
1338
|
-
|
|
1318
|
+
### Embedding migration
|
|
1319
|
+
|
|
1339
1320
|
\`\`\`bash
|
|
1340
1321
|
seclai sources migration get <sourceId>
|
|
1341
|
-
seclai sources migration start <sourceId> --json '{"target_model":"
|
|
1322
|
+
seclai sources migration start <sourceId> --json '{"target_model":"text-embedding-3-large"}'
|
|
1342
1323
|
seclai sources migration cancel <sourceId>
|
|
1343
1324
|
\`\`\`
|
|
1344
|
-
`;
|
|
1345
|
-
var KB_MEMORY_SKILL = `# Seclai CLI \u2014 Knowledge Bases & Memory Banks
|
|
1346
1325
|
|
|
1347
|
-
|
|
1326
|
+
### Contents (indexed content)
|
|
1327
|
+
|
|
1328
|
+
\`\`\`bash
|
|
1329
|
+
seclai contents get <contentVersionId> [--start N] [--end N]
|
|
1330
|
+
seclai contents delete <contentVersionId>
|
|
1331
|
+
seclai contents upload <contentVersionId> --file ./updated.pdf [--title "Title"] [--file-name name] [--mime-type type]
|
|
1332
|
+
seclai contents replace-text <contentVersionId> --json '{"text":"Replacement text","title":"Updated"}'
|
|
1333
|
+
seclai contents embeddings <contentVersionId> [--page N] [--limit N]
|
|
1334
|
+
\`\`\`
|
|
1335
|
+
|
|
1336
|
+
### Knowledge bases
|
|
1337
|
+
|
|
1348
1338
|
\`\`\`bash
|
|
1349
1339
|
seclai kb list [--page N] [--limit N] [--sort field] [--order asc|desc]
|
|
1350
|
-
seclai kb create --json '{"name":"
|
|
1340
|
+
seclai kb create --json '{"name":"Support KB","description":"Customer support articles"}'
|
|
1351
1341
|
seclai kb get <kbId>
|
|
1352
|
-
seclai kb update <kbId> --json '{"name":"Updated"}'
|
|
1342
|
+
seclai kb update <kbId> --json '{"name":"Updated KB"}'
|
|
1353
1343
|
seclai kb delete <kbId>
|
|
1354
1344
|
\`\`\`
|
|
1355
1345
|
|
|
1356
|
-
|
|
1346
|
+
### Memory banks
|
|
1347
|
+
|
|
1357
1348
|
\`\`\`bash
|
|
1358
1349
|
seclai memory list [--page N] [--limit N] [--sort field] [--order asc|desc]
|
|
1359
|
-
|
|
1350
|
+
# type: "conversation" (chat history) or "general" (structured facts)
|
|
1351
|
+
seclai memory create --json '{"name":"Chat Memory","type":"conversation"}'
|
|
1360
1352
|
seclai memory get <memoryBankId>
|
|
1361
|
-
seclai memory update <memoryBankId> --json '{"name":"
|
|
1353
|
+
seclai memory update <memoryBankId> --json '{"name":"Renamed"}'
|
|
1362
1354
|
seclai memory delete <memoryBankId>
|
|
1363
1355
|
\`\`\`
|
|
1364
1356
|
|
|
1365
|
-
|
|
1357
|
+
### Memory bank utilities
|
|
1358
|
+
|
|
1366
1359
|
\`\`\`bash
|
|
1367
1360
|
seclai memory stats <memoryBankId>
|
|
1368
1361
|
seclai memory agents <memoryBankId>
|
|
1369
1362
|
seclai memory compact <memoryBankId>
|
|
1370
1363
|
seclai memory delete-source <memoryBankId>
|
|
1371
1364
|
seclai memory templates
|
|
1372
|
-
seclai memory test-compaction <memoryBankId> --json '{"prompt":"
|
|
1373
|
-
seclai memory test-compaction-standalone --json '{"prompt":"
|
|
1365
|
+
seclai memory test-compaction <memoryBankId> --json '{"prompt":"Summarize the conversation"}'
|
|
1366
|
+
seclai memory test-compaction-standalone --json '{"prompt":"Summarize the conversation"}'
|
|
1374
1367
|
\`\`\`
|
|
1375
1368
|
|
|
1376
|
-
|
|
1369
|
+
### Memory bank AI
|
|
1370
|
+
|
|
1377
1371
|
\`\`\`bash
|
|
1378
1372
|
seclai memory ai generate --user-input "Configure compaction for chat memory"
|
|
1379
1373
|
seclai memory ai last
|
|
1380
1374
|
seclai memory ai accept <conversationId> --json '{"accepted":true}'
|
|
1381
1375
|
\`\`\`
|
|
1382
|
-
`;
|
|
1383
|
-
var EVALS_SOLUTIONS_SKILL = `# Seclai CLI \u2014 Evaluations & Solutions
|
|
1384
1376
|
|
|
1385
|
-
|
|
1377
|
+
### Evaluations \u2014 criteria
|
|
1378
|
+
|
|
1386
1379
|
\`\`\`bash
|
|
1387
1380
|
seclai evals criteria list <agentId> [--page N] [--limit N]
|
|
1388
|
-
seclai evals criteria create <agentId> --json '{"name":"Quality"
|
|
1381
|
+
seclai evals criteria create <agentId> --json '{"name":"Response Quality","description":"...","eval_type":"llm_judge"}'
|
|
1389
1382
|
seclai evals criteria get <criteriaId>
|
|
1390
|
-
seclai evals criteria update <criteriaId> --json '{"name":"Updated"}'
|
|
1383
|
+
seclai evals criteria update <criteriaId> --json '{"name":"Updated Criteria"}'
|
|
1391
1384
|
seclai evals criteria delete <criteriaId>
|
|
1392
1385
|
seclai evals criteria summary <criteriaId>
|
|
1393
1386
|
\`\`\`
|
|
1394
1387
|
|
|
1395
|
-
|
|
1388
|
+
### Evaluations \u2014 results & runs
|
|
1389
|
+
|
|
1396
1390
|
\`\`\`bash
|
|
1397
1391
|
seclai evals results list <criteriaId> [--page N] [--limit N]
|
|
1398
1392
|
seclai evals results create <criteriaId> --json '{"run_id":"...","score":0.9}'
|
|
1399
|
-
\`\`\`
|
|
1400
|
-
|
|
1401
|
-
## Other Evaluation Commands
|
|
1402
|
-
\`\`\`bash
|
|
1403
1393
|
seclai evals compatible-runs <criteriaId> [--page N] [--limit N]
|
|
1404
|
-
seclai evals test-draft <agentId> --json '{"criteria":{
|
|
1394
|
+
seclai evals test-draft <agentId> --json '{"criteria":{"name":"Test","eval_type":"llm_judge"},"run_id":"..."}'
|
|
1405
1395
|
seclai evals agent-results <agentId> [--page N] [--limit N]
|
|
1406
1396
|
seclai evals agent-runs <agentId> [--page N] [--limit N]
|
|
1407
1397
|
seclai evals non-manual-summary <agentId>
|
|
1408
1398
|
\`\`\`
|
|
1409
1399
|
|
|
1410
|
-
|
|
1400
|
+
### Solutions
|
|
1401
|
+
|
|
1411
1402
|
\`\`\`bash
|
|
1412
1403
|
seclai solutions list [--page N] [--limit N] [--sort field] [--order asc|desc]
|
|
1413
|
-
seclai solutions create --json '{"name":"
|
|
1404
|
+
seclai solutions create --json '{"name":"Customer Support Solution"}'
|
|
1414
1405
|
seclai solutions get <solutionId>
|
|
1415
1406
|
seclai solutions update <solutionId> --json '{"name":"Updated"}'
|
|
1416
1407
|
seclai solutions delete <solutionId>
|
|
1417
1408
|
\`\`\`
|
|
1418
1409
|
|
|
1419
|
-
|
|
1410
|
+
### Solution links
|
|
1411
|
+
|
|
1420
1412
|
\`\`\`bash
|
|
1421
|
-
|
|
1422
|
-
seclai solutions
|
|
1413
|
+
# link resources \u2014 each flag takes a JSON array of IDs
|
|
1414
|
+
seclai solutions link <solutionId> --agents '["agentId1"]' --kb '["kbId1"]' --sources '["sourceId1"]'
|
|
1415
|
+
seclai solutions unlink <solutionId> --agents '["agentId1"]'
|
|
1423
1416
|
\`\`\`
|
|
1424
1417
|
|
|
1425
|
-
|
|
1418
|
+
### Solution conversations & AI
|
|
1419
|
+
|
|
1426
1420
|
\`\`\`bash
|
|
1427
1421
|
seclai solutions convos list <solutionId>
|
|
1428
|
-
seclai solutions convos add <solutionId> --json '{"message":"
|
|
1422
|
+
seclai solutions convos add <solutionId> --json '{"message":"How should I structure this?"}'
|
|
1429
1423
|
seclai solutions convos mark <solutionId> <conversationId> --json '{"accepted":true}'
|
|
1430
|
-
\`\`\`
|
|
1431
1424
|
|
|
1432
|
-
## Solution AI
|
|
1433
|
-
\`\`\`bash
|
|
1434
1425
|
seclai solutions ai generate <solutionId> --user-input "Add an FAQ source"
|
|
1435
|
-
seclai solutions ai kb <solutionId> --user-input "Create a knowledge base"
|
|
1436
|
-
seclai solutions ai source <solutionId> --user-input "Create a file source"
|
|
1426
|
+
seclai solutions ai kb <solutionId> --user-input "Create a knowledge base for docs"
|
|
1427
|
+
seclai solutions ai source <solutionId> --user-input "Create a file source for PDFs"
|
|
1437
1428
|
seclai solutions ai accept <solutionId> <conversationId> --json '{"accepted":true}'
|
|
1438
1429
|
seclai solutions ai decline <solutionId> <conversationId>
|
|
1439
1430
|
\`\`\`
|
|
1440
|
-
`;
|
|
1441
|
-
var ALERTS_GOVERNANCE_SKILL = `# Seclai CLI \u2014 Alerts, Governance, Models & Search
|
|
1442
1431
|
|
|
1443
|
-
|
|
1432
|
+
### Alerts
|
|
1433
|
+
|
|
1444
1434
|
\`\`\`bash
|
|
1445
|
-
seclai alerts list [--page N] [--limit N] [--status <
|
|
1435
|
+
seclai alerts list [--page N] [--limit N] [--status <status>] [--severity <severity>]
|
|
1446
1436
|
seclai alerts get <alertId>
|
|
1447
1437
|
seclai alerts status <alertId> --json '{"status":"resolved"}'
|
|
1448
|
-
seclai alerts comment <alertId> --json '{"comment":"Fixed"}'
|
|
1438
|
+
seclai alerts comment <alertId> --json '{"comment":"Fixed the issue"}'
|
|
1449
1439
|
seclai alerts subscribe <alertId>
|
|
1450
1440
|
seclai alerts unsubscribe <alertId>
|
|
1451
1441
|
\`\`\`
|
|
1452
1442
|
|
|
1453
|
-
|
|
1443
|
+
### Alert configurations
|
|
1444
|
+
|
|
1454
1445
|
\`\`\`bash
|
|
1455
1446
|
seclai alerts configs list [--page N] [--limit N]
|
|
1456
|
-
seclai alerts configs create --json '{"name":"
|
|
1447
|
+
seclai alerts configs create --json '{"name":"Latency Alert","description":"...","threshold":5000}'
|
|
1457
1448
|
seclai alerts configs get <configId>
|
|
1458
|
-
seclai alerts configs update <configId> --json '{"
|
|
1449
|
+
seclai alerts configs update <configId> --json '{"threshold":3000}'
|
|
1459
1450
|
seclai alerts configs delete <configId>
|
|
1460
1451
|
\`\`\`
|
|
1461
1452
|
|
|
1462
|
-
|
|
1453
|
+
### Alert preferences
|
|
1454
|
+
|
|
1463
1455
|
\`\`\`bash
|
|
1464
1456
|
seclai alerts prefs list
|
|
1465
|
-
seclai alerts prefs update <
|
|
1457
|
+
seclai alerts prefs update <organizationId> <alertType> --json '{"enabled":true}'
|
|
1466
1458
|
\`\`\`
|
|
1467
1459
|
|
|
1468
|
-
|
|
1460
|
+
### Governance AI
|
|
1461
|
+
|
|
1469
1462
|
\`\`\`bash
|
|
1470
1463
|
seclai governance ai generate --user-input "Create a content safety policy"
|
|
1471
1464
|
seclai governance ai list
|
|
@@ -1473,7 +1466,8 @@ seclai governance ai accept <conversationId>
|
|
|
1473
1466
|
seclai governance ai decline <conversationId>
|
|
1474
1467
|
\`\`\`
|
|
1475
1468
|
|
|
1476
|
-
|
|
1469
|
+
### Model alerts
|
|
1470
|
+
|
|
1477
1471
|
\`\`\`bash
|
|
1478
1472
|
seclai models alerts list [--page N] [--limit N]
|
|
1479
1473
|
seclai models alerts mark-read <alertId>
|
|
@@ -1482,14 +1476,16 @@ seclai models alerts unread-count
|
|
|
1482
1476
|
seclai models recommendations <modelId>
|
|
1483
1477
|
\`\`\`
|
|
1484
1478
|
|
|
1485
|
-
|
|
1479
|
+
### Search
|
|
1480
|
+
|
|
1486
1481
|
\`\`\`bash
|
|
1487
1482
|
seclai search --query "deployment guide" [--limit N] [--entity-type <type>]
|
|
1488
1483
|
\`\`\`
|
|
1489
1484
|
|
|
1490
|
-
|
|
1485
|
+
### AI assistant (global)
|
|
1486
|
+
|
|
1491
1487
|
\`\`\`bash
|
|
1492
|
-
seclai ai feedback --json '{"feedback":"
|
|
1488
|
+
seclai ai feedback --json '{"feedback":"The response was helpful"}'
|
|
1493
1489
|
seclai ai kb --user-input "Create a support knowledge base"
|
|
1494
1490
|
seclai ai source --user-input "Create a documentation source"
|
|
1495
1491
|
seclai ai solution --user-input "Build a customer support solution"
|
|
@@ -1499,15 +1495,237 @@ seclai ai accept <conversationId> --json '{"accepted":true}'
|
|
|
1499
1495
|
seclai ai decline <conversationId>
|
|
1500
1496
|
seclai ai memory-accept <conversationId> --json '{"accepted":true}'
|
|
1501
1497
|
\`\`\`
|
|
1498
|
+
|
|
1499
|
+
### Skills
|
|
1500
|
+
|
|
1501
|
+
\`\`\`bash
|
|
1502
|
+
# install skill files into AI coding tool directories (auto-detects or specify)
|
|
1503
|
+
seclai skills install [--tool copilot|claude|cursor|windsurf|codex|kiro|cline|roo|gemini|antigravity|all] [--dir .]
|
|
1504
|
+
\`\`\`
|
|
1505
|
+
|
|
1506
|
+
### MCP server
|
|
1507
|
+
|
|
1508
|
+
\`\`\`bash
|
|
1509
|
+
# configure MCP server access in AI coding tool config files
|
|
1510
|
+
seclai mcp configure --key <apiKey> [--target claude-code|cursor|claude-desktop|windsurf|all] [--dir .]
|
|
1511
|
+
|
|
1512
|
+
# show the MCP config JSON snippet
|
|
1513
|
+
seclai mcp show [--key <apiKey>]
|
|
1514
|
+
\`\`\`
|
|
1515
|
+
|
|
1516
|
+
## Example: Create a source and upload content
|
|
1517
|
+
|
|
1518
|
+
\`\`\`bash
|
|
1519
|
+
seclai sources create --json '{"name":"Product Docs","description":"Product documentation source"}'
|
|
1520
|
+
# note the id from the output
|
|
1521
|
+
seclai sources upload <sourceId> --file ./docs.pdf --title "Product Manual" --metadata '{"version":"2.0"}'
|
|
1522
|
+
seclai sources get <sourceId>
|
|
1523
|
+
\`\`\`
|
|
1524
|
+
|
|
1525
|
+
## Example: Set up a knowledge base with an agent
|
|
1526
|
+
|
|
1527
|
+
\`\`\`bash
|
|
1528
|
+
seclai kb create --json '{"name":"Support KB","description":"Customer support articles"}'
|
|
1529
|
+
seclai agents create --json '{"name":"Support Bot","description":"Answers customer questions"}'
|
|
1530
|
+
seclai agents ai gen-steps <agentId> --user-input "Build a QA chatbot that searches the Support KB"
|
|
1531
|
+
seclai agents ai mark <agentId> <conversationId> --json '{"accepted":true}'
|
|
1532
|
+
seclai agents run <agentId> --json '{"input":"How do I reset my password?"}' --stream
|
|
1533
|
+
\`\`\`
|
|
1534
|
+
|
|
1535
|
+
## Example: Evaluate agent quality
|
|
1536
|
+
|
|
1537
|
+
\`\`\`bash
|
|
1538
|
+
# create eval criteria
|
|
1539
|
+
seclai evals criteria create <agentId> --json '{"name":"Answer Accuracy","eval_type":"llm_judge","description":"Does the answer correctly address the question?"}'
|
|
1540
|
+
# find compatible runs
|
|
1541
|
+
seclai evals compatible-runs <criteriaId> --limit 5
|
|
1542
|
+
# test the criteria against a run without persisting
|
|
1543
|
+
seclai evals test-draft <agentId> --json '{"criteria":{"name":"Answer Accuracy","eval_type":"llm_judge"},"run_id":"<runId>"}'
|
|
1544
|
+
# create a persisted result
|
|
1545
|
+
seclai evals results create <criteriaId> --json '{"run_id":"<runId>","score":0.95}'
|
|
1546
|
+
# view summary
|
|
1547
|
+
seclai evals criteria summary <criteriaId>
|
|
1548
|
+
\`\`\`
|
|
1549
|
+
|
|
1550
|
+
## Example: Solution with linked resources
|
|
1551
|
+
|
|
1552
|
+
\`\`\`bash
|
|
1553
|
+
seclai solutions create --json '{"name":"Customer Support"}'
|
|
1554
|
+
seclai solutions link <solutionId> --agents '["<agentId>"]' --kb '["<kbId>"]' --sources '["<sourceId>"]'
|
|
1555
|
+
seclai solutions get <solutionId>
|
|
1556
|
+
\`\`\`
|
|
1557
|
+
|
|
1558
|
+
## Example: Memory-powered agent
|
|
1559
|
+
|
|
1560
|
+
\`\`\`bash
|
|
1561
|
+
seclai memory create --json '{"name":"User Preferences","type":"general"}'
|
|
1562
|
+
seclai agents create --json '{"name":"Personal Assistant","description":"Remembers user preferences"}'
|
|
1563
|
+
seclai agents ai gen-steps <agentId> --user-input "Build a chat agent that remembers user preferences. Use general memory bank <memoryBankId>"
|
|
1564
|
+
seclai agents ai mark <agentId> <conversationId> --json '{"accepted":true}'
|
|
1565
|
+
\`\`\`
|
|
1566
|
+
|
|
1567
|
+
## Example: Governance policy setup
|
|
1568
|
+
|
|
1569
|
+
\`\`\`bash
|
|
1570
|
+
seclai governance ai generate --user-input "Create a content safety policy that blocks harmful outputs"
|
|
1571
|
+
seclai governance ai list
|
|
1572
|
+
seclai governance ai accept <conversationId>
|
|
1573
|
+
\`\`\`
|
|
1574
|
+
|
|
1575
|
+
## Specific topics
|
|
1576
|
+
|
|
1577
|
+
* **Streaming & event modes** [references/streaming.md](references/streaming.md)
|
|
1578
|
+
* **File uploads & content management** [references/uploads.md](references/uploads.md)
|
|
1579
|
+
* **Evaluations workflow** [references/evaluations.md](references/evaluations.md)
|
|
1580
|
+
`;
|
|
1581
|
+
var STREAMING_REF = `# Streaming Agent Runs
|
|
1582
|
+
|
|
1583
|
+
## Modes
|
|
1584
|
+
|
|
1585
|
+
### --stream
|
|
1586
|
+
Wait for the agent run to complete via SSE. Prints the final result as a single JSON object.
|
|
1587
|
+
Useful when you want to block until done.
|
|
1588
|
+
|
|
1589
|
+
\`\`\`bash
|
|
1590
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --stream
|
|
1591
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --stream --timeout-ms 120000
|
|
1592
|
+
\`\`\`
|
|
1593
|
+
|
|
1594
|
+
### --events
|
|
1595
|
+
Stream individual SSE events as NDJSON (one JSON object per line). Use for real-time processing.
|
|
1596
|
+
|
|
1597
|
+
\`\`\`bash
|
|
1598
|
+
# all events, full event objects
|
|
1599
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --events
|
|
1600
|
+
|
|
1601
|
+
# only data payloads (no event metadata)
|
|
1602
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --events --output data
|
|
1603
|
+
|
|
1604
|
+
# only status events
|
|
1605
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --events --output status
|
|
1606
|
+
|
|
1607
|
+
# filter specific event types
|
|
1608
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --events --event-filter "status,data"
|
|
1609
|
+
\`\`\`
|
|
1610
|
+
|
|
1611
|
+
Output modes for --events:
|
|
1612
|
+
- \`full\`: entire SSE event object (default)
|
|
1613
|
+
- \`data\`: only the data payload of each event
|
|
1614
|
+
- \`status\`: only events with status information
|
|
1615
|
+
|
|
1616
|
+
### --poll
|
|
1617
|
+
Poll the API at intervals for run completion. Does not use SSE.
|
|
1618
|
+
|
|
1619
|
+
\`\`\`bash
|
|
1620
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --poll
|
|
1621
|
+
seclai agents run <agentId> --json '{"input":"Hello"}' --poll --poll-interval-ms 5000 --include-step-outputs
|
|
1622
|
+
\`\`\`
|
|
1623
|
+
|
|
1624
|
+
### No flag
|
|
1625
|
+
Fire-and-forget: starts the run and immediately returns the run ID.
|
|
1626
|
+
|
|
1627
|
+
\`\`\`bash
|
|
1628
|
+
seclai agents run <agentId> --json '{"input":"Hello"}'
|
|
1629
|
+
# returns: {"id":"run_...","status":"queued",...}
|
|
1630
|
+
# check later:
|
|
1631
|
+
seclai agents runs get <runId>
|
|
1632
|
+
\`\`\`
|
|
1633
|
+
`;
|
|
1634
|
+
var UPLOADS_REF = `# File Uploads & Content Management
|
|
1635
|
+
|
|
1636
|
+
## Upload to a source
|
|
1637
|
+
\`\`\`bash
|
|
1638
|
+
seclai sources upload <sourceId> --file ./doc.pdf
|
|
1639
|
+
seclai sources upload <sourceId> --file ./doc.pdf --title "My Doc" --metadata '{"category":"docs"}' --file-name "custom-name.pdf" --mime-type "application/pdf"
|
|
1640
|
+
seclai sources upload <sourceId> --file ./doc.pdf --metadata-file ./meta.json
|
|
1641
|
+
\`\`\`
|
|
1642
|
+
|
|
1643
|
+
## Upload text directly
|
|
1644
|
+
\`\`\`bash
|
|
1645
|
+
seclai sources upload-text <sourceId> --json '{"text":"Article content here...","title":"My Article"}'
|
|
1646
|
+
\`\`\`
|
|
1647
|
+
|
|
1648
|
+
## Upload input for agent runs
|
|
1649
|
+
\`\`\`bash
|
|
1650
|
+
seclai agents upload-input <agentId> --file ./input.pdf
|
|
1651
|
+
seclai agents upload-input <agentId> --file ./data.csv --file-name "report.csv" --mime-type "text/csv"
|
|
1652
|
+
seclai agents input-status <agentId> <uploadId>
|
|
1653
|
+
\`\`\`
|
|
1654
|
+
|
|
1655
|
+
## Replace content
|
|
1656
|
+
\`\`\`bash
|
|
1657
|
+
# replace with file
|
|
1658
|
+
seclai contents upload <contentVersionId> --file ./updated.pdf
|
|
1659
|
+
|
|
1660
|
+
# replace with text
|
|
1661
|
+
seclai contents replace-text <contentVersionId> --json '{"text":"Updated content","title":"Revised Article"}'
|
|
1662
|
+
\`\`\`
|
|
1663
|
+
|
|
1664
|
+
## Read content
|
|
1665
|
+
\`\`\`bash
|
|
1666
|
+
# full content
|
|
1667
|
+
seclai contents get <contentVersionId>
|
|
1668
|
+
|
|
1669
|
+
# text slice (0-based offsets)
|
|
1670
|
+
seclai contents get <contentVersionId> --start 0 --end 1000
|
|
1671
|
+
|
|
1672
|
+
# view embeddings
|
|
1673
|
+
seclai contents embeddings <contentVersionId> [--page N] [--limit N]
|
|
1674
|
+
\`\`\`
|
|
1675
|
+
`;
|
|
1676
|
+
var EVALUATIONS_REF = `# Evaluations Workflow
|
|
1677
|
+
|
|
1678
|
+
## Step 1: Create evaluation criteria for an agent
|
|
1679
|
+
\`\`\`bash
|
|
1680
|
+
seclai evals criteria create <agentId> --json '{"name":"Answer Accuracy","description":"Does the answer correctly address the question?","eval_type":"llm_judge"}'
|
|
1681
|
+
\`\`\`
|
|
1682
|
+
|
|
1683
|
+
## Step 2: Find runs to evaluate
|
|
1684
|
+
\`\`\`bash
|
|
1685
|
+
# list all runs for an agent
|
|
1686
|
+
seclai agents runs list <agentId> --limit 10
|
|
1687
|
+
|
|
1688
|
+
# or find runs compatible with specific criteria
|
|
1689
|
+
seclai evals compatible-runs <criteriaId> --limit 10
|
|
1690
|
+
\`\`\`
|
|
1691
|
+
|
|
1692
|
+
## Step 3: Test criteria before committing
|
|
1693
|
+
\`\`\`bash
|
|
1694
|
+
seclai evals test-draft <agentId> --json '{"criteria":{"name":"Answer Accuracy","eval_type":"llm_judge","description":"..."},"run_id":"<runId>"}'
|
|
1695
|
+
\`\`\`
|
|
1696
|
+
|
|
1697
|
+
## Step 4: Create evaluation results
|
|
1698
|
+
\`\`\`bash
|
|
1699
|
+
seclai evals results create <criteriaId> --json '{"run_id":"<runId>","score":0.95}'
|
|
1700
|
+
\`\`\`
|
|
1701
|
+
|
|
1702
|
+
## Step 5: Review summaries
|
|
1703
|
+
\`\`\`bash
|
|
1704
|
+
seclai evals criteria summary <criteriaId>
|
|
1705
|
+
seclai evals agent-results <agentId>
|
|
1706
|
+
seclai evals agent-runs <agentId> --limit 20
|
|
1707
|
+
seclai evals non-manual-summary <agentId>
|
|
1708
|
+
\`\`\`
|
|
1709
|
+
|
|
1710
|
+
## Managing criteria
|
|
1711
|
+
\`\`\`bash
|
|
1712
|
+
seclai evals criteria list <agentId>
|
|
1713
|
+
seclai evals criteria get <criteriaId>
|
|
1714
|
+
seclai evals criteria update <criteriaId> --json '{"name":"Updated Name"}'
|
|
1715
|
+
seclai evals criteria delete <criteriaId>
|
|
1716
|
+
\`\`\`
|
|
1717
|
+
|
|
1718
|
+
## Viewing results
|
|
1719
|
+
\`\`\`bash
|
|
1720
|
+
seclai evals results list <criteriaId> [--page N] [--limit N]
|
|
1721
|
+
\`\`\`
|
|
1502
1722
|
`;
|
|
1503
1723
|
function getToolConfig(tool, destDir) {
|
|
1504
1724
|
const skillFiles = [
|
|
1505
1725
|
{ name: "SKILL.md", content: SKILL_MD },
|
|
1506
|
-
{ name: "references/
|
|
1507
|
-
{ name: "references/
|
|
1508
|
-
{ name: "references/
|
|
1509
|
-
{ name: "references/evals-solutions.md", content: EVALS_SOLUTIONS_SKILL },
|
|
1510
|
-
{ name: "references/alerts-governance.md", content: ALERTS_GOVERNANCE_SKILL }
|
|
1726
|
+
{ name: "references/streaming.md", content: STREAMING_REF },
|
|
1727
|
+
{ name: "references/uploads.md", content: UPLOADS_REF },
|
|
1728
|
+
{ name: "references/evaluations.md", content: EVALUATIONS_REF }
|
|
1511
1729
|
];
|
|
1512
1730
|
switch (tool) {
|
|
1513
1731
|
case "copilot":
|
|
@@ -1586,6 +1804,126 @@ function register13(program, rt) {
|
|
|
1586
1804
|
});
|
|
1587
1805
|
}
|
|
1588
1806
|
|
|
1807
|
+
// src/commands/mcp.ts
|
|
1808
|
+
import { existsSync as existsSync2 } from "fs";
|
|
1809
|
+
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
1810
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
1811
|
+
import { homedir, platform } from "os";
|
|
1812
|
+
var MCP_URL = "https://api.seclai.com/mcp";
|
|
1813
|
+
function buildMcpEntry(apiKey) {
|
|
1814
|
+
return {
|
|
1815
|
+
type: "streamable-http",
|
|
1816
|
+
url: MCP_URL,
|
|
1817
|
+
headers: { "X-API-Key": apiKey }
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
function getTargets(destDir) {
|
|
1821
|
+
const home = homedir();
|
|
1822
|
+
const os = platform();
|
|
1823
|
+
const targets = [
|
|
1824
|
+
// Project-scoped configs
|
|
1825
|
+
{ name: "claude-code", path: join2(destDir, ".mcp.json"), scope: "project" },
|
|
1826
|
+
{ name: "cursor", path: join2(destDir, ".cursor", "mcp.json"), scope: "project" }
|
|
1827
|
+
];
|
|
1828
|
+
if (os === "win32") {
|
|
1829
|
+
targets.push({
|
|
1830
|
+
name: "claude-desktop",
|
|
1831
|
+
path: join2(process.env["APPDATA"] ?? join2(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json"),
|
|
1832
|
+
scope: "global"
|
|
1833
|
+
});
|
|
1834
|
+
} else if (os === "darwin") {
|
|
1835
|
+
targets.push({
|
|
1836
|
+
name: "claude-desktop",
|
|
1837
|
+
path: join2(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
1838
|
+
scope: "global"
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
targets.push({ name: "windsurf", path: join2(home, ".codeium", "windsurf", "mcp_config.json"), scope: "global" });
|
|
1842
|
+
return targets;
|
|
1843
|
+
}
|
|
1844
|
+
async function mergeConfig(filePath, apiKey) {
|
|
1845
|
+
let existing = {};
|
|
1846
|
+
if (existsSync2(filePath)) {
|
|
1847
|
+
try {
|
|
1848
|
+
const parsed = JSON.parse(await readFile2(filePath, "utf8"));
|
|
1849
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return false;
|
|
1850
|
+
existing = parsed;
|
|
1851
|
+
} catch {
|
|
1852
|
+
return false;
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
const raw = existing["mcpServers"];
|
|
1856
|
+
const servers = typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
|
|
1857
|
+
servers["seclai"] = buildMcpEntry(apiKey);
|
|
1858
|
+
existing["mcpServers"] = servers;
|
|
1859
|
+
await mkdir2(dirname2(filePath), { recursive: true });
|
|
1860
|
+
await writeFile2(filePath, JSON.stringify(existing, null, 2) + "\n", "utf8");
|
|
1861
|
+
return true;
|
|
1862
|
+
}
|
|
1863
|
+
function detectTargets(destDir) {
|
|
1864
|
+
const all = getTargets(destDir);
|
|
1865
|
+
return all.filter((t) => {
|
|
1866
|
+
if (t.scope === "global") return existsSync2(dirname2(t.path));
|
|
1867
|
+
if (t.name === "claude-code") return existsSync2(join2(destDir, ".claude")) || existsSync2(join2(destDir, "CLAUDE.md"));
|
|
1868
|
+
if (t.name === "cursor") return existsSync2(join2(destDir, ".cursor"));
|
|
1869
|
+
return false;
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
function register14(program, rt) {
|
|
1873
|
+
const mcp = program.command("mcp").description("Configure the Seclai MCP server for AI coding tools.");
|
|
1874
|
+
mcp.command("configure").description(
|
|
1875
|
+
"Add the Seclai MCP server to AI coding tool config files.\n\nTargets: claude-code, cursor, claude-desktop, windsurf.\nUse --target to pick a specific tool, or 'all' for all known targets."
|
|
1876
|
+
).requiredOption("--key <key>", "Seclai API key to embed in the config.").option("--target <name>", "Target tool (claude-code|cursor|claude-desktop|windsurf|all). Auto-detects if omitted.").option("--dir <path>", "Project directory for project-scoped configs (default: current directory).", ".").action(async (opts) => {
|
|
1877
|
+
await run(rt, async () => {
|
|
1878
|
+
const destDir = opts.dir;
|
|
1879
|
+
const apiKey = opts.key;
|
|
1880
|
+
const allTargets = getTargets(destDir);
|
|
1881
|
+
let targets;
|
|
1882
|
+
if (opts.target === "all") {
|
|
1883
|
+
targets = allTargets;
|
|
1884
|
+
} else if (opts.target) {
|
|
1885
|
+
const found = allTargets.find((t) => t.name === opts.target);
|
|
1886
|
+
if (!found) {
|
|
1887
|
+
rt.writeErr(`Unknown target "${opts.target}". Use: claude-code, cursor, claude-desktop, windsurf, or all.
|
|
1888
|
+
`);
|
|
1889
|
+
rt.setExitCode(1);
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
targets = [found];
|
|
1893
|
+
} else {
|
|
1894
|
+
targets = detectTargets(destDir);
|
|
1895
|
+
if (targets.length === 0) {
|
|
1896
|
+
targets = [allTargets[0]];
|
|
1897
|
+
rt.writeErr("No MCP-compatible tool detected, defaulting to claude-code (.mcp.json).\n");
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
let configured = 0;
|
|
1901
|
+
const failures = [];
|
|
1902
|
+
for (const target of targets) {
|
|
1903
|
+
const ok = await mergeConfig(target.path, apiKey);
|
|
1904
|
+
if (ok) {
|
|
1905
|
+
configured++;
|
|
1906
|
+
rt.writeErr(`Configured seclai MCP for ${target.name} \u2192 ${target.path}
|
|
1907
|
+
`);
|
|
1908
|
+
} else {
|
|
1909
|
+
failures.push(target.name);
|
|
1910
|
+
rt.writeErr(`Failed to parse existing config at ${target.path}, skipping.
|
|
1911
|
+
`);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
const allOk = failures.length === 0;
|
|
1915
|
+
printJson(rt, { ok: allOk, targets: targets.map((t) => t.name), filesWritten: configured, ...failures.length > 0 ? { failures } : {} });
|
|
1916
|
+
if (!allOk) rt.setExitCode(1);
|
|
1917
|
+
});
|
|
1918
|
+
});
|
|
1919
|
+
mcp.command("show").description("Show the Seclai MCP server JSON configuration snippet.").option("--key <key>", "API key to include (default: placeholder).").action(async (opts) => {
|
|
1920
|
+
await run(rt, async () => {
|
|
1921
|
+
const entry = buildMcpEntry(opts.key ?? "YOUR_API_KEY");
|
|
1922
|
+
printJson(rt, { mcpServers: { seclai: entry } });
|
|
1923
|
+
});
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1589
1927
|
// src/commands/completion.ts
|
|
1590
1928
|
var BASH = `#!/usr/bin/env bash
|
|
1591
1929
|
# seclai bash completion \u2014 add to ~/.bashrc:
|
|
@@ -1597,7 +1935,7 @@ _seclai_completions() {
|
|
|
1597
1935
|
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
1598
1936
|
|
|
1599
1937
|
# Top-level commands
|
|
1600
|
-
commands="agents sources contents kb memory evals solutions governance alerts models search ai skills completion help"
|
|
1938
|
+
commands="agents sources contents kb memory evals solutions governance alerts models search ai skills mcp completion help"
|
|
1601
1939
|
|
|
1602
1940
|
case "\${COMP_WORDS[1]}" in
|
|
1603
1941
|
agents)
|
|
@@ -1650,6 +1988,7 @@ _seclai_completions() {
|
|
|
1650
1988
|
esac ;;
|
|
1651
1989
|
ai) COMPREPLY=( $(compgen -W "feedback kb source solution memory memory-history accept decline memory-accept" -- "$cur") ); return ;;
|
|
1652
1990
|
skills) COMPREPLY=( $(compgen -W "install" -- "$cur") ); return ;;
|
|
1991
|
+
mcp) COMPREPLY=( $(compgen -W "configure show" -- "$cur") ); return ;;
|
|
1653
1992
|
completion) COMPREPLY=( $(compgen -W "bash zsh fish" -- "$cur") ); return ;;
|
|
1654
1993
|
esac
|
|
1655
1994
|
|
|
@@ -1678,6 +2017,7 @@ _seclai() {
|
|
|
1678
2017
|
'search:Search across Seclai resources'
|
|
1679
2018
|
'ai:Top-level AI assistant'
|
|
1680
2019
|
'skills:Install skill files for AI coding tools'
|
|
2020
|
+
'mcp:Configure the Seclai MCP server'
|
|
1681
2021
|
'completion:Generate shell completion scripts'
|
|
1682
2022
|
'help:Display help for command'
|
|
1683
2023
|
)
|
|
@@ -1730,6 +2070,9 @@ _seclai() {
|
|
|
1730
2070
|
skills)
|
|
1731
2071
|
local -a sub=(install)
|
|
1732
2072
|
_describe 'subcommand' sub ;;
|
|
2073
|
+
mcp)
|
|
2074
|
+
local -a sub=(configure show)
|
|
2075
|
+
_describe 'subcommand' sub ;;
|
|
1733
2076
|
completion)
|
|
1734
2077
|
local -a sub=(bash zsh fish)
|
|
1735
2078
|
_describe 'shell' sub ;;
|
|
@@ -1742,7 +2085,7 @@ _seclai "$@"
|
|
|
1742
2085
|
var FISH = `# seclai fish completion \u2014 save to ~/.config/fish/completions/seclai.fish
|
|
1743
2086
|
# seclai completion fish > ~/.config/fish/completions/seclai.fish
|
|
1744
2087
|
|
|
1745
|
-
set -l top agents sources contents kb memory evals solutions governance alerts models search ai skills completion help
|
|
2088
|
+
set -l top agents sources contents kb memory evals solutions governance alerts models search ai skills mcp completion help
|
|
1746
2089
|
|
|
1747
2090
|
# Top-level
|
|
1748
2091
|
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "agents" -d "Manage agents"
|
|
@@ -1758,6 +2101,7 @@ complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "models" -d "
|
|
|
1758
2101
|
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "search" -d "Search resources"
|
|
1759
2102
|
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "ai" -d "AI assistant"
|
|
1760
2103
|
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "skills" -d "Skill files"
|
|
2104
|
+
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "mcp" -d "MCP server config"
|
|
1761
2105
|
complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "completion" -d "Shell completions"
|
|
1762
2106
|
|
|
1763
2107
|
# agents
|
|
@@ -1796,6 +2140,9 @@ complete -c seclai -n "__fish_seen_subcommand_from ai; and not __fish_seen_subco
|
|
|
1796
2140
|
# skills
|
|
1797
2141
|
complete -c seclai -n "__fish_seen_subcommand_from skills; and not __fish_seen_subcommand_from install" -f -a "install"
|
|
1798
2142
|
|
|
2143
|
+
# mcp
|
|
2144
|
+
complete -c seclai -n "__fish_seen_subcommand_from mcp; and not __fish_seen_subcommand_from configure show" -f -a "configure show"
|
|
2145
|
+
|
|
1799
2146
|
# completion
|
|
1800
2147
|
complete -c seclai -n "__fish_seen_subcommand_from completion; and not __fish_seen_subcommand_from bash zsh fish" -f -a "bash zsh fish"
|
|
1801
2148
|
|
|
@@ -1805,7 +2152,7 @@ complete -c seclai -l compact -d "Output compact JSON"
|
|
|
1805
2152
|
complete -c seclai -s V -l version -d "Output version"
|
|
1806
2153
|
`;
|
|
1807
2154
|
var SCRIPTS = { bash: BASH, zsh: ZSH, fish: FISH };
|
|
1808
|
-
function
|
|
2155
|
+
function register15(program, rt) {
|
|
1809
2156
|
const completion = program.command("completion").description("Generate shell completion scripts.").argument("<shell>", "Shell type: bash, zsh, or fish.").action(async (shell) => {
|
|
1810
2157
|
const script = SCRIPTS[shell];
|
|
1811
2158
|
if (!script) {
|
|
@@ -1875,6 +2222,7 @@ Examples:
|
|
|
1875
2222
|
register12(program, rt);
|
|
1876
2223
|
register13(program, rt);
|
|
1877
2224
|
register14(program, rt);
|
|
2225
|
+
register15(program, rt);
|
|
1878
2226
|
return program;
|
|
1879
2227
|
}
|
|
1880
2228
|
async function runCli(argv, rt = defaultRuntime()) {
|