@kweaver-ai/kweaver-sdk 0.5.2 → 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 (56) hide show
  1. package/README.md +19 -1
  2. package/README.zh.md +19 -1
  3. package/dist/api/agent-chat.d.ts +7 -1
  4. package/dist/api/agent-chat.js +146 -40
  5. package/dist/api/agent-list.js +13 -13
  6. package/dist/api/business-domains.js +9 -5
  7. package/dist/api/context-loader.js +4 -1
  8. package/dist/api/conversations.js +4 -9
  9. package/dist/api/dataflow2.d.ts +95 -0
  10. package/dist/api/dataflow2.js +80 -0
  11. package/dist/api/headers.d.ts +2 -0
  12. package/dist/api/headers.js +7 -2
  13. package/dist/api/skills.js +2 -10
  14. package/dist/api/vega.d.ts +0 -16
  15. package/dist/api/vega.js +0 -33
  16. package/dist/auth/oauth.d.ts +1 -1
  17. package/dist/auth/oauth.js +64 -7
  18. package/dist/cli.js +21 -1
  19. package/dist/client.d.ts +9 -0
  20. package/dist/client.js +48 -8
  21. package/dist/commands/auth.js +80 -32
  22. package/dist/commands/bkn-schema.js +22 -0
  23. package/dist/commands/call.js +8 -5
  24. package/dist/commands/dataflow.d.ts +1 -0
  25. package/dist/commands/dataflow.js +251 -0
  26. package/dist/commands/explore-bkn.d.ts +79 -0
  27. package/dist/commands/explore-bkn.js +273 -0
  28. package/dist/commands/explore-chat.d.ts +3 -0
  29. package/dist/commands/explore-chat.js +193 -0
  30. package/dist/commands/explore-vega.d.ts +3 -0
  31. package/dist/commands/explore-vega.js +71 -0
  32. package/dist/commands/explore.d.ts +9 -0
  33. package/dist/commands/explore.js +258 -0
  34. package/dist/commands/vega.js +2 -104
  35. package/dist/config/no-auth.d.ts +3 -0
  36. package/dist/config/no-auth.js +5 -0
  37. package/dist/config/store.d.ts +8 -0
  38. package/dist/config/store.js +22 -0
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/kweaver.d.ts +5 -0
  42. package/dist/kweaver.js +32 -2
  43. package/dist/resources/bkn.js +2 -3
  44. package/dist/resources/knowledge-networks.js +3 -8
  45. package/dist/resources/vega.d.ts +0 -6
  46. package/dist/resources/vega.js +1 -10
  47. package/dist/templates/explorer/app.js +136 -0
  48. package/dist/templates/explorer/bkn.js +747 -0
  49. package/dist/templates/explorer/chat.js +980 -0
  50. package/dist/templates/explorer/dashboard.js +82 -0
  51. package/dist/templates/explorer/index.html +35 -0
  52. package/dist/templates/explorer/style.css +2440 -0
  53. package/dist/templates/explorer/vega.js +291 -0
  54. package/dist/utils/http.d.ts +3 -0
  55. package/dist/utils/http.js +37 -1
  56. package/package.json +9 -5
