@kweaver-ai/kweaver-sdk 0.5.1 → 0.6.0

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.
Files changed (95) hide show
  1. package/README.md +25 -2
  2. package/README.zh.md +24 -1
  3. package/dist/api/agent-chat.d.ts +8 -2
  4. package/dist/api/agent-chat.js +150 -44
  5. package/dist/api/agent-list.d.ts +35 -0
  6. package/dist/api/agent-list.js +95 -21
  7. package/dist/api/bkn-backend.d.ts +60 -0
  8. package/dist/api/bkn-backend.js +103 -10
  9. package/dist/api/business-domains.js +9 -5
  10. package/dist/api/context-loader.js +4 -1
  11. package/dist/api/conversations.d.ts +6 -3
  12. package/dist/api/conversations.js +29 -35
  13. package/dist/api/dataflow.js +1 -10
  14. package/dist/api/dataflow2.d.ts +95 -0
  15. package/dist/api/dataflow2.js +80 -0
  16. package/dist/api/datasources.js +1 -10
  17. package/dist/api/dataviews.js +1 -10
  18. package/dist/api/headers.d.ts +11 -0
  19. package/dist/api/headers.js +30 -0
  20. package/dist/api/knowledge-networks.d.ts +41 -0
  21. package/dist/api/knowledge-networks.js +69 -22
  22. package/dist/api/ontology-query.d.ts +14 -1
  23. package/dist/api/ontology-query.js +63 -49
  24. package/dist/api/semantic-search.js +2 -12
  25. package/dist/api/skills.d.ts +141 -0
  26. package/dist/api/skills.js +208 -0
  27. package/dist/api/vega.d.ts +54 -7
  28. package/dist/api/vega.js +112 -25
  29. package/dist/auth/oauth.d.ts +5 -1
  30. package/dist/auth/oauth.js +351 -95
  31. package/dist/cli.js +49 -5
  32. package/dist/client.d.ts +12 -0
  33. package/dist/client.js +52 -8
  34. package/dist/commands/agent.d.ts +33 -1
  35. package/dist/commands/agent.js +721 -49
  36. package/dist/commands/auth.js +226 -55
  37. package/dist/commands/bkn-ops.d.ts +77 -0
  38. package/dist/commands/bkn-ops.js +1056 -0
  39. package/dist/commands/bkn-query.d.ts +14 -0
  40. package/dist/commands/bkn-query.js +370 -0
  41. package/dist/commands/bkn-schema.d.ts +135 -0
  42. package/dist/commands/bkn-schema.js +1483 -0
  43. package/dist/commands/bkn-utils.d.ts +36 -0
  44. package/dist/commands/bkn-utils.js +102 -0
  45. package/dist/commands/bkn.d.ts +7 -113
  46. package/dist/commands/bkn.js +175 -2429
  47. package/dist/commands/call.js +8 -5
  48. package/dist/commands/dataflow.d.ts +1 -0
  49. package/dist/commands/dataflow.js +251 -0
  50. package/dist/commands/dataview.d.ts +7 -0
  51. package/dist/commands/dataview.js +38 -2
  52. package/dist/commands/ds.d.ts +1 -0
  53. package/dist/commands/ds.js +8 -1
  54. package/dist/commands/explore-bkn.d.ts +79 -0
  55. package/dist/commands/explore-bkn.js +273 -0
  56. package/dist/commands/explore-chat.d.ts +3 -0
  57. package/dist/commands/explore-chat.js +193 -0
  58. package/dist/commands/explore-vega.d.ts +3 -0
  59. package/dist/commands/explore-vega.js +71 -0
  60. package/dist/commands/explore.d.ts +9 -0
  61. package/dist/commands/explore.js +258 -0
  62. package/dist/commands/import-csv.d.ts +2 -0
  63. package/dist/commands/import-csv.js +3 -2
  64. package/dist/commands/skill.d.ts +26 -0
  65. package/dist/commands/skill.js +524 -0
  66. package/dist/commands/vega.js +372 -117
  67. package/dist/config/jwt.d.ts +6 -0
  68. package/dist/config/jwt.js +21 -0
  69. package/dist/config/no-auth.d.ts +3 -0
  70. package/dist/config/no-auth.js +5 -0
  71. package/dist/config/store.d.ts +45 -5
  72. package/dist/config/store.js +385 -30
  73. package/dist/index.d.ts +6 -1
  74. package/dist/index.js +5 -1
  75. package/dist/kweaver.d.ts +5 -0
  76. package/dist/kweaver.js +32 -2
  77. package/dist/resources/bkn.d.ts +4 -0
  78. package/dist/resources/bkn.js +6 -3
  79. package/dist/resources/conversations.d.ts +5 -2
  80. package/dist/resources/conversations.js +17 -3
  81. package/dist/resources/knowledge-networks.js +3 -8
  82. package/dist/resources/skills.d.ts +47 -0
  83. package/dist/resources/skills.js +47 -0
  84. package/dist/resources/vega.d.ts +11 -6
  85. package/dist/resources/vega.js +37 -10
  86. package/dist/templates/explorer/app.js +136 -0
  87. package/dist/templates/explorer/bkn.js +747 -0
  88. package/dist/templates/explorer/chat.js +980 -0
  89. package/dist/templates/explorer/dashboard.js +82 -0
  90. package/dist/templates/explorer/index.html +35 -0
  91. package/dist/templates/explorer/style.css +2440 -0
  92. package/dist/templates/explorer/vega.js +291 -0
  93. package/dist/utils/http.d.ts +3 -0
  94. package/dist/utils/http.js +37 -1
  95. package/package.json +9 -5
