@seclai/cli 1.0.4 → 1.0.6

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
@@ -14,7 +14,7 @@ npm i -g @seclai/cli
14
14
 
15
15
  Command reference (latest):
16
16
 
17
- https://seclai.github.io/seclai-cli/1.0.4/
17
+ https://seclai.github.io/seclai-cli/1.0.6/
18
18
 
19
19
  ## Authentication
20
20
 
@@ -45,6 +45,7 @@ Upload a file to a source connection:
45
45
  ```bash
46
46
  seclai sources upload 2b1f0f3a-1d2c-4b5a-8e9f-0a1b2c3d4e5f --file ./mydoc.pdf
47
47
  seclai sources upload 2b1f0f3a-1d2c-4b5a-8e9f-0a1b2c3d4e5f --file ./notes.txt --title "Notes" --mime-type text/plain
48
+ seclai sources upload 2b1f0f3a-1d2c-4b5a-8e9f-0a1b2c3d4e5f --file ./mydoc.pdf --metadata '{"category":"docs","author":"Ada"}'
48
49
  ```
49
50
 
50
51
  ### Agents
@@ -110,6 +111,14 @@ seclai contents embeddings a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d
110
111
  seclai contents embeddings a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d --page 1 --limit 20
111
112
  ```
112
113
 
114
+ Replace a content version by uploading a new file (keeps the same content version ID):
115
+
116
+ ```bash
117
+ seclai contents upload a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d --file ./updated.pdf
118
+ seclai contents upload a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d --file ./updated.pdf --metadata '{"revision":2}'
119
+ seclai contents replace a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d --file ./updated.pdf # alias
120
+ ```
121
+
113
122
  ## Development
114
123
 
115
124
  ### Base URL
package/dist/cli.js CHANGED
@@ -49,6 +49,13 @@ async function readJsonInput(rt, opts) {
49
49
  }
50
50
  throw new Error("Missing JSON input. Provide --json or --json-file.");
51
51
  }
52
+ async function readJsonObjectInput(rt, opts) {
53
+ const value = await readJsonInput(rt, opts);
54
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
55
+ throw new Error("Expected a JSON object.");
56
+ }
57
+ return value;
58
+ }
52
59
  function getCliVersion() {
53
60
  try {
54
61
  const packageJsonPath = new URL("../package.json", import.meta.url);
@@ -118,14 +125,42 @@ async function run(rt, main) {
118
125
  function createProgram(rt = defaultRuntime()) {
119
126
  const program = new Command();
120
127
  const cliVersion = getCliVersion();
121
- program.name("seclai").description(`Seclai Command Line Interface (v${cliVersion})`).version(cliVersion, "-V, --version", "output the version").option("--api-key <key>", "API key (defaults to SECLAI_API_KEY)");
128
+ program.name("seclai").description(
129
+ `Seclai Command Line Interface (v${cliVersion})
130
+
131
+ Use this CLI to interact with Seclai from scripts and CI: manage connected content sources, run agents, and inspect agent runs and indexed content.
132
+
133
+ All commands return JSON to stdout by default, which makes it easy to pipe into tools like jq.`
134
+ ).version(cliVersion, "-V, --version", "output the version").option(
135
+ "--api-key <key>",
136
+ "Seclai API key (defaults to SECLAI_API_KEY). You can create/manage keys in the Seclai dashboard (Settings \u2192 API Keys)."
137
+ );
138
+ program.addHelpText(
139
+ "after",
140
+ `
141
+ Environment:
142
+ SECLAI_API_KEY Default API key (alternative to --api-key)
143
+ SECLAI_API_URL Override API base URL (default: https://api.seclai.com). Intended for dev/staging.
144
+
145
+ Examples:
146
+ seclai sources list
147
+ seclai sources upload <sourceConnectionId> --file ./document.pdf --metadata '{"category":"docs"}'
148
+ seclai contents upload <sourceConnectionContentVersionId> --file ./updated.pdf
149
+ seclai agents run <agentId> --json '{"input":"Hello"}'
150
+ seclai agents run <agentId> --json-file - --stream --timeout-ms 60000 < run.json
151
+ `
152
+ );
122
153
  program.configureOutput({
123
154
  writeOut: (str) => rt.writeOut(str),
124
155
  writeErr: (str) => rt.writeErr(str)
125
156
  });
126
157
  program.exitOverride();
127
- const sources = program.command("sources").alias("source").description("Manage sources");
128
- sources.command("list").description("List sources").option("--page <n>", "Page number", (v) => Number(v)).option("--limit <n>", "Page size", (v) => Number(v)).option("--sort <field>", "Sort field").option("--order <asc|desc>", "Sort order").option("--account-id <id>", "Filter by account id").action(async (opts) => {
158
+ const sources = program.command("sources").alias("source").description(
159
+ "Manage content sources connected to Seclai.\n\nSources are how Seclai ingests content (e.g., websites, RSS feeds, document uploads) into a knowledge base so agents can retrieve and cite it."
160
+ );
161
+ sources.command("list").description(
162
+ "List sources available to your organization/account.\n\nUse this to discover source connections and their IDs before uploading documents or debugging indexing."
163
+ ).option("--page <n>", "Page number for pagination (1-based).", (v) => Number(v)).option("--limit <n>", "Page size (number of items to return).", (v) => Number(v)).option("--sort <field>", "Sort field (API-defined; commonly created_at or updated_at).").option("--order <asc|desc>", "Sort direction: asc or desc.").option("--account-id <id>", "Filter results to a specific account/organization id.").action(async (opts) => {
129
164
  await run(rt, async () => {
130
165
  const global = program.opts();
131
166
  const client = createClient(global);
@@ -139,34 +174,60 @@ function createProgram(rt = defaultRuntime()) {
139
174
  printJson(rt, res);
140
175
  });
141
176
  });
142
- sources.command("upload").description("Upload a file to a source connection").argument("<sourceConnectionId>", "Source connection id").requiredOption("--file <path>", "Path to local file").option("--title <title>", "Optional title").option("--file-name <name>", "Filename to send (defaults to basename)").option("--mime-type <type>", "MIME type").action(async (sourceConnectionId, opts) => {
177
+ sources.command("upload").description(
178
+ "Upload a local file to an existing source connection.\n\nThis is commonly used for document-upload sources inside a knowledge base. The uploaded file becomes indexed content that agents can retrieve from.\n\nNote: file size limits and supported MIME types are defined by the Seclai API (see the API reference for the upload endpoint)."
179
+ ).argument(
180
+ "<sourceConnectionId>",
181
+ "Source connection ID to upload into. You can find this in the Seclai dashboard or by listing sources."
182
+ ).requiredOption("--file <path>", "Path to a local file to upload.").option("--title <title>", "Optional human-readable title to associate with the uploaded content.").option(
183
+ "--metadata <json>",
184
+ `Optional metadata JSON object to attach to the upload (e.g. '{"category":"docs"}'). Use '-' to read JSON from stdin.`
185
+ ).option(
186
+ "--metadata-file <path>",
187
+ "Path to a JSON file containing a metadata object. Use '-' to read JSON from stdin."
188
+ ).option(
189
+ "--file-name <name>",
190
+ "Override the filename sent to the API (defaults to the basename of --file). Useful when uploading from temp paths."
191
+ ).option("--mime-type <type>", "Explicit MIME type (e.g., application/pdf, text/plain).").action(async (sourceConnectionId, opts) => {
143
192
  await run(rt, async () => {
144
193
  const global = program.opts();
145
194
  const client = createClient(global);
146
195
  const bytes = new Uint8Array(await readFile(opts.file));
147
196
  const uploadOpts = { file: bytes };
148
197
  if (opts.title !== void 0) uploadOpts.title = opts.title;
198
+ if (opts.metadata !== void 0 || opts.metadataFile !== void 0) {
199
+ uploadOpts.metadata = await readJsonObjectInput(rt, { json: opts.metadata, jsonFile: opts.metadataFile });
200
+ }
149
201
  if (opts.fileName !== void 0) uploadOpts.fileName = opts.fileName;
150
202
  if (opts.mimeType !== void 0) uploadOpts.mimeType = opts.mimeType;
151
203
  const res = await client.uploadFileToSource(sourceConnectionId, uploadOpts);
152
204
  printJson(rt, res);
153
205
  });
154
206
  });
155
- const agents = program.command("agents").description("Run agents and manage runs");
156
- agents.command("run").description("Run an agent").argument("<agentId>", "Agent id").option("--json <json>", "Request body JSON (string or '-')").option("--json-file <path>", "Request body JSON file path (or '-')").option("--stream", "Use streaming SSE endpoint and wait for completion").option("--timeout-ms <n>", "Client-side timeout in milliseconds", (v) => Number(v)).action(async (agentId, opts) => {
207
+ const agents = program.command("agents").description(
208
+ "Run agents and manage agent runs.\n\nAgents are workflows/assistants backed by your configured knowledge base and model settings. Running an agent creates a run, which you can inspect later for status, outputs, and (optionally) step-level details."
209
+ );
210
+ agents.command("run").description(
211
+ "Run an agent by ID and print the run result as JSON.\n\nThe request body is passed through to the Seclai API as-is (see the API docs for the specific agent/run schema).\n\nFor automation, prefer --json-file and pipe input via stdin (use '-' as the path)."
212
+ ).argument("<agentId>", "Agent ID to run (from the Seclai dashboard).").option("--json <json>", "Inline JSON request body. Use '-' to read JSON from stdin.").option("--json-file <path>", "Path to a JSON file containing the request body. Use '-' to read from stdin.").option(
213
+ "--stream",
214
+ "Wait for completion using the streaming (SSE) endpoint. The CLI prints the final result when the run is done."
215
+ ).option(
216
+ "--timeout-ms <n>",
217
+ "Client-side timeout (milliseconds) when using --stream. This controls how long the CLI waits; it does not change server-side execution limits.",
218
+ (v) => Number(v)
219
+ ).action(async (agentId, opts) => {
157
220
  await run(rt, async () => {
158
221
  const global = program.opts();
159
222
  const client = createClient(global);
160
223
  const body = await readJsonInput(rt, { json: opts.json, jsonFile: opts.jsonFile });
161
224
  let res;
162
225
  if (opts.stream) {
163
- const streamFn = client.runStreamingAgentAndWait;
164
- if (!streamFn) {
165
- throw new Error(
166
- "This version of @seclai/sdk does not support streaming agent runs yet. Upgrade @seclai/sdk to a version that includes runStreamingAgentAndWait."
167
- );
168
- }
169
- res = await streamFn(agentId, body, opts.timeoutMs !== void 0 ? { timeoutMs: opts.timeoutMs } : void 0);
226
+ res = await client.runStreamingAgentAndWait(
227
+ agentId,
228
+ body,
229
+ opts.timeoutMs !== void 0 ? { timeoutMs: opts.timeoutMs } : void 0
230
+ );
170
231
  } else {
171
232
  res = await client.runAgent(agentId, body);
172
233
  }
@@ -174,7 +235,9 @@ function createProgram(rt = defaultRuntime()) {
174
235
  });
175
236
  });
176
237
  const agentRuns = agents.command("runs").description("Manage agent runs");
177
- agentRuns.command("list").description("List runs for an agent").argument("<agentId>", "Agent id").option("--page <n>", "Page number", (v) => Number(v)).option("--limit <n>", "Page size", (v) => Number(v)).action(async (agentId, opts) => {
238
+ agentRuns.command("list").description(
239
+ "List runs for a specific agent.\n\nThis is useful for monitoring recent executions, checking statuses, and obtaining run IDs for follow-up commands."
240
+ ).argument("<agentId>", "Agent ID whose runs you want to list.").option("--page <n>", "Page number for pagination (1-based).", (v) => Number(v)).option("--limit <n>", "Page size (number of runs to return).", (v) => Number(v)).action(async (agentId, opts) => {
178
241
  await run(rt, async () => {
179
242
  const global = program.opts();
180
243
  const client = createClient(global);
@@ -182,7 +245,12 @@ function createProgram(rt = defaultRuntime()) {
182
245
  printJson(rt, res);
183
246
  });
184
247
  });
185
- agentRuns.command("get").description("Get a specific agent run").argument("<agentId>", "Agent id").argument("<runId>", "Run id").option("--include-step-outputs", "Include step outputs (may be omitted by default)").action(async (agentId, runId, opts) => {
248
+ agentRuns.command("get").description(
249
+ "Fetch a specific agent run and print it as JSON.\n\nUse this to inspect status, timestamps, and outputs. Optionally include step outputs for deeper debugging (may be large)."
250
+ ).argument("<runId>", "Run ID to retrieve.").option(
251
+ "--include-step-outputs",
252
+ "Include step-level outputs when available. This may increase response size and latency."
253
+ ).action(async (agentId, runId, opts) => {
186
254
  await run(rt, async () => {
187
255
  const global = program.opts();
188
256
  const client = createClient(global);
@@ -190,7 +258,9 @@ function createProgram(rt = defaultRuntime()) {
190
258
  printJson(rt, res);
191
259
  });
192
260
  });
193
- agentRuns.command("delete").description("Cancel/delete a specific agent run").argument("<agentId>", "Agent id").argument("<runId>", "Run id").action(async (agentId, runId) => {
261
+ agentRuns.command("delete").description(
262
+ "Cancel or delete a specific agent run by ID.\n\nIf a run is still in progress, this requests cancellation. If it has already completed, behavior depends on the API (it may delete or mark the run)."
263
+ ).argument("<runId>", "Run ID to cancel/delete.").action(async (runId) => {
194
264
  await run(rt, async () => {
195
265
  const global = program.opts();
196
266
  const client = createClient(global);
@@ -198,8 +268,15 @@ function createProgram(rt = defaultRuntime()) {
198
268
  printJson(rt, res);
199
269
  });
200
270
  });
201
- const runs = program.command("runs").alias("agent-runs").description("Manage agent runs by run id");
202
- runs.command("get").description("Get a specific agent run by run id").argument("<runId>", "Run id").option("--include-step-outputs", "Include step outputs (may be omitted by default)").action(async (runId, opts) => {
271
+ const runs = program.command("runs").alias("agent-runs").description(
272
+ "Manage agent runs by run ID (globally unique)."
273
+ );
274
+ runs.command("get").description(
275
+ "Fetch a specific agent run by run ID and print it as JSON.\n\nUse --include-step-outputs to include step-level details when available (may be large)."
276
+ ).argument("<runId>", "Run ID to retrieve.").option(
277
+ "--include-step-outputs",
278
+ "Include step-level outputs when available. This may increase response size and latency."
279
+ ).action(async (runId, opts) => {
203
280
  await run(rt, async () => {
204
281
  const global = program.opts();
205
282
  const client = createClient(global);
@@ -207,7 +284,9 @@ function createProgram(rt = defaultRuntime()) {
207
284
  printJson(rt, res);
208
285
  });
209
286
  });
210
- runs.command("delete").description("Cancel/delete a specific agent run by run id").argument("<runId>", "Run id").action(async (runId) => {
287
+ runs.command("delete").description(
288
+ "Cancel or delete a specific agent run by run ID.\n\nIf the run is in progress, this requests cancellation. If it is completed, behavior depends on the API (it may delete or mark the run)."
289
+ ).argument("<runId>", "Run ID to cancel/delete.").action(async (runId) => {
211
290
  await run(rt, async () => {
212
291
  const global = program.opts();
213
292
  const client = createClient(global);
@@ -215,8 +294,45 @@ function createProgram(rt = defaultRuntime()) {
215
294
  printJson(rt, res);
216
295
  });
217
296
  });
218
- const contents = program.command("contents").description("Inspect content and embeddings");
219
- contents.command("get").description("Get content detail").argument("<sourceConnectionContentVersion>", "Content version id").option("--start <n>", "Start offset", (v) => Number(v)).option("--end <n>", "End offset", (v) => Number(v)).action(async (sourceConnectionContentVersion, opts) => {
297
+ const contents = program.command("contents").description(
298
+ "Inspect indexed content and embeddings.\n\nWhen Seclai ingests data from sources into a knowledge base, it creates content versions and generates vector embeddings for retrieval. These commands help you debug what was indexed and what embeddings were produced."
299
+ );
300
+ contents.command("upload").alias("replace").description(
301
+ "Upload a local file to replace the underlying data for an existing content version.\n\nThis calls the content replace upload endpoint (/contents/{source_connection_content_version}/upload).\n\nUse this when you want to keep the same content version ID but update the file contents (e.g., new revision of a PDF)."
302
+ ).argument(
303
+ "<sourceConnectionContentVersion>",
304
+ "Content version ID to replace (from Seclai dashboard or API responses)."
305
+ ).requiredOption("--file <path>", "Path to a local file to upload.").option("--title <title>", "Optional title to associate with the uploaded content.").option(
306
+ "--metadata <json>",
307
+ `Optional metadata JSON object to attach to the upload (e.g. '{"revision":2}'). Use '-' to read JSON from stdin.`
308
+ ).option(
309
+ "--metadata-file <path>",
310
+ "Path to a JSON file containing a metadata object. Use '-' to read JSON from stdin."
311
+ ).option(
312
+ "--file-name <name>",
313
+ "Override the filename sent to the API (defaults to the basename of --file). Useful when uploading from temp paths."
314
+ ).option("--mime-type <type>", "Explicit MIME type (e.g., application/pdf, text/plain).").action(async (sourceConnectionContentVersion, opts) => {
315
+ await run(rt, async () => {
316
+ const global = program.opts();
317
+ const client = createClient(global);
318
+ const bytes = new Uint8Array(await readFile(opts.file));
319
+ const uploadOpts = { file: bytes };
320
+ if (opts.title !== void 0) uploadOpts.title = opts.title;
321
+ if (opts.metadata !== void 0 || opts.metadataFile !== void 0) {
322
+ uploadOpts.metadata = await readJsonObjectInput(rt, { json: opts.metadata, jsonFile: opts.metadataFile });
323
+ }
324
+ if (opts.fileName !== void 0) uploadOpts.fileName = opts.fileName;
325
+ if (opts.mimeType !== void 0) uploadOpts.mimeType = opts.mimeType;
326
+ const res = await client.uploadFileToContent(sourceConnectionContentVersion, uploadOpts);
327
+ printJson(rt, res);
328
+ });
329
+ });
330
+ contents.command("get").description(
331
+ "Get details for a specific content version.\n\nThis typically includes extracted text/metadata produced during indexing. Use --start/--end to fetch a slice of the text for faster inspection."
332
+ ).argument(
333
+ "<sourceConnectionContentVersion>",
334
+ "Content version ID to retrieve (from Seclai dashboard or API responses)."
335
+ ).option("--start <n>", "Start offset for returned text (0-based).", (v) => Number(v)).option("--end <n>", "End offset for returned text (exclusive).", (v) => Number(v)).action(async (sourceConnectionContentVersion, opts) => {
220
336
  await run(rt, async () => {
221
337
  const global = program.opts();
222
338
  const client = createClient(global);
@@ -227,7 +343,9 @@ function createProgram(rt = defaultRuntime()) {
227
343
  printJson(rt, res);
228
344
  });
229
345
  });
230
- contents.command("delete").description("Delete a content version").argument("<sourceConnectionContentVersion>", "Content version id").action(async (sourceConnectionContentVersion) => {
346
+ contents.command("delete").description(
347
+ "Delete a specific content version from Seclai.\n\nUse with care: removing a content version can affect retrieval results for agents that rely on the associated knowledge base."
348
+ ).argument("<sourceConnectionContentVersion>", "Content version ID to delete.").action(async (sourceConnectionContentVersion) => {
231
349
  await run(rt, async () => {
232
350
  const global = program.opts();
233
351
  const client = createClient(global);
@@ -235,7 +353,9 @@ function createProgram(rt = defaultRuntime()) {
235
353
  printJson(rt, { ok: true });
236
354
  });
237
355
  });
238
- contents.command("embeddings").description("List embeddings for a content version").argument("<sourceConnectionContentVersion>", "Content version id").option("--page <n>", "Page number", (v) => Number(v)).option("--limit <n>", "Page size", (v) => Number(v)).action(async (sourceConnectionContentVersion, opts) => {
356
+ contents.command("embeddings").description(
357
+ "List embeddings generated for a content version.\n\nEmbeddings power similarity search and retrieval for knowledge base agents. Listing them is useful for debugging indexing and verifying that content produced vectors."
358
+ ).argument("<sourceConnectionContentVersion>", "Content version ID whose embeddings you want to list.").option("--page <n>", "Page number for pagination (1-based).", (v) => Number(v)).option("--limit <n>", "Page size (number of embeddings to return).", (v) => Number(v)).action(async (sourceConnectionContentVersion, opts) => {
239
359
  await run(rt, async () => {
240
360
  const global = program.opts();
241
361
  const client = createClient(global);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFile } from \"node:fs/promises\";\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport process from \"node:process\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\n\nimport {\n Seclai,\n SeclaiAPIStatusError,\n SeclaiAPIValidationError,\n SeclaiConfigurationError,\n} from \"@seclai/sdk\";\n\ntype GlobalOptions = {\n apiKey?: string;\n};\n\nexport type CliRuntime = {\n stdin: NodeJS.ReadableStream;\n writeOut: (text: string) => void;\n writeErr: (text: string) => void;\n setExitCode: (code: number) => void;\n};\n\nfunction defaultRuntime(): CliRuntime {\n return {\n stdin: process.stdin,\n writeOut: (text) => {\n process.stdout.write(text);\n },\n writeErr: (text) => {\n process.stderr.write(text);\n },\n setExitCode: (code) => {\n process.exitCode = code;\n },\n };\n}\n\nasync function readStdinText(rt: CliRuntime): Promise<string> {\n return await new Promise((resolve, reject) => {\n let data = \"\";\n rt.stdin.setEncoding(\"utf8\");\n rt.stdin.on(\"data\", (chunk: string) => (data += chunk));\n rt.stdin.on(\"end\", () => resolve(data));\n rt.stdin.on(\"error\", reject);\n });\n}\n\nasync function readJsonInput(\n rt: CliRuntime,\n opts: {\n json?: string;\n jsonFile?: string;\n }\n): Promise<unknown> {\n if (opts.json !== undefined && opts.jsonFile !== undefined) {\n throw new Error(\"Provide only one of --json or --json-file\");\n }\n\n if (opts.jsonFile !== undefined) {\n const text =\n opts.jsonFile === \"-\" ? await readStdinText(rt) : await readFile(opts.jsonFile, \"utf8\");\n return JSON.parse(text);\n }\n\n if (opts.json !== undefined) {\n const text = opts.json === \"-\" ? await readStdinText(rt) : opts.json;\n return JSON.parse(text);\n }\n\n throw new Error(\"Missing JSON input. Provide --json or --json-file.\");\n}\n\nfunction getCliVersion(): string {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url);\n const raw = readFileSync(packageJsonPath, \"utf8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n return typeof parsed.version === \"string\" ? parsed.version : \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nfunction createClient(opts: GlobalOptions): Seclai {\n const seclaiOpts: { apiKey?: string; baseUrl?: string } = {};\n if (opts.apiKey !== undefined) seclaiOpts.apiKey = opts.apiKey;\n\n // Be explicit about the default API host. (The SDK also supports SECLAI_API_URL.)\n const envUrl = process.env.SECLAI_API_URL;\n seclaiOpts.baseUrl = envUrl && envUrl.length > 0 ? envUrl : \"https://api.seclai.com\";\n\n return new Seclai(seclaiOpts);\n}\n\nfunction printJson(rt: CliRuntime, value: unknown): void {\n rt.writeOut(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction printError(rt: CliRuntime, err: unknown): void {\n if (err instanceof SeclaiAPIValidationError) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n rt.writeErr(`status: ${err.statusCode}\\n`);\n rt.writeErr(`url: ${err.url}\\n`);\n if (err.responseText) rt.writeErr(`response: ${err.responseText}\\n`);\n if (err.validationError) printJson(rt, { validationError: err.validationError });\n return;\n }\n\n if (err instanceof SeclaiAPIStatusError) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n rt.writeErr(`status: ${err.statusCode}\\n`);\n rt.writeErr(`url: ${err.url}\\n`);\n if (err.responseText) rt.writeErr(`response: ${err.responseText}\\n`);\n return;\n }\n\n if (err instanceof SeclaiConfigurationError) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n return;\n }\n\n if (err instanceof Error) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n return;\n }\n\n rt.writeErr(String(err));\n rt.writeErr(\"\\n\");\n}\n\nasync function run(rt: CliRuntime, main: () => Promise<void>): Promise<void> {\n try {\n await main();\n } catch (err) {\n printError(rt, err);\n rt.setExitCode(1);\n }\n}\n\nexport function createProgram(rt: CliRuntime = defaultRuntime()): Command {\n const program = new Command();\n const cliVersion = getCliVersion();\n\n program\n .name(\"seclai\")\n .description(`Seclai Command Line Interface (v${cliVersion})`)\n .version(cliVersion, \"-V, --version\", \"output the version\")\n .option(\"--api-key <key>\", \"API key (defaults to SECLAI_API_KEY)\");\n\n program.configureOutput({\n writeOut: (str) => rt.writeOut(str),\n writeErr: (str) => rt.writeErr(str),\n });\n // Prevent commander from calling process.exit() (needed for testability)\n program.exitOverride();\n\n // sources\n const sources = program\n .command(\"sources\")\n .alias(\"source\")\n .description(\"Manage sources\");\n\nsources\n .command(\"list\")\n .description(\"List sources\")\n .option(\"--page <n>\", \"Page number\", (v) => Number(v))\n .option(\"--limit <n>\", \"Page size\", (v) => Number(v))\n .option(\"--sort <field>\", \"Sort field\")\n .option(\"--order <asc|desc>\", \"Sort order\")\n .option(\"--account-id <id>\", \"Filter by account id\")\n .action(async (opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.listSources({\n page: opts.page,\n limit: opts.limit,\n sort: opts.sort,\n order: opts.order,\n accountId: opts.accountId,\n });\n printJson(rt, res);\n });\n });\n\nsources\n .command(\"upload\")\n .description(\"Upload a file to a source connection\")\n .argument(\"<sourceConnectionId>\", \"Source connection id\")\n .requiredOption(\"--file <path>\", \"Path to local file\")\n .option(\"--title <title>\", \"Optional title\")\n .option(\"--file-name <name>\", \"Filename to send (defaults to basename)\")\n .option(\"--mime-type <type>\", \"MIME type\")\n .action(async (sourceConnectionId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n\n const bytes = new Uint8Array(await readFile(opts.file));\n\n const uploadOpts: {\n file: Uint8Array;\n title?: string;\n fileName?: string;\n mimeType?: string;\n } = { file: bytes };\n if (opts.title !== undefined) uploadOpts.title = opts.title;\n if (opts.fileName !== undefined) uploadOpts.fileName = opts.fileName;\n if (opts.mimeType !== undefined) uploadOpts.mimeType = opts.mimeType;\n\n const res = await client.uploadFileToSource(sourceConnectionId, uploadOpts);\n printJson(rt, res);\n });\n });\n\n// agents\nconst agents = program.command(\"agents\").description(\"Run agents and manage runs\");\n\nagents\n .command(\"run\")\n .description(\"Run an agent\")\n .argument(\"<agentId>\", \"Agent id\")\n .option(\"--json <json>\", \"Request body JSON (string or '-')\")\n .option(\"--json-file <path>\", \"Request body JSON file path (or '-')\")\n .option(\"--stream\", \"Use streaming SSE endpoint and wait for completion\")\n .option(\"--timeout-ms <n>\", \"Client-side timeout in milliseconds\", (v) => Number(v))\n .action(async (agentId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n\n const body = await readJsonInput(rt, { json: opts.json, jsonFile: opts.jsonFile });\n\n let res: unknown;\n if (opts.stream) {\n const streamFn = (client as any).runStreamingAgentAndWait as\n | undefined\n | ((agentId: string, body: unknown, opts?: { timeoutMs?: number }) => Promise<unknown>);\n if (!streamFn) {\n throw new Error(\n \"This version of @seclai/sdk does not support streaming agent runs yet. Upgrade @seclai/sdk to a version that includes runStreamingAgentAndWait.\"\n );\n }\n res = await streamFn(agentId, body, opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : undefined);\n } else {\n res = await client.runAgent(agentId, body as any);\n }\n printJson(rt, res);\n });\n });\n\nconst agentRuns = agents.command(\"runs\").description(\"Manage agent runs\");\n\nagentRuns\n .command(\"list\")\n .description(\"List runs for an agent\")\n .argument(\"<agentId>\", \"Agent id\")\n .option(\"--page <n>\", \"Page number\", (v) => Number(v))\n .option(\"--limit <n>\", \"Page size\", (v) => Number(v))\n .action(async (agentId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.listAgentRuns(agentId, { page: opts.page, limit: opts.limit });\n printJson(rt, res);\n });\n });\n\nagentRuns\n .command(\"get\")\n .description(\"Get a specific agent run\")\n .argument(\"<agentId>\", \"Agent id\")\n .argument(\"<runId>\", \"Run id\")\n .option(\"--include-step-outputs\", \"Include step outputs (may be omitted by default)\")\n .action(async (agentId: string, runId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n // Backward-compatible CLI: agentId is accepted but no longer required by the API.\n const res = await client.getAgentRun(runId, opts.includeStepOutputs ? { includeStepOutputs: true } : undefined);\n printJson(rt, res);\n });\n });\n\nagentRuns\n .command(\"delete\")\n .description(\"Cancel/delete a specific agent run\")\n .argument(\"<agentId>\", \"Agent id\")\n .argument(\"<runId>\", \"Run id\")\n .action(async (agentId: string, runId: string) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n // Backward-compatible CLI: agentId is accepted but no longer required by the API.\n const res = await client.deleteAgentRun(runId);\n printJson(rt, res);\n });\n });\n\n// runs (run id is globally unique)\nconst runs = program\n .command(\"runs\")\n .alias(\"agent-runs\")\n .description(\"Manage agent runs by run id\");\n\nruns\n .command(\"get\")\n .description(\"Get a specific agent run by run id\")\n .argument(\"<runId>\", \"Run id\")\n .option(\"--include-step-outputs\", \"Include step outputs (may be omitted by default)\")\n .action(async (runId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.getAgentRun(runId, opts.includeStepOutputs ? { includeStepOutputs: true } : undefined);\n printJson(rt, res);\n });\n });\n\nruns\n .command(\"delete\")\n .description(\"Cancel/delete a specific agent run by run id\")\n .argument(\"<runId>\", \"Run id\")\n .action(async (runId: string) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.deleteAgentRun(runId);\n printJson(rt, res);\n });\n });\n\n// contents\nconst contents = program.command(\"contents\").description(\"Inspect content and embeddings\");\n\ncontents\n .command(\"get\")\n .description(\"Get content detail\")\n .argument(\"<sourceConnectionContentVersion>\", \"Content version id\")\n .option(\"--start <n>\", \"Start offset\", (v) => Number(v))\n .option(\"--end <n>\", \"End offset\", (v) => Number(v))\n .action(async (sourceConnectionContentVersion: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.getContentDetail(sourceConnectionContentVersion, {\n start: opts.start,\n end: opts.end,\n });\n printJson(rt, res);\n });\n });\n\ncontents\n .command(\"delete\")\n .description(\"Delete a content version\")\n .argument(\"<sourceConnectionContentVersion>\", \"Content version id\")\n .action(async (sourceConnectionContentVersion: string) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n await client.deleteContent(sourceConnectionContentVersion);\n printJson(rt, { ok: true });\n });\n });\n\ncontents\n .command(\"embeddings\")\n .description(\"List embeddings for a content version\")\n .argument(\"<sourceConnectionContentVersion>\", \"Content version id\")\n .option(\"--page <n>\", \"Page number\", (v) => Number(v))\n .option(\"--limit <n>\", \"Page size\", (v) => Number(v))\n .action(async (sourceConnectionContentVersion: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.listContentEmbeddings(sourceConnectionContentVersion, {\n page: opts.page,\n limit: opts.limit,\n });\n printJson(rt, res);\n });\n });\n\n return program;\n}\n\nexport async function runCli(argv: string[], rt: CliRuntime = defaultRuntime()): Promise<number> {\n let observedExitCode = 0;\n const wrappedRt: CliRuntime = {\n ...rt,\n setExitCode: (code) => {\n observedExitCode = code;\n rt.setExitCode(code);\n },\n };\n\n const program = createProgram(wrappedRt);\n let exitCode = 0;\n\n try {\n await program.parseAsync(argv);\n } catch (err: any) {\n // commander throws a CommanderError on help/version/etc due to exitOverride()\n const maybeExitCode = typeof err?.exitCode === \"number\" ? err.exitCode : undefined;\n if (maybeExitCode !== undefined) {\n exitCode = maybeExitCode;\n } else {\n printError(wrappedRt, err);\n exitCode = 1;\n }\n }\n\n const finalExitCode = observedExitCode !== 0 ? observedExitCode : exitCode;\n wrappedRt.setExitCode(finalExitCode);\n return finalExitCode;\n}\n\n// Only run when executed as an entrypoint, not when imported (e.g. during tests).\nif (process.argv[1]) {\n // `process.argv[1]` can be a symlink (common with npm global installs).\n // Compare realpaths so the guard works reliably.\n try {\n const entryReal = realpathSync(process.argv[1]);\n const selfReal = realpathSync(fileURLToPath(import.meta.url));\n if (entryReal === selfReal) {\n await runCli(process.argv);\n }\n } catch {\n // Fall back to a URL comparison (best-effort).\n const entryHref = pathToFileURL(process.argv[1]).href;\n if (import.meta.url === entryHref) {\n await runCli(process.argv);\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFile } from \"node:fs/promises\";\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport process from \"node:process\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\n\nimport {\n Seclai,\n SeclaiAPIStatusError,\n SeclaiAPIValidationError,\n SeclaiConfigurationError,\n} from \"@seclai/sdk\";\n\ntype GlobalOptions = {\n apiKey?: string;\n};\n\nexport type CliRuntime = {\n stdin: NodeJS.ReadableStream;\n writeOut: (text: string) => void;\n writeErr: (text: string) => void;\n setExitCode: (code: number) => void;\n};\n\nfunction defaultRuntime(): CliRuntime {\n return {\n stdin: process.stdin,\n writeOut: (text) => {\n process.stdout.write(text);\n },\n writeErr: (text) => {\n process.stderr.write(text);\n },\n setExitCode: (code) => {\n process.exitCode = code;\n },\n };\n}\n\nasync function readStdinText(rt: CliRuntime): Promise<string> {\n return await new Promise((resolve, reject) => {\n let data = \"\";\n rt.stdin.setEncoding(\"utf8\");\n rt.stdin.on(\"data\", (chunk: string) => (data += chunk));\n rt.stdin.on(\"end\", () => resolve(data));\n rt.stdin.on(\"error\", reject);\n });\n}\n\nasync function readJsonInput(\n rt: CliRuntime,\n opts: {\n json?: string;\n jsonFile?: string;\n }\n): Promise<unknown> {\n if (opts.json !== undefined && opts.jsonFile !== undefined) {\n throw new Error(\"Provide only one of --json or --json-file\");\n }\n\n if (opts.jsonFile !== undefined) {\n const text =\n opts.jsonFile === \"-\" ? await readStdinText(rt) : await readFile(opts.jsonFile, \"utf8\");\n return JSON.parse(text);\n }\n\n if (opts.json !== undefined) {\n const text = opts.json === \"-\" ? await readStdinText(rt) : opts.json;\n return JSON.parse(text);\n }\n\n throw new Error(\"Missing JSON input. Provide --json or --json-file.\");\n}\n\nasync function readJsonObjectInput(\n rt: CliRuntime,\n opts: {\n json?: string;\n jsonFile?: string;\n }\n): Promise<Record<string, unknown>> {\n const value = await readJsonInput(rt, opts);\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(\"Expected a JSON object.\");\n }\n return value as Record<string, unknown>;\n}\n\nfunction getCliVersion(): string {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url);\n const raw = readFileSync(packageJsonPath, \"utf8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n return typeof parsed.version === \"string\" ? parsed.version : \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nfunction createClient(opts: GlobalOptions): Seclai {\n const seclaiOpts: { apiKey?: string; baseUrl?: string } = {};\n if (opts.apiKey !== undefined) seclaiOpts.apiKey = opts.apiKey;\n\n // Be explicit about the default API host. (The SDK also supports SECLAI_API_URL.)\n const envUrl = process.env.SECLAI_API_URL;\n seclaiOpts.baseUrl = envUrl && envUrl.length > 0 ? envUrl : \"https://api.seclai.com\";\n\n return new Seclai(seclaiOpts);\n}\n\nfunction printJson(rt: CliRuntime, value: unknown): void {\n rt.writeOut(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction printError(rt: CliRuntime, err: unknown): void {\n if (err instanceof SeclaiAPIValidationError) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n rt.writeErr(`status: ${err.statusCode}\\n`);\n rt.writeErr(`url: ${err.url}\\n`);\n if (err.responseText) rt.writeErr(`response: ${err.responseText}\\n`);\n if (err.validationError) printJson(rt, { validationError: err.validationError });\n return;\n }\n\n if (err instanceof SeclaiAPIStatusError) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n rt.writeErr(`status: ${err.statusCode}\\n`);\n rt.writeErr(`url: ${err.url}\\n`);\n if (err.responseText) rt.writeErr(`response: ${err.responseText}\\n`);\n return;\n }\n\n if (err instanceof SeclaiConfigurationError) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n return;\n }\n\n if (err instanceof Error) {\n rt.writeErr(`${err.name}: ${err.message}\\n`);\n return;\n }\n\n rt.writeErr(String(err));\n rt.writeErr(\"\\n\");\n}\n\nasync function run(rt: CliRuntime, main: () => Promise<void>): Promise<void> {\n try {\n await main();\n } catch (err) {\n printError(rt, err);\n rt.setExitCode(1);\n }\n}\n\nexport function createProgram(rt: CliRuntime = defaultRuntime()): Command {\n const program = new Command();\n const cliVersion = getCliVersion();\n\n program\n .name(\"seclai\")\n .description(\n `Seclai Command Line Interface (v${cliVersion})\\n\\n` +\n `Use this CLI to interact with Seclai from scripts and CI: manage connected content sources, run agents, and inspect agent runs and indexed content.\\n\\n` +\n `All commands return JSON to stdout by default, which makes it easy to pipe into tools like jq.`\n )\n .version(cliVersion, \"-V, --version\", \"output the version\")\n .option(\n \"--api-key <key>\",\n \"Seclai API key (defaults to SECLAI_API_KEY). You can create/manage keys in the Seclai dashboard (Settings → API Keys).\"\n );\n\n program.addHelpText(\n \"after\",\n `\\nEnvironment:\\n` +\n ` SECLAI_API_KEY Default API key (alternative to --api-key)\\n` +\n ` SECLAI_API_URL Override API base URL (default: https://api.seclai.com). Intended for dev/staging.\\n\\n` +\n `Examples:\\n` +\n ` seclai sources list\\n` +\n ` seclai sources upload <sourceConnectionId> --file ./document.pdf --metadata '{\"category\":\"docs\"}'\\n` +\n ` seclai contents upload <sourceConnectionContentVersionId> --file ./updated.pdf\\n` +\n ` seclai agents run <agentId> --json '{\"input\":\"Hello\"}'\\n` +\n ` seclai agents run <agentId> --json-file - --stream --timeout-ms 60000 < run.json\\n`\n );\n\n program.configureOutput({\n writeOut: (str) => rt.writeOut(str),\n writeErr: (str) => rt.writeErr(str),\n });\n // Prevent commander from calling process.exit() (needed for testability)\n program.exitOverride();\n\n // sources\n const sources = program\n .command(\"sources\")\n .alias(\"source\")\n .description(\n \"Manage content sources connected to Seclai.\\n\\n\" +\n \"Sources are how Seclai ingests content (e.g., websites, RSS feeds, document uploads) into a knowledge base so agents can retrieve and cite it.\"\n );\n\nsources\n .command(\"list\")\n .description(\n \"List sources available to your organization/account.\\n\\n\" +\n \"Use this to discover source connections and their IDs before uploading documents or debugging indexing.\"\n )\n .option(\"--page <n>\", \"Page number for pagination (1-based).\", (v) => Number(v))\n .option(\"--limit <n>\", \"Page size (number of items to return).\", (v) => Number(v))\n .option(\"--sort <field>\", \"Sort field (API-defined; commonly created_at or updated_at).\")\n .option(\"--order <asc|desc>\", \"Sort direction: asc or desc.\")\n .option(\"--account-id <id>\", \"Filter results to a specific account/organization id.\")\n .action(async (opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.listSources({\n page: opts.page,\n limit: opts.limit,\n sort: opts.sort,\n order: opts.order,\n accountId: opts.accountId,\n });\n printJson(rt, res);\n });\n });\n\nsources\n .command(\"upload\")\n .description(\n \"Upload a local file to an existing source connection.\\n\\n\" +\n \"This is commonly used for document-upload sources inside a knowledge base. The uploaded file becomes indexed content that agents can retrieve from.\\n\\n\" +\n \"Note: file size limits and supported MIME types are defined by the Seclai API (see the API reference for the upload endpoint).\"\n )\n .argument(\n \"<sourceConnectionId>\",\n \"Source connection ID to upload into. You can find this in the Seclai dashboard or by listing sources.\"\n )\n .requiredOption(\"--file <path>\", \"Path to a local file to upload.\")\n .option(\"--title <title>\", \"Optional human-readable title to associate with the uploaded content.\")\n .option(\n \"--metadata <json>\",\n \"Optional metadata JSON object to attach to the upload (e.g. '{\\\"category\\\":\\\"docs\\\"}'). Use '-' to read JSON from stdin.\"\n )\n .option(\n \"--metadata-file <path>\",\n \"Path to a JSON file containing a metadata object. Use '-' to read JSON from stdin.\"\n )\n .option(\n \"--file-name <name>\",\n \"Override the filename sent to the API (defaults to the basename of --file). Useful when uploading from temp paths.\"\n )\n .option(\"--mime-type <type>\", \"Explicit MIME type (e.g., application/pdf, text/plain).\")\n .action(async (sourceConnectionId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n\n const bytes = new Uint8Array(await readFile(opts.file));\n\n const uploadOpts: {\n file: Uint8Array;\n title?: string;\n metadata?: Record<string, unknown>;\n fileName?: string;\n mimeType?: string;\n } = { file: bytes };\n if (opts.title !== undefined) uploadOpts.title = opts.title;\n if (opts.metadata !== undefined || opts.metadataFile !== undefined) {\n uploadOpts.metadata = await readJsonObjectInput(rt, { json: opts.metadata, jsonFile: opts.metadataFile });\n }\n if (opts.fileName !== undefined) uploadOpts.fileName = opts.fileName;\n if (opts.mimeType !== undefined) uploadOpts.mimeType = opts.mimeType;\n\n const res = await client.uploadFileToSource(sourceConnectionId, uploadOpts);\n printJson(rt, res);\n });\n });\n\n// agents\nconst agents = program\n .command(\"agents\")\n .description(\n \"Run agents and manage agent runs.\\n\\n\" +\n \"Agents are workflows/assistants backed by your configured knowledge base and model settings. Running an agent creates a run, which you can inspect later for status, outputs, and (optionally) step-level details.\"\n );\n\nagents\n .command(\"run\")\n .description(\n \"Run an agent by ID and print the run result as JSON.\\n\\n\" +\n \"The request body is passed through to the Seclai API as-is (see the API docs for the specific agent/run schema).\\n\\n\" +\n \"For automation, prefer --json-file and pipe input via stdin (use '-' as the path).\"\n )\n .argument(\"<agentId>\", \"Agent ID to run (from the Seclai dashboard).\")\n .option(\"--json <json>\", \"Inline JSON request body. Use '-' to read JSON from stdin.\")\n .option(\"--json-file <path>\", \"Path to a JSON file containing the request body. Use '-' to read from stdin.\")\n .option(\n \"--stream\",\n \"Wait for completion using the streaming (SSE) endpoint. The CLI prints the final result when the run is done.\"\n )\n .option(\n \"--timeout-ms <n>\",\n \"Client-side timeout (milliseconds) when using --stream. This controls how long the CLI waits; it does not change server-side execution limits.\",\n (v) => Number(v)\n )\n .action(async (agentId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n\n const body = await readJsonInput(rt, { json: opts.json, jsonFile: opts.jsonFile });\n\n let res: unknown;\n if (opts.stream) {\n res = await client.runStreamingAgentAndWait(\n agentId,\n body as any,\n opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : undefined\n );\n } else {\n res = await client.runAgent(agentId, body as any);\n }\n printJson(rt, res);\n });\n });\n\nconst agentRuns = agents.command(\"runs\").description(\"Manage agent runs\");\n\nagentRuns\n .command(\"list\")\n .description(\n \"List runs for a specific agent.\\n\\n\" +\n \"This is useful for monitoring recent executions, checking statuses, and obtaining run IDs for follow-up commands.\"\n )\n .argument(\"<agentId>\", \"Agent ID whose runs you want to list.\")\n .option(\"--page <n>\", \"Page number for pagination (1-based).\", (v) => Number(v))\n .option(\"--limit <n>\", \"Page size (number of runs to return).\", (v) => Number(v))\n .action(async (agentId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.listAgentRuns(agentId, { page: opts.page, limit: opts.limit });\n printJson(rt, res);\n });\n });\n\nagentRuns\n .command(\"get\")\n .description(\n \"Fetch a specific agent run and print it as JSON.\\n\\n\" +\n \"Use this to inspect status, timestamps, and outputs. Optionally include step outputs for deeper debugging (may be large).\"\n )\n .argument(\"<runId>\", \"Run ID to retrieve.\")\n .option(\n \"--include-step-outputs\",\n \"Include step-level outputs when available. This may increase response size and latency.\"\n )\n .action(async (agentId: string, runId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.getAgentRun(runId, opts.includeStepOutputs ? { includeStepOutputs: true } : undefined);\n printJson(rt, res);\n });\n });\n\nagentRuns\n .command(\"delete\")\n .description(\n \"Cancel or delete a specific agent run by ID.\\n\\n\" +\n \"If a run is still in progress, this requests cancellation. If it has already completed, behavior depends on the API (it may delete or mark the run).\"\n )\n .argument(\"<runId>\", \"Run ID to cancel/delete.\")\n .action(async (runId: string) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.deleteAgentRun(runId);\n printJson(rt, res);\n });\n });\n\n// runs (run id is globally unique)\nconst runs = program\n .command(\"runs\")\n .alias(\"agent-runs\")\n .description(\n \"Manage agent runs by run ID (globally unique).\"\n );\n\nruns\n .command(\"get\")\n .description(\n \"Fetch a specific agent run by run ID and print it as JSON.\\n\\n\" +\n \"Use --include-step-outputs to include step-level details when available (may be large).\"\n )\n .argument(\"<runId>\", \"Run ID to retrieve.\")\n .option(\n \"--include-step-outputs\",\n \"Include step-level outputs when available. This may increase response size and latency.\"\n )\n .action(async (runId: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.getAgentRun(runId, opts.includeStepOutputs ? { includeStepOutputs: true } : undefined);\n printJson(rt, res);\n });\n });\n\nruns\n .command(\"delete\")\n .description(\n \"Cancel or delete a specific agent run by run ID.\\n\\n\" +\n \"If the run is in progress, this requests cancellation. If it is completed, behavior depends on the API (it may delete or mark the run).\"\n )\n .argument(\"<runId>\", \"Run ID to cancel/delete.\")\n .action(async (runId: string) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.deleteAgentRun(runId);\n printJson(rt, res);\n });\n });\n\n// contents\nconst contents = program\n .command(\"contents\")\n .description(\n \"Inspect indexed content and embeddings.\\n\\n\" +\n \"When Seclai ingests data from sources into a knowledge base, it creates content versions and generates vector embeddings for retrieval. These commands help you debug what was indexed and what embeddings were produced.\"\n );\n\ncontents\n .command(\"upload\")\n .alias(\"replace\")\n .description(\n \"Upload a local file to replace the underlying data for an existing content version.\\n\\n\" +\n \"This calls the content replace upload endpoint (/contents/{source_connection_content_version}/upload).\\n\\n\" +\n \"Use this when you want to keep the same content version ID but update the file contents (e.g., new revision of a PDF).\"\n )\n .argument(\n \"<sourceConnectionContentVersion>\",\n \"Content version ID to replace (from Seclai dashboard or API responses).\"\n )\n .requiredOption(\"--file <path>\", \"Path to a local file to upload.\")\n .option(\"--title <title>\", \"Optional title to associate with the uploaded content.\")\n .option(\n \"--metadata <json>\",\n \"Optional metadata JSON object to attach to the upload (e.g. '{\\\"revision\\\":2}'). Use '-' to read JSON from stdin.\"\n )\n .option(\n \"--metadata-file <path>\",\n \"Path to a JSON file containing a metadata object. Use '-' to read JSON from stdin.\"\n )\n .option(\n \"--file-name <name>\",\n \"Override the filename sent to the API (defaults to the basename of --file). Useful when uploading from temp paths.\"\n )\n .option(\"--mime-type <type>\", \"Explicit MIME type (e.g., application/pdf, text/plain).\")\n .action(async (sourceConnectionContentVersion: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n\n const bytes = new Uint8Array(await readFile(opts.file));\n\n const uploadOpts: {\n file: Uint8Array;\n title?: string;\n metadata?: Record<string, unknown>;\n fileName?: string;\n mimeType?: string;\n } = { file: bytes };\n\n if (opts.title !== undefined) uploadOpts.title = opts.title;\n if (opts.metadata !== undefined || opts.metadataFile !== undefined) {\n uploadOpts.metadata = await readJsonObjectInput(rt, { json: opts.metadata, jsonFile: opts.metadataFile });\n }\n if (opts.fileName !== undefined) uploadOpts.fileName = opts.fileName;\n if (opts.mimeType !== undefined) uploadOpts.mimeType = opts.mimeType;\n\n const res = await client.uploadFileToContent(sourceConnectionContentVersion, uploadOpts);\n printJson(rt, res);\n });\n });\n\ncontents\n .command(\"get\")\n .description(\n \"Get details for a specific content version.\\n\\n\" +\n \"This typically includes extracted text/metadata produced during indexing. Use --start/--end to fetch a slice of the text for faster inspection.\"\n )\n .argument(\n \"<sourceConnectionContentVersion>\",\n \"Content version ID to retrieve (from Seclai dashboard or API responses).\"\n )\n .option(\"--start <n>\", \"Start offset for returned text (0-based).\", (v) => Number(v))\n .option(\"--end <n>\", \"End offset for returned text (exclusive).\", (v) => Number(v))\n .action(async (sourceConnectionContentVersion: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.getContentDetail(sourceConnectionContentVersion, {\n start: opts.start,\n end: opts.end,\n });\n printJson(rt, res);\n });\n });\n\ncontents\n .command(\"delete\")\n .description(\n \"Delete a specific content version from Seclai.\\n\\n\" +\n \"Use with care: removing a content version can affect retrieval results for agents that rely on the associated knowledge base.\"\n )\n .argument(\"<sourceConnectionContentVersion>\", \"Content version ID to delete.\")\n .action(async (sourceConnectionContentVersion: string) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n await client.deleteContent(sourceConnectionContentVersion);\n printJson(rt, { ok: true });\n });\n });\n\ncontents\n .command(\"embeddings\")\n .description(\n \"List embeddings generated for a content version.\\n\\n\" +\n \"Embeddings power similarity search and retrieval for knowledge base agents. Listing them is useful for debugging indexing and verifying that content produced vectors.\"\n )\n .argument(\"<sourceConnectionContentVersion>\", \"Content version ID whose embeddings you want to list.\")\n .option(\"--page <n>\", \"Page number for pagination (1-based).\", (v) => Number(v))\n .option(\"--limit <n>\", \"Page size (number of embeddings to return).\", (v) => Number(v))\n .action(async (sourceConnectionContentVersion: string, opts) => {\n await run(rt, async () => {\n const global = program.opts<GlobalOptions>();\n const client = createClient(global);\n const res = await client.listContentEmbeddings(sourceConnectionContentVersion, {\n page: opts.page,\n limit: opts.limit,\n });\n printJson(rt, res);\n });\n });\n\n return program;\n}\n\nexport async function runCli(argv: string[], rt: CliRuntime = defaultRuntime()): Promise<number> {\n let observedExitCode = 0;\n const wrappedRt: CliRuntime = {\n ...rt,\n setExitCode: (code) => {\n observedExitCode = code;\n rt.setExitCode(code);\n },\n };\n\n const program = createProgram(wrappedRt);\n let exitCode = 0;\n\n try {\n await program.parseAsync(argv);\n } catch (err: any) {\n // commander throws a CommanderError on help/version/etc due to exitOverride()\n const maybeExitCode = typeof err?.exitCode === \"number\" ? err.exitCode : undefined;\n if (maybeExitCode !== undefined) {\n exitCode = maybeExitCode;\n } else {\n printError(wrappedRt, err);\n exitCode = 1;\n }\n }\n\n const finalExitCode = observedExitCode !== 0 ? observedExitCode : exitCode;\n wrappedRt.setExitCode(finalExitCode);\n return finalExitCode;\n}\n\n// Only run when executed as an entrypoint, not when imported (e.g. during tests).\nif (process.argv[1]) {\n // `process.argv[1]` can be a symlink (common with npm global installs).\n // Compare realpaths so the guard works reliably.\n try {\n const entryReal = realpathSync(process.argv[1]);\n const selfReal = realpathSync(fileURLToPath(import.meta.url));\n if (entryReal === selfReal) {\n await runCli(process.argv);\n }\n } catch {\n // Fall back to a URL comparison (best-effort).\n const entryHref = pathToFileURL(process.argv[1]).href;\n if (import.meta.url === entryHref) {\n await runCli(process.argv);\n }\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seclai/cli",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Seclai Command Line Interface",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "typecheck": "tsc -p tsconfig.json --noEmit"
27
27
  },
28
28
  "dependencies": {
29
- "@seclai/sdk": "^1.0.6",
29
+ "@seclai/sdk": "^1.0.7",
30
30
  "commander": "^13.1.0"
31
31
  },
32
32
  "devDependencies": {