@@ -0,0 +1,95 @@
1
+ export interface DataflowListItem {
2
+ id: string;
3
+ title?: string;
4
+ status?: string;
5
+ trigger?: string;
6
+ creator?: string;
7
+ updated_at?: number;
8
+ version_id?: string;
9
+ }
10
+ export interface DataflowListResponse {
11
+ dags: DataflowListItem[];
12
+ limit?: number;
13
+ page?: number;
14
+ total?: number;
15
+ }
16
+ export interface DataflowRunSource {
17
+ name?: string;
18
+ content_type?: string;
19
+ size?: number;
20
+ [key: string]: unknown;
21
+ }
22
+ export interface DataflowRunItem {
23
+ id: string;
24
+ status?: string;
25
+ started_at?: number;
26
+ ended_at?: number | null;
27
+ reason?: string | null;
28
+ source?: DataflowRunSource;
29
+ }
30
+ export interface DataflowRunsResponse {
31
+ results: DataflowRunItem[];
32
+ limit?: number;
33
+ page?: number;
34
+ total?: number;
35
+ }
36
+ export interface DataflowLogMetadata {
37
+ duration?: number;
38
+ [key: string]: unknown;
39
+ }
40
+ export interface DataflowLogItem {
41
+ id: string;
42
+ operator?: string;
43
+ status?: string;
44
+ started_at?: number;
45
+ updated_at?: number;
46
+ inputs?: unknown;
47
+ outputs?: unknown;
48
+ taskId?: string;
49
+ metadata?: DataflowLogMetadata;
50
+ }
51
+ export interface DataflowLogsResponse {
52
+ results: DataflowLogItem[];
53
+ limit?: number;
54
+ page?: number;
55
+ total?: number;
56
+ }
57
+ export interface DataflowRunResponse {
58
+ dag_instance_id: string;
59
+ }
60
+ interface BaseOptions {
61
+ baseUrl: string;
62
+ accessToken: string;
63
+ businessDomain?: string;
64
+ }
65
+ export interface RunDataflowWithFileOptions extends BaseOptions {
66
+ dagId: string;
67
+ fileName: string;
68
+ fileBytes: Uint8Array;
69
+ }
70
+ export interface RunDataflowWithRemoteUrlOptions extends BaseOptions {
71
+ dagId: string;
72
+ url: string;
73
+ name: string;
74
+ }
75
+ export interface ListDataflowRunsOptions extends BaseOptions {
76
+ dagId: string;
77
+ page?: number;
78
+ limit?: number;
79
+ sortBy?: string;
80
+ order?: string;
81
+ startTime?: number;
82
+ endTime?: number;
83
+ }
84
+ export interface GetDataflowLogsPageOptions extends BaseOptions {
85
+ dagId: string;
86
+ instanceId: string;
87
+ page: number;
88
+ limit?: number;
89
+ }
90
+ export declare function listDataflows(options: BaseOptions): Promise<DataflowListResponse>;
91
+ export declare function runDataflowWithFile(options: RunDataflowWithFileOptions): Promise<DataflowRunResponse>;
92
+ export declare function runDataflowWithRemoteUrl(options: RunDataflowWithRemoteUrlOptions): Promise<DataflowRunResponse>;
93
+ export declare function listDataflowRuns(options: ListDataflowRunsOptions): Promise<DataflowRunsResponse>;
94
+ export declare function getDataflowLogsPage(options: GetDataflowLogsPageOptions): Promise<DataflowLogsResponse>;
95
+ export {};
@@ -0,0 +1,80 @@
1
+ import { HttpError } from "../utils/http.js";
2
+ import { buildHeaders } from "./headers.js";
3
+ async function parseJsonOrThrow(response) {
4
+ const body = await response.text();
5
+ if (!response.ok) {
6
+ throw new HttpError(response.status, response.statusText, body);
7
+ }
8
+ return JSON.parse(body);
9
+ }
10
+ export async function listDataflows(options) {
11
+ const { baseUrl, accessToken, businessDomain = "bd_public" } = options;
12
+ const base = baseUrl.replace(/\/+$/, "");
13
+ const url = `${base}/api/automation/v2/dags?type=data-flow&page=0&limit=-1`;
14
+ const response = await fetch(url, {
15
+ method: "GET",
16
+ headers: buildHeaders(accessToken, businessDomain),
17
+ });
18
+ return parseJsonOrThrow(response);
19
+ }
20
+ export async function runDataflowWithFile(options) {
21
+ const { baseUrl, accessToken, businessDomain = "bd_public", dagId, fileName, fileBytes } = options;
22
+ const base = baseUrl.replace(/\/+$/, "");
23
+ const url = `${base}/api/automation/v2/dataflow-doc/trigger/${encodeURIComponent(dagId)}`;
24
+ const form = new FormData();
25
+ form.set("file", new Blob([fileBytes]), fileName);
26
+ const response = await fetch(url, {
27
+ method: "POST",
28
+ headers: buildHeaders(accessToken, businessDomain),
29
+ body: form,
30
+ });
31
+ return parseJsonOrThrow(response);
32
+ }
33
+ export async function runDataflowWithRemoteUrl(options) {
34
+ const { baseUrl, accessToken, businessDomain = "bd_public", dagId, url, name } = options;
35
+ const base = baseUrl.replace(/\/+$/, "");
36
+ const endpoint = `${base}/api/automation/v2/dataflow-doc/trigger/${encodeURIComponent(dagId)}`;
37
+ const response = await fetch(endpoint, {
38
+ method: "POST",
39
+ headers: {
40
+ ...buildHeaders(accessToken, businessDomain),
41
+ "content-type": "application/json",
42
+ },
43
+ body: JSON.stringify({
44
+ source_from: "remote",
45
+ url,
46
+ name,
47
+ }),
48
+ });
49
+ return parseJsonOrThrow(response);
50
+ }
51
+ export async function listDataflowRuns(options) {
52
+ const { baseUrl, accessToken, businessDomain = "bd_public", dagId, page = 0, limit = 100, sortBy, order, startTime, endTime, } = options;
53
+ const base = baseUrl.replace(/\/+$/, "");
54
+ const url = new URL(`${base}/api/automation/v2/dag/${encodeURIComponent(dagId)}/results`);
55
+ url.searchParams.set("page", String(page));
56
+ url.searchParams.set("limit", String(limit));
57
+ if (sortBy)
58
+ url.searchParams.set("sortBy", sortBy);
59
+ if (order)
60
+ url.searchParams.set("order", order);
61
+ if (startTime != null)
62
+ url.searchParams.set("start_time", String(startTime));
63
+ if (endTime != null)
64
+ url.searchParams.set("end_time", String(endTime));
65
+ const response = await fetch(url.toString(), {
66
+ method: "GET",
67
+ headers: buildHeaders(accessToken, businessDomain),
68
+ });
69
+ return parseJsonOrThrow(response);
70
+ }
71
+ export async function getDataflowLogsPage(options) {
72
+ const { baseUrl, accessToken, businessDomain = "bd_public", dagId, instanceId, page, limit = 10 } = options;
73
+ const base = baseUrl.replace(/\/+$/, "");
74
+ const url = `${base}/api/automation/v2/dag/${encodeURIComponent(dagId)}/result/${encodeURIComponent(instanceId)}?page=${page}&limit=${limit}`;
75
+ const response = await fetch(url, {
76
+ method: "GET",
77
+ headers: buildHeaders(accessToken, businessDomain),
78
+ });
79
+ return parseJsonOrThrow(response);
80
+ }
@@ -5,5 +5,7 @@
5
5
  * environment variables KWEAVER_ACCOUNT_ID and KWEAVER_ACCOUNT_TYPE.
