@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.
@@ -1,4 +1,4 @@
1
- import { ensureValidToken, formatHttpError } from "../auth/oauth.js";
1
+ import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
2
2
  import { knSearch, knSchemaSearch, queryObjectInstance, queryInstanceSubgraph, getLogicPropertiesValues, getActionInfo, listTools, listResources, readResource, listResourceTemplates, listPrompts, getPrompt, } from "../api/context-loader.js";
3
3
  import { addContextLoaderEntry, getCurrentContextLoaderKn, getCurrentPlatform, loadContextLoaderConfig, removeContextLoaderEntry, setCurrentContextLoader, } from "../config/store.js";
4
4
  const MCP_NOT_CONFIGURED = "Context-loader MCP is not configured. Run: kweaver context-loader config set --kn-id <kn-id>";
@@ -54,59 +54,56 @@ Examples:
54
54
  if (subcommand === "config") {
55
55
  return runConfigCommand(rest);
56
56
  }
57
- const token = await ensureValidToken();
58
- const base = ensureContextLoaderConfig();
59
- const options = { ...base, accessToken: token.accessToken };
60
57
  let pretty = true;
61
58
  const prettyIdx = rest.indexOf("--pretty");
62
59
  if (prettyIdx !== -1) {
63
60
  pretty = true;
64
61
  rest.splice(prettyIdx, 1);
65
62
  }
63
+ const dispatch = async () => {
64
+ const token = await ensureValidToken();
65
+ const base = ensureContextLoaderConfig();
66
+ const options = { ...base, accessToken: token.accessToken };
67
+ if (subcommand === "tools")
68
+ return runListTools(options, rest, pretty);
69
+ if (subcommand === "resources")
70
+ return runListResources(options, rest, pretty);
71
+ if (subcommand === "resource")
72
+ return runReadResource(options, rest, pretty);
73
+ if (subcommand === "templates")
74
+ return runListTemplates(options, rest, pretty);
75
+ if (subcommand === "prompts")
76
+ return runListPrompts(options, rest, pretty);
77
+ if (subcommand === "prompt")
78
+ return runGetPrompt(options, rest, pretty);
79
+ if (subcommand === "kn-search")
80
+ return runKnSearch(options, rest, pretty);
81
+ if (subcommand === "kn-schema-search")
82
+ return runKnSchemaSearch(options, rest, pretty);
83
+ if (subcommand === "query-object-instance")
84
+ return runQueryObjectInstance(options, rest, pretty);
85
+ if (subcommand === "query-instance-subgraph")
86
+ return runQueryInstanceSubgraph(options, rest, pretty);
87
+ if (subcommand === "get-logic-properties")
88
+ return runGetLogicProperties(options, rest, pretty);
89
+ if (subcommand === "get-action-info")
90
+ return runGetActionInfo(options, rest, pretty);
91
+ return -1;
92
+ };
66
93
  try {
67
- if (subcommand === "tools") {
68
- return await runListTools(options, rest, pretty);
69
- }
70
- if (subcommand === "resources") {
71
- return await runListResources(options, rest, pretty);
72
- }
73
- if (subcommand === "resource") {
74
- return await runReadResource(options, rest, pretty);
75
- }
76
- if (subcommand === "templates") {
77
- return await runListTemplates(options, rest, pretty);
78
- }
79
- if (subcommand === "prompts") {
80
- return await runListPrompts(options, rest, pretty);
81
- }
82
- if (subcommand === "prompt") {
83
- return await runGetPrompt(options, rest, pretty);
84
- }
85
- if (subcommand === "kn-search") {
86
- return await runKnSearch(options, rest, pretty);
87
- }
88
- if (subcommand === "kn-schema-search") {
89
- return await runKnSchemaSearch(options, rest, pretty);
90
- }
91
- if (subcommand === "query-object-instance") {
92
- return await runQueryObjectInstance(options, rest, pretty);
93
- }
94
- if (subcommand === "query-instance-subgraph") {
95
- return await runQueryInstanceSubgraph(options, rest, pretty);
96
- }
97
- if (subcommand === "get-logic-properties") {
98
- return await runGetLogicProperties(options, rest, pretty);
99
- }
100
- if (subcommand === "get-action-info") {
101
- return await runGetActionInfo(options, rest, pretty);
102
- }
94
+ return await with401RefreshRetry(async () => {
95
+ const code = await dispatch();
96
+ if (code === -1) {
97
+ console.error(`Unknown context-loader subcommand: ${subcommand}`);
98
+ return 1;
99
+ }
100
+ return code;
101
+ });
103
102
  }