@@ -1,4 +1,6 @@
1
- import { autoSelectBusinessDomain, clearPlatformSession, deletePlatform, getConfigDir, getCurrentPlatform, getPlatformAlias, hasPlatform, listPlatforms, loadClientConfig, loadTokenConfig, resolvePlatformIdentifier, setCurrentPlatform, setPlatformAlias, } from "../config/store.js";
1
+ import { isNoAuth } from "../config/no-auth.js";
2
+ import { autoSelectBusinessDomain, clearPlatformSession, deletePlatform, deleteUser, getActiveUser, getConfigDir, getCurrentPlatform, getPlatformAlias, hasPlatform, listPlatforms, listUserProfiles, loadClientConfig, loadTokenConfig, resolveBusinessDomain, resolvePlatformIdentifier, resolveUserId, saveNoAuthPlatform, setActiveUser, setCurrentPlatform, setPlatformAlias, } from "../config/store.js";
3
+ import { decodeJwtPayload } from "../config/jwt.js";
2
4
  import { buildCopyCommand, formatHttpError, normalizeBaseUrl, oauth2Login, playwrightLogin, refreshTokenLogin, } from "../auth/oauth.js";
3
5
  export async function runAuthCommand(args) {
4
6
  const target = args[0];
@@ -9,10 +11,12 @@ kweaver auth <url> Login (shorthand; same options as login)
9
11
  kweaver auth whoami [url|alias] Show current user identity (from id_token)
10
12
  kweaver auth export [url|alias] [--json] Export credentials; run printed command on a headless host
11
13
  kweaver auth status [url|alias] Show current auth status
12
- kweaver auth list List saved platforms
14
+ kweaver auth list List all platforms and users (tree view)
13
15
  kweaver auth use <url|alias> Switch active platform
14
- kweaver auth logout [url|alias] Logout (clear local token)
15
- kweaver auth delete <url|alias> Delete saved credentials
16
+ kweaver auth users [url|alias] List all user profiles (with usernames) for a platform
17
+ kweaver auth switch [url|alias] --user <id|username> Switch active user for a platform
18
+ kweaver auth logout [url|alias] [--user <id>] Logout (clear local token)
19
+ kweaver auth delete <url|alias> [--user <id>] Delete saved credentials
16
20
 
17
21
  Login options:
18
22
  --alias <name> Save platform with a short alias (use with use / status / logout)
@@ -23,15 +27,20 @@ Login options:
23
27
  --refresh-token <t> Use on a machine without a browser: exchange refresh token for access token.
24
28
  Requires --client-id and --client-secret.
25
29
  Get these from the callback page after browser login or \`auth export\`.
30
+ --port <n> Local callback port (default: 9010). Use when 9010 is occupied.
31
+ --redirect-uri <uri> Full OAuth2 redirect URI override. Localhost URIs start a local server;
32
+ non-localhost URIs use a manual paste-the-callback-URL flow.
33
+ When set, --port is ignored. Example: --redirect-uri http://127.0.0.1:9010/callback
26
34
  -u, --username Username (with -p triggers Playwright headless login)
27
35
  -p, --password Password
28
36
  --playwright Force Playwright browser login even without -u/-p
29
- --insecure, -k Skip TLS certificate verification (self-signed / dev HTTPS only)`);
37
+ --insecure, -k Skip TLS certificate verification (self-signed / dev HTTPS only)
38
+ --no-auth Save platform without OAuth (servers with no authentication). Same as detecting OAuth 404 during login.`);
30
39
  return 0;
31
40
  }
32
41
  if (target === "login") {
33
42
  if (rest[0] === "--help" || rest[0] === "-h") {
34
- console.log(`kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass] [--playwright] [--refresh-token T --client-id ID --client-secret S]`);
43
+ console.log(`kweaver auth login <platform-url> [--alias <name>] [--no-auth] [-u user] [-p pass] [--playwright] [--refresh-token T --client-id ID --client-secret S]`);
35
44
  return 0;
36
45
  }
37
46
  const url = rest[0];
@@ -47,7 +56,13 @@ Login options:
47
56
  if (target === "export") {
48
57
  return runAuthExportCommand(rest);
49
58
  }
50
- const LOGIN_SUBCOMMANDS = new Set(["status", "list", "use", "delete", "logout", "export", "whoami"]);
59
+ if (target === "users") {
60
+ return runAuthUsersCommand(rest);
61
+ }
62
+ if (target === "switch") {
63
+ return runAuthSwitchCommand(rest);
64
+ }
65
+ const LOGIN_SUBCOMMANDS = new Set(["status", "list", "use", "delete", "logout", "export", "whoami", "users", "switch"]);
51
66
  if (target && !LOGIN_SUBCOMMANDS.has(target)) {
52
67
  try {
53
68
  const normalizedTarget = normalizeBaseUrl(target);
@@ -58,9 +73,47 @@ Login options:
58
73
  const clientId = readOption(args, "--client-id");
59
74
  const clientSecret = readOption(args, "--client-secret");
60
75
  const refreshToken = readOption(args, "--refresh-token");
76
+ const customRedirectUri = readOption(args, "--redirect-uri");
77
+ const customPortStr = readOption(args, "--port");
78
+ const customPort = customPortStr ? parseInt(customPortStr, 10) : undefined;
61
79
  const tlsInsecure = args.includes("--insecure") || args.includes("-k");
80
+ const noAuth = args.includes("--no-auth");
81
+ const KNOWN_LOGIN_FLAGS = new Set([
82
+ "--alias", "--client-id", "--client-secret", "--refresh-token",
83
+ "--port", "--redirect-uri", "--username", "-u", "--password", "-p",
84
+ "--playwright", "--insecure", "-k", "--no-auth",
85
+ ]);
86
+ const KNOWN_VALUE_FLAGS = new Set([
87
+ "--alias", "--client-id", "--client-secret", "--refresh-token",
88
+ "--port", "--redirect-uri", "--username", "-u", "--password", "-p",
89
+ ]);
90
+ for (let i = 0; i < args.length; i++) {
91
+ const a = args[i];
92
+ if (a.startsWith("-") && a !== target && !KNOWN_LOGIN_FLAGS.has(a)) {
93
+ console.error(`Unknown option: ${a}`);
94
+ console.error("Run 'kweaver auth --help' to see available options.");
95
+ return 1;
96
+ }
97
+ if (KNOWN_VALUE_FLAGS.has(a))
98
+ i++;
99
+ }
100
+ if (customPort !== undefined && (Number.isNaN(customPort) || customPort < 1 || customPort > 65535)) {
101
+ console.error("Invalid --port value. Expected a number between 1 and 65535.");
102
+ return 1;
103
+ }
104
+ if (noAuth && refreshToken) {
105
+ console.error("--no-auth cannot be used with --refresh-token.");
106
+ return 1;
107
+ }
108
+ if (noAuth && (username || password || usePlaywright)) {
109
+ console.error("--no-auth cannot be used with Playwright login or -u/-p.");
110
+ return 1;
111
+ }
62
112
  let token;
63
- if (refreshToken) {
113
+ if (noAuth) {
114
+ token = saveNoAuthPlatform(normalizedTarget, { tlsInsecure });
115
+ }
116
+ else if (refreshToken) {
64
117
  if (!clientId || !clientSecret) {
65
118
  console.error("--refresh-token requires --client-id and --client-secret.\n");
66
119
  console.error("Get these values from the callback page after a browser login or `kweaver auth export`.");
@@ -72,17 +125,20 @@ Login options:
72
125
  });
73
126
  }
74
127
  else if (username && password) {
75
- // Headless Playwright login with credentials
76
128
  console.log("Logging in (headless)...");
77
- token = await playwrightLogin(normalizedTarget, { username, password, tlsInsecure });
129
+ token = await playwrightLogin(normalizedTarget, {
130
+ username, password, tlsInsecure,
131
+ port: customPort, redirectUri: customRedirectUri ?? undefined,
132
+ });
78
133
  }
79
134
  else if (usePlaywright) {
80
- // Explicit Playwright fallback
81
135
  console.log("Opening browser for login (Playwright)...");
82
- token = await playwrightLogin(normalizedTarget, { tlsInsecure });
136
+ token = await playwrightLogin(normalizedTarget, {
137
+ tlsInsecure,
138
+ port: customPort, redirectUri: customRedirectUri ?? undefined,
139
+ });
83
140
  }
84
141
  else {
85
- // Default: OAuth2 authorization code flow (supports refresh_token)
86
142
  if (clientId) {
87
143
  console.log(`Opening browser for OAuth2 login (client: ${clientId})...`);
88
144
  }
@@ -93,6 +149,7 @@ Login options:
93
149
  clientId: clientId ?? undefined,
94
150
  clientSecret: clientSecret ?? undefined,
95
151
  tlsInsecure,
152
+ port: customPort, redirectUri: customRedirectUri ?? undefined,
96
153
  });
97
154
  }
98
155
  if (alias) {
@@ -109,19 +166,31 @@ Login options:
109
166
  }
110
167
  }
111
168
  console.log(`Current platform: ${normalizedTarget}`);
112
- console.log(`Access token saved: yes`);
113
- if (token.refreshToken) {
114
- console.log(`Refresh token: yes (auto-refresh enabled)`);
169
+ const activeUser = getActiveUser(normalizedTarget);
170
+ if (activeUser) {
171
+ const userLabel = token.displayName ? `${token.displayName} (${activeUser})` : activeUser;
172
+ console.log(`User: ${userLabel}`);
173
+ }
174
+ if (isNoAuth(token.accessToken)) {
175
+ console.log(`Authentication: none (no-auth mode)`);
115
176
  }
116
177
  else {
178
+ console.log(`Access token saved: yes`);
179
+ }
180
+ if (!isNoAuth(token.accessToken) && token.refreshToken) {
181
+ console.log(`Refresh token: yes (auto-refresh enabled)`);
182
+ }
183
+ else if (!isNoAuth(token.accessToken)) {
117
184
  console.log(`Refresh token: no (token will expire in 1 hour)`);
118
185
  }
119
186
  if (token.expiresAt) {
120
187
  console.log(`Token expires at: ${token.expiresAt}`);
121
188
  }
122
- const selectedBd = await autoSelectBusinessDomain(normalizedTarget, token.accessToken, {
123
- tlsInsecure: token.tlsInsecure,
124
- });
189
+ const selectedBd = isNoAuth(token.accessToken)
190
+ ? resolveBusinessDomain(normalizedTarget)
191
+ : await autoSelectBusinessDomain(normalizedTarget, token.accessToken, {
192
+ tlsInsecure: token.tlsInsecure,
193
+ });
125
194
  console.log(`Business domain: ${selectedBd}`);
126
195
  return 0;
127
196
  }
@@ -148,24 +217,36 @@ Login options:
148
217
  `Config directory: ${getConfigDir()}`,
149
218
  `Platform: ${token.baseUrl}`,
150
219
  `Current platform: ${token.baseUrl === currentPlatform ? "yes" : "no"}`,
151
- `Token present: yes`,
152
220
  ];
153
- lines.push(`Refresh token: ${token.refreshToken ? "yes (auto-refresh enabled)" : "no"}`);
154
- if (token.tlsInsecure) {
155
- lines.push(`TLS: certificate verification disabled (saved; dev only)`);
221
+ if (isNoAuth(token.accessToken)) {
222
+ lines.push(`Authentication: none (no-auth mode)`);
223
+ lines.push(`User: default (built-in profile for no-auth platforms)`);
156
224
  }
157
- if (token.expiresAt) {
158
- const expiry = new Date(token.expiresAt);
159
- const remainingMs = expiry.getTime() - Date.now();
160
- if (remainingMs > 0) {
161
- const remainingMin = Math.ceil(remainingMs / 60_000);
162
- lines.push(`Token status: active (expires in ${remainingMin} min)`);
225
+ else {
226
+ const statusActiveUser = getActiveUser(platform);
227
+ if (statusActiveUser) {
228
+ const statusDisplayName = token.displayName;
229
+ const userLabel = statusDisplayName ? `${statusDisplayName} (${statusActiveUser})` : statusActiveUser;
230
+ lines.push(`User: ${userLabel}`);
163
231
  }
164
- else if (token.refreshToken) {
165
- lines.push(`Token status: expired (will auto-refresh on next command)`);
232
+ lines.push(`Token present: yes`);
233
+ lines.push(`Refresh token: ${token.refreshToken ? "yes (auto-refresh enabled)" : "no"}`);
234
+ if (token.tlsInsecure) {
235
+ lines.push(`TLS: certificate verification disabled (saved; dev only)`);
166
236
  }
167
- else {
168
- lines.push(`Token status: expired (run \`kweaver auth login ${token.baseUrl}\` again)`);
237
+ if (token.expiresAt) {
238
+ const expiry = new Date(token.expiresAt);
239
+ const remainingMs = expiry.getTime() - Date.now();
240
+ if (remainingMs > 0) {
241
+ const remainingMin = Math.ceil(remainingMs / 60_000);
242
+ lines.push(`Token status: active (expires in ${remainingMin} min)`);
243
+ }
244
+ else if (token.refreshToken) {
245
+ lines.push(`Token status: expired (will auto-refresh on next command)`);
246
+ }
247
+ else {
248
+ lines.push(`Token status: expired (run \`kweaver auth login ${token.baseUrl}\` again)`);
249
+ }
169
250
  }
