@seclai/cli 1.2.0 → 1.2.2

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 CHANGED
@@ -42,7 +42,7 @@ npx add-mcp https://api.seclai.com/mcp --header "X-API-Key: $SECLAI_API_KEY" --n
42
42
 
43
43
  ## Documentation
44
44
 
45
- Command reference (latest): https://seclai.github.io/seclai-cli/1.2.0/
45
+ Command reference (latest): https://seclai.github.io/seclai-cli/1.2.2/
46
46
 
47
47
  ## Authentication
48
48
 
@@ -171,6 +171,13 @@ seclai agents def get <agentId>
171
171
  seclai agents def update <agentId> --json '{"steps":[...]}'
172
172
  ```
173
173
 
174
+ #### Agent Export
175
+
176
+ ```bash
177
+ seclai agents export <agentId>
178
+ seclai agents export <agentId> --no-download
179
+ ```
180
+
174
181
  #### Agent Input Upload
175
182
 
176
183
  ```bash
package/dist/cli.js CHANGED
@@ -131,6 +131,9 @@ async function run(rt, main) {
131
131
  rt.setExitCode(1);
132
132
  }
133
133
  }
134
+ function withJsonInputOptions(cmd) {
135
+ return cmd.option("--json <json>", "Inline JSON body. Use '-' to read from stdin.").option("--json-file <path>", "Path to JSON file. Use '-' to read from stdin.");
136
+ }
134
137
  function withFileUploadOptions(cmd) {
135
138
  return cmd.requiredOption("--file <path>", "Path to a local file to upload.").option("--title <title>", "Optional title.").option("--metadata <json>", "Metadata JSON object. Use '-' for stdin.").option("--metadata-file <path>", "Path to metadata JSON file. Use '-' for stdin.").option("--file-name <name>", "Override filename sent to API.").option("--mime-type <type>", "Explicit MIME type.");
136
139
  }