104
103
  catch (error) {
105
104
  console.error(formatHttpError(error));
106
105
  return 1;
107
106
  }
108
- console.error(`Unknown context-loader subcommand: ${subcommand}`);
109
- return 1;
110
107
  }
111
108
  async function runConfigCommand(args) {
112
109
  const [action, ...rest] = args;
@@ -1,7 +1,8 @@
1
1
  import { createInterface } from "node:readline";
2
- import { ensureValidToken, formatHttpError } from "../auth/oauth.js";
2
+ import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
3
3
  import { testDatasource, createDatasource, listDatasources, getDatasource, deleteDatasource, listTablesWithColumns, } from "../api/datasources.js";
4
4
  import { formatCallOutput } from "./call.js";
5
+ import { resolveBusinessDomain } from "../config/store.js";
5
6
  function confirmYes(prompt) {
6
7
  return new Promise((resolve) => {
7
8
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -34,24 +35,28 @@ Subcommands:
34
35
  Test connectivity, register datasource, and discover tables.`);
35
36
  return 0;
36
37
  }
37
- try {
38
- if (subcommand === "list") {
38
+ const dispatch = () => {
39
+ if (subcommand === "list")
39
40
  return runDsListCommand(rest);
40
- }
41
- if (subcommand === "get") {
41
+ if (subcommand === "get")
42
42
  return runDsGetCommand(rest);
43
- }
44
- if (subcommand === "delete") {
43
+ if (subcommand === "delete")
45
44
  return runDsDeleteCommand(rest);
46
- }
47
- if (subcommand === "tables") {
45
+ if (subcommand === "tables")
48
46
  return runDsTablesCommand(rest);
49
- }
50
- if (subcommand === "connect") {
47
+ if (subcommand === "connect")
51
48
  return runDsConnectCommand(rest);
52
- }
53
- console.error(`Unknown ds subcommand: ${subcommand}`);
54
- return 1;
49
+ return Promise.resolve(-1);
50
+ };
51
+ try {
52
+ return await with401RefreshRetry(async () => {
53
+ const code = await dispatch();
54
+ if (code === -1) {
55
+ console.error(`Unknown ds subcommand: ${subcommand}`);
56
+ return 1;
57
+ }
58
+ return code;
59
+ });
55
60
  }
56
61
  catch (error) {
57
62
  console.error(formatHttpError(error));
@@ -61,7 +66,7 @@ Subcommands:
61
66
  export function parseDsListArgs(args) {
62
67
  let keyword;
63
68
  let type;
64
- let businessDomain = "bd_public";
69
+ let businessDomain = "";
65
70
  let pretty = true;
66
71
  for (let i = 0; i < args.length; i += 1) {
67
72
  const arg = args[i];
@@ -84,6 +89,8 @@ export function parseDsListArgs(args) {
84
89
  continue;
85
90
  }
86
91
  }
92
+ if (!businessDomain)
93
+ businessDomain = resolveBusinessDomain();
87
94
  return { keyword, type, businessDomain, pretty };
88
95
  }
89
96
  async function runDsListCommand(args) {
@@ -1,6 +1,7 @@
1
- import { ensureValidToken, formatHttpError } from "../auth/oauth.js";
1
+ import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
2
2
  import { vegaHealth, listVegaCatalogs, getVegaCatalog, vegaCatalogHealthStatus, testVegaCatalogConnection, discoverVegaCatalog, listVegaCatalogResources, listVegaResources, getVegaResource, queryVegaResourceData, previewVegaResource, listVegaConnectorTypes, getVegaConnectorType, listVegaDiscoverTasks, } from "../api/vega.js";
3
3
  import { formatCallOutput } from "./call.js";
4
+ import { resolveBusinessDomain } from "../config/store.js";
4
5
  // ---------------------------------------------------------------------------
5
6
  // Help
6
7
  // ---------------------------------------------------------------------------
@@ -32,7 +33,7 @@ Common flags:
32
33
  // Common flag parser
33
34
  // ---------------------------------------------------------------------------
34
35
  function parseCommonFlags(args) {
35
- let businessDomain = "bd_public";
36
+ let businessDomain = "";
36
37
  let pretty = true;
37
38
  const remaining = [];
38
39
  for (let i = 0; i < args.length; i += 1) {
@@ -47,6 +48,8 @@ function parseCommonFlags(args) {
47
48
  }
48
49
  remaining.push(arg);
49
50
  }
51
+ if (!businessDomain)
52
+ businessDomain = resolveBusinessDomain();
50
53
  return { remaining, businessDomain, pretty };
51
54
  }
52
55
  // ---------------------------------------------------------------------------
@@ -58,21 +61,30 @@ export async function runVegaCommand(args) {
58
61
  printVegaHelp();
59
62
  return 0;
60
63
  }
61
- try {
64
+ const dispatch = () => {
62
65
  if (subcommand === "health")
63
- return await runVegaHealthCommand(rest);
66
+ return runVegaHealthCommand(rest);
64
67
  if (subcommand === "stats")
65
- return await runVegaStatsCommand(rest);
68
+ return runVegaStatsCommand(rest);
66
69
  if (subcommand === "inspect")
67
- return await runVegaInspectCommand(rest);
70
+ return runVegaInspectCommand(rest);
68
71
  if (subcommand === "catalog")
69
- return await runVegaCatalogCommand(rest);
72
+ return runVegaCatalogCommand(rest);
70
73
  if (subcommand === "resource")
71
- return await runVegaResourceCommand(rest);
74
+ return runVegaResourceCommand(rest);
72
75
  if (subcommand === "connector-type")
73
- return await runVegaConnectorTypeCommand(rest);
74
- console.error(`Unknown vega subcommand: ${subcommand}`);
75
- return 1;
76
+ return runVegaConnectorTypeCommand(rest);
77
+ return Promise.resolve(-1);
78
+ };
79
+ try {
80
+ return await with401RefreshRetry(async () => {
81
+ const code = await dispatch();
82
+ if (code === -1) {
83
+ console.error(`Unknown vega subcommand: ${subcommand}`);
84
+ return 1;
85
+ }
86
+ return code;
87
+ });
76
88
  }
77
89
  catch (error) {
78
90
  console.error(formatHttpError(error));
@@ -1,14 +1,3 @@
1
- export interface ClientConfig {
2
- baseUrl: string;
3
- clientId: string;
4
- clientSecret: string;
5
- redirectUri: string;
6
- logoutRedirectUri: string;
7
- scope: string;
8
- lang?: string;
9
- product?: string;
10
- xForwardedPrefix?: string;
11
- }
12
1
  export interface TokenConfig {
13
2
  baseUrl: string;
14
3
  accessToken: string;
@@ -20,13 +9,17 @@ export interface TokenConfig {
20
9
  idToken?: string;
21
10
  obtainedAt: string;
22
11
  }
23
- export interface CallbackSession {
12
+ /** OAuth2 client registration (per platform), used for refresh_token grant. */
13
+ export interface ClientConfig {
24
14
  baseUrl: string;
25
- redirectUri: string;
26
- code: string;
27
- state: string;
15
+ clientId: string;
16
+ clientSecret: string;
17
+ redirectUri?: string;
18
+ logoutRedirectUri?: string;
28
19
  scope?: string;
29
- receivedAt: string;
20
+ lang?: string;
21
+ product?: string;
22
+ xForwardedPrefix?: string;
30
23
  }
31
24
  /** Single context-loader entry (named kn_id). */
32
25
  export interface ContextLoaderEntry {
@@ -51,12 +44,10 @@ export declare function setPlatformAlias(baseUrl: string, alias: string): void;
51
44
  export declare function deletePlatformAlias(baseUrl: string): void;
52
45
  export declare function getPlatformAlias(baseUrl: string): string | null;
53
46
  export declare function resolvePlatformIdentifier(value: string): string | null;
54
- export declare function loadClientConfig(baseUrl?: string): ClientConfig | null;
55
- export declare function saveClientConfig(config: ClientConfig): void;
56
47
  export declare function loadTokenConfig(baseUrl?: string): TokenConfig | null;
57
48
  export declare function saveTokenConfig(config: TokenConfig): void;
58
- export declare function loadCallbackSession(baseUrl?: string): CallbackSession | null;
59
- export declare function saveCallbackSession(session: CallbackSession): void;
49
+ export declare function loadClientConfig(baseUrl?: string): ClientConfig | null;
50
+ export declare function saveClientConfig(baseUrl: string, config: ClientConfig): void;
60
51
  export declare function loadContextLoaderConfig(baseUrl?: string): ContextLoaderConfig | null;
61
52
  export declare function saveContextLoaderConfig(baseUrl: string, config: ContextLoaderConfig): void;
62
53
  export interface CurrentContextLoaderKn {
@@ -69,9 +60,19 @@ export declare function setCurrentContextLoader(baseUrl: string, name: string):
69
60
  export declare function removeContextLoaderEntry(baseUrl: string, name: string): void;
70
61
  export declare function hasPlatform(baseUrl: string): boolean;
71
62
  /**
72
- * Remove token and callback for a platform so the next auth will do a full login.
73
- * Keeps client config so the same app registration can be reused.
63
+ * Remove token for a platform so the next auth will do a full login.
74
64
  */
75
65
  export declare function clearPlatformSession(baseUrl: string): void;
76
66
  export declare function deletePlatform(baseUrl: string): void;
77
67
  export declare function listPlatforms(): PlatformSummary[];
68
+ /** Per-platform config (not auth — general settings). */
69
+ export interface PlatformConfig {
70
+ businessDomain?: string;
71
+ }
72
+ export declare function loadPlatformBusinessDomain(baseUrl: string): string | null;
73
+ export declare function savePlatformBusinessDomain(baseUrl: string, businessDomain: string): void;
74
+ /**
75
+ * Resolve businessDomain: env var > per-platform config > "bd_public".
76
+ * If baseUrl is omitted, uses the current platform.
77
+ */
78
+ export declare function resolveBusinessDomain(baseUrl?: string): string;
@@ -175,19 +175,6 @@ export function resolvePlatformIdentifier(value) {
175
175
  }
176
176
  return normalized;
177
177
  }
178
- export function loadClientConfig(baseUrl) {
179
- ensureStoreReady();
180
- const targetBaseUrl = baseUrl ?? getCurrentPlatform();
181
- if (!targetBaseUrl) {
182
- return null;
183
- }
184
- return readJsonFile(getPlatformFile(targetBaseUrl, "client.json"));
185
- }
186
- export function saveClientConfig(config) {
187
- ensureStoreReady();
188
- ensurePlatformDir(config.baseUrl);
189
- writeJsonFile(getPlatformFile(config.baseUrl, "client.json"), config);
190
- }
191
178
  export function loadTokenConfig(baseUrl) {
192
179
  ensureStoreReady();
193
180
  const targetBaseUrl = baseUrl ?? getCurrentPlatform();
@@ -201,18 +188,18 @@ export function saveTokenConfig(config) {
201
188
  ensurePlatformDir(config.baseUrl);
202
189
  writeJsonFile(getPlatformFile(config.baseUrl, "token.json"), config);
203
190
  }
204
- export function loadCallbackSession(baseUrl) {
191
+ export function loadClientConfig(baseUrl) {
205
192
  ensureStoreReady();
206
193
  const targetBaseUrl = baseUrl ?? getCurrentPlatform();
207
194
  if (!targetBaseUrl) {
208
195
  return null;
209
196
  }
210
- return readJsonFile(getPlatformFile(targetBaseUrl, "callback.json"));
197
+ return readJsonFile(getPlatformFile(targetBaseUrl, "client.json"));
211
198
  }
212
- export function saveCallbackSession(session) {
199
+ export function saveClientConfig(baseUrl, config) {
213
200
  ensureStoreReady();
214
- ensurePlatformDir(session.baseUrl);
215
- writeJsonFile(getPlatformFile(session.baseUrl, "callback.json"), session);
201
+ ensurePlatformDir(baseUrl);
202
+ writeJsonFile(getPlatformFile(baseUrl, "client.json"), { ...config, baseUrl });
216
203
  }
217
204
  function migrateLegacyContextLoader(raw) {
218
205
  const leg = raw;
@@ -258,8 +245,8 @@ export function getCurrentContextLoaderKn(baseUrl) {
258
245
  const targetBaseUrl = baseUrl ?? getCurrentPlatform();
259
246
  if (!targetBaseUrl)
260
247
  return null;
261
- const client = loadClientConfig(targetBaseUrl);
262
- if (!client?.baseUrl)
248
+ const token = loadTokenConfig(targetBaseUrl);
249
+ if (!token?.baseUrl)
263
250
  return null;
264
251
  const config = loadContextLoaderConfig(targetBaseUrl);
265
252
  if (!config)
@@ -268,7 +255,7 @@ export function getCurrentContextLoaderKn(baseUrl) {
268
255
  if (!entry)
269
256
  return null;
270
257
  return {
271
- mcpUrl: buildMcpUrl(client.baseUrl),
258
+ mcpUrl: buildMcpUrl(token.baseUrl),
272
259
  knId: entry.knId,
273
260
  };
274
261
  }
@@ -320,22 +307,17 @@ export function removeContextLoaderEntry(baseUrl, name) {
320
307
  }
321
308
  export function hasPlatform(baseUrl) {
322
309
  ensureStoreReady();
323
- return existsSync(getPlatformFile(baseUrl, "client.json"));
310
+ return existsSync(getPlatformFile(baseUrl, "token.json"));
324
311
  }
325
312
  /**
326
- * Remove token and callback for a platform so the next auth will do a full login.
327
- * Keeps client config so the same app registration can be reused.
313
+ * Remove token for a platform so the next auth will do a full login.
328
314
  */
329
315
  export function clearPlatformSession(baseUrl) {
330
316
  ensureStoreReady();
331
317
  const tokenFile = getPlatformFile(baseUrl, "token.json");
332
- const callbackFile = getPlatformFile(baseUrl, "callback.json");
333
318
  if (existsSync(tokenFile)) {
334
319
  rmSync(tokenFile, { force: true });
335
320
  }
336
- if (existsSync(callbackFile)) {
337
- rmSync(callbackFile, { force: true });
338
- }
339
321
  }
340
322
  export function deletePlatform(baseUrl) {
341
323
  ensureStoreReady();
@@ -364,17 +346,49 @@ export function listPlatforms() {
364
346
  if (!statSync(dirPath).isDirectory()) {
365
347
  continue;
366
348
  }
367
- const client = readJsonFile(join(dirPath, "client.json"));
368
- if (!client?.baseUrl) {
349
+ const token = readJsonFile(join(dirPath, "token.json"));
350
+ if (!token?.baseUrl) {
369
351
  continue;
370
352
  }
371
353
  items.push({
372
- baseUrl: client.baseUrl,
373
- hasToken: existsSync(join(dirPath, "token.json")),
374
- isCurrent: client.baseUrl === currentPlatform,
375
- alias: getPlatformAlias(client.baseUrl) ?? undefined,
354
+ baseUrl: token.baseUrl,
355
+ hasToken: true,
356
+ isCurrent: token.baseUrl === currentPlatform,
357
+ alias: getPlatformAlias(token.baseUrl) ?? undefined,
376
358
  });
377
359
  }
378
360
  items.sort((a, b) => a.baseUrl.localeCompare(b.baseUrl));
379
361
  return items;
380
362
  }
363
+ function loadPlatformConfig(baseUrl) {
364
+ ensureStoreReady();
365
+ return readJsonFile(getPlatformFile(baseUrl, "config.json"));
366
+ }
367
+ function savePlatformConfig(baseUrl, config) {
368
+ ensureStoreReady();
369
+ ensurePlatformDir(baseUrl);
370
+ writeJsonFile(getPlatformFile(baseUrl, "config.json"), config);
371
+ }
372
+ export function loadPlatformBusinessDomain(baseUrl) {
373
+ return loadPlatformConfig(baseUrl)?.businessDomain ?? null;
374
+ }
375
+ export function savePlatformBusinessDomain(baseUrl, businessDomain) {
376
+ const existing = loadPlatformConfig(baseUrl) ?? {};
377
+ savePlatformConfig(baseUrl, { ...existing, businessDomain });
378
+ }
379
+ /**
380
+ * Resolve businessDomain: env var > per-platform config > "bd_public".
381
+ * If baseUrl is omitted, uses the current platform.
382
+ */
383
+ export function resolveBusinessDomain(baseUrl) {
384
+ const fromEnv = process.env.KWEAVER_BUSINESS_DOMAIN;
385
+ if (fromEnv)
386
+ return fromEnv;
387
+ const targetUrl = baseUrl ?? getCurrentPlatform();
388
+ if (targetUrl) {
389
+ const fromConfig = loadPlatformBusinessDomain(targetUrl);
390
+ if (fromConfig)
391
+ return fromConfig;
392
+ }
393
+ return "bd_public";
394
+ }
package/dist/index.d.ts CHANGED
@@ -50,5 +50,5 @@ export { BknResource } from "./resources/bkn.js";
50
50
  export { ConversationsResource } from "./resources/conversations.js";
51
51
  export { ContextLoaderResource } from "./resources/context-loader.js";
52
52
  export { HttpError, NetworkRequestError, fetchTextOrThrow } from "./utils/http.js";
53
- export type { ClientConfig, TokenConfig, ContextLoaderEntry, ContextLoaderConfig, PlatformSummary, } from "./config/store.js";
53
+ export type { TokenConfig, ContextLoaderEntry, ContextLoaderConfig, } from "./config/store.js";
54
54
  export { getConfigDir, getCurrentPlatform } from "./config/store.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kweaver-ai/kweaver-sdk",
3
- "version": "0.4.2",
3
+ "version": "0.4.5",
4
4
  "description": "KWeaver TypeScript SDK — CLI tool and programmatic API for knowledge networks and Decision Agents.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -53,6 +53,14 @@
53
53
  "tsx": "^4.20.5",
54
54
  "typescript": "^5.9.3"
55
55
  },
56
+ "peerDependencies": {
57
+ "playwright": ">=1.40.0"
58
+ },
59
+ "peerDependenciesMeta": {
60
+ "playwright": {
61
+ "optional": true
62
+ }
63
+ },
56
64
  "dependencies": {
57
65
  "@kweaver-ai/bkn": "^0.1.0",
58
66
  "ink": "^6.8.0",