170
251
  }
171
252
  for (const line of lines) {
@@ -183,8 +264,20 @@ Login options:
183
264
  console.log(`Config directory: ${getConfigDir()}`);
184
265
  for (const platform of platforms) {
185
266
  const marker = platform.baseUrl === currentPlatform ? "*" : "-";
186
- const aliasPart = platform.alias ? ` alias=${platform.alias}` : "";
187
- console.log(`${marker} ${platform.baseUrl}${aliasPart} token=${platform.hasToken ? "yes" : "no"}`);
267
+ const aliasPart = platform.alias ? ` (${platform.alias})` : "";
268
+ const tok = loadTokenConfig(platform.baseUrl);
269
+ const noAuthPart = tok && isNoAuth(tok.accessToken) ? " (no-auth)" : "";
270
+ console.log(`${marker} ${platform.baseUrl}${aliasPart}${noAuthPart}`);
271
+ const profiles = listUserProfiles(platform.baseUrl);
272
+ const activeUser = getActiveUser(platform.baseUrl);
273
+ for (let i = 0; i < profiles.length; i++) {
274
+ const p = profiles[i];
275
+ const isLast = i === profiles.length - 1;
276
+ const branch = isLast ? "└──" : "├──";
277
+ const activeMarker = p.userId === activeUser ? " *" : "";
278
+ const label = p.username ? `${p.username} (${p.userId})` : p.userId;
279
+ console.log(` ${branch} ${label}${activeMarker}`);
280
+ }
188
281
  }
189
282
  return 0;
190
283
  }
