@kweaver-ai/kweaver-sdk 0.4.2 → 0.4.5

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.
@@ -2,8 +2,8 @@ import { createInterface } from "node:readline";
2
2
  import { spawnSync } from "node:child_process";
3
3
  import { mkdirSync, readFileSync, readdirSync, statSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
- import { loadNetwork, allObjects, allRelations, allActions, generateChecksum } from "@kweaver-ai/bkn";
6
- import { ensureValidToken, formatHttpError } from "../auth/oauth.js";
5
+ import { loadNetwork, allObjects, allRelations, allActions, generateChecksum, validateNetwork } from "@kweaver-ai/bkn";
6
+ import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
7
7
  import { listKnowledgeNetworks, getKnowledgeNetwork, createKnowledgeNetwork, updateKnowledgeNetwork, deleteKnowledgeNetwork, listObjectTypes, listRelationTypes, listActionTypes, getObjectType, createObjectTypes, updateObjectType, deleteObjectTypes, getRelationType, createRelationTypes, updateRelationType, deleteRelationTypes, buildKnowledgeNetwork, getBuildStatus, } from "../api/knowledge-networks.js";
8
8
  import { objectTypeQuery, objectTypeProperties, subgraph, actionTypeQuery, actionTypeExecute, actionExecutionGet, actionLogsList, actionLogGet, actionLogCancel, } from "../api/ontology-query.js";
9
9
  import { semanticSearch } from "../api/semantic-search.js";
@@ -11,6 +11,7 @@ import { listTablesWithColumns } from "../api/datasources.js";
11
11
  import { createDataView } from "../api/dataviews.js";
12
12
  import { downloadBkn, uploadBkn } from "../api/bkn-backend.js";
13
13
  import { formatCallOutput } from "./call.js";
14
+ import { resolveBusinessDomain } from "../config/store.js";
14
15
  export function formatSimpleKnList(text, pretty, includeDetail = false) {
15
16
  const parsed = JSON.parse(text);
16
17
  const entries = Array.isArray(parsed.entries) ? parsed.entries : [];
@@ -27,7 +28,7 @@ export function parseKnListArgs(args) {
27
28
  let limit = 50;
28
29
  let sort = "update_time";
29
30
  let direction = "desc";
30
- let businessDomain = "bd_public";
31
+ let businessDomain = "";
31
32
  let detail = false;
32
33
  let pretty = true;
33
34
  let verbose = false;
@@ -98,13 +99,15 @@ export function parseKnListArgs(args) {
98
99
  }
99
100
  throw new Error(`Unsupported kn list argument: ${arg}`);
100
101
  }
102
+ if (!businessDomain)
103
+ businessDomain = resolveBusinessDomain();
101
104
  return { offset, limit, sort, direction, businessDomain, detail, pretty, verbose, name_pattern, tag };
102
105
  }
103
106
  export function parseKnGetArgs(args) {
104
107
  let knId = "";
105
108
  let stats = false;
106
109
  let exportMode = false;
107
- let businessDomain = "bd_public";
110
+ let businessDomain = "";
108
111
  let pretty = true;
109
112
  for (let i = 0; i < args.length; i += 1) {
110
113
  const arg = args[i];
@@ -140,6 +143,8 @@ export function parseKnGetArgs(args) {
140
143
  if (!knId) {
141
144
  throw new Error("Missing kn-id. Usage: kweaver bkn get <kn-id> [options]");
142
145
  }
146
+ if (!businessDomain)
147
+ businessDomain = resolveBusinessDomain();
143
148
  return { knId, stats, export: exportMode, businessDomain, pretty };
144
149
  }
145
150
  const BODY_FILE_FLAGS = [
@@ -155,7 +160,7 @@ export function parseKnCreateArgs(args) {
155
160
  let bodyFile;
156
161
  let import_mode;
157
162
  let validate_dependency;
158
- let businessDomain = "bd_public";
163
+ let businessDomain = "";
159
164
  let pretty = true;
160
165
  const flags = {};
161
166
  for (let i = 0; i < args.length; i += 1) {
@@ -233,12 +238,14 @@ export function parseKnCreateArgs(args) {
233
238
  payload.color = flags.color;
234
239
  body = JSON.stringify(payload);
235
240
  }
241
+ if (!businessDomain)
242
+ businessDomain = resolveBusinessDomain();
236
243
  return { body, import_mode, validate_dependency, businessDomain, pretty };
237
244
  }
238
245
  export function parseKnUpdateArgs(args) {
239
246
  let knId = "";
240
247
  let bodyFile;
241
- let businessDomain = "bd_public";
248
+ let businessDomain = "";
242
249
  let pretty = true;
243
250
  const flags = {};
244
251
  for (let i = 0; i < args.length; i += 1) {
@@ -308,11 +315,13 @@ export function parseKnUpdateArgs(args) {
308
315
  payload.color = flags.color;
309
316
  body = JSON.stringify(payload);
310
317
  }
318
+ if (!businessDomain)
319
+ businessDomain = resolveBusinessDomain();
311
320
  return { knId, body, businessDomain, pretty };
312
321
  }
313
322
  export function parseKnDeleteArgs(args) {
314
323
  let knId = "";
315
- let businessDomain = "bd_public";
324
+ let businessDomain = "";
316
325
  let yes = false;
317
326
  for (let i = 0; i < args.length; i += 1) {
318
327
  const arg = args[i];
@@ -340,12 +349,14 @@ export function parseKnDeleteArgs(args) {
340
349
  if (!knId) {
341
350
  throw new Error("Missing kn-id. Usage: kweaver bkn delete <kn-id>");
342
351
  }
352
+ if (!businessDomain)
353
+ businessDomain = resolveBusinessDomain();
343
354
  return { knId, businessDomain, yes };
344
355
  }
345
356
  export function parseKnPushArgs(args) {
346
357
  let directory = "";
347
358
  let branch = "main";
348
- let businessDomain = "bd_public";
359
+ let businessDomain = "";
349
360
  let pretty = true;
350
361
  for (let i = 0; i < args.length; i += 1) {
351
362
  const arg = args[i];
@@ -381,13 +392,15 @@ export function parseKnPushArgs(args) {
381
392
  if (!directory) {
382
393
  throw new Error("Missing directory. Usage: kweaver bkn push <directory> [--branch main] [-bd value]");
383
394
  }
395
+ if (!businessDomain)
396
+ businessDomain = resolveBusinessDomain();
384
397
  return { directory, branch, businessDomain, pretty };
385
398
  }
386
399
  export function parseKnPullArgs(args) {
387
400
  let knId = "";
388
401
  let directory = "";
389
402
  let branch = "main";
390
- let businessDomain = "bd_public";
403
+ let businessDomain = "";
391
404
  for (let i = 0; i < args.length; i += 1) {
392
405
  const arg = args[i];
393
406
  if (arg === "--help" || arg === "-h") {
@@ -426,6 +439,8 @@ export function parseKnPullArgs(args) {
426
439
  if (!knId) {
427
440
  throw new Error("Missing kn-id. Usage: kweaver bkn pull <kn-id> [<directory>] [--branch main] [-bd value]");
428
441
  }
442
+ if (!businessDomain)
443
+ businessDomain = resolveBusinessDomain();
429
444
  return { knId, directory: directory || knId, branch, businessDomain };
430
445
  }
431
446
  function parseJsonObject(text, errorMessage) {
@@ -456,7 +471,7 @@ function parseSearchAfterArray(text) {
456
471
  }
457
472
  export function parseKnObjectTypeQueryArgs(args) {
458
473
  let pretty = true;
459
- let businessDomain = "bd_public";
474
+ let businessDomain = "";
460
475
  let limit;
461
476
  let searchAfter;
462
477
  const positionalArgs = [];
@@ -515,6 +530,8 @@ export function parseKnObjectTypeQueryArgs(args) {
515
530
  if (typeof body.limit !== "number" || !Number.isFinite(body.limit) || body.limit < 1) {
516
531
  throw new Error("Missing limit. Provide it in body JSON or via --limit <n>.");
517
532
  }
533
+ if (!businessDomain)
534
+ businessDomain = resolveBusinessDomain();
518
535
  return {
519
536
  knId,
520
537
  otId,
@@ -533,6 +550,7 @@ Subcommands:
533
550
  update <kn-id> [options] Update a knowledge network
534
551
  delete <kn-id> Delete a knowledge network
535
552
  build <kn-id> [--wait|--no-wait] [--timeout n] Trigger full build
553
+ validate <directory> Validate a local BKN directory (no upload)
536
554
  push <directory> [--branch main] Upload BKN directory as tar
537
555
  pull <kn-id> [<directory>] [--branch main] Download BKN tar and extract
538
556
  export <kn-id> Export knowledge network (alias for get --export)
@@ -566,62 +584,61 @@ export async function runKnCommand(args) {
566
584
  console.log(KN_HELP);
567
585
  return 0;
568
586
  }
569
- if (subcommand === "list") {
570
- return runKnListCommand(rest);
571
- }
572
- if (subcommand === "get") {
573
- return runKnGetCommand(rest);
574
- }
575
- if (subcommand === "create") {
576
- return runKnCreateCommand(rest);
577
- }
578
- if (subcommand === "create-from-ds") {
579
- return runKnCreateFromDsCommand(rest);
580
- }
581
- if (subcommand === "update") {
582
- return runKnUpdateCommand(rest);
583
- }
584
- if (subcommand === "delete") {
585
- return runKnDeleteCommand(rest);
586
- }
587
- if (subcommand === "build") {
588
- return runKnBuildCommand(rest);
589
- }
590
- if (subcommand === "push") {
591
- return runKnPushCommand(rest);
592
- }
593
- if (subcommand === "pull") {
594
- return runKnPullCommand(rest);
595
- }
596
- if (subcommand === "export") {
597
- return runKnGetCommand([...(rest[0] ? [rest[0]] : []), "--export", ...rest.slice(1)]);
598
- }
599
- if (subcommand === "stats") {
600
- return runKnGetCommand([...(rest[0] ? [rest[0]] : []), "--stats", ...rest.slice(1)]);
601
- }
602
- if (subcommand === "search") {
603
- return runKnSearchCommand(rest);
604
- }
605
- if (subcommand === "object-type") {
606
- return runKnObjectTypeCommand(rest);
607
- }
608
- if (subcommand === "relation-type") {
609
- return runKnRelationTypeCommand(rest);
610
- }
611
- if (subcommand === "subgraph") {
612
- return runKnSubgraphCommand(rest);
613
- }
614
- if (subcommand === "action-type") {
615
- return runKnActionTypeCommand(rest);
616
- }
617
- if (subcommand === "action-execution") {
618
- return runKnActionExecutionCommand(rest);
587
+ const dispatch = () => {
588
+ if (subcommand === "list")
589
+ return runKnListCommand(rest);
590
+ if (subcommand === "get")
591
+ return runKnGetCommand(rest);
592
+ if (subcommand === "create")
593
+ return runKnCreateCommand(rest);
594
+ if (subcommand === "create-from-ds")
595
+ return runKnCreateFromDsCommand(rest);
596
+ if (subcommand === "update")
597
+ return runKnUpdateCommand(rest);
598
+ if (subcommand === "delete")
599
+ return runKnDeleteCommand(rest);
600
+ if (subcommand === "build")
601
+ return runKnBuildCommand(rest);
602
+ if (subcommand === "validate")
603
+ return runKnValidateCommand(rest);
604
+ if (subcommand === "push")
605
+ return runKnPushCommand(rest);
606
+ if (subcommand === "pull")
607
+ return runKnPullCommand(rest);
608
+ if (subcommand === "export")
609
+ return runKnGetCommand([...(rest[0] ? [rest[0]] : []), "--export", ...rest.slice(1)]);
610
+ if (subcommand === "stats")
611
+ return runKnGetCommand([...(rest[0] ? [rest[0]] : []), "--stats", ...rest.slice(1)]);
612
+ if (subcommand === "search")
613
+ return runKnSearchCommand(rest);
614
+ if (subcommand === "object-type")
615
+ return runKnObjectTypeCommand(rest);
616
+ if (subcommand === "relation-type")
617
+ return runKnRelationTypeCommand(rest);
618
+ if (subcommand === "subgraph")
619
+ return runKnSubgraphCommand(rest);
620
+ if (subcommand === "action-type")
621
+ return runKnActionTypeCommand(rest);
622
+ if (subcommand === "action-execution")
623
+ return runKnActionExecutionCommand(rest);
624
+ if (subcommand === "action-log")
625
+ return runKnActionLogCommand(rest);
626
+ return Promise.resolve(-1);
627
+ };
628
+ try {
629
+ return await with401RefreshRetry(async () => {
630
+ const code = await dispatch();
631
+ if (code === -1) {
632
+ console.error(`Unknown bkn subcommand: ${subcommand}`);
633
+ return 1;
634
+ }
635
+ return code;
636
+ });
619
637
  }
620
- if (subcommand === "action-log") {
621
- return runKnActionLogCommand(rest);
638
+ catch (error) {
639
+ console.error(formatHttpError(error));
640
+ return 1;
622
641
  }
623
- console.error(`Unknown bkn subcommand: ${subcommand}`);
624
- return 1;
625
642
  }
626
643
  /** Parse object-type create args: --name --dataview-id --primary-key --display-key [--property '<json>' ...] */
627
644
  function parseObjectTypeCreateArgs(args) {
@@ -629,7 +646,7 @@ function parseObjectTypeCreateArgs(args) {
629
646
  let dataviewId = "";
630
647
  let primaryKey = "";
631
648
  let displayKey = "";
632
- let businessDomain = "bd_public";
649
+ let businessDomain = "";
633
650
  let branch = "main";
634
651
  let pretty = true;
635
652
  const properties = [];
@@ -695,13 +712,15 @@ function parseObjectTypeCreateArgs(args) {
695
712
  }));
696
713
  }
697
714
  const body = JSON.stringify({ entries: [entry], branch });
715
+ if (!businessDomain)
716
+ businessDomain = resolveBusinessDomain();
698
717
  return { knId, body, businessDomain, branch, pretty };
699
718
  }
700
719
  /** Parse object-type update args: --name X [--display-key Y] */
701
720
  function parseObjectTypeUpdateArgs(args) {
702
721
  let name;
703
722
  let displayKey;
704
- let businessDomain = "bd_public";
723
+ let businessDomain = "";
705
724
  let pretty = true;
706
725
  const positional = [];
707
726
  for (let i = 0; i < args.length; i += 1) {
@@ -739,11 +758,13 @@ function parseObjectTypeUpdateArgs(args) {
739
758
  if (Object.keys(payload).length === 0) {
740
759
  throw new Error("No update fields. Use --name or --display-key.");
741
760
  }
761
+ if (!businessDomain)
762
+ businessDomain = resolveBusinessDomain();
742
763
  return { knId, otId, body: JSON.stringify(payload), businessDomain, pretty };
743
764
  }
744
765
  /** Parse object-type delete args: <kn-id> <ot-ids> [-y] */
745
766
  function parseObjectTypeDeleteArgs(args) {
746
- let businessDomain = "bd_public";
767
+ let businessDomain = "";
747
768
  let yes = false;
748
769
  const positional = [];
749
770
  for (let i = 0; i < args.length; i += 1) {
@@ -765,12 +786,14 @@ function parseObjectTypeDeleteArgs(args) {
765
786
  if (!knId || !otIds) {
766
787
  throw new Error("Usage: kweaver bkn object-type delete <kn-id> <ot-ids> [-y]");
767
788
  }
789
+ if (!businessDomain)
790
+ businessDomain = resolveBusinessDomain();
768
791
  return { knId, otIds, businessDomain, yes };
769
792
  }
770
793
  /** Parse common flags for ontology-query subcommands; returns { filteredArgs, pretty, businessDomain } */
771
794
  function parseOntologyQueryFlags(args) {
772
795
  let pretty = true;
773
- let businessDomain = "bd_public";
796
+ let businessDomain = "";
774
797
  const filteredArgs = [];
775
798
  for (let i = 0; i < args.length; i += 1) {
776
799
  const arg = args[i];
@@ -788,11 +811,13 @@ function parseOntologyQueryFlags(args) {
788
811
  }
789
812
  filteredArgs.push(arg);
790
813
  }
814
+ if (!businessDomain)
815
+ businessDomain = resolveBusinessDomain();
791
816
  return { filteredArgs, pretty, businessDomain };
792
817
  }
793
818
  export function parseKnActionTypeExecuteArgs(args) {
794
819
  let pretty = true;
795
- let businessDomain = "bd_public";
820
+ let businessDomain = "";
796
821
  let wait = true;
797
822
  let timeout = 300;
798
823
  const positional = [];
@@ -831,6 +856,8 @@ export function parseKnActionTypeExecuteArgs(args) {
831
856
  if (!knId || !atId || !body) {
832
857
  throw new Error("Missing kn-id, at-id, or body. Usage: kweaver bkn action-type execute <kn-id> <at-id> '<json>' [options]");
833
858
  }
859
+ if (!businessDomain)
860
+ businessDomain = resolveBusinessDomain();
834
861
  return {
835
862
  knId,
836
863
  atId,
@@ -1031,7 +1058,7 @@ function parseRelationTypeCreateArgs(args) {
1031
1058
  let name = "";
1032
1059
  let source = "";
1033
1060
  let target = "";
1034
- let businessDomain = "bd_public";
1061
+ let businessDomain = "";
1035
1062
  let branch = "main";
1036
1063
  let pretty = true;
1037
1064
  const mappings = [];
@@ -1091,12 +1118,14 @@ function parseRelationTypeCreateArgs(args) {
1091
1118
  })),
1092
1119
  };
1093
1120
  const body = JSON.stringify({ entries: [entry], branch });
1121
+ if (!businessDomain)
1122
+ businessDomain = resolveBusinessDomain();
1094
1123
  return { knId, body, businessDomain, branch, pretty };
1095
1124
  }
1096
1125
  /** Parse relation-type update args: [--name X] */
1097
1126
  function parseRelationTypeUpdateArgs(args) {
1098
1127
  let name;
1099
- let businessDomain = "bd_public";
1128
+ let businessDomain = "";
1100
1129
  let pretty = true;
1101
1130
  const positional = [];
1102
1131
  for (let i = 0; i < args.length; i += 1) {
@@ -1125,11 +1154,13 @@ function parseRelationTypeUpdateArgs(args) {
1125
1154
  if (name === undefined) {
1126
1155
  throw new Error("No update fields. Use --name.");
1127
1156
  }
1157
+ if (!businessDomain)
1158
+ businessDomain = resolveBusinessDomain();
1128
1159
  return { knId, rtId, body: JSON.stringify({ name }), businessDomain, pretty };
1129
1160
  }
1130
1161
  /** Parse relation-type delete args: <kn-id> <rt-ids> [-y] */
1131
1162
  function parseRelationTypeDeleteArgs(args) {
1132
- let businessDomain = "bd_public";
1163
+ let businessDomain = "";
1133
1164
  let yes = false;
1134
1165
  const positional = [];
1135
1166
  for (let i = 0; i < args.length; i += 1) {
@@ -1151,6 +1182,8 @@ function parseRelationTypeDeleteArgs(args) {
1151
1182
  if (!knId || !rtIds) {
1152
1183
  throw new Error("Usage: kweaver bkn relation-type delete <kn-id> <rt-ids> [-y]");
1153
1184
  }
1185
+ if (!businessDomain)
1186
+ businessDomain = resolveBusinessDomain();
1154
1187
  return { knId, rtIds, businessDomain, yes };
1155
1188
  }
1156
1189
  async function runKnRelationTypeCommand(args) {
@@ -1527,7 +1560,7 @@ Options for list: --limit, --need-total, --action-type-id, --status, --trigger-t
1527
1560
  return 0;
1528
1561
  }
1529
1562
  let pretty = true;
1530
- let businessDomain = "bd_public";
1563
+ let businessDomain = "";
1531
1564
  let limit;
1532
1565
  let needTotal;
1533
1566
  let actionTypeId;
@@ -1581,6 +1614,8 @@ Options for list: --limit, --need-total, --action-type-id, --status, --trigger-t
1581
1614
  }
1582
1615
  filteredArgs.push(arg);
1583
1616
  }
1617
+ if (!businessDomain)
1618
+ businessDomain = resolveBusinessDomain();
1584
1619
  try {
1585
1620
  const token = await ensureValidToken();
1586
1621
  const base = {
@@ -1820,7 +1855,7 @@ function parseKnCreateFromDsArgs(args) {
1820
1855
  let tablesStr = "";
1821
1856
  let build = true;
1822
1857
  let timeout = 300;
1823
- let businessDomain = "bd_public";
1858
+ let businessDomain = "";
1824
1859
  let pretty = true;
1825
1860
  for (let i = 0; i < args.length; i += 1) {
1826
1861
  const arg = args[i];
@@ -1864,6 +1899,8 @@ function parseKnCreateFromDsArgs(args) {
1864
1899
  if (!dsId || !name) {
1865
1900
  throw new Error("Usage: kweaver bkn create-from-ds <ds-id> --name X [options]");
1866
1901
  }
1902
+ if (!businessDomain)
1903
+ businessDomain = resolveBusinessDomain();
1867
1904
  return { dsId, name, tables, build, timeout, businessDomain, pretty };
1868
1905
  }
1869
1906
  async function runKnCreateFromDsCommand(args) {
@@ -2069,7 +2106,7 @@ export function parseKnBuildArgs(args) {
2069
2106
  let knId = "";
2070
2107
  let wait = true;
2071
2108
  let timeout = 300;
2072
- let businessDomain = "bd_public";
2109
+ let businessDomain = "";
2073
2110
  for (let i = 0; i < args.length; i += 1) {
2074
2111
  const arg = args[i];
2075
2112
  if (arg === "--help" || arg === "-h")
@@ -2101,6 +2138,8 @@ export function parseKnBuildArgs(args) {
2101
2138
  if (!knId) {
2102
2139
  throw new Error("Missing kn-id. Usage: kweaver bkn build <kn-id> [options]");
2103
2140
  }
2141
+ if (!businessDomain)
2142
+ businessDomain = resolveBusinessDomain();
2104
2143
  return { knId, wait, timeout, businessDomain };
2105
2144
  }
2106
2145
  async function runKnBuildCommand(args) {
@@ -2206,6 +2245,51 @@ Options:
2206
2245
  <directory> Output directory (default: <kn-id>)
2207
2246
  --branch <s> Branch name (default: main)
2208
2247
  -bd, --biz-domain Business domain (default: bd_public)`;
2248
+ async function runKnValidateCommand(args) {
2249
+ if (args.includes("--help") || args.includes("-h")) {
2250
+ console.log("Usage: kweaver bkn validate <directory>\n\nValidate a local BKN directory without uploading.");
2251
+ return 0;
2252
+ }
2253
+ const directory = args.find((a) => !a.startsWith("-"));
2254
+ if (!directory) {
2255
+ console.error("Missing directory. Usage: kweaver bkn validate <directory>");
2256
+ return 1;
2257
+ }
2258
+ const absDir = resolve(directory);
2259
+ try {
2260
+ const stat = statSync(absDir);
2261
+ if (!stat.isDirectory()) {
2262
+ console.error(`Not a directory: ${directory}`);
2263
+ return 1;
2264
+ }
2265
+ }
2266
+ catch (err) {
2267
+ if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
2268
+ console.error(`Directory not found: ${directory}`);
2269
+ return 1;
2270
+ }
2271
+ throw err;
2272
+ }
2273
+ try {
2274
+ const network = await loadNetwork(absDir);
2275
+ const result = validateNetwork(network);
2276
+ if (!result.ok) {
2277
+ for (const e of result.errors)
2278
+ console.error(` - ${e}`);
2279
+ console.error(`BKN validation failed: ${result.errors.length} error(s)`);
2280
+ return 1;
2281
+ }
2282
+ const objs = allObjects(network);
2283
+ const rels = allRelations(network);
2284
+ const acts = allActions(network);
2285
+ console.log(`Valid: ${objs.length} object types, ${rels.length} relation types, ${acts.length} action types`);
2286
+ return 0;
2287
+ }
2288
+ catch (error) {
2289
+ console.error(`BKN validation failed: ${error instanceof Error ? error.message : String(error)}`);
2290
+ return 1;
2291
+ }
2292
+ }
2209
2293
  async function runKnPushCommand(args) {
2210
2294
  let options;
2211
2295
  try {
@@ -2320,7 +2404,7 @@ export function parseKnSearchArgs(args) {
2320
2404
  let maxConcepts = 10;
2321
2405
  let mode = "keyword_vector_retrieval";
2322
2406
  let pretty = false;
2323
- let businessDomain = process.env.KWEAVER_BUSINESS_DOMAIN ?? "bd_public";
2407
+ let businessDomain = process.env.KWEAVER_BUSINESS_DOMAIN ?? "";
2324
2408
  const positional = [];
2325
2409
  for (let i = 0; i < args.length; i++) {
2326
2410
  const arg = args[i];
@@ -2351,6 +2435,8 @@ export function parseKnSearchArgs(args) {
2351
2435
  if (!knId || !query) {
2352
2436
  throw new Error("Usage: kweaver bkn search <kn-id> <query> [options]");
2353
2437
  }
2438
+ if (!businessDomain)
2439
+ businessDomain = resolveBusinessDomain();
2354
2440
  return { knId, query, maxConcepts, mode, pretty, businessDomain };
2355
2441
  }
2356
2442
  async function runKnSearchCommand(args) {
@@ -1,5 +1,6 @@
1
- import { ensureValidToken, formatHttpError } from "../auth/oauth.js";
1
+ import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
2
2
  import { HttpError } from "../utils/http.js";
3
+ import { resolveBusinessDomain } from "../config/store.js";
3
4
  export function parseCallArgs(args) {
4
5
  const headers = new Headers();
5
6
  let method = "GET";
@@ -7,7 +8,7 @@ export function parseCallArgs(args) {
7
8
  let url;
8
9
  let pretty = true;
9
10
  let verbose = false;
10
- let businessDomain = "bd_public";
11
+ let businessDomain = "";
11
12
  for (let index = 0; index < args.length; index += 1) {
12
13
  const arg = args[index];
13
14
  if (arg === "-X" || arg === "--request") {
@@ -68,6 +69,8 @@ export function parseCallArgs(args) {
68
69
  if (!url) {
69
70
  throw new Error("Missing request URL");
70
71
  }
72
+ if (!businessDomain)
73
+ businessDomain = resolveBusinessDomain();
71
74
  return { url, method, headers, body, pretty, verbose, businessDomain };
72
75
  }
73
76
  function injectAuthHeaders(headers, accessToken, businessDomain) {
@@ -136,21 +139,22 @@ Options:
136
139
  console.error(formatHttpError(error));
137
140
  return 1;
138
141
  }
139
- try {
142
+ const execute = async () => {
140
143
  const token = await ensureValidToken();
141
144
  // Prepend baseUrl when the URL is a relative path (no scheme)
142
- if (invocation.url.startsWith("/")) {
143
- invocation.url = token.baseUrl.replace(/\/+$/, "") + invocation.url;
144
- }
145
- injectAuthHeaders(invocation.headers, token.accessToken, invocation.businessDomain);
145
+ const url = invocation.url.startsWith("/")
146
+ ? token.baseUrl.replace(/\/+$/, "") + invocation.url
147
+ : invocation.url;
148
+ const headers = new Headers(invocation.headers);
149
+ injectAuthHeaders(headers, token.accessToken, invocation.businessDomain);
146
150
  if (invocation.verbose) {
147
- for (const line of formatVerboseRequest(invocation)) {
151
+ for (const line of formatVerboseRequest({ ...invocation, url, headers })) {
148
152
  console.error(line);
149
153
  }
150
154
  }
151
- const response = await fetch(invocation.url, {
155
+ const response = await fetch(url, {
152
156
  method: invocation.method,
153
- headers: invocation.headers,
157
+ headers,
154
158
  body: invocation.body,
155
159
  });
156
160
  const rawText = await response.text();
@@ -162,6 +166,9 @@ Options:
162
166
  console.log(formatCallOutput(text, invocation.pretty));
163
167
  }
164
168
  return 0;
169
+ };
170
+ try {
171
+ return await with401RefreshRetry(async () => execute());
165
172
  }
166
173
  catch (error) {
167
174
  console.error(formatHttpError(error));
@@ -0,0 +1 @@
1
+ export declare function runConfigCommand(args: string[]): Promise<number>;
@@ -0,0 +1,52 @@
1
+ import { getCurrentPlatform, resolveBusinessDomain, savePlatformBusinessDomain, loadPlatformBusinessDomain, } from "../config/store.js";
2
+ const HELP = `kweaver config
3
+
4
+ Subcommands:
5
+ set-bd <value> Set the default business domain for the current platform
6
+ show Show current config (platform, business domain)
7
+ --help Show this message
8
+
9
+ Examples:
10
+ kweaver config set-bd 54308785-4438-43df-9490-a7fd11df5765
11
+ kweaver config show`;
12
+ export async function runConfigCommand(args) {
13
+ const [sub, ...rest] = args;
14
+ if (!sub || sub === "--help" || sub === "-h" || sub === "help") {
15
+ console.log(HELP);
16
+ return 0;
17
+ }
18
+ if (sub === "show") {
19
+ const platform = getCurrentPlatform();
20
+ if (!platform) {
21
+ console.error("No active platform. Run `kweaver auth login <url>` first.");
22
+ return 1;
23
+ }
24
+ const bd = resolveBusinessDomain(platform);
25
+ const source = process.env.KWEAVER_BUSINESS_DOMAIN
26
+ ? "env"
27
+ : loadPlatformBusinessDomain(platform)
28
+ ? "config"
29
+ : "default";
30
+ console.log(`Platform: ${platform}`);
31
+ console.log(`Business Domain: ${bd} (${source})`);
32
+ return 0;
33
+ }
34
+ if (sub === "set-bd") {
35
+ const value = rest[0];
36
+ if (!value || value.startsWith("-")) {
37
+ console.error("Usage: kweaver config set-bd <value>");
38
+ return 1;
39
+ }
40
+ const platform = getCurrentPlatform();
41
+ if (!platform) {
42
+ console.error("No active platform. Run `kweaver auth login <url>` first.");
43
+ return 1;
44
+ }
45
+ savePlatformBusinessDomain(platform, value);
46
+ console.log(`Business domain set to: ${value}`);
47
+ return 0;
48
+ }
49
+ console.error(`Unknown config subcommand: ${sub}`);
50
+ console.log(HELP);
51
+ return 1;
52
+ }