@openbkn/bkn-sdk 0.1.1 → 0.1.3-rc.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
@@ -8,6 +8,7 @@ import {
8
8
  activePlatform,
9
9
  attachToken,
10
10
  changePasswordSafe,
11
+ classifyPath,
11
12
  createClient,
12
13
  credentialDeviceLogin,
13
14
  currentToken,
@@ -16,9 +17,11 @@ import {
16
17
  deletePlatform,
17
18
  deviceLogin,
18
19
  exportCreds,
20
+ filesUnder,
19
21
  formatError,
20
22
  getUserSafe,
21
23
  isHeadless,
24
+ lifecycleHint,
22
25
  listPlatforms,
23
26
  logout,
24
27
  openBrowser,
@@ -26,16 +29,19 @@ import {
26
29
  parsePkMap,
27
30
  rawCall,
28
31
  readPlatformConfig,
32
+ releaseLifecycleSessions,
29
33
  renderReportMarkdown,
34
+ renderTree,
30
35
  resolveContext,
31
36
  setActivePlatform,
32
37
  status,
33
38
  switchUser,
34
39
  toExitCode,
35
40
  use,
41
+ validateFixturePath,
36
42
  whoami,
37
43
  writePlatformConfig
38
- } from "./chunk-NC6DZ2AU.js";
44
+ } from "./chunk-PC2F54XD.js";
39
45
 
40
46
  // src/cli.ts
41
47
  import { Command as Command17 } from "commander";
@@ -43,12 +49,12 @@ import { Command as Command17 } from "commander";
43
49
  // package.json
44
50
  var package_default = {
45
51
  name: "@openbkn/bkn-sdk",
46
- version: "0.1.1",
52
+ version: "0.1.3-rc.1",
47
53
  description: "Unified TypeScript SDK + CLI for the BKN (Business Knowledge Network) platform.",
48
54
  type: "module",
49
55
  license: "Apache-2.0",
50
56
  engines: {
51
- node: ">=18"
57
+ node: ">=22.19.0"
52
58
  },
53
59
  bin: {
54
60
  openbkn: "./dist/cli.js"
@@ -78,6 +84,7 @@ var package_default = {
78
84
  lint: "npm run check:deps && biome check . && tsc --noEmit",
79
85
  format: "biome format --write .",
80
86
  test: "vitest run",
87
+ "test:e2e:trace-business": "npm run build && node test/e2e/bkn-trace-business-interaction.mjs",
81
88
  "test:cover": "vitest run --coverage",
82
89
  ci: "npm run lint && npm test",
83
90
  prepublishOnly: "npm run ci && npm run build"
@@ -87,9 +94,9 @@ var package_default = {
87
94
  chalk: "^5.4.1",
88
95
  commander: "^13.1.0",
89
96
  "csv-parse": "^6.2.1",
90
- "js-yaml": "^4.2.0",
97
+ "js-yaml": "^4.3.0",
91
98
  jszip: "^3.10.1",
92
- undici: "^8.7.0",
99
+ undici: "^8.9.0",
93
100
  zod: "^3.24.1"
94
101
  },
95
102
  devDependencies: {
@@ -174,10 +181,15 @@ function renderOrgTree(nodes, prefix = "") {
174
181
  // src/utils/output.ts
175
182
  function printJson(value, opts = {}) {
176
183
  if (opts.json || opts.compact) {
177
- process.stdout.write(`${JSON.stringify(value, null, opts.compact ? 0 : 2)}
184
+ const json = JSON.stringify(value === void 0 ? null : value, null, opts.compact ? 0 : 2);
185
+ process.stdout.write(`${json}
178
186
  `);
179
187
  return;
180
188
  }
189
+ if (value === void 0) {
190
+ process.stdout.write("(ok)\n");
191
+ return;
192
+ }
181
193
  const rows = toRows(value);
182
194
  if (rows) {
183
195
  const fullColumns = columnsOf(rows).filter((c) => rows.some((r) => stringifyCell(r[c]) !== ""));
@@ -248,8 +260,7 @@ var NOISE_COLS = /* @__PURE__ */ new Set([
248
260
  "status_message",
249
261
  "last_check_time",
250
262
  "last_discover_status",
251
- "health_check_result",
252
- "health_check_enabled"
263
+ "health_check_result"
253
264
  ]);
254
265
  var isNoiseCol = (c) => NOISE_COLS.has(c) || /_time$/.test(c);
255
266
  var isKeyCol = (c) => /^(id|name|key|title|label)$/i.test(c) || /_(id|name|key)$/i.test(c) || /^(status|state|type|category|mode|enabled|version|branch)$/i.test(c);
@@ -322,14 +333,25 @@ function promptLine(query, hidden = false) {
322
333
 
323
334
  // src/commands/_shared.ts
324
335
  import { readFileSync } from "fs";
336
+ function traceOptionsFrom(o) {
337
+ const conversationId = (typeof o.conversationId === "string" ? o.conversationId : void 0) ?? process.env.BKN_CONVERSATION_ID;
338
+ const interactionId = (typeof o.interactionId === "string" ? o.interactionId : void 0) ?? process.env.BKN_INTERACTION_ID;
339
+ if (!conversationId && !interactionId) return void 0;
340
+ return {
341
+ ...conversationId ? { conversationId } : {},
342
+ ...interactionId ? { interactionId } : {}
343
+ };
344
+ }
325
345
  function clientFrom(cmd) {
326
346
  const o = cmd.optsWithGlobals();
347
+ const trace = traceOptionsFrom(o);
327
348
  return createClient({
328
349
  baseUrl: o.baseUrl,
329
350
  token: o.token,
330
351
  user: o.user,
331
352
  businessDomain: o.bizDomain,
332
- insecure: o.insecure
353
+ insecure: o.insecure,
354
+ ...trace ? { trace } : {}
333
355
  });
334
356
  }
335
357
  function outputOptions(cmd) {
@@ -1349,9 +1371,6 @@ function bknCommand() {
1349
1371
  outputOptions(cmd)
1350
1372
  );
1351
1373
  });
1352
- objectType?.command("properties <kn-id> <ot-id>").description("Get an object type's calculated properties").action(async (knId, otId, _opts, cmd) => {
1353
- printJson(await clientFrom(cmd).kn.objectTypeProperties(knId, otId), outputOptions(cmd));
1354
- });
1355
1374
  bkn.command("create <name>").description("Create an (empty) knowledge network").option("--branch <b>", "branch", "main").action(async (name, opts, cmd) => {
1356
1375
  printJson(await clientFrom(cmd).kn.create({ name, branch: opts.branch }), outputOptions(cmd));
1357
1376
  });
@@ -1480,19 +1499,6 @@ function bknCommand() {
1480
1499
  sched.command("delete <kn-id> <schedule-ids>").description("Delete action schedule(s) (comma-joined ids)").action(async (knId, ids, _o, cmd) => {
1481
1500
  printJson(await clientFrom(cmd).kn.actionScheduleDelete(knId, ids), outputOptions(cmd));
1482
1501
  });
1483
- const job = bkn.command("job").description("Build jobs \u2014 list/get/tasks");
1484
- job.command("list <kn-id>").description("List jobs").action(async (knId, _o, cmd) => {
1485
- printJson(await clientFrom(cmd).kn.jobs(knId), outputOptions(cmd));
1486
- });
1487
- job.command("get <kn-id> <job-id>").description("Get a job").action(async (knId, jobId, _o, cmd) => {
1488
- printJson(await clientFrom(cmd).kn.job(knId, jobId), outputOptions(cmd));
1489
- });
1490
- job.command("tasks <kn-id> <job-id>").description("List a job's tasks").action(async (knId, jobId, _o, cmd) => {
1491
- printJson(await clientFrom(cmd).kn.jobTasks(knId, jobId), outputOptions(cmd));
1492
- });
1493
- job.command("delete <kn-id> <job-ids>").description("Delete job(s) (comma-joined ids)").action(async (knId, ids, _o, cmd) => {
1494
- printJson(await clientFrom(cmd).kn.jobDelete(knId, ids), outputOptions(cmd));
1495
- });
1496
1502
  bkn.command("push <directory>").description("Pack a BKN directory into a tar and import it as a knowledge network").option("--branch <name>", "target branch", "main").option("--build", "submit a Vega build task for each object type declaring a vector index").option(
1497
1503
  "--embedding-model <id>",
1498
1504
  "embedding model id for declared vector indexes (with --build)"
@@ -1584,12 +1590,14 @@ function callCommand() {
1584
1590
  []
1585
1591
  ).option("-v, --verbose", "print request line to stderr").action(async (url, opts, cmd2) => {
1586
1592
  const g = cmd2.optsWithGlobals();
1593
+ const trace = traceOptionsFrom(g);
1587
1594
  const ctx = resolveContext({
1588
1595
  baseUrl: g.baseUrl,
1589
1596
  token: g.token,
1590
1597
  user: g.user,
1591
1598
  businessDomain: g.bizDomain,
1592
- insecure: g.insecure
1599
+ insecure: g.insecure,
1600
+ ...trace ? { trace } : {}
1593
1601
  });
1594
1602
  const res = await rawCall(ctx, url, {
1595
1603
  method: opts.request,
@@ -1606,7 +1614,11 @@ function callCommand() {
1606
1614
  process.stdout.write(res.body.endsWith("\n") ? res.body : `${res.body}
1607
1615
  `);
1608
1616
  }
1609
- if (res.status >= 400) process.exitCode = 1;
1617
+ if (res.status >= 400) {
1618
+ const hint = lifecycleHint(res.body);
1619
+ if (hint) console.error(hint);
1620
+ process.exitCode = 1;
1621
+ }
1610
1622
  });
1611
1623
  return group(cmd, "AUTHENTICATION & CONFIG");
1612
1624
  }
@@ -1822,9 +1834,13 @@ function dataflowCommand() {
1822
1834
  cmd.command("list").description("List all dataflows").action(async (_opts, cmd2) => {
1823
1835
  printJson(await clientFrom(cmd2).dataflows.list(), outputOptions(cmd2));
1824
1836
  });
1825
- cmd.command("runs <dagId>").description("List run records for one dataflow").option("--since <date>", "filter runs since a date").action(async (dagId, opts, cmd2) => {
1837
+ cmd.command("runs <dagId>").description("List run records for one dataflow").option("--since <date>", "filter runs since a date").option("--limit <n>", "page size (backend default 20)", int6).option("--page <n>", "page (0-based; backend default 0)", int6).action(async (dagId, opts, cmd2) => {
1826
1838
  printJson(
1827
- await clientFrom(cmd2).dataflows.runs(dagId, { since: opts.since }),
1839
+ await clientFrom(cmd2).dataflows.runs(dagId, {
1840
+ since: opts.since,
1841
+ page: opts.page,
1842
+ limit: opts.limit
1843
+ }),
1828
1844
  outputOptions(cmd2)
1829
1845
  );
1830
1846
  });
@@ -1899,7 +1915,6 @@ var ROUTES = {
1899
1915
  }),
1900
1916
  "POST /api/bkn/instances": (c, _q, b) => c.kn.objectTypeQuery(str(b.knId), str(b.objectTypeId), b.body ?? {}),
1901
1917
  "POST /api/bkn/subgraph": (c, _q, b) => c.kn.subgraph(str(b.knId), b.body ?? b),
1902
- "POST /api/bkn/properties": (c, _q, b) => c.kn.objectTypeProperties(str(b.knId), str(b.objectTypeId)),
1903
1918
  "GET /api/vega/catalogs": (c) => c.vega.catalogs(),
1904
1919
  "GET /api/vega/catalog": (c, q) => c.vega.getCatalog(req(q, "catalogId")),
1905
1920
  "GET /api/vega/catalog-resources": (c, q) => c.vega.catalogResources(req(q, "catalogId"), q.get("category") ?? void 0),
@@ -2120,20 +2135,24 @@ function resourceCommand() {
2120
2135
  });
2121
2136
  printJson(data, outputOptions(cmd2));
2122
2137
  });
2123
- cmd.command("find").description("Search resources by name (fuzzy; --exact for strict)").requiredOption("--name <name>", "resource name to search").option("--exact", "exact name match").option("--catalog-id <id>", "limit to a catalog").option("--datasource-id <id>", "alias of --catalog-id").action(async (opts, cmd2) => {
2138
+ cmd.command("find").description("Search resources by name (fuzzy; --exact for strict)").requiredOption("--name <name>", "resource name to search").option("--exact", "exact name match").option("--catalog-id <id>", "limit to a catalog").option("--datasource-id <id>", "alias of --catalog-id").option("--limit <n>", "rows to scan before filtering", int9, DEFAULT_LIST_LIMIT).action(async (opts, cmd2) => {
2124
2139
  const data = await clientFrom(cmd2).resource.find(opts.name, {
2125
2140
  exact: opts.exact,
2126
- datasourceId: opts.catalogId ?? opts.datasourceId
2141
+ datasourceId: opts.catalogId ?? opts.datasourceId,
2142
+ limit: opts.limit
2127
2143
  });
2128
2144
  printJson(data, outputOptions(cmd2));
2129
2145
  });
2130
2146
  cmd.command("get <id>").description("Get resource details").action(async (id, _opts, cmd2) => {
2131
2147
  printJson(await clientFrom(cmd2).resource.get(id), outputOptions(cmd2));
2132
2148
  });
2133
- cmd.command("query <id>").description("Fetch data rows from a resource").option("--limit <n>", "row limit", int9, DEFAULT_QUERY_LIMIT).option("--offset <n>", "row offset", int9, 0).option("--need-total", "include total count").action(async (id, opts, cmd2) => {
2149
+ cmd.command("query <id>").description("Fetch data rows from a resource").option("--limit <n>", "row limit", int9, DEFAULT_QUERY_LIMIT).option("--offset <n>", "row offset", int9, 0).option("--paging-mode <mode>", "paging mode: single | cursor").option("--keep-alive-sec <s>", "cursor keep-alive in seconds (60\u20133600)", int9).option("--cursor <cursor>", "opaque cursor returned by the previous page").option("--need-total", "include total count").action(async (id, opts, cmd2) => {
2134
2150
  const data = await clientFrom(cmd2).resource.query(id, {
2135
2151
  limit: opts.limit,
2136
2152
  offset: opts.offset,
2153
+ pagingMode: opts.pagingMode,
2154
+ keepAliveSec: opts.keepAliveSec,
2155
+ cursor: opts.cursor,
2137
2156
  needTotal: opts.needTotal
2138
2157
  });
2139
2158
  printJson(data, outputOptions(cmd2));
@@ -2147,6 +2166,29 @@ function resourceCommand() {
2147
2166
  // src/commands/skill.ts
2148
2167
  import { Command as Command13 } from "commander";
2149
2168
  var int10 = (v) => Number.parseInt(v, 10);
2169
+ var positiveInt = (flag) => (v) => {
2170
+ if (!/^\d+$/.test(v)) {
2171
+ throw new InputError(`${flag} must be a positive integer (got '${v}')`);
2172
+ }
2173
+ const n = Number.parseInt(v, 10);
2174
+ if (!Number.isSafeInteger(n) || n <= 0) {
2175
+ throw new InputError(`${flag} must be a positive integer (got '${v}')`);
2176
+ }
2177
+ return n;
2178
+ };
2179
+ var MOCKED_EXIT_CODE = 125;
2180
+ function sandboxExitCode(result) {
2181
+ if (result?.mocked) return MOCKED_EXIT_CODE;
2182
+ const code = result?.exit_code ?? 0;
2183
+ if (!Number.isSafeInteger(code) || code < 0) return 1;
2184
+ return code > 255 ? 1 : code;
2185
+ }
2186
+ var SKILL_SOURCES = ["custom", "internal"];
2187
+ function checkSource(source) {
2188
+ if (source === void 0 || SKILL_SOURCES.includes(source)) return source;
2189
+ throw new InputError(`--source must be one of: ${SKILL_SOURCES.join(" | ")} (got '${source}')`);
2190
+ }
2191
+ var draftOption = (c) => c.option("--draft", "read the draft (management) version instead of the published one");
2150
2192
  function skillCommand() {
2151
2193
  const cmd = new Command13("skill").description("Skill registry and market");
2152
2194
  const listOpts = (c) => c.option("--name <s>", "filter by name").option("--source <s>", "filter by source").option("--status <s>", "filter by status").option("--limit <n>", "page size", int10, DEFAULT_LIST_LIMIT).option("--page <n>", "page", int10, 1);
@@ -2185,11 +2227,97 @@ function skillCommand() {
2185
2227
  cmd.command("delete <skill-id>").description("Delete a skill").action(async (id, _opts, cmd2) => {
2186
2228
  printJson(await clientFrom(cmd2).skills.delete(id), outputOptions(cmd2));
2187
2229
  });
2188
- cmd.command("content <skill-id>").description("Read a skill's SKILL.md content index").action(async (id, _opts, cmd2) => {
2189
- printJson(await clientFrom(cmd2).skills.content(id), outputOptions(cmd2));
2230
+ draftOption(cmd.command("content <skill-id>")).description("Read a skill's SKILL.md content index").option("--raw", "write SKILL.md's own text instead of the index JSON").action(async (id, opts, cmd2) => {
2231
+ const skills = clientFrom(cmd2).skills;
2232
+ if (opts.raw) {
2233
+ process.stdout.write(await skills.contentRaw(id, { draft: opts.draft }));
2234
+ return;
2235
+ }
2236
+ printJson(await skills.content(id, { draft: opts.draft }), outputOptions(cmd2));
2237
+ });
2238
+ draftOption(cmd.command("read-file <skill-id> <rel-path>")).description("Read a file inside a skill (progressive)").option("--raw", "write the file's own text instead of the response JSON").action(async (id, relPath, opts, cmd2) => {
2239
+ const skills = clientFrom(cmd2).skills;
2240
+ if (opts.raw) {
2241
+ process.stdout.write(await skills.readFileRaw(id, relPath, { draft: opts.draft }));
2242
+ return;
2243
+ }
2244
+ printJson(await skills.readFile(id, relPath, { draft: opts.draft }), outputOptions(cmd2));
2245
+ });
2246
+ draftOption(cmd.command("files <skill-id> [path]")).description("List a skill's files (one level; --tree for the whole hierarchy)").option("--tree", "render the full hierarchy instead of one level").action(async (id, path, opts, cmd2) => {
2247
+ const skills = clientFrom(cmd2).skills;
2248
+ const out = outputOptions(cmd2);
2249
+ if (opts.tree) {
2250
+ const all = await skills.fileManifest(id, { draft: opts.draft });
2251
+ if (path !== void 0) {
2252
+ const kind = classifyPath(all, path);
2253
+ if (kind === "file")
2254
+ throw new InputError(`'${path}' is a file \u2014 use \`skill read-file\`.`);
2255
+ if (kind === "missing") throw new InputError(`'${path}' not found in skill ${id}.`);
2256
+ }
2257
+ const files = filesUnder(all, path);
2258
+ const bytes = files.reduce((sum, f) => sum + (f.size ?? 0), 0);
2259
+ if (out.json || out.compact) {
2260
+ printJson(
2261
+ {
2262
+ skillId: id,
2263
+ path: path ?? "",
2264
+ files: files.map((f) => ({
2265
+ relPath: f.rel_path,
2266
+ fileType: f.file_type,
2267
+ size: f.size,
2268
+ mime: f.mime_type
2269
+ })),
2270
+ totalFiles: files.length,
2271
+ totalSize: bytes
2272
+ },
2273
+ out
2274
+ );
2275
+ return;
2276
+ }
2277
+ process.stdout.write(`${renderTree(files)}
2278
+
2279
+ ${files.length} files, ${bytes} B
2280
+ `);
2281
+ return;
2282
+ }
2283
+ const listing = await skills.files(id, path, { draft: opts.draft });
2284
+ if (out.json || out.compact) {
2285
+ printJson(listing, out);
2286
+ return;
2287
+ }
2288
+ printJson(
2289
+ listing.entries.map(
2290
+ (e) => e.type === "dir" ? { name: `${e.name}/`, type: "dir", size: e.size, mime: "" } : { name: e.name, type: e.fileType ?? "file", size: e.size, mime: e.mime ?? "" }
2291
+ ),
2292
+ out
2293
+ );
2294
+ process.stdout.write(
2295
+ `${listing.entries.length} entries here; ${listing.totalFiles} files, ${listing.totalSize} B below
2296
+ `
2297
+ );
2298
+ });
2299
+ cmd.command("names <ids...>").description("Resolve skill ids to names (unknown ids are skipped)").action(async (ids, _opts, cmd2) => {
2300
+ printJson(await clientFrom(cmd2).skills.names(ids), outputOptions(cmd2));
2190
2301
  });
2191
- cmd.command("read-file <skill-id> <rel-path>").description("Read a file inside a skill (progressive)").action(async (id, relPath, _opts, cmd2) => {
2192
- printJson(await clientFrom(cmd2).skills.readFile(id, relPath), outputOptions(cmd2));
2302
+ cmd.command("execute <skill-id>").description("Run a skill in the platform sandbox").requiredOption("--entry <shell>", "shell command to run inside the skill's work dir").option(
2303
+ "--timeout <seconds>",
2304
+ "sandbox time limit (the sandbox's own limit when omitted)",
2305
+ positiveInt("--timeout")
2306
+ ).option("--raw", "write the run's stdout/stderr straight through").option("--exit-code", "exit with the sandbox's exit code").action(async (id, opts, cmd2) => {
2307
+ const result = await clientFrom(cmd2).skills.execute(id, {
2308
+ entryShell: opts.entry,
2309
+ timeout: opts.timeout
2310
+ });
2311
+ if (result?.mocked) {
2312
+ process.stderr.write("warning: sandbox reported mocked=true \u2014 the skill did not run\n");
2313
+ }
2314
+ if (opts.raw) {
2315
+ if (result?.stdout) process.stdout.write(result.stdout);
2316
+ if (result?.stderr) process.stderr.write(result.stderr);
2317
+ } else {
2318
+ printJson(result, outputOptions(cmd2));
2319
+ }
2320
+ if (opts.exitCode) process.exitCode = sandboxExitCode(result);
2193
2321
  });
2194
2322
  cmd.command("history <skill-id>").description("Show a skill's version history").action(async (id, _opts, cmd2) => {
2195
2323
  printJson(await clientFrom(cmd2).skills.history(id), outputOptions(cmd2));
@@ -2200,15 +2328,21 @@ function skillCommand() {
2200
2328
  outputOptions(cmd2)
2201
2329
  );
2202
2330
  });
2203
- cmd.command("register <directory>").description("Zip a local skill directory and register it").option("--source <s>", "source tag").option("--extend-info <json>", "extra metadata as JSON").action(async (dir, opts, cmd2) => {
2331
+ cmd.command("register <directory>").description("Zip a local skill directory and register it").option("--source <s>", `source tag: ${SKILL_SOURCES.join(" | ")}`, "custom").option("--extend-info <json>", "extra metadata as JSON").action(async (dir, opts, cmd2) => {
2204
2332
  const extendInfo = opts.extendInfo ? JSON.parse(opts.extendInfo) : void 0;
2205
2333
  printJson(
2206
- await clientFrom(cmd2).skills.register(dir, { source: opts.source, extendInfo }),
2334
+ await clientFrom(cmd2).skills.register(dir, {
2335
+ source: checkSource(opts.source),
2336
+ extendInfo
2337
+ }),
2207
2338
  outputOptions(cmd2)
2208
2339
  );
2209
2340
  });
2210
- cmd.command("download <skill-id> [out-path]").description("Download a skill archive to a local .zip").action(async (skillId, outPath, _o, cmd2) => {
2211
- printJson(await clientFrom(cmd2).skills.download(skillId, outPath), outputOptions(cmd2));
2341
+ draftOption(cmd.command("download <skill-id> [out-path]")).description("Download a skill archive to a local .zip").action(async (skillId, outPath, opts, cmd2) => {
2342
+ printJson(
2343
+ await clientFrom(cmd2).skills.download(skillId, outPath, { draft: opts.draft }),
2344
+ outputOptions(cmd2)
2345
+ );
2212
2346
  });
2213
2347
  cmd.command("install <skill-id> [directory]").description("Download a skill archive and extract it locally").action(async (skillId, dir, _o, cmd2) => {
2214
2348
  printJson(await clientFrom(cmd2).skills.install(skillId, dir), outputOptions(cmd2));
@@ -2281,8 +2415,15 @@ function toolboxCommand() {
2281
2415
  }
2282
2416
  function toolCommand() {
2283
2417
  const cmd = new Command14("tool").description("Tools inside a toolbox");
2284
- cmd.command("list").description("List tools in a toolbox").requiredOption("--toolbox <box-id>", "toolbox id").action(async (opts, cmd2) => {
2285
- printJson(await clientFrom(cmd2).toolboxes.tools(opts.toolbox), outputOptions(cmd2));
2418
+ cmd.command("list").description("List tools in a toolbox").requiredOption("--toolbox <box-id>", "toolbox id").option("--limit <n>", "page size (backend default 10, max 100)", int11).option("--page <n>", "page (1-based; backend default 1)", int11).option("--all", "return every tool, ignoring page size").action(async (opts, cmd2) => {
2419
+ printJson(
2420
+ await clientFrom(cmd2).toolboxes.tools(opts.toolbox, {
2421
+ page: opts.page,
2422
+ pageSize: opts.limit,
2423
+ all: opts.all
2424
+ }),
2425
+ outputOptions(cmd2)
2426
+ );
2286
2427
  });
2287
2428
  cmd.command("enable <tool-ids...>").description("Enable one or more tools").requiredOption("--toolbox <box-id>", "toolbox id").action(async (toolIds, opts, cmd2) => {
2288
2429
  printJson(
@@ -2420,6 +2561,111 @@ function traceCommand() {
2420
2561
  const cmd = new Command15("trace").description(
2421
2562
  "BKN Trace \u2014 fetch spans, diagnose (symbolic + LLM rubric), scan, eval-set, schema validate"
2422
2563
  );
2564
+ cmd.command("graph <trace-id>").description("Fetch normalized trace graph by trace id").action(async (traceId, _opts, cmd2) => {
2565
+ printJson(await clientFrom(cmd2).trace.graph(traceId), outputOptions(cmd2));
2566
+ });
2567
+ const conversations = cmd.command("conversations").description("Manage Trace conversations");
2568
+ conversations.command("list").description("List conversations in the authorized owner scope").option("--limit <n>", "page size, 1..100", (value) => Number.parseInt(value, 10)).action(async (opts, cmd2) => {
2569
+ printJson(
2570
+ await clientFrom(cmd2).trace.lifecycle.listConversations({ limit: opts.limit }),
2571
+ outputOptions(cmd2)
2572
+ );
2573
+ });
2574
+ conversations.command("ensure-current <external-conversation-key>").description("Ensure the current Core-owned conversation generation").option("--one-shot", "create a one-shot conversation").option("--idempotency-key <key>", "stable idempotency key").action(async (externalConversationKey, opts, cmd2) => {
2575
+ printJson(
2576
+ await clientFrom(cmd2).trace.lifecycle.ensureConversation({
2577
+ external_conversation_key: externalConversationKey,
2578
+ idempotency_key: opts.idempotencyKey,
2579
+ one_shot: Boolean(opts.oneShot)
2580
+ }),
2581
+ outputOptions(cmd2)
2582
+ );
2583
+ });
2584
+ conversations.command("create-new-generation <external-conversation-key>").description("Create the next Core-owned conversation generation").requiredOption("--idempotency-key <key>", "stable idempotency key").action(async (externalConversationKey, opts, cmd2) => {
2585
+ printJson(
2586
+ await clientFrom(cmd2).trace.lifecycle.createNewConversationGeneration({
2587
+ external_conversation_key: externalConversationKey,
2588
+ idempotency_key: opts.idempotencyKey
2589
+ }),
2590
+ outputOptions(cmd2)
2591
+ );
2592
+ });
2593
+ conversations.command("resume <conversation-id>").description("Resume an existing authorized conversation").action(async (conversationId, _opts, cmd2) => {
2594
+ printJson(
2595
+ await clientFrom(cmd2).trace.lifecycle.resumeConversation({
2596
+ conversation_id: conversationId
2597
+ }),
2598
+ outputOptions(cmd2)
2599
+ );
2600
+ });
2601
+ conversations.command("get <conversation-id>").description("Get an authorized conversation").action(async (conversationId, _opts, cmd2) => {
2602
+ printJson(
2603
+ await clientFrom(cmd2).trace.lifecycle.getConversation(conversationId),
2604
+ outputOptions(cmd2)
2605
+ );
2606
+ });
2607
+ conversations.command("close <conversation-id>").description("Close an active conversation").option("--idempotency-key <key>", "stable idempotency key").action(async (conversationId, opts, cmd2) => {
2608
+ printJson(
2609
+ await clientFrom(cmd2).trace.lifecycle.closeConversation(conversationId, {
2610
+ idempotency_key: opts.idempotencyKey
2611
+ }),
2612
+ outputOptions(cmd2)
2613
+ );
2614
+ });
2615
+ const interactions = cmd.command("interactions").description("Inspect Trace interactions");
2616
+ interactions.command("start <conversation-id>").description("Start one managed interaction").requiredOption("--idempotency-key <key>", "stable idempotency key").option("--agent-name <name>", "conversation-level Agent display name").option(
2617
+ "--lease-seconds <n>",
2618
+ "interaction lease duration",
2619
+ (value) => Number.parseInt(value, 10)
2620
+ ).action(async (conversationId, opts, cmd2) => {
2621
+ printJson(
2622
+ await clientFrom(cmd2).trace.lifecycle.startInteraction(conversationId, {
2623
+ idempotency_key: opts.idempotencyKey,
2624
+ agent_name: opts.agentName,
2625
+ lease_seconds: opts.leaseSeconds
2626
+ }),
2627
+ outputOptions(cmd2)
2628
+ );
2629
+ });
2630
+ interactions.command("get <interaction-id>").description("Get an authorized interaction").action(async (interactionId, _opts, cmd2) => {
2631
+ printJson(
2632
+ await clientFrom(cmd2).trace.lifecycle.getInteraction(interactionId),
2633
+ outputOptions(cmd2)
2634
+ );
2635
+ });
2636
+ for (const action of ["complete", "fail", "cancel", "handoff"]) {
2637
+ interactions.command(`${action} <interaction-id>`).description(`${action} a managed interaction using a 3.0 completion manifest`).requiredOption("--body-file <path>", "read completion manifest JSON from a protected file").action(async (interactionId, opts, cmd2) => {
2638
+ const input = readBody(opts);
2639
+ const lifecycle = clientFrom(cmd2).trace.lifecycle;
2640
+ const terminal = {
2641
+ complete: lifecycle.completeInteraction,
2642
+ fail: lifecycle.failInteraction,
2643
+ cancel: lifecycle.cancelInteraction,
2644
+ handoff: lifecycle.handoffInteraction
2645
+ }[action];
2646
+ printJson(await terminal(interactionId, input), outputOptions(cmd2));
2647
+ });
2648
+ }
2649
+ const operations = cmd.command("operations").description("Inspect and retry operations");
2650
+ operations.command("get <operation-id>").description("Get an authorized operation").action(async (operationId, _opts, cmd2) => {
2651
+ printJson(
2652
+ await clientFrom(cmd2).trace.lifecycle.getOperation(operationId),
2653
+ outputOptions(cmd2)
2654
+ );
2655
+ });
2656
+ operations.command("retry <operation-id>").description("Create the next retry attempt for an eligible failed operation").requiredOption("--body-file <path>", "read retry request JSON from a protected file").action(async (operationId, opts, cmd2) => {
2657
+ printJson(
2658
+ await clientFrom(cmd2).trace.lifecycle.retryOperationAttempt(
2659
+ operationId,
2660
+ readBody(opts)
2661
+ ),
2662
+ outputOptions(cmd2)
2663
+ );
2664
+ });
2665
+ const receipts = cmd.command("receipts").description("Inspect durable operation receipts");
2666
+ receipts.command("get <receipt-id>").description("Get an authorized operation receipt").action(async (receiptId, _opts, cmd2) => {
2667
+ printJson(await clientFrom(cmd2).trace.lifecycle.getReceipt(receiptId), outputOptions(cmd2));
2668
+ });
2423
2669
  cmd.command("get <conversation-id>").description("Fetch all trace spans for a conversation").option("--max-spans <n>", "max spans", (v) => Number.parseInt(v, 10)).action(async (conversationId, opts, cmd2) => {
2424
2670
  printJson(
2425
2671
  await clientFrom(cmd2).trace.spans(conversationId, { maxSpans: opts.maxSpans }),
@@ -2471,12 +2717,60 @@ function traceCommand() {
2471
2717
  printJson(result, outputOptions(cmd2));
2472
2718
  if (!result.valid) process.exitCode = 1;
2473
2719
  });
2720
+ cmd.command("validate-fixture <path>").description("Validate BKN Trace 1.0/2.0/2.1 fixture JSON files").action(async (path, _opts, cmd2) => {
2721
+ const result = validateFixturePath(path);
2722
+ printJson(result, outputOptions(cmd2));
2723
+ if (!result.ok) process.exitCode = 1;
2724
+ });
2474
2725
  return group(cmd, "TRACE AI");
2475
2726
  }
2476
2727
 
2477
2728
  // src/commands/vega.ts
2478
2729
  import { Command as Command16 } from "commander";
2479
2730
  var int12 = (v) => Number.parseInt(v, 10);
2731
+ var bool = (value) => {
2732
+ if (value === "true") return true;
2733
+ if (value === "false") return false;
2734
+ throw new InputError("boolean value must be true or false");
2735
+ };
2736
+ var parseJsonObject = (value, flag) => {
2737
+ let parsed;
2738
+ try {
2739
+ parsed = JSON.parse(value);
2740
+ } catch {
2741
+ throw new InputError(`${flag} must be valid JSON`);
2742
+ }
2743
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
2744
+ throw new InputError(`${flag} must be a JSON object`);
2745
+ }
2746
+ return parsed;
2747
+ };
2748
+ var parseStringRecord = (value, flag) => {
2749
+ const parsed = parseJsonObject(value, flag);
2750
+ if (Object.values(parsed).some((item) => typeof item !== "string")) {
2751
+ throw new InputError(`${flag} values must be strings`);
2752
+ }
2753
+ return parsed;
2754
+ };
2755
+ var healthCheckSchedule = (mode, cronExpr) => {
2756
+ if (!mode) {
2757
+ if (cronExpr) throw new InputError("a health-check cron expression requires enabled mode");
2758
+ return void 0;
2759
+ }
2760
+ if (mode === "enabled") {
2761
+ if (!cronExpr) {
2762
+ throw new InputError("a health-check cron expression is required in enabled mode");
2763
+ }
2764
+ return { mode, cronExpr };
2765
+ }
2766
+ if (mode === "inherit" || mode === "disabled") {
2767
+ if (cronExpr) {
2768
+ throw new InputError("a health-check cron expression is only valid in enabled mode");
2769
+ }
2770
+ return { mode };
2771
+ }
2772
+ throw new InputError("health-check mode must be inherit, enabled, or disabled");
2773
+ };
2480
2774
  var parsePairs2 = (raw) => {
2481
2775
  if (!raw) return void 0;
2482
2776
  return raw.split(",").map((part) => {
@@ -2511,48 +2805,54 @@ function vegaCommand() {
2511
2805
  catalog.command("get <id>").description("Get a catalog by id").action(async (id, _opts, cmd) => {
2512
2806
  printJson(await clientFrom(cmd).vega.getCatalog(id), outputOptions(cmd));
2513
2807
  });
2514
- catalog.command("resources <id>").description("List resources under a catalog").option("--category <c>", "filter by category (e.g. table)").action(async (id, opts, cmd) => {
2515
- printJson(await clientFrom(cmd).vega.catalogResources(id, opts.category), outputOptions(cmd));
2808
+ catalog.command("resources <id>").description("List resources under a catalog").option("--category <c>", "filter by category (e.g. table)").option("--limit <n>", "page size (backend default 20, max 1000; -1 = all)", int12).option("--offset <n>", "page offset", int12, 0).action(async (id, opts, cmd) => {
2809
+ printJson(
2810
+ await clientFrom(cmd).vega.catalogResources(id, opts.category, opts.limit, opts.offset),
2811
+ outputOptions(cmd)
2812
+ );
2516
2813
  });
2517
- catalog.command("health <ids...>").description("Health-status for one or more catalogs").action(async (ids, _opts, cmd) => {
2518
- printJson(await clientFrom(cmd).vega.catalogHealth(ids), outputOptions(cmd));
2814
+ catalog.command("health <id>").description("Health-status for a catalog").action(async (id, _opts, cmd) => {
2815
+ printJson(await clientFrom(cmd).vega.catalogHealth(id), outputOptions(cmd));
2519
2816
  });
2520
- catalog.command("create").description("Create a catalog (data source)").requiredOption("--name <s>", "catalog name").requiredOption("--connector-type <s>", "connector type (e.g. mysql)").requiredOption("--connector-config <json>", "connector config JSON").option("--id <id>", "explicit catalog id").option("--tags <t1,t2>", "comma-separated tags").option("--description <s>", "description").option("--enabled", "create enabled (default: disabled)").option("--internal", "create an internal catalog").option("--extensions <json>", "extension key/value JSON object").action(async (opts, cmd) => {
2521
- let connectorConfig;
2522
- try {
2523
- connectorConfig = JSON.parse(opts.connectorConfig);
2524
- } catch {
2525
- throw new Error("--connector-config must be valid JSON");
2526
- }
2527
- const extensions = opts.extensions ? JSON.parse(opts.extensions) : void 0;
2817
+ catalog.command("create").description("Create a catalog (data source)").requiredOption("--name <s>", "catalog name").requiredOption("--connector-type <s>", "connector type (e.g. mysql)").requiredOption("--connector-config <json>", "connector config JSON").option("--id <id>", "explicit catalog id").option("--tags <t1,t2>", "comma-separated tags").option("--description <s>", "description").option("--enabled", "create enabled (default: disabled)").option("--internal", "create an internal catalog").option("--extensions <json>", "extension key/value JSON object").option("--allow-unhealthy", "save the catalog when its connection test fails").option("--health-check-mode <mode>", "health schedule: inherit | enabled | disabled").option("--health-check-cron <expr>", "cron expression for enabled health checks").action(async (opts, cmd) => {
2818
+ const connectorConfig = parseJsonObject(opts.connectorConfig, "--connector-config");
2819
+ const extensions = opts.extensions ? parseStringRecord(opts.extensions, "--extensions") : void 0;
2528
2820
  printJson(
2529
- await clientFrom(cmd).vega.createCatalog({
2530
- id: opts.id,
2531
- name: opts.name,
2532
- connectorType: opts.connectorType,
2533
- connectorConfig,
2534
- tags: opts.tags ? String(opts.tags).split(",").map((t) => t.trim()).filter(Boolean) : void 0,
2535
- description: opts.description,
2536
- enabled: opts.enabled ? true : void 0,
2537
- internal: opts.internal ? true : void 0,
2538
- extensions
2539
- }),
2821
+ await clientFrom(cmd).vega.createCatalog(
2822
+ {
2823
+ id: opts.id,
2824
+ name: opts.name,
2825
+ connectorType: opts.connectorType,
2826
+ connectorConfig,
2827
+ tags: opts.tags ? String(opts.tags).split(",").map((t) => t.trim()).filter(Boolean) : void 0,
2828
+ description: opts.description,
2829
+ enabled: opts.enabled ? true : void 0,
2830
+ internal: opts.internal ? true : void 0,
2831
+ extensions,
2832
+ healthCheckSchedule: healthCheckSchedule(opts.healthCheckMode, opts.healthCheckCron)
2833
+ },
2834
+ { allowUnhealthy: opts.allowUnhealthy ? true : void 0 }
2835
+ ),
2540
2836
  outputOptions(cmd)
2541
2837
  );
2542
2838
  });
2543
- catalog.command("update <id>").description("Update a catalog").option("--name <s>", "catalog name").option("--connector-type <s>", "connector type").option("--connector-config <json>", "connector config JSON").option("--tags <t1,t2>", "comma-separated tags").option("--description <s>", "description").option("--enabled <bool>", "enabled state").option("--extensions <json>", "extension key/value JSON object").action(async (id, opts, cmd) => {
2544
- const connectorConfig = opts.connectorConfig ? JSON.parse(opts.connectorConfig) : void 0;
2545
- const extensions = opts.extensions ? JSON.parse(opts.extensions) : void 0;
2839
+ catalog.command("update <id>").description("Fully update a catalog").requiredOption("--name <s>", "catalog name").requiredOption("--connector-type <s>", "connector type").requiredOption("--enabled <bool>", "current enabled state", bool).option("--connector-config <json>", "connector config JSON").option("--tags <t1,t2>", "comma-separated tags").option("--description <s>", "description").option("--extensions <json>", "extension key/value JSON object").option("--allow-unhealthy", "save the update when its connection test fails").action(async (id, opts, cmd) => {
2840
+ const connectorConfig = opts.connectorConfig ? parseJsonObject(opts.connectorConfig, "--connector-config") : void 0;
2841
+ const extensions = opts.extensions ? parseStringRecord(opts.extensions, "--extensions") : void 0;
2546
2842
  printJson(
2547
- await clientFrom(cmd).vega.updateCatalog(id, {
2548
- name: opts.name,
2549
- connectorType: opts.connectorType,
2550
- connectorConfig,
2551
- tags: opts.tags ? String(opts.tags).split(",").map((t) => t.trim()).filter(Boolean) : void 0,
2552
- description: opts.description,
2553
- enabled: opts.enabled === void 0 ? void 0 : opts.enabled === "true",
2554
- extensions
2555
- }),
2843
+ await clientFrom(cmd).vega.updateCatalog(
2844
+ id,
2845
+ {
2846
+ name: opts.name,
2847
+ connectorType: opts.connectorType,
2848
+ connectorConfig,
2849
+ tags: opts.tags ? String(opts.tags).split(",").map((t) => t.trim()).filter(Boolean) : void 0,
2850
+ description: opts.description,
2851
+ enabled: opts.enabled,
2852
+ extensions
2853
+ },
2854
+ { allowUnhealthy: opts.allowUnhealthy ? true : void 0 }
2855
+ ),
2556
2856
  outputOptions(cmd)
2557
2857
  );
2558
2858
  });
@@ -2568,6 +2868,26 @@ function vegaCommand() {
2568
2868
  catalog.command("test-connection <id>").description("Test a catalog connection").action(async (id, _opts, cmd) => {
2569
2869
  printJson(await clientFrom(cmd).vega.testCatalogConnection(id), outputOptions(cmd));
2570
2870
  });
2871
+ catalog.command("test-connection-config").description("Test an unpersisted catalog connection configuration").requiredOption("--connector-type <s>", "connector type").requiredOption("--connector-config <json>", "connector config JSON").action(async (opts, cmd) => {
2872
+ printJson(
2873
+ await clientFrom(cmd).vega.testCatalogConnectionConfig({
2874
+ connectorType: opts.connectorType,
2875
+ connectorConfig: parseJsonObject(opts.connectorConfig, "--connector-config")
2876
+ }),
2877
+ outputOptions(cmd)
2878
+ );
2879
+ });
2880
+ catalog.command("health-check-schedule <id>").description("Get a catalog health-check schedule").action(async (id, _opts, cmd) => {
2881
+ printJson(await clientFrom(cmd).vega.catalogHealthCheckSchedule(id), outputOptions(cmd));
2882
+ });
2883
+ catalog.command("set-health-check-schedule <id>").description("Update a catalog health-check schedule").requiredOption("--mode <mode>", "health schedule: inherit | enabled | disabled").option("--cron <expr>", "cron expression for enabled health checks").action(async (id, opts, cmd) => {
2884
+ const schedule = healthCheckSchedule(opts.mode, opts.cron);
2885
+ if (!schedule) throw new InputError("--mode is required");
2886
+ printJson(
2887
+ await clientFrom(cmd).vega.updateCatalogHealthCheckSchedule(id, schedule),
2888
+ outputOptions(cmd)
2889
+ );
2890
+ });
2571
2891
  catalog.command("discover <id>").description("Trigger catalog resource discovery").option("--wait", "wait for discovery to complete").action(async (id, opts, cmd) => {
2572
2892
  printJson(
2573
2893
  await clientFrom(cmd).vega.discoverCatalog(id, Boolean(opts.wait)),
@@ -2581,12 +2901,12 @@ function vegaCommand() {
2581
2901
  connector.command("get <type>").description("Get a connector type").action(async (type, _opts, cmd) => {
2582
2902
  printJson(await clientFrom(cmd).vega.connectorType(type), outputOptions(cmd));
2583
2903
  });
2584
- vega.command("sql").description("Run SQL / OpenSearch DSL directly against a vega-backend data source").requiredOption("--resource-type <type>", "source type (mysql | postgresql | opensearch | \u2026)").option("--query-type <type>", "query mode: standard | stream").option(
2904
+ vega.command("sql").description("Run SQL / OpenSearch DSL directly against a vega-backend data source").option(
2585
2905
  "--query <sql>",
2586
2906
  "SQL string; reference a resource with a {{<resource-id>}} placeholder"
2587
- ).option("--stream-size <n>", "streaming batch size (100\u201310000)", int12).option("--query-timeout <s>", "query timeout in seconds (1\u20133600)", int12).option(
2907
+ ).option("--input-dialect <dialect>", "SQL input dialect: postgres | mysql | trino | duckdb").option("--paging-mode <mode>", "paging mode: single | cursor").option("--limit <n>", "page size (cursor mode requires it)", int12).option("--offset <n>", "first-page offset", int12).option("--keep-alive-sec <s>", "cursor keep-alive in seconds (60\u20133600)", int12).option("--cursor <cursor>", "opaque cursor returned by the previous page").option("--need-total", "include the complete total count").option("--query-timeout-sec <s>", "query timeout in seconds (1\u20133600)", int12).option(
2588
2908
  "-d, --data <json>",
2589
- "full request body as JSON (advanced; wins over --query/--resource-type)"
2909
+ "full request body as JSON (advanced; wins over individual query flags)"
2590
2910
  ).action(async (opts, cmd) => {
2591
2911
  let body;
2592
2912
  if (opts.data) {
@@ -2595,16 +2915,34 @@ function vegaCommand() {
2595
2915
  } catch {
2596
2916
  throw new InputError("--data must be valid JSON");
2597
2917
  }
2918
+ } else if (opts.cursor) {
2919
+ if (opts.query || opts.inputDialect || opts.pagingMode || opts.limit !== void 0 || opts.offset !== void 0 || opts.keepAliveSec !== void 0 || opts.queryTimeoutSec !== void 0) {
2920
+ throw new InputError("--cursor cannot be combined with initial-query options");
2921
+ }
2922
+ body = {
2923
+ paging: { cursor: opts.cursor },
2924
+ ...opts.needTotal ? { need_total: true } : {}
2925
+ };
2598
2926
  } else {
2599
2927
  if (!opts.query) {
2600
- throw new InputError("Provide --query (and optionally --resource-type), or --data.");
2928
+ throw new InputError("Provide --query, --cursor, or --data.");
2929
+ }
2930
+ if (opts.pagingMode === "cursor" && opts.limit === void 0) {
2931
+ throw new InputError("--limit is required when --paging-mode cursor");
2601
2932
  }
2933
+ const paging = {
2934
+ ...opts.pagingMode ? { mode: opts.pagingMode } : {},
2935
+ ...opts.limit !== void 0 ? { limit: opts.limit } : {},
2936
+ ...opts.offset !== void 0 ? { offset: opts.offset } : {},
2937
+ ...opts.keepAliveSec !== void 0 ? { keep_alive_sec: opts.keepAliveSec } : {}
2938
+ };
2602
2939
  body = {
2603
2940
  query: opts.query,
2604
- resource_type: opts.resourceType,
2605
- ...opts.queryType ? { query_type: opts.queryType } : {},
2606
- ...opts.streamSize !== void 0 ? { stream_size: opts.streamSize } : {},
2607
- ...opts.queryTimeout !== void 0 ? { query_timeout: opts.queryTimeout } : {}
2941
+ query_format: "sql",
2942
+ ...opts.inputDialect ? { input_dialect: opts.inputDialect } : {},
2943
+ ...Object.keys(paging).length ? { paging } : {},
2944
+ ...opts.needTotal ? { need_total: true } : {},
2945
+ ...opts.queryTimeoutSec !== void 0 ? { query_timeout_sec: opts.queryTimeoutSec } : {}
2608
2946
  };
2609
2947
  }
2610
2948
  printJson(await clientFrom(cmd).vega.sql(body), outputOptions(cmd));
@@ -2665,11 +3003,16 @@ function vegaCommand() {
2665
3003
  );
2666
3004
  printJson(task, outputOptions(cmd));
2667
3005
  });
2668
- dataset.command("build-status <resource-id> <task-id>").description("Show a BuildTask's state and progress").action(async (_resourceId, taskId, _opts, cmd) => {
3006
+ dataset.command("build-status <task-id>").description("Show a BuildTask's state and progress").action(async (taskId, _opts, cmd) => {
2669
3007
  const task = await clientFrom(cmd).vega.buildStatus(taskId);
2670
3008
  printJson(task, outputOptions(cmd));
2671
3009
  });
2672
- dataset.command("build-list").description("List BuildTasks").option("--limit <n>", "page size", int12, DEFAULT_LIST_LIMIT).option("--offset <n>", "page offset", int12, 0).option("--resource-id <id>", "filter by resource id").option("--catalog-id <id>", "filter by catalog id").option("--status <status>", "comma-separated statuses").option("--active", "only running/init tasks").option("--mode <mode>", "filter by mode: batch | streaming").option("--order-by <field>", "default | created_at | updated_at | status | mode").option("--order <dir>", "asc | desc").action(async (opts, cmd) => {
3010
+ dataset.command("build-list").description("List BuildTasks").option("--limit <n>", "page size", int12, DEFAULT_LIST_LIMIT).option("--offset <n>", "page offset", int12, 0).option("--resource-id <id>", "filter by resource id").option("--catalog-id <id>", "filter by catalog id").option("--status <status>", "comma-separated statuses").option("--active", "only running/init tasks").option("--mode <mode>", "filter by mode: batch | streaming").option("--order-by <field>", "created_at | updated_at").option("--order <dir>", "asc | desc").action(async (opts, cmd) => {
3011
+ if (opts.orderBy === "default") {
3012
+ throw new InputError(
3013
+ '--order-by default is no longer supported; use "created_at" or "updated_at"'
3014
+ );
3015
+ }
2673
3016
  printJson(
2674
3017
  await clientFrom(cmd).vega.buildTasks({
2675
3018
  limit: opts.limit,
@@ -2685,7 +3028,7 @@ function vegaCommand() {
2685
3028
  outputOptions(cmd)
2686
3029
  );
2687
3030
  });
2688
- dataset.command("build-start <task-id>").description("Start a BuildTask").option("--reset", "restart from the beginning").action(async (taskId, opts, cmd) => {
3031
+ dataset.command("build-start <task-id>").description("Start a BuildTask").option("--reset", "restart a full task from the beginning (ignored for incremental tasks)").action(async (taskId, opts, cmd) => {
2689
3032
  printJson(
2690
3033
  await clientFrom(cmd).vega.startBuildTask(taskId, { reset: opts.reset }),
2691
3034
  outputOptions(cmd)
@@ -2708,7 +3051,7 @@ function vegaCommand() {
2708
3051
 
2709
3052
  // src/cli.ts
2710
3053
  var program = new Command17();
2711
- program.name("openbkn").description("Operate the BKN platform from the CLI").version(package_default.version, "-V, --version", "output the version number").option("--base-url <url>", "platform base URL (env: BKN_BASE_URL)").option("--token <value>", "access token (env: BKN_TOKEN)").option("--user <id|name>", "use specific user credentials (env: BKN_USER)").option("--json", "machine-readable JSON output").option("--compact", "single-line JSON output").option("--full", "human view: show all columns (default trims to the key ones)").option("--biz-domain <s>", "business domain (alias: -bd)").option("-k, --insecure", "skip TLS verification (dev / self-signed only)").showHelpAfterError();
3054
+ program.name("openbkn").description("Operate the BKN platform from the CLI").version(package_default.version, "-V, --version", "output the version number").option("--base-url <url>", "platform base URL (env: BKN_BASE_URL)").option("--token <value>", "access token (env: BKN_TOKEN)").option("--user <id|name>", "use specific user credentials (env: BKN_USER)").option("--json", "machine-readable JSON output").option("--compact", "single-line JSON output").option("--full", "human view: show all columns (default trims to the key ones)").option("--biz-domain <s>", "business domain (alias: -bd)").option("--conversation-id <id>", "BKN Trace conversation id (env: BKN_CONVERSATION_ID)").option("--interaction-id <id>", "BKN Trace interaction id (env: BKN_INTERACTION_ID)").option("-k, --insecure", "skip TLS verification (dev / self-signed only)").showHelpAfterError();
2712
3055
  program.addCommand(authCommand());
2713
3056
  program.addCommand(callCommand());
2714
3057
  program.addCommand(configCommand());
@@ -2732,6 +3075,8 @@ try {
2732
3075
  await program.parseAsync(argv);
2733
3076
  } catch (err) {
2734
3077
  console.error(formatError(err));
3078
+ await releaseLifecycleSessions();
2735
3079
  process.exit(toExitCode(err));
2736
3080
  }
3081
+ await releaseLifecycleSessions();
2737
3082
  //# sourceMappingURL=cli.js.map