@@ -204,16 +297,24 @@ Login options:
204
297
  return 0;
205
298
  }
206
299
  if (target === "delete") {
207
- const resolvedTarget = args[1] ? resolvePlatformIdentifier(args[1]) : "";
300
+ const deleteUserArg = readOption(args, "--user");
301
+ const positionalArgs = args.slice(1).filter((a) => a !== "--user" && a !== deleteUserArg);
302
+ const resolvedTarget = positionalArgs[0] ? resolvePlatformIdentifier(positionalArgs[0]) : "";
208
303
  const deleteTarget = resolvedTarget && /^https?:\/\//.test(resolvedTarget) ? normalizeBaseUrl(resolvedTarget) : resolvedTarget;
209
304
  if (!deleteTarget) {
210
- console.error("Usage: kweaver auth delete <platform-url|alias>");
305
+ console.error("Usage: kweaver auth delete <platform-url|alias> [--user <userId|username>]");
211
306
  return 1;
212
307
  }
213
308
  if (!hasPlatform(deleteTarget)) {
214
309
  console.error(`No saved token for ${deleteTarget}.`);
215
310
  return 1;
216
311
  }
312
+ if (deleteUserArg) {
313
+ const deleteUserId = resolveUserId(deleteTarget, deleteUserArg) ?? deleteUserArg;
314
+ deleteUser(deleteTarget, deleteUserId);
315
+ console.log(`Deleted user ${deleteUserId} from ${deleteTarget}`);
316
+ return 0;
317
+ }
217
318
  const wasCurrent = getCurrentPlatform() === deleteTarget;
218
319
  deletePlatform(deleteTarget);
219
320
  console.log(`Deleted platform: ${deleteTarget}`);
@@ -224,10 +325,12 @@ Login options:
224
325
  return 0;
225
326
  }