@@ -169,7 +172,7 @@ async function readAiInput(rt, opts) {
169
172
 
170
173
  // src/commands/agents.ts
171
174
  function register(program, rt) {
172
- const agents = program.command("agents").description("Manage agents, runs, definitions, and AI assistance.");
175
+ const agents = program.command("agents").description("Manage agents, runs, definitions, export, and AI assistance.");
173
176
  agents.command("list").description("List agents.").option("--page <n>", "Page number.", (v) => Number(v)).option("--limit <n>", "Page size.", (v) => Number(v)).action(async (opts) => {
174
177
  await run(rt, async () => {
175
178
  const client = createClient(program.opts());
@@ -302,6 +305,12 @@ function register(program, rt) {
302
305
  printJson(rt, await client.updateAgentDefinition(agentId, body));
303
306
  });
304
307
  });
308
+ agents.command("export").description("Export an agent definition as a portable JSON snapshot.").argument("<agentId>", "Agent ID.").option("--no-download", "Omit Content-Disposition header (inline response).").action(async (agentId, opts) => {
309
+ await run(rt, async () => {
310
+ const client = createClient(program.opts());
311
+ printJson(rt, await client.exportAgent(agentId, opts.download));
312
+ });
313
+ });
305
314
  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) => {
306
315
  await run(rt, async () => {
307
316
  const client = createClient(program.opts());
@@ -1035,7 +1044,23 @@ function register9(program, rt) {
1035
1044
 
1036
1045
  // src/commands/models.ts
1037
1046
  function register10(program, rt) {
1038
- const models = program.command("models").description("Model alerts and recommendations.");
1047
+ const models = program.command("models").description("Models, model alerts, recommendations, and playground experiments.");
1048
+ models.command("list").description("List models grouped by provider.").option("--provider <provider>", "Filter by provider name.").option("--supports-tool-use", "Only models that support tool use.").option("--supports-thinking", "Only models that support thinking.").action(async (opts) => {
1049
+ await run(rt, async () => {
1050
+ const client = createClient(program.opts());
1051
+ const o = {};
1052
+ if (opts.provider !== void 0) o.provider = opts.provider;
1053
+ if (opts.supportsToolUse !== void 0) o.supportsToolUse = opts.supportsToolUse;
1054
+ if (opts.supportsThinking !== void 0) o.supportsThinking = opts.supportsThinking;
1055
+ printJson(rt, await client.listModels(o));
1056
+ });
1057
+ });
1058
+ models.command("get").description("Get full details for a specific model.").argument("<modelId>", "Model ID.").action(async (modelId) => {
1059
+ await run(rt, async () => {
1060
+ const client = createClient(program.opts());
1061
+ printJson(rt, await client.getModel(modelId));
1062
+ });
1063
+ });
1039
1064
  const alerts = models.command("alerts").description("Model alerts.");
1040
1065
  alerts.command("list").description("List model alerts.").option("--page <n>", "Page number.", (v) => Number(v)).option("--limit <n>", "Page size.", (v) => Number(v)).action(async (opts) => {
1041
1066
  await run(rt, async () => {
@@ -1069,6 +1094,38 @@ function register10(program, rt) {
1069
1094
  printJson(rt, await client.getModelRecommendations(modelId));
1070
1095
  });
1071
1096
  });
1097
+ const experiments = models.command("experiments").description("Model playground experiments.");
1098
+ experiments.command("list").description("List model playground experiments.").option("--days <n>", "Filter to last N days.", (v) => Number(v)).option("--start-date <date>", "Start date (ISO 8601).").option("--end-date <date>", "End date (ISO 8601).").option("--limit <n>", "Page size.", (v) => Number(v)).option("--offset <n>", "Offset.", (v) => Number(v)).action(async (opts) => {
1099
+ await run(rt, async () => {
1100
+ const client = createClient(program.opts());
1101
+ const o = {};
1102
+ if (opts.days !== void 0) o.days = opts.days;
1103
+ if (opts.startDate !== void 0) o.startDate = opts.startDate;
1104
+ if (opts.endDate !== void 0) o.endDate = opts.endDate;
1105
+ if (opts.limit !== void 0) o.limit = opts.limit;
1106
+ if (opts.offset !== void 0) o.offset = opts.offset;
1107
+ printJson(rt, await client.listExperiments(o));
1108
+ });
1109
+ });
1110
+ withJsonInputOptions(experiments.command("create").description("Create a model playground experiment.")).action(async (opts) => {
1111
+ await run(rt, async () => {
1112
+ const client = createClient(program.opts());
1113
+ const body = await readJsonInput(rt, { json: opts.json, jsonFile: opts.jsonFile });
1114
+ printJson(rt, await client.createExperiment(body));
1115
+ });
1116
+ });
1117
+ experiments.command("get").description("Get a model playground experiment by ID.").argument("<experimentId>", "Experiment ID.").action(async (experimentId) => {
1118
+ await run(rt, async () => {
1119
+ const client = createClient(program.opts());
1120
+ printJson(rt, await client.getExperiment(experimentId));
1121
+ });
1122
+ });
1123
+ experiments.command("cancel").description("Cancel a running model playground experiment.").argument("<experimentId>", "Experiment ID.").action(async (experimentId) => {
1124
+ await run(rt, async () => {
1125
+ const client = createClient(program.opts());
1126
+ printJson(rt, await client.cancelExperiment(experimentId));
1127
+ });
1128
+ });
1072
1129
  }
1073
1130
 
1074
1131
  // src/commands/search.ts
@@ -1948,7 +2005,7 @@ _seclai_completions() {
1948
2005
  runs) COMPREPLY=( $(compgen -W "list get delete cancel search eval-results" -- "$cur") ); return ;;
1949
2006
  def) COMPREPLY=( $(compgen -W "get update" -- "$cur") ); return ;;
1950
2007
  ai) COMPREPLY=( $(compgen -W "gen-steps step-config history mark" -- "$cur") ); return ;;
1951
- *) COMPREPLY=( $(compgen -W "list create get update delete run runs def upload-input input-status ai" -- "$cur") ); return ;;
2008
+ *) COMPREPLY=( $(compgen -W "list create get update delete run runs def export upload-input input-status ai" -- "$cur") ); return ;;
1952
2009
  esac ;;
1953
2010
  sources|source)
1954
2011
  case "\${COMP_WORDS[2]}" in
@@ -2040,7 +2097,7 @@ _seclai() {
2040
2097
  args)
2041
2098
  case \${words[1]} in
2042
2099
  agents)
2043
- local -a sub=(list create get update delete run runs def upload-input input-status ai)
2100
+ local -a sub=(list create get update delete run runs def export upload-input input-status ai)
2044
2101
  _describe 'subcommand' sub ;;
2045
2102
  sources|source)
2046
2103
  local -a sub=(list create get update delete upload upload-text exports migration)
@@ -2110,7 +2167,7 @@ complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "mcp" -d "MCP
2110
2167
  complete -c seclai -n "not __fish_seen_subcommand_from $top" -f -a "completion" -d "Shell completions"
2111
2168
 
2112
2169
  # agents
2113
- complete -c seclai -n "__fish_seen_subcommand_from agents; and not __fish_seen_subcommand_from list create get update delete run runs def upload-input input-status ai" -f -a "list create get update delete run runs def upload-input input-status ai"
2170
+ complete -c seclai -n "__fish_seen_subcommand_from agents; and not __fish_seen_subcommand_from list create get update delete run runs def export upload-input input-status ai" -f -a "list create get update delete run runs def export upload-input input-status ai"
2114
2171
 
2115
2172
  # sources
2116
2173
  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"