@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/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: readFile2 } = await import("fs/promises");
306
- const bytes = new Uint8Array(await readFile2(opts.file));
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
- ## Quick Reference
1181
-
1182
- | Domain | Command | Description |
1183
- |--------|---------|-------------|
1184
- | Agents | \`seclai agents list/create/get/update/delete\` | Manage agents |
1185
- | Agent Runs | \`seclai agents run <id> --json '...'\` | Run an agent |
1186
- | Agent Runs | \`seclai agents runs list/get/delete/cancel/search\` | Manage runs |
1187
- | Agent Def | \`seclai agents def get/update\` | Agent step definitions |
1188
- | Sources | \`seclai sources list/create/get/update/delete/upload/upload-text\` | Content sources |
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
- \`\`\`bash
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
- ## Detailed References
1225
+ ## Commands
1247
1226
 
1248
- - [Agents](references/agents.md) \u2014 CRUD, runs, definitions, AI assistant
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":"Updated"}'
1233
+ seclai agents update <agentId> --json '{"name":"Renamed"}'
1262
1234
  seclai agents delete <agentId>
1263
1235
  \`\`\`
1264
1236
 
1265
- ## Running Agents
1237
+ ### Running agents
1238
+
1266
1239
  \`\`\`bash
1267
- # Simple run
1240
+ # simple run \u2014 returns the final result
1268
1241
  seclai agents run <agentId> --json '{"input":"Hello"}'
1269
1242
 
1270
- # Stream (wait for final result via SSE)
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
- # Stream individual events as NDJSON
1274
- seclai agents run <agentId> --json '{"input":"Hello"}' --events [--event-filter "status,data"] [--output full|data|status]
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
- # Poll-based
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
- ## Runs Management
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
- ## Agent Definition
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
- ## Input Uploads
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
- ## AI Assistant
1280
+ ### Agent AI assistant
1281
+
1303
1282
  \`\`\`bash
1304
- seclai agents ai gen-steps <agentId> --user-input "Build a chat agent"
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
- ## CRUD
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":"My Source",...}'
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
- ## File Upload
1299
+ ### Source uploads
1300
+
1322
1301
  \`\`\`bash
1323
- seclai sources upload <sourceId> --file ./doc.pdf [--title "Title"] [--metadata '{"k":"v"}'] [--file-name name] [--mime-type type]
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
- ## Exports
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
- ## Embedding Migration
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
- ## Knowledge Bases
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":"My KB",...}'
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
- ## Memory Banks
1346
+ ### Memory banks
1347
+
1357
1348
  \`\`\`bash
1358
1349
  seclai memory list [--page N] [--limit N] [--sort field] [--order asc|desc]
1359
- seclai memory create --json '{"name":"My Bank","type":"conversation"}'
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":"Updated"}'
1353
+ seclai memory update <memoryBankId> --json '{"name":"Renamed"}'
1362
1354
  seclai memory delete <memoryBankId>
1363
1355
  \`\`\`
1364
1356
 
1365
- ## Memory Bank Utilities
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
- ## Memory Bank AI
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
- ## Evaluation Criteria
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
- ## Evaluation Results
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":{...},"run_id":"..."}'
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
- ## Solutions
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":"My Solution"}'
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
- ## Solution Links
1410
+ ### Solution links
1411
+
1420
1412
  \`\`\`bash
1421
- seclai solutions link <solutionId> --agents '["id1","id2"]' --kb '["id3"]' --sources '["id4"]'
1422
- seclai solutions unlink <solutionId> --agents '["id1"]'
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
- ## Solution Conversations
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
- ## Alerts
1432
+ ### Alerts
1433
+
1444
1434
  \`\`\`bash
1445
- seclai alerts list [--page N] [--limit N] [--status <s>] [--severity <s>]
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
- ## Alert Configurations
1443
+ ### Alert configurations
1444
+
1454
1445
  \`\`\`bash
1455
1446
  seclai alerts configs list [--page N] [--limit N]
1456
- seclai alerts configs create --json '{"name":"My Config",...}'
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 '{"name":"Updated"}'
1449
+ seclai alerts configs update <configId> --json '{"threshold":3000}'
1459
1450
  seclai alerts configs delete <configId>
1460
1451
  \`\`\`
1461
1452
 
1462
- ## Alert Preferences
1453
+ ### Alert preferences
1454
+
1463
1455
  \`\`\`bash
1464
1456
  seclai alerts prefs list
1465
- seclai alerts prefs update <orgId> <alertType> --json '{"enabled":true}'
1457
+ seclai alerts prefs update <organizationId> <alertType> --json '{"enabled":true}'
1466
1458
  \`\`\`
1467
1459
 
1468
- ## Governance AI
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
- ## Model Alerts
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
- ## Search
1479
+ ### Search
1480
+
1486
1481
  \`\`\`bash
1487
1482
  seclai search --query "deployment guide" [--limit N] [--entity-type <type>]
1488
1483
  \`\`\`
1489
1484
 
1490
- ## AI Assistant
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/agents.md", content: AGENTS_SKILL },
1507
- { name: "references/sources.md", content: SOURCES_SKILL },
1508
- { name: "references/kb-memory.md", content: KB_MEMORY_SKILL },
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 register14(program, rt) {
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()) {