226
327
  if (target === "logout") {
227
- const resolvedTarget = args[1] ? resolvePlatformIdentifier(args[1]) : getCurrentPlatform();
328
+ const logoutUserArg = readOption(args, "--user");
329
+ const positionalArgs = args.slice(1).filter((a) => a !== "--user" && a !== logoutUserArg);
330
+ const resolvedTarget = positionalArgs[0] ? resolvePlatformIdentifier(positionalArgs[0]) : getCurrentPlatform();
228
331
  const logoutTarget = resolvedTarget && /^https?:\/\//.test(resolvedTarget) ? normalizeBaseUrl(resolvedTarget) : resolvedTarget;
229
332
  if (!logoutTarget) {
230
- console.error("Usage: kweaver auth logout [platform-url|alias]");
333
+ console.error("Usage: kweaver auth logout [platform-url|alias] [--user <userId|username>]");
231
334
  console.error("No current platform. Specify a platform to logout.");
232
335
  return 1;
233
336
  }
@@ -235,8 +338,10 @@ Login options:
235
338
  console.error(`No saved token for ${logoutTarget}.`);
236
339
  return 1;
237
340
  }
238
- clearPlatformSession(logoutTarget);
239
- console.log(`Logged out: ${logoutTarget}`);
341
+ const logoutUserId = logoutUserArg ? resolveUserId(logoutTarget, logoutUserArg) ?? logoutUserArg : undefined;
342
+ clearPlatformSession(logoutTarget, logoutUserId);
343
+ const userHint = logoutUserId ? ` (user: ${logoutUserId})` : "";
344
+ console.log(`Logged out: ${logoutTarget}${userHint}`);
240
345
  console.log(`Run \`kweaver auth login ${logoutTarget}\` to sign in again.`);
