@kweaver-ai/kweaver-sdk 0.6.5 → 0.6.7

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,18 +1,8 @@
1
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";
2
+ import { autoSelectBusinessDomain, clearPlatformSession, deletePlatform, deleteUser, getActiveUser, getConfigDir, getCurrentPlatform, getPlatformAlias, hasPlatform, listPlatforms, listUserProfiles, loadClientConfig, loadTokenConfig, loadUserTokenConfig, resolveBusinessDomain, resolvePlatformIdentifier, resolveUserId, saveNoAuthPlatform, setActiveUser, setCurrentPlatform, setPlatformAlias, } from "../config/store.js";
3
3
  import { decodeJwtPayload } from "../config/jwt.js";
4
- import { buildCopyCommand, formatHttpError, isStudiowebShellUnavailableError, normalizeBaseUrl, oauth2Login, oauth2PasswordSigninLogin, playwrightLogin, refreshTokenLogin, } from "../auth/oauth.js";
5
- /** True when the `playwright` npm package can be imported (browser binaries may still need `npx playwright install`). */
6
- async function isPlaywrightPackageResolvable() {
7
- try {
8
- const modName = "playwright";
9
- await import(/* webpackIgnore: true */ modName);
10
- return true;
11
- }
12
- catch {
13
- return false;
14
- }
15
- }
4
+ import { eacpModifyPassword } from "../auth/eacp-modify-password.js";
5
+ import { buildCopyCommand, formatHttpError, InitialPasswordChangeRequiredError, normalizeBaseUrl, oauth2Login, oauth2PasswordSigninLogin, promptForUsername, promptForPassword, refreshTokenLogin, } from "../auth/oauth.js";
16
6
  export async function runAuthCommand(args) {
17
7
  const target = args[0];
18
8
  const rest = args.slice(1);
@@ -28,6 +18,7 @@ kweaver auth users [url|alias] List all user profiles (with usernames) for
28
18
  kweaver auth switch [url|alias] --user <id|username> Switch active user for a platform
29
19
  kweaver auth logout [url|alias] [--user <id>] Logout (clear local token)
30
20
  kweaver auth delete <url|alias> [--user <id>] Delete saved credentials
21
+ kweaver auth change-password [<url>] [-u <account>] [-o <old>] [-n <new>] Change password
31
22
 
32
23
  Login options:
33
24
  --alias <name> Save platform with a short alias (use with use / status / logout)
@@ -39,24 +30,25 @@ Login options:
39
30
  Requires --client-id and --client-secret.
40
31
  Get these from the callback page after browser login or \`auth export\`.
41
32
  --port <n> Local callback port (default: 9010). Use when 9010 is occupied.
42
- --no-browser Do not open a browser; print the auth URL and prompt for the callback URL or code (stdin).
43
- Use on headless servers or when automatic browser launch fails.
44
- -u, --username Username (with -p: tries HTTP /oauth2/signin first when the Studio web shell is available)
45
- -p, --password Password (with -u: falls back to Playwright headless only when studioweb is unavailable and Playwright is installed)
46
- --http-signin With -u/-p: HTTP POST /oauth2/signin only (no Playwright fallback). Uses the built-in RSA public key.
47
- --playwright With -u/-p: force Playwright (skip HTTP sign-in). Without -u/-p: open Playwright for manual login.
33
+ --no-browser Do not open a browser. Without -u/-p: print the auth URL and prompt for the
34
+ callback URL or code (stdin). With -u and/or -p: route through HTTP sign-in
35
+ (any missing credential is prompted; password is hidden when stdin is a TTY).
36
+ -u, --username Username for HTTP /oauth2/signin (POST). If -p is omitted, password is prompted.
37
+ -p, --password Password for HTTP /oauth2/signin (POST). If -u is omitted, username is prompted.
38
+ --http-signin Force HTTP /oauth2/signin (no browser). Missing -u/-p are prompted from stdin.
39
+ --new-password <pwd> After HTTP sign-in error 401001017 (initial password), set the new password non-interactively, then retry login.
48
40
  --insecure, -k Skip TLS certificate verification (self-signed / dev HTTPS only)
49
41
  --no-auth Save platform without OAuth (servers with no authentication). Same as detecting OAuth 404 during login.`);