6
6
  * These are required by older platform versions (e.g. dip-poc.aishu.cn)
7
7
  * that do not infer account info from the token automatically.
8
+ *
9
+ * When accessToken is the no-auth sentinel, `authorization` and `token` are omitted.
8
10
  */
9
11
  export declare function buildHeaders(accessToken: string, businessDomain: string): Record<string, string>;
@@ -1,3 +1,4 @@
1
+ import { isNoAuth } from "../config/no-auth.js";
1
2
  /**
2
3
  * Shared HTTP header builder for all KWeaver API calls.
3
4
  *
@@ -5,16 +6,20 @@
5
6
  * environment variables KWEAVER_ACCOUNT_ID and KWEAVER_ACCOUNT_TYPE.
6
7
  * These are required by older platform versions (e.g. dip-poc.aishu.cn)
7
8
  * that do not infer account info from the token automatically.
9
+ *
10
+ * When accessToken is the no-auth sentinel, `authorization` and `token` are omitted.
8
11
  */
9
12
  export function buildHeaders(accessToken, businessDomain) {
10
13
  const headers = {
11
14
  accept: "application/json, text/plain, */*",
12
15
  "accept-language": "zh-cn",
13
- authorization: `Bearer ${accessToken}`,
14
- token: accessToken,
15
16
  "x-business-domain": businessDomain,
16
17
  "x-language": "zh-cn",
17
18
  };
19
+ if (!isNoAuth(accessToken)) {
20
+ headers.authorization = `Bearer ${accessToken}`;
21
+ headers.token = accessToken;
22
+ }
18
23
  const accountId = process.env.KWEAVER_ACCOUNT_ID;
19
24
  const accountType = process.env.KWEAVER_ACCOUNT_TYPE;
20
25
  if (accountId)
@@ -2,19 +2,11 @@ import { spawnSync } from "node:child_process";
2
2
  import { Buffer } from "node:buffer";
3
3
  import { existsSync, mkdirSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { basename, resolve } from "node:path";
5
+ import { buildHeaders as buildPlatformHeaders } from "./headers.js";
5
6
  import { HttpError, fetchTextOrThrow } from "../utils/http.js";
6
7
  const SKILL_API_PREFIX = "/api/agent-operator-integration/v1";
7
- function buildHeaders(accessToken, businessDomain) {
8
- return {
9
- accept: "application/json, text/plain, */*",
10
- authorization: `Bearer ${accessToken}`,
11
- token: accessToken,
12
- "x-business-domain": businessDomain,
13
- "x-language": "zh-cn",
14
- };
15
- }
16
8
  function baseHeaders(opts) {
17
- return buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public");
9
+ return buildPlatformHeaders(opts.accessToken, opts.businessDomain ?? "bd_public");
18
10
  }
19
11
  function buildUrl(baseUrl, path) {
20
12
  return `${baseUrl.replace(/\/+$/, "")}${path}`;
@@ -165,15 +165,6 @@ export interface SetVegaConnectorTypeEnabledOptions {
165
165
  businessDomain?: string;
166
166
  }
167
167
  export declare function setVegaConnectorTypeEnabled(options: SetVegaConnectorTypeEnabledOptions): Promise<string>;
168
- export interface ListVegaDiscoverTasksOptions {
169
- baseUrl: string;
170
- accessToken: string;
171
- status?: string;
172
- limit?: number;
173
- offset?: number;
174
- businessDomain?: string;
175
- }
176
- export declare function listVegaDiscoverTasks(options: ListVegaDiscoverTasksOptions): Promise<string>;
177
168
  export interface CreateVegaDatasetDocsOptions {
178
169
  baseUrl: string;
179
170
  accessToken: string;
@@ -237,10 +228,3 @@ export interface ListAllVegaResourcesOptions {
237
228
  businessDomain?: string;
238
229
  }
239
230
  export declare function listAllVegaResources(options: ListAllVegaResourcesOptions): Promise<string>;
240
- export interface GetVegaDiscoverTaskOptions {
241
- baseUrl: string;
242
- accessToken: string;
243
- id: string;
244
- businessDomain?: string;
245
- }
246
- export declare function getVegaDiscoverTask(options: GetVegaDiscoverTaskOptions): Promise<string>;
package/dist/api/vega.js CHANGED
@@ -346,26 +346,6 @@ export async function setVegaConnectorTypeEnabled(options) {
346
346
  throw new HttpError(response.status, response.statusText, body);
347
347
  return body;
348
348
  }
349
- export async function listVegaDiscoverTasks(options) {
350
- const { baseUrl, accessToken, status, limit, offset, businessDomain = "bd_public", } = options;
351
- const base = baseUrl.replace(/\/+$/, "");
352
- const url = new URL(`${base}${VEGA_BASE}/discover-tasks`);
353
- if (status)
354
- url.searchParams.set("status", status);
355
- if (limit !== undefined)
356
- url.searchParams.set("limit", String(limit));
357
- if (offset !== undefined)
358
- url.searchParams.set("offset", String(offset));
359
- const response = await fetch(url.toString(), {
360
- method: "GET",
361
- headers: buildHeaders(accessToken, businessDomain),
362
- });
363
- const body = await response.text();
364
- if (!response.ok) {
365
- throw new HttpError(response.status, response.statusText, body);
366
- }
367
- return body;
368
- }
369
349
  export async function createVegaDatasetDocs(options) {
370
350
  const { baseUrl, accessToken, id, body: requestBody, businessDomain = "bd_public" } = options;
371
351
  const base = baseUrl.replace(/\/+$/, "");
@@ -495,16 +475,3 @@ export async function listAllVegaResources(options) {
495
475
  throw new HttpError(response.status, response.statusText, body);
496
476
  return body;
497
477
  }
498
- export async function getVegaDiscoverTask(options) {
499
- const { baseUrl, accessToken, id, businessDomain = "bd_public" } = options;
500
- const base = baseUrl.replace(/\/+$/, "");
501
- const url = `${base}${VEGA_BASE}/discover-tasks/${encodeURIComponent(id)}`;
502
- const response = await fetch(url, {
503
- method: "GET",
504
- headers: buildHeaders(accessToken, businessDomain),
505
- });
506
- const body = await response.text();
507
- if (!response.ok)
508
- throw new HttpError(response.status, response.statusText, body);
509
- return body;
510
- }
@@ -21,7 +21,7 @@ export declare function normalizeBaseUrl(value: string): string;
21
21
  */
22
22
  export declare function oauth2Login(baseUrl: string, options?: {
23
23
  port?: number;
24
- /** Full redirect URI override (e.g. "http://127.0.0.1:8080/callback" or a remote URL). */
24
+ /** Full redirect URI override (e.g. "http://127.0.0.1:9010/callback" or a remote URL). */
25
25
  redirectUri?: string;
26
26
  scope?: string;
27
27
  clientId?: string;
@@ -1,5 +1,6 @@
1
- import { deleteClientConfig, getCurrentPlatform, loadClientConfig, loadTokenConfig, loadUserTokenConfig, resolveUserId, saveClientConfig, saveTokenConfig, setCurrentPlatform, } from "../config/store.js";
2
- import { HttpError, NetworkRequestError } from "../utils/http.js";
1
+ import { isNoAuth } from "../config/no-auth.js";
2
+ import { deleteClientConfig, getCurrentPlatform, loadClientConfig, loadTokenConfig, loadUserTokenConfig, resolveUserId, saveClientConfig, saveNoAuthPlatform, saveTokenConfig, setCurrentPlatform, } from "../config/store.js";
3
+ import { HttpError, NetworkRequestError, fetchWithRetry } from "../utils/http.js";
3
4
  const TOKEN_TTL_SECONDS = 3600;
4
5
  /** Seconds before access token expiry to trigger refresh (matches Python ConfigAuth). */
5
6
  const REFRESH_THRESHOLD_SEC = 60;
@@ -282,7 +283,17 @@ export async function oauth2Login(baseUrl, options) {
282
283
  const listenPort = parsedRedirect?.port ?? port;
283
284
  const callbackPathname = parsedRedirect?.pathname ?? "/callback";
284
285
  // Step 1: Determine client — use provided client ID or fall back to dynamic registration
285
- let client = await resolveOrRegisterClient(base, redirectUri, scope, options);
286
+ let client;
287
+ try {
288
+ client = await resolveOrRegisterClient(base, redirectUri, scope, options);
289
+ }
290
+ catch (e) {
291
+ if (e instanceof HttpError && e.status === 404) {
292
+ process.stderr.write("OAuth2 endpoint not found (404). Saving platform in no-auth mode.\n");
293
+ return saveNoAuthPlatform(base, { tlsInsecure: options?.tlsInsecure });
294
+ }
295
+ throw e;
296
+ }
286
297
  // Use PKCE when no client secret is available (public client / platform client).
287
298
  const usePkce = !client.clientSecret;
288
299
  const pkce = usePkce ? await generatePkce() : null;
@@ -515,7 +526,17 @@ export async function playwrightLogin(baseUrl, options) {
515
526
  const callbackPathname = parsedRedirect?.pathname ?? "/callback";
516
527
  const hasCredentials = !!(options?.username && options?.password);
517
528
  // Step 1: Ensure registered OAuth2 client (with stale-client auto-recovery)
518
- let client = await resolveOrRegisterClient(base, redirectUri, scope);
529
+ let client;
530
+ try {
531
+ client = await resolveOrRegisterClient(base, redirectUri, scope);
532
+ }
533
+ catch (e) {
534
+ if (e instanceof HttpError && e.status === 404) {
535
+ process.stderr.write("OAuth2 endpoint not found (404). Saving platform in no-auth mode.\n");
536
+ return saveNoAuthPlatform(base, { tlsInsecure: options?.tlsInsecure });
537
+ }
538
+ throw e;
539
+ }
519
540
  // Step 2: Generate CSRF state
520
541
  const state = randomBytes(12).toString("hex");
521
542
  // Step 3: Build authorization URL
@@ -676,6 +697,9 @@ export async function refreshTokenLogin(baseUrl, options) {
676
697
  return token;
677
698
  }
678
699
  function tokenNeedsRefresh(token) {
700
+ if (isNoAuth(token.accessToken)) {
701
+ return false;
702
+ }
679
703
  if (!token.expiresAt) {
680
704
  return false;
681
705
  }
@@ -692,6 +716,9 @@ function tokenNeedsRefresh(token) {
692
716
  */
693
717
  export async function refreshAccessToken(token) {
694
718
  const baseUrl = normalizeBaseUrl(token.baseUrl);
719
+ if (isNoAuth(token.accessToken)) {
720
+ throw new Error(`Cannot refresh no-auth session for ${baseUrl}.`);
721
+ }
695
722
  const refreshToken = token.refreshToken?.trim();
696
723
  if (!refreshToken) {
697
724
  throw new Error(`Token expired and no refresh_token available for ${baseUrl}. Run \`kweaver auth login ${baseUrl}\` again.`);
@@ -710,7 +737,7 @@ export async function refreshAccessToken(token) {
710
737
  });
711
738
  let response;
712
739
  try {
713
- response = await runWithTlsInsecure(token.tlsInsecure, () => fetch(url, {
740
+ response = await runWithTlsInsecure(token.tlsInsecure, () => fetchWithRetry(url, {
714
741
  method: "POST",
715
742
  headers: {
716
743
  Authorization: `Basic ${credentials}`,
@@ -777,11 +804,24 @@ export async function ensureValidToken(opts) {
777
804
  return {
778
805
  baseUrl: normalizeBaseUrl(envBaseUrl),
779
806
  accessToken: rawToken,
780
- tokenType: "bearer",
807
+ tokenType: isNoAuth(rawToken) ? "none" : "bearer",
781
808
  scope: "",
782
809
  obtainedAt: new Date().toISOString(),
783
810
  };
784
811
  }
812
+ if (!opts?.forceRefresh && envToken && !envBaseUrl) {
813
+ const currentPlatformForEnv = getCurrentPlatform();
814
+ if (currentPlatformForEnv) {
815
+ const rawToken = envToken.replace(/^Bearer\s+/i, "");
816
+ return {
817
+ baseUrl: normalizeBaseUrl(currentPlatformForEnv),
818
+ accessToken: rawToken,
819
+ tokenType: isNoAuth(rawToken) ? "none" : "bearer",
820
+ scope: "",
821
+ obtainedAt: new Date().toISOString(),
822
+ };
823
+ }
824
+ }
785
825
  const currentPlatform = getCurrentPlatform();
786
826
  if (!currentPlatform) {
787
827
  throw new Error("No active platform selected. Run `kweaver auth login <platform-url>` first.");
@@ -803,6 +843,9 @@ export async function ensureValidToken(opts) {
803
843
  if (!token) {
804
844
  throw new Error(`No saved token for ${currentPlatform}. Run \`kweaver auth login ${currentPlatform}\` first.`);
805
845
  }
846
+ if (isNoAuth(token.accessToken)) {
847
+ return token;
848
+ }
806
849
  if (opts?.forceRefresh) {
807
850
  return refreshAccessToken(token);
808
851
  }
@@ -845,6 +888,9 @@ export async function with401RefreshRetry(fn) {
845
888
  if (!latest) {
846
889
  throw error;
847
890
  }
891
+ if (isNoAuth(latest.accessToken)) {
892
+ throw error;
893
+ }
848
894
  try {
849
895
  await refreshAccessToken(latest);
850
896
  }
@@ -869,6 +915,9 @@ export async function withTokenRetry(fn) {
869
915
  }
870
916
  catch (error) {
871
917
  if (error instanceof HttpError && error.status === 401) {
918
+ if (isNoAuth(token.accessToken)) {
919
+ throw error;
920
+ }
872
921
  const platformUrl = normalizeBaseUrl(token.baseUrl);
873
922
  const envUser = process.env.KWEAVER_USER;
874
923
  let latest;
@@ -918,6 +967,11 @@ function formatOAuthErrorBody(body) {
918
967
  }
919
968
  return lines.join("\n");
920
969
  }
970
+ function isTlsVerificationDisabledForProcess() {
971
+ return (process.env.NODE_TLS_REJECT_UNAUTHORIZED === "0" ||
972
+ process.env.KWEAVER_TLS_INSECURE === "1" ||
973
+ process.env.KWEAVER_TLS_INSECURE === "true");
974
+ }
921
975
  export function formatHttpError(error) {
922
976
  if (error instanceof HttpError) {
923
977
  const oauthMessage = formatOAuthErrorBody(error.body);
@@ -938,7 +992,10 @@ export function formatHttpError(error) {
938
992
  if (error instanceof Error) {
939
993
  const cause = "cause" in error && error.cause instanceof Error ? error.cause.message : "";
940
994
  if (cause && error.message === "fetch failed") {
941
- return `${error.message}: ${cause}\nHint: use --insecure (-k) to skip TLS verification for self-signed certificates.`;
995
+ const hint = isTlsVerificationDisabledForProcess()
996
+ ? "Hint: TLS verification is already disabled for this process. Check network reachability, TLS termination, or proxy stability."
997
+ : "Hint: use --insecure (-k) to skip TLS verification for self-signed certificates.";
998
+ return `${error.message}: ${cause}\n${hint}`;
942
999
  }
943
1000
  return error.message;
944
1001
  }
package/dist/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { NO_AUTH_TOKEN } from "./config/no-auth.js";
1
2
  import { applyTlsEnvFromSavedTokens } from "./config/tls-env.js";
2
3
  import { runAgentCommand } from "./commands/agent.js";
3
4
  import { runAuthCommand } from "./commands/auth.js";
@@ -5,7 +6,9 @@ import { runKnCommand } from "./commands/bkn.js";
5
6
  import { runCallCommand } from "./commands/call.js";
6
7
  import { runConfigCommand } from "./commands/config.js";
7
8
  import { runContextLoaderCommand } from "./commands/context-loader.js";
9
+ import { runDataflowCommand } from "./commands/dataflow.js";
8
10
  import { runDsCommand } from "./commands/ds.js";
11
+ import { runExploreCommand } from "./commands/explore.js";
9
12
  import { runDataviewCommand } from "./commands/dataview.js";
10
13
  import { runSkillCommand } from "./commands/skill.js";
11
14
  import { runTokenCommand } from "./commands/token.js";
@@ -18,7 +21,7 @@ Usage:
18
21
  kweaver --version | -V
19
22
  kweaver --help | -h
20
23
 
21
- kweaver auth <platform-url> [--alias name] [-u user] [-p pass] [--playwright] [--insecure|-k]
24
+ kweaver auth <platform-url> [--alias name] [--no-auth] [-u user] [-p pass] [--playwright] [--insecure|-k]
22
25
  kweaver auth login <platform-url> (alias for auth <url>)
23
26
  kweaver auth login <url> --client-id ID --client-secret S --refresh-token T (run on host without browser)
24
27
  kweaver auth whoami [platform-url|alias] [--json]
@@ -55,6 +58,11 @@ Usage:
55
58
  kweaver ds tables <id> [--keyword X] [--pretty]
56
59
  kweaver ds connect <db_type> <host> <port> <database> --account X --password Y [--schema S] [--name N]
57
60
 
61
+ kweaver dataflow list [-bd value]
62
+ kweaver dataflow run <dagId> (--file <path> | --url <remote-url> --name <filename>) [-bd value]
63
+ kweaver dataflow runs <dagId> [--since <date-like>] [-bd value]
64
+ kweaver dataflow logs <dagId> <instanceId> [--detail] [-bd value]
65
+
58
66
  kweaver dataview list [--datasource-id id] [--type atomic|custom] [--limit n] [-bd value] [--pretty]
59
67
  kweaver dataview find --name <name> [--exact] [--datasource-id id] [--wait] [--timeout ms] [-bd value] [--pretty]
60
68
  kweaver dataview get <id> [-bd value] [--pretty]
@@ -114,6 +122,7 @@ Commands:
114
122
  call (curl) Call an API with curl-style flags and auto-injected token headers
115
123
  agent Agent CRUD, chat, sessions, history, publish/unpublish
116
124
  ds Manage datasources (list, get, delete, tables, connect)
125
+ dataflow Dataflow document workflows (list, run, runs, logs)
117
126
  dataview|dv List, find, get, query (SQL), delete data views (atomic / custom)
118
127
  bkn Knowledge network (CRUD, build, validate, export, stats, push/pull,
119
128
  object-type, relation-type, subgraph, action-type, action-execution, action-log)
@@ -125,6 +134,11 @@ Commands:
125
134
  }
126
135
  export async function run(argv) {
127
136
  applyTlsEnvFromSavedTokens();
137
+ const noAuthEnv = process.env.KWEAVER_NO_AUTH;
138
+ if ((noAuthEnv === "1" || noAuthEnv === "true" || noAuthEnv === "yes") &&
139
+ !process.env.KWEAVER_TOKEN) {
140
+ process.env.KWEAVER_TOKEN = NO_AUTH_TOKEN;
141
+ }
128
142
  // Global --user flag: override active user for this invocation
129
143
  const userIdx = argv.indexOf("--user");
130
144
  let filteredArgv = argv;
@@ -153,6 +167,9 @@ export async function run(argv) {
153
167
  if (command === "ds") {
154
168
  return runDsCommand(rest);
155
169
  }
170
+ if (command === "dataflow") {
171
+ return runDataflowCommand(rest);
172
+ }
156
173
  if (command === "dataview" || command === "dv") {
157
174
  return runDataviewCommand(rest);
158
175
  }
@@ -162,6 +179,9 @@ export async function run(argv) {
162
179
  if (command === "agent") {
163
180
  return runAgentCommand(rest);
164
181
  }
182
+ if (command === "explore") {
183
+ return runExploreCommand(rest);
184
+ }
165
185
  if (command === "bkn") {
166
186
  return runKnCommand(rest);
167
187
  }
package/dist/client.d.ts CHANGED
@@ -40,8 +40,17 @@ export interface KWeaverClientOptions {
40
40
  * When true, read credentials exclusively from ~/.kweaver/ (saved by
41
41
  * `kweaver auth login`), ignoring KWEAVER_BASE_URL / KWEAVER_TOKEN env vars.
42
42
  * Useful when env vars hold stale tokens or are intended for other tooling.
43
+ * Incompatible with `auth: false` — the constructor throws if both are set.
43
44
  */
44
45
  config?: boolean;
46
+ /**
47
+ * When false, use no-auth mode: API requests omit Authorization / token headers.
48
+ * Requires a resolvable base URL: `baseUrl`, `KWEAVER_BASE_URL`, or the active
49
+ * platform from `kweaver auth login`. Incompatible with `config: true` — use
50
+ * saved `~/.kweaver/` credentials (including `__NO_AUTH__`) via `config: true`
51
+ * alone instead of passing `auth: false`.
52
+ */
53
+ auth?: boolean;
45
54
  }
46
55
  /**
47
56
  * Main entry point for the KWeaver TypeScript SDK.
package/dist/client.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { applyTlsEnvFromSavedTokens } from "./config/tls-env.js";
2
+ import { NO_AUTH_TOKEN, isNoAuth } from "./config/no-auth.js";
2
3
  import { getCurrentPlatform, loadTokenConfig, } from "./config/store.js";
4
+ import { buildHeaders } from "./api/headers.js";
3
5
  import { ensureValidToken } from "./auth/oauth.js";
4
6
  import { AgentsResource } from "./resources/agents.js";
5
7
  import { ConversationsResource } from "./resources/conversations.js";
@@ -64,8 +66,39 @@ export class KWeaverClient {
64
66
  skills;
65
67
  constructor(opts = {}) {
66
68
  const envDomain = process.env.KWEAVER_BUSINESS_DOMAIN;
69
+ if (opts.auth === false && opts.config) {
70
+ throw new Error("KWeaverClient: auth: false is incompatible with config: true.");
71
+ }
67
72
  let baseUrl;
68
73
  let accessToken;
74
+ if (opts.auth === false) {
75
+ {
76
+ const envUrl = process.env.KWEAVER_BASE_URL;
77
+ baseUrl = opts.baseUrl ?? envUrl;
78
+ if (!baseUrl) {
79
+ const platform = getCurrentPlatform();
80
+ if (platform)
81
+ baseUrl = platform;
82
+ }
83
+ }
84
+ if (!baseUrl) {
85
+ throw new Error("KWeaverClient: baseUrl is required when auth is false. " +
86
+ "Pass it explicitly, set KWEAVER_BASE_URL, or run `kweaver auth login`.");
87
+ }
88
+ this._baseUrl = baseUrl.replace(/\/+$/, "");
89
+ this._accessToken = NO_AUTH_TOKEN;
90
+ this._businessDomain = opts.businessDomain ?? envDomain ?? "bd_public";
91
+ this.knowledgeNetworks = new KnowledgeNetworksResource(this);
92
+ this.agents = new AgentsResource(this);
93
+ this.bkn = new BknResource(this);
94
+ this.conversations = new ConversationsResource(this);
95
+ this.dataflows = new DataflowsResource(this);
96
+ this.datasources = new DataSourcesResource(this);
97
+ this.dataviews = new DataViewsResource(this);
98
+ this.vega = new VegaResource(this);
99
+ this.skills = new SkillsResource(this);
100
+ return;
101
+ }
69
102
  if (opts.config) {
70
103
  // config: true — read exclusively from ~/.kweaver/, ignore env vars
71
104
  const platform = getCurrentPlatform();
@@ -140,15 +173,22 @@ export class KWeaverClient {
140
173
  accessToken: token.accessToken,
141
174
  ...opts,
142
175
  });
143
- // Quick probe — if the token was revoked server-side, force refresh
144
- try {
145
- const probe = await fetch(`${token.baseUrl.replace(/\/+$/, "")}/api/ontology-manager/v1/knowledge-networks?limit=1`, { headers: { authorization: `Bearer ${token.accessToken}`, token: token.accessToken } });
146
- if (probe.status === 401) {
147
- throw new Error("Access token revoked. Run `kweaver auth login` to re-authenticate.");
176
+ if (!isNoAuth(token.accessToken)) {
177
+ // Quick probe — if the token was revoked server-side, force refresh
178
+ try {
179
+ const bd = client.base().businessDomain;
180
+ const probe = await fetch(`${token.baseUrl.replace(/\/+$/, "")}/api/ontology-manager/v1/knowledge-networks?limit=1`, { headers: buildHeaders(token.accessToken, bd) });
181
+ if (probe.status === 401) {
182
+ throw new Error("Access token revoked. Run `kweaver auth login` to re-authenticate.");
183
+ }
184
+ }
185
+ catch (e) {
186
+ if (e instanceof Error &&
187
+ e.message.startsWith("Access token revoked")) {
188
+ throw e;
189
+ }
190
+ // Network error — return client as-is, let the caller deal with it
148
191
  }
149
- }
150
- catch {
151
- // Network error — return client as-is, let the caller deal with it
152
192
  }
153
193
  return client;
154
194
  }