241
346
  return 0;
242
347
  }
@@ -246,22 +351,82 @@ Login options:
246
351
  console.error(" kweaver auth status [platform-url|alias]");
247
352
  console.error(" kweaver auth list");
248
353
  console.error(" kweaver auth use <platform-url|alias>");
249
- console.error(" kweaver auth logout [platform-url|alias]");
250
- console.error(" kweaver auth delete <platform-url|alias>");
354
+ console.error(" kweaver auth users [platform-url|alias]");
355
+ console.error(" kweaver auth switch [platform-url|alias] --user <userId>");
356
+ console.error(" kweaver auth logout [platform-url|alias] [--user <userId>]");
357
+ console.error(" kweaver auth delete <platform-url|alias> [--user <userId>]");
251
358
  return 1;
252
359
  }
253
- function decodeJwtPayload(jwt) {
254
- const parts = jwt.split(".");
255
- if (parts.length !== 3)
256
- return null;
257
- try {
258
- const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
259
- const json = Buffer.from(base64, "base64").toString("utf8");
260
- return JSON.parse(json);
261
- }
262
- catch {
263
- return null;
360
+ function resolvePlatformArg(args) {
361
+ const positional = args.find((a) => !a.startsWith("-"));
362
+ const resolved = positional ? resolvePlatformIdentifier(positional) : null;
363
+ if (resolved && /^https?:\/\//.test(resolved))
364
+ return normalizeBaseUrl(resolved);
365
+ return resolved ?? getCurrentPlatform();
366
+ }
367
+ function runAuthUsersCommand(args) {
368
+ if (args[0] === "--help" || args[0] === "-h") {
369
+ console.log(`kweaver auth users [platform-url|alias]
370
+
371
+ List all user profiles stored for a platform.
372
+ Each line shows: userId (username) where username is decoded from the id_token.
373
+ You can use either userId or username with --user in switch/logout/delete.`);
374
+ return 0;
264
375
  }
376
+ const platform = resolvePlatformArg(args);
377
+ if (!platform) {
378
+ console.error("No active platform. Run `kweaver auth login <platform-url>` first.");
379
+ return 1;
380
+ }
381
+ const profiles = listUserProfiles(platform);
382
+ if (profiles.length === 0) {
383
+ console.error(`No user profiles for ${platform}.`);
384
+ return 1;
385
+ }
386
+ const active = getActiveUser(platform);
387
+ console.log(`Platform: ${platform}`);
388
+ for (const p of profiles) {
389
+ const marker = p.userId === active ? "*" : "-";
390
+ const displayName = p.username ? ` (${p.username})` : "";
391
+ console.log(`${marker} ${p.userId}${displayName}`);
392
+ }
393
+ return 0;
394
+ }
395
+ function runAuthSwitchCommand(args) {
396
+ if (args[0] === "--help" || args[0] === "-h") {
397
+ console.log(`kweaver auth switch [platform-url|alias] --user <userId|username>
398
+
399
+ Switch the active user for a platform.
400
+ You can specify either the userId (sub claim) or the username (preferred_username from id_token).`);
401
+ return 0;
402
+ }
403
+ const userArg = readOption(args, "--user");
404
+ if (!userArg) {
405
+ console.error("Usage: kweaver auth switch [platform-url|alias] --user <userId|username>");
406
+ return 1;
407
+ }
408
+ const filteredArgs = args.filter((a) => a !== "--user" && a !== userArg);
409
+ const platform = resolvePlatformArg(filteredArgs);
410
+ if (!platform) {
411
+ console.error("No active platform. Run `kweaver auth login <platform-url>` first.");
412
+ return 1;
413
+ }
414
+ const resolvedId = resolveUserId(platform, userArg);
415
+ if (!resolvedId) {
416
+ console.error(`User '${userArg}' not found for ${platform}.`);
417
+ const profiles = listUserProfiles(platform);
418
+ if (profiles.length > 0) {
419
+ const hints = profiles.map((p) => p.username ? `${p.userId} (${p.username})` : p.userId);
420
+ console.error(`Available users: ${hints.join(", ")}`);
421
+ }
422
+ return 1;
423
+ }
424
+ setActiveUser(platform, resolvedId);
425
+ const profiles = listUserProfiles(platform);
426
+ const profile = profiles.find((p) => p.userId === resolvedId);
427
+ const displayName = profile?.username ? ` (${profile.username})` : "";
428
+ console.log(`Switched to user ${resolvedId}${displayName} on ${platform}`);
429
+ return 0;
265
430
  }
266
431
  function runAuthWhoamiCommand(args) {
267
432
  if (args[0] === "--help" || args[0] === "-h") {
@@ -295,11 +460,17 @@ Options:
295
460
  console.error("Failed to decode id_token.");
296
461
  return 1;
297
462
  }
463
+ const displayNameValue = token.displayName ?? null;
298
464
  if (jsonOutput) {
299
- console.log(JSON.stringify({ platform, ...payload }, null, 2));
465
+ const out = { platform, ...payload };
466
+ if (displayNameValue)
467
+ out.displayName = displayNameValue;
468
+ console.log(JSON.stringify(out, null, 2));
300
469
  return 0;
301
470
  }
302
471
  console.log(`Platform: ${platform}`);
472
+ if (displayNameValue)
473
+ console.log(`Username: ${displayNameValue}`);
303
474
  console.log(`User ID: ${payload.sub ?? "(unknown)"}`);
304
475
  console.log(`Issuer: ${payload.iss ?? "(unknown)"}`);
305
476
  if (payload.sid)
@@ -0,0 +1,77 @@
1
+ import { type BknEncodingImportOptions } from "../utils/bkn-encoding.js";
2
+ export declare function parseKnBuildArgs(args: string[]): {
3
+ knId: string;
4
+ wait: boolean;
5
+ timeout: number;
6
+ businessDomain: string;
7
+ };
8
+ export declare function runKnBuildCommand(args: string[]): Promise<number>;
9
+ export declare function runKnValidateCommand(args: string[]): Promise<number>;
10
+ export interface KnPushOptions {
11
+ directory: string;
12
+ branch: string;
13
+ businessDomain: string;
14
+ pretty: boolean;
15
+ encodingOptions: BknEncodingImportOptions;
16
+ }
17
+ export declare function parseKnPushArgs(args: string[]): KnPushOptions;
18
+ export interface KnPullOptions {
19
+ knId: string;
20
+ directory: string;
21
+ branch: string;
22
+ businessDomain: string;
23
+ }
24
+ export declare function parseKnPullArgs(args: string[]): KnPullOptions;
25
+ export declare function packDirectoryToTar(dirPath: string): Buffer;
26
+ export declare function extractTarToDirectory(tarBuffer: Buffer, dirPath: string): void;
27
+ export declare function runKnPushCommand(args: string[]): Promise<number>;
28
+ export declare function runKnPullCommand(args: string[]): Promise<number>;
29
+ export declare function parseKnCreateFromDsArgs(args: string[]): {
30
+ dsId: string;
31
+ name: string;
32
+ tables: string[];
33
+ build: boolean;
34
+ timeout: number;
35
+ businessDomain: string;
36
+ pretty: boolean;
37
+ };
38
+ /** Generate a BKN ObjectType YAML markdown file for a table. */
39
+ export declare function generateObjectTypeBkn(tableName: string, dvId: string, pk: string, dk: string, columns: Array<{
40
+ name: string;
41
+ type: string;
42
+ }>): string;
43
+ export declare function runKnCreateFromDsCommand(args: string[], sampleRows?: Record<string, Array<Record<string, string | null>>>): Promise<number>;
44
+ export declare function parseKnCreateFromCsvArgs(args: string[]): {
45
+ dsId: string;
46
+ files: string;
47
+ name: string;
48
+ tablePrefix: string;
49
+ batchSize: number;
50
+ tables: string[];
51
+ build: boolean;
52
+ timeout: number;
53
+ businessDomain: string;
54
+ };
55
+ export declare function runKnCreateFromCsvCommand(args: string[]): Promise<number>;
56
+ export interface ActionScheduleParsed {
57
+ action: string;
58
+ knId: string;
59
+ itemId: string;
60
+ body: string;
61
+ extra: string;
62
+ yes: boolean;
63
+ pretty: boolean;
64
+ businessDomain: string;
65
+ }
66
+ export declare function parseActionScheduleArgs(args: string[]): ActionScheduleParsed;
67
+ export declare function runKnActionScheduleCommand(args: string[]): Promise<number>;
68
+ export interface JobParsed {
69
+ action: string;
70
+ knId: string;
71
+ itemId: string;
72
+ yes: boolean;
73
+ pretty: boolean;
74
+ businessDomain: string;
75
+ }
76
+ export declare function parseJobArgs(args: string[]): JobParsed;
77
+ export declare function runKnJobCommand(args: string[]): Promise<number>;