50
42
  return 0;
51
43
  }
52
44
  if (target === "login") {
53
45
  if (rest[0] === "--help" || rest[0] === "-h") {
54
- console.log(`kweaver auth login <platform-url> [--alias <name>] [--no-auth] [--no-browser] [-u user] [-p pass] [--http-signin] [--playwright] [--refresh-token T --client-id ID --client-secret S]`);
46
+ console.log(`kweaver auth login <platform-url> [--alias <name>] [--no-auth] [--no-browser] [-u user] [-p pass] [--new-password <pwd>] [--http-signin] [--refresh-token T --client-id ID --client-secret S]`);
55
47
  return 0;
56
48
  }
57
49
  const url = rest[0];
58
50
  if (!url || url.startsWith("-")) {
59
- console.error("Usage: kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass] [--playwright]");
51
+ console.error("Usage: kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass]");
60
52
  return 1;
61
53
  }
62
54
  return runAuthCommand([url, ...rest.slice(1)]);
@@ -73,14 +65,16 @@ Login options:
73
65
  if (target === "switch") {
74
66
  return runAuthSwitchCommand(rest);
75
67
  }
68
+ if (target === "change-password") {
69
+ return runAuthChangePasswordCommand(rest);
70
+ }
76
71
  const LOGIN_SUBCOMMANDS = new Set(["status", "list", "use", "delete", "logout", "export", "whoami", "users", "switch"]);
77
72
  if (target && !LOGIN_SUBCOMMANDS.has(target)) {
78
73
  try {
79
74
  const normalizedTarget = normalizeBaseUrl(target);
80
75
  const alias = readOption(args, "--alias");
81
- const username = readOption(args, "--username") ?? readOption(args, "-u");
82
- const password = readOption(args, "--password") ?? readOption(args, "-p");
83
- const usePlaywright = args.includes("--playwright");
76
+ let username = readOption(args, "--username") ?? readOption(args, "-u");
77
+ let password = readOption(args, "--password") ?? readOption(args, "-p");
84
78
  const httpSignin = args.includes("--http-signin");
85
79
  const oauthProduct = readOption(args, "--oauth-product");
86
80
  const signinPublicKeyFile = readOption(args, "--signin-public-key-file");
@@ -92,6 +86,7 @@ Login options:
92
86
  const tlsInsecure = args.includes("--insecure") || args.includes("-k");
93
87
  const noAuth = args.includes("--no-auth");
94
88
  const noBrowser = args.includes("--no-browser");
89
+ const newPasswordFlag = readOption(args, "--new-password");
95
90
  if (args.includes("--redirect-uri")) {
96
91
  console.error("Warning: --redirect-uri is deprecated and ignored. The redirect URI is always http://127.0.0.1:<port>/callback.");
97
92
  }
@@ -99,13 +94,15 @@ Login options:
99
94
  "--alias", "--client-id", "--client-secret", "--refresh-token",
100
95
  "--port", "--no-browser", "--username", "-u", "--password", "-p",
101
96
  "--http-signin",
97
+ "--new-password",
102
98
  "--oauth-product",
103
99
  "--signin-public-key-file",
104
- "--playwright", "--insecure", "-k", "--no-auth", "--redirect-uri",
100
+ "--insecure", "-k", "--no-auth", "--redirect-uri",
105
101
  ]);
106
102
  const KNOWN_VALUE_FLAGS = new Set([
107
103
  "--alias", "--client-id", "--client-secret", "--refresh-token",
108
104
  "--port", "--username", "-u", "--password", "-p", "--redirect-uri",
105
+ "--new-password",
109
106
  "--oauth-product",
110
107
  "--signin-public-key-file",
111
108
  ]);
@@ -130,30 +127,38 @@ Login options:
130
127
  if (noAuth && noBrowser) {
131
128
  console.error("--no-auth does not require a browser; --no-browser is ignored.");
132
129
  }
133
- if (noAuth && (username || password || usePlaywright || httpSignin)) {
134
- console.error("--no-auth cannot be used with Playwright login, HTTP sign-in, or -u/-p.");
130
+ if (noAuth && (username || password || httpSignin)) {
131
+ console.error("--no-auth cannot be used with HTTP sign-in or -u/-p.");
135
132
  return 1;
136
133
  }
137
- if (noBrowser && (username || password || usePlaywright || httpSignin)) {
138
- console.error("--no-browser cannot be used with Playwright login, HTTP sign-in, or -u/-p.");
134
+ if (newPasswordFlag !== undefined && (!username || !password)) {
135
+ console.error("--new-password requires -u/--username and -p/--password (HTTP sign-in).");
139
136
  return 1;
140
137
  }
141
- if (httpSignin && usePlaywright) {
142
- console.error("--http-signin cannot be used with --playwright.");
143
- return 1;
138
+ if (noBrowser && httpSignin) {
139
+ // HTTP sign-in already runs without a browser; --no-browser is a no-op signal here.
140
+ console.error("--http-signin already runs without a browser; --no-browser is redundant and ignored.");
144
141
  }
145
142
  if (httpSignin && refreshToken) {
146
143
  console.error("--http-signin cannot be used with --refresh-token.");
147
144
  return 1;
148
145
  }
149
- if (httpSignin && (!username || !password)) {
150
- console.error("--http-signin requires -u/--username and -p/--password.");
151
- return 1;
152
- }
153
146
  if (noBrowser && refreshToken) {
154
147
  console.error("--no-browser cannot be used with --refresh-token.");
155
148
  return 1;
156
149
  }
150
+ // Headless credential login: if the user signalled HTTP sign-in (--http-signin,
151
+ // or partial -u/-p, or --no-browser combined with -u/-p) but didn't provide both
152
+ // credentials inline, prompt for the missing one(s) on stderr. Password is read
153
+ // without echo when stdin is a TTY.
154
+ const wantsCredentialLogin = !noAuth && !refreshToken &&
155
+ (httpSignin || (noBrowser && (username || password)) || (!!username !== !!password));
156
+ if (wantsCredentialLogin) {
157
+ if (!username)
158
+ username = await promptForUsername("Username");
159
+ if (!password)
160
+ password = await promptForPassword("Password");
161
+ }
157
162
  let token;
158
163
  if (noAuth) {
159
164
  token = saveNoAuthPlatform(normalizedTarget, { tlsInsecure });
@@ -169,30 +174,9 @@ Login options:
169
174
  clientId, clientSecret, refreshToken, tlsInsecure,
170
175
  });
171
176
  }
172
- else if (username && password && httpSignin) {
173
- console.log("Logging in (HTTP /oauth2/signin)...");
174
- token = await oauth2PasswordSigninLogin(normalizedTarget, {
175
- username,
176
- password,
177
- tlsInsecure,
178
- port: customPort,
179
- clientId: clientId ?? undefined,
180
- clientSecret: clientSecret ?? undefined,
181
- oauthProduct: oauthProduct ?? undefined,
182
- signinPublicKeyPemPath: signinPublicKeyFile ?? undefined,
183
- });
184
- }
185
- else if (username && password && usePlaywright) {
186
- console.log("Logging in (headless, Playwright)...");
187
- token = await playwrightLogin(normalizedTarget, {
188
- username,
189
- password,
190
- tlsInsecure,
191
- port: customPort,
192
- });
193
- }
194
177
  else if (username && password) {
195
- const signinOpts = {
178
+ console.log("Logging in (HTTP /oauth2/signin)...");
179
+ token = await loginWithInitialPasswordRecovery(normalizedTarget, {
196
180
  username,
197
181
  password,
198
182
  tlsInsecure,
@@ -201,40 +185,7 @@ Login options:
201
185
  clientSecret: clientSecret ?? undefined,
202
186
  oauthProduct: oauthProduct ?? undefined,
203
187
  signinPublicKeyPemPath: signinPublicKeyFile ?? undefined,
204
- };
205
- console.log("Logging in (HTTP /oauth2/signin)...");
206
- try {
207
- token = await oauth2PasswordSigninLogin(normalizedTarget, signinOpts);
208
- }
209
- catch (err) {
210
- if (!isStudiowebShellUnavailableError(err)) {
211
- throw err;
212
- }
213
- const playwrightOk = await isPlaywrightPackageResolvable();
214
- if (playwrightOk) {
215
- process.stderr.write("Studio web sign-in shell is not available; falling back to Playwright headless login.\n");
216
- console.log("Logging in (headless, Playwright)...");
217
- token = await playwrightLogin(normalizedTarget, {
218
- username,
219
- password,
220
- tlsInsecure,
221
- port: customPort,
222
- });
223
- }
224
- else {
225
- console.error("Studio web sign-in shell is not available on this platform, and the Playwright package is not installed.");
226
- console.error("Install Playwright for headless browser login: npm install playwright && npx playwright install chromium");
227
- console.error("Alternatively, use OAuth without credentials:");
228
- console.error(` kweaver auth login ${normalizedTarget} --no-browser`);
229
- throw err;
230
- }
231
- }
232
- }
233
- else if (usePlaywright) {
234
- console.log("Opening browser for login (Playwright)...");
235
- token = await playwrightLogin(normalizedTarget, {
236
- tlsInsecure, port: customPort,
237
- });
188
+ }, { newPasswordFlag, tlsInsecure });
238
189
  }
239
190
  else {
240
191
  if (noBrowser) {
@@ -456,7 +407,7 @@ Login options:
456
407
  console.log(`Run \`kweaver auth login ${logoutTarget}\` to sign in again.`);
457
408
  return 0;
458
409
  }
459
- console.error("Usage: kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass] [--playwright]");
410
+ console.error("Usage: kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass]");
460
411
  console.error(" kweaver auth whoami [platform-url|alias] [--json]");
461
412
  console.error(" kweaver auth export [platform-url|alias] [--json]");
462
413
  console.error(" kweaver auth status [platform-url|alias]");
@@ -684,3 +635,217 @@ function readOption(args, name) {
684
635
  }
685
636
  return args[index + 1];
686
637
  }
638
+ const EACP_NEW_PWD_MIN = 6;
639
+ const EACP_NEW_PWD_MAX = 100;
640
+ function validateNewPasswordLengthForEacp(pwd) {
641
+ if (pwd.length < EACP_NEW_PWD_MIN || pwd.length > EACP_NEW_PWD_MAX) {
642
+ throw new Error(`New password must be between ${EACP_NEW_PWD_MIN} and ${EACP_NEW_PWD_MAX} characters.`);
643
+ }
644
+ }
645
+ function formatEacpModifyFailure(status, json, body) {
646
+ if (json && typeof json === "object" && json !== null) {
647
+ const o = json;
648
+ const msg = typeof o.message === "string" && o.message.trim() !== ""
649
+ ? o.message
650
+ : typeof o.cause === "string"
651
+ ? o.cause
652
+ : "";
653
+ if (msg)
654
+ return `Password change failed (HTTP ${status}): ${msg}`;
655
+ }
656
+ return `Password change failed (HTTP ${status}): ${body.slice(0, 500)}`;
657
+ }
658
+ async function promptYesNo(message) {
659
+ const { createInterface } = await import("node:readline");
660
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
661
+ return await new Promise((resolve, reject) => {
662
+ let answered = false;
663
+ rl.on("close", () => {
664
+ if (!answered)
665
+ reject(new Error("Login cancelled."));
666
+ });
667
+ rl.question(`${message} [Y/n] `, (answer) => {
668
+ answered = true;
669
+ rl.close();
670
+ const a = answer.trim().toLowerCase();
671
+ resolve(a === "" || a === "y" || a === "yes");
672
+ });
673
+ });
674
+ }
675
+ async function loginWithInitialPasswordRecovery(normalizedTarget, signinOpts, recovery) {
676
+ try {
677
+ return await oauth2PasswordSigninLogin(normalizedTarget, signinOpts);
678
+ }
679
+ catch (e) {
680
+ if (!(e instanceof InitialPasswordChangeRequiredError))
681
+ throw e;
682
+ const err = e;
683
+ const account = signinOpts.username;
684
+ const oldPwd = signinOpts.password;
685
+ let newPwd = recovery.newPasswordFlag;
686
+ if (newPwd !== undefined) {
687
+ validateNewPasswordLengthForEacp(newPwd);
688
+ }
689
+ else if (process.stderr.isTTY) {
690
+ process.stderr.write(`${err.serverMessage}\n`);
691
+ const ok = await promptYesNo(`Account "${account}" must change its initial password. Proceed with password change now?`);
692
+ if (!ok) {
693
+ throw new Error("Initial password change declined. Run again when ready.");
694
+ }
695
+ const np1 = await promptForPassword("New password (6-100 characters)");
696
+ const np2 = await promptForPassword("Confirm new password");
697
+ if (np1 !== np2) {
698
+ throw new Error("New passwords do not match.");
699
+ }
700
+ validateNewPasswordLengthForEacp(np1);
701
+ newPwd = np1;
702
+ }
703
+ else {
704
+ throw new Error("This account must change its initial password (error 401001017). Re-run with --new-password <password> (non-interactive).");
705
+ }
706
+ const mod = await eacpModifyPassword(normalizedTarget, {
707
+ account,
708
+ oldPassword: oldPwd,
709
+ newPassword: newPwd,
710
+ tlsInsecure: recovery.tlsInsecure,
711
+ });
712
+ if (!mod.ok) {
713
+ throw new Error(formatEacpModifyFailure(mod.status, mod.json, mod.body));
714
+ }
715
+ return oauth2PasswordSigninLogin(normalizedTarget, {
716
+ ...signinOpts,
717
+ password: newPwd,
718
+ });
719
+ }
720
+ }
721
+ async function runAuthChangePasswordCommand(args) {
722
+ if (args[0] === "--help" || args[0] === "-h") {
723
+ console.log(`kweaver auth change-password [<platform-url>] [options]
724
+
725
+ Change the EACP account password via POST /api/eacp/v1/auth1/modifypassword.
726
+ No saved OAuth token is required.
727
+
728
+ Options:
729
+ -u, --account <name> Account / login name. On TTY, defaults to the current active user
730
+ after a confirmation prompt. Required in non-interactive mode.
731
+ -o, --old-password <pwd> Current password (omit on TTY to be prompted)
732
+ -n, --new-password <pwd> New password, 6-100 characters (omit on TTY to be prompted)
733
+ --insecure, -k Skip TLS certificate verification (defaults to the platform's saved
734
+ preference set at login with -k; pass to override per-call)
735
+
736
+ Platform URL is optional; defaults to the current active platform (kweaver auth use).`);
737
+ return 0;
738
+ }
739
+ const KNOWN_CP_FLAGS = new Set([
740
+ "-u",
741
+ "--account",
742
+ "-o",
743
+ "--old-password",
744
+ "-n",
745
+ "--new-password",
746
+ "--insecure",
747
+ "-k",
748
+ "--help",
749
+ "-h",
750
+ ]);
751
+ const KNOWN_CP_VALUE = new Set([
752
+ "-u",
753
+ "--account",
754
+ "-o",
755
+ "--old-password",
756
+ "-n",
757
+ "--new-password",
758
+ ]);
759
+ // First positional (if present and not a flag) is the platform URL or alias.
760
+ const positional = args[0] && !args[0].startsWith("-") ? args[0] : undefined;
761
+ const flagArgs = positional ? args.slice(1) : args;
762
+ for (let i = 0; i < flagArgs.length; i++) {
763
+ const a = flagArgs[i];
764
+ if (a.startsWith("-") && !KNOWN_CP_FLAGS.has(a)) {
765
+ console.error(`Unknown option: ${a}`);
766
+ console.error("Run 'kweaver auth change-password --help' for usage.");
767
+ return 1;
768
+ }
769
+ if (KNOWN_CP_VALUE.has(a))
770
+ i++;
771
+ }
772
+ const normalizedTarget = resolvePlatformArg(positional ? [positional] : []);
773
+ if (!normalizedTarget) {
774
+ console.error("No platform resolved. Pass <platform-url|alias> or run `kweaver auth use <url|alias>` first.");
775
+ return 1;
776
+ }
777
+ let account = readOption(flagArgs, "--account") ?? readOption(flagArgs, "-u");
778
+ let oldPassword = readOption(flagArgs, "--old-password") ?? readOption(flagArgs, "-o");
779
+ let newPassword = readOption(flagArgs, "--new-password") ?? readOption(flagArgs, "-n");
780
+ const explicitTlsInsecure = flagArgs.includes("--insecure") || flagArgs.includes("-k");
781
+ // Resolve the active user's saved token; we use it both to default the account
782
+ // and to inherit the platform's saved tlsInsecure preference (set at login with -k).
783
+ const activeUser = getActiveUser(normalizedTarget);
784
+ const activeToken = activeUser ? loadUserTokenConfig(normalizedTarget, activeUser) : null;
785
+ const tlsInsecure = explicitTlsInsecure || activeToken?.tlsInsecure === true;
786
+ const interactive = process.stdin.isTTY === true && process.stderr.isTTY === true;
787
+ const accountWasExplicit = !!account?.trim();
788
+ // Account resolution (with safety guards):
789
+ // - Explicit -u always wins.
790
+ // - Non-TTY + no -u: REFUSE. Silently using the active account in CI / pipes
791
+ // would let scripts modify the wrong account's password without warning.
792
+ // - TTY + no -u: default to the active user's displayName, but require an
793
+ // interactive yes/no confirmation before proceeding.
794
+ if (!accountWasExplicit) {
795
+ const defaultAccount = activeToken?.displayName?.trim();
796
+ if (!defaultAccount) {
797
+ console.error("Cannot determine current account on the platform. Pass -u/--account, or log in first (kweaver auth login ...).");
798
+ return 1;
799
+ }
800
+ if (!interactive) {
801
+ console.error(`Refusing to default account in non-interactive mode. Pass -u/--account explicitly (would have used "${defaultAccount}").`);
802
+ return 1;
803
+ }
804
+ const ok = await promptYesNo(`Change password for account "${defaultAccount}" on ${normalizedTarget}?`);
805
+ if (!ok) {
806
+ console.error("Aborted by user.");
807
+ return 1;
808
+ }
809
+ account = defaultAccount;
810
+ }
811
+ const trimmedAccount = account.trim();
812
+ try {
813
+ if (!interactive) {
814
+ if (!oldPassword || !newPassword) {
815
+ console.error("In non-interactive mode, --old-password and --new-password are required.");
816
+ return 1;
817
+ }
818
+ }
819
+ else {
820
+ if (!oldPassword) {
821
+ oldPassword = await promptForPassword("Old password");
822
+ }
823
+ if (!newPassword) {
824
+ const n1 = await promptForPassword("New password (6-100 characters)");
825
+ const n2 = await promptForPassword("Confirm new password");
826
+ if (n1 !== n2) {
827
+ console.error("New passwords do not match.");
828
+ return 1;
829
+ }
830
+ newPassword = n1;
831
+ }
832
+ }
833
+ validateNewPasswordLengthForEacp(newPassword);
834
+ const result = await eacpModifyPassword(normalizedTarget, {
835
+ account: trimmedAccount,
836
+ oldPassword: oldPassword,
837
+ newPassword: newPassword,
838
+ tlsInsecure,
839
+ });
840
+ if (!result.ok) {
841
+ console.error(`${formatEacpModifyFailure(result.status, result.json, result.body)} (account="${trimmedAccount}")`);
842
+ return 1;
843
+ }
844
+ console.log(`Password changed for ${trimmedAccount} on ${normalizedTarget}`);
845
+ return 0;
846
+ }
847
+ catch (e) {
848
+ console.error(`${formatHttpError(e)}\n(account="${trimmedAccount}")`);
849
+ return 1;
850
+ }
851
+ }
package/dist/index.d.ts CHANGED
@@ -62,4 +62,5 @@ export type { TokenConfig, ContextLoaderEntry, ContextLoaderConfig, } from "./co
62
62
  export type { UserProfile } from "./config/store.js";
63
63
  export { NO_AUTH_TOKEN, isNoAuth, saveNoAuthPlatform, autoSelectBusinessDomain, getConfigDir, getCurrentPlatform, getActiveUser, setActiveUser, listUsers, listUserProfiles, resolveUserId, extractUserId, } from "./config/store.js";
64
64
  export { decodeJwtPayload, extractUserIdFromJwt } from "./config/jwt.js";
65
- export { DEFAULT_SIGNIN_RSA_MODULUS_HEX, oauth2PasswordSigninLogin, parseSigninPageHtmlProps, rsaModulusHexToSpkiPem, STUDIOWEB_LOGIN_PUBLIC_KEY_PEM, } from "./auth/oauth.js";
65
+ export { DEFAULT_SIGNIN_RSA_MODULUS_HEX, InitialPasswordChangeRequiredError, oauth2PasswordSigninLogin, parseSigninPageHtmlProps, rsaModulusHexToSpkiPem, STUDIOWEB_LOGIN_PUBLIC_KEY_PEM, } from "./auth/oauth.js";
66
+ export { eacpModifyPassword, encryptModifyPwd } from "./auth/eacp-modify-password.js";
package/dist/index.js CHANGED
@@ -50,4 +50,5 @@ export { NO_AUTH_TOKEN, isNoAuth, saveNoAuthPlatform, autoSelectBusinessDomain,
50
50
  // ── JWT utilities ─────────────────────────────────────────────────────────────
51
51
  export { decodeJwtPayload, extractUserIdFromJwt } from "./config/jwt.js";
52
52
  // ── OAuth (advanced — CLI uses these internally; optional for custom login tools) ─
53
- export { DEFAULT_SIGNIN_RSA_MODULUS_HEX, oauth2PasswordSigninLogin, parseSigninPageHtmlProps, rsaModulusHexToSpkiPem, STUDIOWEB_LOGIN_PUBLIC_KEY_PEM, } from "./auth/oauth.js";
53
+ export { DEFAULT_SIGNIN_RSA_MODULUS_HEX, InitialPasswordChangeRequiredError, oauth2PasswordSigninLogin, parseSigninPageHtmlProps, rsaModulusHexToSpkiPem, STUDIOWEB_LOGIN_PUBLIC_KEY_PEM, } from "./auth/oauth.js";
54
+ export { eacpModifyPassword, encryptModifyPwd } from "./auth/eacp-modify-password.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kweaver-ai/kweaver-sdk",
3
- "version": "0.6.5",
3
+ "version": "0.6.7",
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",
@@ -51,21 +51,11 @@
51
51
  "@types/node": "^24.6.0",
52
52
  "@types/react": "^19.2.14",
53
53
  "@types/yargs": "^17.0.35",
54
- "playwright": "^1.58.2",
55
54
  "tsx": "^4.20.5",
56
55
  "typescript": "^5.9.3"
57
56
  },
58
- "peerDependencies": {
59
- "playwright": ">=1.40.0"
60
- },
61
- "peerDependenciesMeta": {
62
- "playwright": {
63
- "optional": true
64
- }
65
- },
66
57
  "dependencies": {
67
58
  "@kweaver-ai/bkn": "^0.1.0",
68
- "@playwright/test": "^1.58.2",
69
59
  "chardet": "^2.1.1",
70
60
  "columnify": "^1.6.0",
71
61
  "csv-parse": "^6.2.1",