@alchemy/cli 0.7.4 → 0.8.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.
@@ -11,8 +11,8 @@ import {
11
11
  prepareLogin,
12
12
  revokeToken,
13
13
  waitForCallback
14
- } from "./chunk-C5HNQOLB.js";
15
- import "./chunk-2BALTY22.js";
14
+ } from "./chunk-NGF46GZP.js";
15
+ import "./chunk-46LMXT54.js";
16
16
  export {
17
17
  AUTH_PORT,
18
18
  DEFAULT_EXPIRES_IN_SECONDS,
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
+ import {
4
+ registerAuth,
5
+ selectAppAfterAuth
6
+ } from "./chunk-EKS2THJU.js";
7
+ import "./chunk-NGF46GZP.js";
8
+ import "./chunk-L7VFXQSF.js";
9
+ import "./chunk-JWLZAO7S.js";
10
+ import "./chunk-DGZYRBXR.js";
11
+ import "./chunk-ROBA7SR7.js";
12
+ import "./chunk-46LMXT54.js";
13
+ export {
14
+ registerAuth,
15
+ selectAppAfterAuth
16
+ };
@@ -375,6 +375,13 @@ function errAccessKeyRequired() {
375
375
  "Get an access key: https://www.alchemy.com/docs/reference/admin-api/overview"
376
376
  );
377
377
  }
378
+ function errLoginRequired() {
379
+ return new CLIError(
380
+ ErrorCode.AUTH_REQUIRED,
381
+ "Sign in to Alchemy to continue. Run 'alchemy auth login', then retry.",
382
+ "alchemy auth login"
383
+ );
384
+ }
378
385
  function errInvalidAPIKey(details) {
379
386
  return new CLIError(
380
387
  ErrorCode.INVALID_API_KEY,
@@ -541,6 +548,7 @@ export {
541
548
  CLIError,
542
549
  errAuthRequired,
543
550
  errAccessKeyRequired,
551
+ errLoginRequired,
544
552
  errInvalidAPIKey,
545
553
  errNetworkNotEnabled,
546
554
  errNetwork,
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env node
2
+ if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
+ import {
4
+ gasManagerClientFromFlags,
5
+ toAdminNetworkId
6
+ } from "./chunk-JWLZAO7S.js";
7
+ import {
8
+ dim,
9
+ green,
10
+ promptAutocomplete,
11
+ promptConfirm,
12
+ promptText,
13
+ withSpinner
14
+ } from "./chunk-DGZYRBXR.js";
15
+ import {
16
+ load,
17
+ save
18
+ } from "./chunk-ROBA7SR7.js";
19
+ import {
20
+ errAppRequired,
21
+ errInvalidArgs,
22
+ errLoginRequired
23
+ } from "./chunk-46LMXT54.js";
24
+
25
+ // src/lib/policy-prompt.ts
26
+ var CREATE_NEW_SENTINEL = "__create_new__";
27
+ var DEFAULT_SPONSORSHIP_EXPIRY_MS = "600000";
28
+ var DEFAULT_SOLANA_MAX_COUNT = "1000";
29
+ function flavorNoun(flavor) {
30
+ return flavor === "solana" ? "fee sponsorship" : "gas sponsorship";
31
+ }
32
+ async function selectOrCreatePolicy(opts) {
33
+ const cfg = load();
34
+ const appId = cfg.app?.id;
35
+ if (!appId) throw errAppRequired();
36
+ const client = opts.client ?? gasManagerClientFromFlags(opts.program);
37
+ const flavorLabel = flavorNoun(opts.flavor);
38
+ const policies = await withSpinner(
39
+ "Fetching gas policies\u2026",
40
+ "Policies fetched",
41
+ () => client.listAllPolicies({ appId })
42
+ );
43
+ const matching = filterPolicies(policies, opts.flavor, opts.network);
44
+ let selectedId = null;
45
+ if (matching.length === 0) {
46
+ console.log(
47
+ ` ${dim(`No ${flavorLabel} policies found for ${opts.network} on app ${appId}. Let's create one.`)}`
48
+ );
49
+ const created = await runCreate(opts, client, appId);
50
+ if (!created) return null;
51
+ selectedId = created.policyId;
52
+ } else {
53
+ const selected = await promptAutocomplete({
54
+ message: `Select a ${flavorLabel} policy for ${opts.network}`,
55
+ placeholder: "Policy name or ID",
56
+ options: [
57
+ ...matching.map((p) => ({
58
+ label: formatPolicyOption(p),
59
+ value: p.policyId
60
+ })),
61
+ { label: "Create a new policy", value: CREATE_NEW_SENTINEL }
62
+ ],
63
+ cancelMessage: "Cancelled policy selection.",
64
+ commitLabel: null
65
+ });
66
+ if (selected === null) return null;
67
+ if (selected === CREATE_NEW_SENTINEL) {
68
+ const created = await runCreate(opts, client, appId);
69
+ if (!created) return null;
70
+ selectedId = created.policyId;
71
+ } else {
72
+ selectedId = selected;
73
+ }
74
+ }
75
+ if (!opts.skipPersistPrompt && selectedId) {
76
+ await maybePersist(opts.flavor, selectedId);
77
+ }
78
+ return selectedId;
79
+ }
80
+ async function createPolicyInteractive(opts) {
81
+ const cfg = load();
82
+ const appId = cfg.app?.id;
83
+ if (!appId) throw errAppRequired();
84
+ const client = opts.client ?? gasManagerClientFromFlags(opts.program);
85
+ const result = await runCreate(opts, client, appId);
86
+ return result;
87
+ }
88
+ function filterPolicies(policies, flavor, network) {
89
+ const adminId = toAdminNetworkId(network);
90
+ return policies.filter((p) => {
91
+ if (p.policyType !== flavor) return false;
92
+ if (!Array.isArray(p.networks)) return false;
93
+ return p.networks.includes(adminId);
94
+ });
95
+ }
96
+ function formatPolicyOption(p) {
97
+ const status = p.status === "active" ? green("active") : dim(p.status);
98
+ return `${p.policyName} (${p.policyId.slice(0, 10)}\u2026) \u2014 ${status}`;
99
+ }
100
+ async function runCreate(opts, client, appId) {
101
+ const name = await promptText({
102
+ message: "Policy name",
103
+ cancelMessage: "Cancelled policy creation."
104
+ });
105
+ if (name === null) return null;
106
+ if (!name.trim()) {
107
+ console.log(` ${dim("Skipped policy creation (no name).")}`);
108
+ return null;
109
+ }
110
+ const adminNetworkId = toAdminNetworkId(opts.network);
111
+ const nowUnix = String(Math.floor(Date.now() / 1e3));
112
+ const payload = opts.flavor === "sponsorship" ? {
113
+ policyName: name.trim(),
114
+ policyType: "sponsorship",
115
+ appId,
116
+ networks: [adminNetworkId],
117
+ rules: {
118
+ startTimeUnix: nowUnix,
119
+ sponsorshipExpiryMs: DEFAULT_SPONSORSHIP_EXPIRY_MS
120
+ }
121
+ } : {
122
+ policyName: name.trim(),
123
+ policyType: "solana",
124
+ appId,
125
+ networks: [adminNetworkId],
126
+ solanaRules: {
127
+ startTimeUnix: nowUnix,
128
+ maxCount: DEFAULT_SOLANA_MAX_COUNT
129
+ }
130
+ };
131
+ const created = await withSpinner(
132
+ "Creating policy\u2026",
133
+ "Policy created",
134
+ () => client.createPolicy(payload)
135
+ );
136
+ console.log(` ${green("\u2713")} Created ${created.policyName} (${created.policyId})`);
137
+ const activate = await promptConfirm({
138
+ message: "Activate this policy now? (required before use)",
139
+ initialValue: true,
140
+ cancelMessage: "Skipped activation."
141
+ });
142
+ let activated = false;
143
+ if (activate === true) {
144
+ await withSpinner(
145
+ "Activating policy\u2026",
146
+ "Policy active",
147
+ () => client.setPolicyStatus(created.policyId, "active")
148
+ );
149
+ activated = true;
150
+ } else {
151
+ console.log(
152
+ ` ${dim("Policy left inactive. Activate later with `alchemy gas-manager policy activate " + created.policyId + "`.")}`
153
+ );
154
+ }
155
+ return { policyId: created.policyId, status: "created", activated };
156
+ }
157
+ async function maybePersist(flavor, policyId) {
158
+ const confirmed = await promptConfirm({
159
+ message: "Save as default policy for this CLI?",
160
+ initialValue: true,
161
+ cancelMessage: "Skipped saving default."
162
+ });
163
+ if (confirmed !== true) return;
164
+ const cfg = load();
165
+ const updated = flavor === "sponsorship" ? { ...cfg, evm_gas_policy_id: policyId } : { ...cfg, solana_fee_policy_id: policyId };
166
+ save(updated);
167
+ const key = flavor === "sponsorship" ? "evm-gas-policy-id" : "solana-fee-policy-id";
168
+ console.log(` ${green("\u2713")} Saved ${key} = ${policyId}`);
169
+ }
170
+ function errSponsorshipNeedsPolicy(flavor) {
171
+ const flag = flavor === "sponsorship" ? "--gas-policy-id" : "--fee-policy-id";
172
+ const label = flavor === "sponsorship" ? "Gas sponsorship" : "Fee sponsorship";
173
+ return errInvalidArgs(
174
+ `${label} requires a policy ID. Run 'alchemy gas-manager policy list' to pick one, pass ${flag} <id>, or run interactively to be prompted.`
175
+ );
176
+ }
177
+ function errNotLoggedInForPolicyLookup() {
178
+ return errLoginRequired();
179
+ }
180
+
181
+ export {
182
+ selectOrCreatePolicy,
183
+ createPolicyInteractive,
184
+ errSponsorshipNeedsPolicy,
185
+ errNotLoggedInForPolicyLookup
186
+ };
@@ -2,10 +2,10 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  configPath
5
- } from "./chunk-JUCUKTP3.js";
5
+ } from "./chunk-ROBA7SR7.js";
6
6
  import {
7
7
  esc
8
- } from "./chunk-2BALTY22.js";
8
+ } from "./chunk-46LMXT54.js";
9
9
 
10
10
  // src/lib/update-check.ts
11
11
  import { execFileSync } from "child_process";
@@ -53,7 +53,7 @@ function semverLT(a, b) {
53
53
  return false;
54
54
  }
55
55
  function currentVersion() {
56
- return true ? "0.7.4" : "0.0.0";
56
+ return true ? "0.8.0" : "0.0.0";
57
57
  }
58
58
  function toUpdateStatus(latestVersion, checkedAt) {
59
59
  const current = currentVersion();
@@ -5,7 +5,7 @@ import {
5
5
  isJSONMode,
6
6
  quiet,
7
7
  rgb
8
- } from "./chunk-2BALTY22.js";
8
+ } from "./chunk-46LMXT54.js";
9
9
 
10
10
  // src/lib/terminal-ui.ts
11
11
  import * as readline from "readline";
@@ -4,14 +4,14 @@ import {
4
4
  completeLogin,
5
5
  prepareLogin,
6
6
  revokeToken
7
- } from "./chunk-C5HNQOLB.js";
7
+ } from "./chunk-NGF46GZP.js";
8
8
  import {
9
9
  isInteractiveAllowed
10
- } from "./chunk-64A5W4M2.js";
10
+ } from "./chunk-L7VFXQSF.js";
11
11
  import {
12
12
  AdminClient,
13
13
  resolveAuthToken
14
- } from "./chunk-K6V3R7SH.js";
14
+ } from "./chunk-JWLZAO7S.js";
15
15
  import {
16
16
  bold,
17
17
  brand,
@@ -20,13 +20,13 @@ import {
20
20
  promptAutocomplete,
21
21
  promptText,
22
22
  withSpinner
23
- } from "./chunk-5IL2PMZ6.js";
23
+ } from "./chunk-DGZYRBXR.js";
24
24
  import {
25
25
  configPath,
26
26
  load,
27
27
  maskIf,
28
28
  save
29
- } from "./chunk-JUCUKTP3.js";
29
+ } from "./chunk-ROBA7SR7.js";
30
30
  import {
31
31
  CLIError,
32
32
  ErrorCode,
@@ -34,7 +34,7 @@ import {
34
34
  exitWithError,
35
35
  isJSONMode,
36
36
  printHuman
37
- } from "./chunk-2BALTY22.js";
37
+ } from "./chunk-46LMXT54.js";
38
38
 
39
39
  // src/commands/auth.ts
40
40
  function registerAuth(program) {
@@ -2,11 +2,11 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  isInteractiveAllowed
5
- } from "./chunk-64A5W4M2.js";
5
+ } from "./chunk-L7VFXQSF.js";
6
6
  import {
7
7
  resolveAuthToken,
8
8
  resolveWalletSession
9
- } from "./chunk-K6V3R7SH.js";
9
+ } from "./chunk-JWLZAO7S.js";
10
10
 
11
11
  // src/lib/onboarding.ts
12
12
  var SETUP_CAPABILITY_ORDER = [
@@ -4,7 +4,7 @@ import {
4
4
  configDir,
5
5
  load,
6
6
  save
7
- } from "./chunk-JUCUKTP3.js";
7
+ } from "./chunk-ROBA7SR7.js";
8
8
  import {
9
9
  CLIError,
10
10
  ErrorCode,
@@ -17,6 +17,7 @@ import {
17
17
  errInvalidAPIKey,
18
18
  errInvalidAccessKey,
19
19
  errInvalidArgs,
20
+ errLoginRequired,
20
21
  errNetwork,
21
22
  errNetworkNotEnabled,
22
23
  errNotFound,
@@ -29,7 +30,7 @@ import {
29
30
  parseBaseURLOverride,
30
31
  redactSensitiveText,
31
32
  verbose
32
- } from "./chunk-2BALTY22.js";
33
+ } from "./chunk-46LMXT54.js";
33
34
 
34
35
  // src/lib/resolve.ts
35
36
  import { readFileSync as readFileSync2 } from "fs";
@@ -293,6 +294,12 @@ var NATIVE_TOKEN_SYMBOLS = {
293
294
  function isSolanaNetwork(networkId) {
294
295
  return networkId.startsWith("solana-");
295
296
  }
297
+ function toAdminNetworkId(slug) {
298
+ return slug.trim().toUpperCase().replace(/-/g, "_");
299
+ }
300
+ function fromAdminNetworkId(id) {
301
+ return id.trim().toLowerCase().replace(/_/g, "-");
302
+ }
296
303
  function nativeTokenSymbol(networkId) {
297
304
  const prefix = networkId.replace(/-(mainnet|testnet|sepolia|holesky|hoodi|devnet|amoy|fuji|cardona|saigon|chiado|signet|mocha|blaze|curtis|bepolia).*$/, "");
298
305
  return NATIVE_TOKEN_SYMBOLS[prefix] ?? "ETH";
@@ -862,6 +869,166 @@ var AdminClient = class _AdminClient {
862
869
  }
863
870
  };
864
871
 
872
+ // src/lib/gas-manager-client.ts
873
+ var GasManagerClient = class _GasManagerClient {
874
+ static get HOST() {
875
+ return `manage.g.${getBaseDomain()}`;
876
+ }
877
+ // Test/debug only: route requests to a local mock.
878
+ static BASE_URL_ENV = "ALCHEMY_GAS_MANAGER_BASE_URL";
879
+ credential;
880
+ constructor(credential) {
881
+ if (typeof credential === "string") {
882
+ this.validateAccessKey(credential);
883
+ this.credential = { type: "access_key", key: credential };
884
+ } else {
885
+ if (credential.type === "access_key") {
886
+ this.validateAccessKey(credential.key);
887
+ } else if (!credential.token.trim()) {
888
+ throw errAuthRequired();
889
+ }
890
+ this.credential = credential;
891
+ }
892
+ }
893
+ baseURL() {
894
+ const override = this.baseURLOverride();
895
+ if (override) return override.toString().replace(/\/$/, "");
896
+ return `https://manage.g.${getBaseDomain()}`;
897
+ }
898
+ allowedHosts() {
899
+ const hosts = /* @__PURE__ */ new Set([_GasManagerClient.HOST]);
900
+ const override = this.baseURLOverride();
901
+ if (override) hosts.add(override.hostname);
902
+ return hosts;
903
+ }
904
+ allowInsecureTransport(hostname) {
905
+ return isLocalhost(hostname);
906
+ }
907
+ baseURLOverride() {
908
+ return parseBaseURLOverride(_GasManagerClient.BASE_URL_ENV);
909
+ }
910
+ validateAccessKey(accessKey) {
911
+ if (!accessKey.trim() || /\s/.test(accessKey)) {
912
+ throw errInvalidAccessKey();
913
+ }
914
+ }
915
+ assertSafeRequestTarget(url) {
916
+ let parsed;
917
+ try {
918
+ parsed = new URL(url);
919
+ } catch {
920
+ throw errInvalidArgs("Invalid gas manager API URL.");
921
+ }
922
+ if (!this.allowedHosts().has(parsed.hostname)) {
923
+ throw errInvalidArgs(`Refusing to send credentials to unexpected host: ${parsed.hostname}`);
924
+ }
925
+ if (parsed.protocol !== "https:" && !this.allowInsecureTransport(parsed.hostname)) {
926
+ throw errInvalidArgs("Refusing to send credentials over non-HTTPS connection.");
927
+ }
928
+ }
929
+ async request(method, path, body) {
930
+ const url = `${this.baseURL()}${path}`;
931
+ debug(`${method} ${url}`);
932
+ this.assertSafeRequestTarget(url);
933
+ const token = this.credential.type === "access_key" ? this.credential.key : this.credential.token;
934
+ const resp = await fetchWithTimeout(url, {
935
+ method,
936
+ redirect: "error",
937
+ headers: {
938
+ Authorization: `Bearer ${token}`,
939
+ "Content-Type": "application/json",
940
+ Accept: "application/json"
941
+ },
942
+ ...body !== void 0 && { body: JSON.stringify(body) }
943
+ });
944
+ if (resp.status === 401) {
945
+ throw this.credential.type === "auth_token" ? errLoginRequired() : errInvalidAccessKey();
946
+ }
947
+ if (resp.status === 403) {
948
+ const detail = await resp.text().catch(() => "");
949
+ let reason;
950
+ try {
951
+ const parsed = JSON.parse(detail);
952
+ reason = parsed?.error?.msg ?? parsed?.message ?? parsed?.error ?? void 0;
953
+ } catch {
954
+ reason = detail || void 0;
955
+ }
956
+ if (this.credential.type === "auth_token") {
957
+ const tail = reason ? ` (${reason})` : "";
958
+ throw new CLIError(
959
+ ErrorCode.AUTH_REQUIRED,
960
+ `Access denied for this Alchemy account or app${tail}. Re-authenticate with 'alchemy auth login' or check that the default app is one you have permission to manage.`,
961
+ "alchemy auth login"
962
+ );
963
+ }
964
+ throw errAccessDenied(typeof reason === "string" ? reason : void 0);
965
+ }
966
+ if (resp.status === 404) {
967
+ const text = await resp.text().catch(() => "");
968
+ throw errNotFound(text || path);
969
+ }
970
+ if (resp.status === 429) throw errRateLimited();
971
+ if (!resp.ok) {
972
+ const text = await resp.text().catch(() => "");
973
+ throw errAdminAPI(resp.status, text);
974
+ }
975
+ return resp.json();
976
+ }
977
+ async listPolicies(opts) {
978
+ const params = new URLSearchParams();
979
+ params.set("appId", opts.appId);
980
+ if (opts.limit !== void 0) params.set("limit", String(opts.limit));
981
+ if (opts.after) params.set("after", opts.after);
982
+ if (opts.before) params.set("before", opts.before);
983
+ const resp = await this.request(
984
+ "GET",
985
+ `/api/gasManager/policies?${params.toString()}`
986
+ );
987
+ return resp.data;
988
+ }
989
+ async listAllPolicies(opts) {
990
+ const policies = [];
991
+ const seen = /* @__PURE__ */ new Set();
992
+ let after;
993
+ do {
994
+ const page = await this.listPolicies({
995
+ appId: opts.appId,
996
+ ...opts.limit !== void 0 && { limit: opts.limit },
997
+ ...after && { after }
998
+ });
999
+ policies.push(...page.policies);
1000
+ const next = page.after ?? void 0;
1001
+ if (next && seen.has(next)) break;
1002
+ if (next) seen.add(next);
1003
+ after = next;
1004
+ } while (after);
1005
+ return policies;
1006
+ }
1007
+ async getPolicy(policyId) {
1008
+ const resp = await this.request(
1009
+ "GET",
1010
+ `/api/gasManager/policy/${encodeURIComponent(policyId)}`
1011
+ );
1012
+ return resp.data.policy;
1013
+ }
1014
+ async createPolicy(payload) {
1015
+ const resp = await this.request(
1016
+ "POST",
1017
+ "/api/gasManager/policy",
1018
+ payload
1019
+ );
1020
+ return resp.data.policy;
1021
+ }
1022
+ async setPolicyStatus(policyId, status) {
1023
+ const resp = await this.request(
1024
+ "PUT",
1025
+ `/api/gasManager/policy/${encodeURIComponent(policyId)}/status`,
1026
+ { status }
1027
+ );
1028
+ return resp.data.policy;
1029
+ }
1030
+ };
1031
+
865
1032
  // src/lib/wallet-session.ts
866
1033
  import { generateKeyPairSync, randomUUID } from "crypto";
867
1034
  import { readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from "fs";
@@ -1094,6 +1261,15 @@ function adminClientFromFlags(program) {
1094
1261
  if (authToken) return new AdminClient({ type: "auth_token", token: authToken });
1095
1262
  throw errAccessKeyRequired();
1096
1263
  }
1264
+ function hasAuthLoginToken(cfg) {
1265
+ return Boolean(resolveAuthToken(cfg));
1266
+ }
1267
+ function gasManagerClientFromFlags(_program) {
1268
+ const cfg = load();
1269
+ const authToken = resolveAuthToken(cfg);
1270
+ if (!authToken) throw errLoginRequired();
1271
+ return new GasManagerClient({ type: "auth_token", token: authToken });
1272
+ }
1097
1273
  function resolveX402(program, cfg) {
1098
1274
  const opts = getCommandOptions(program);
1099
1275
  if (opts.x402) return true;
@@ -1240,6 +1416,8 @@ export {
1240
1416
  getRPCNetworks,
1241
1417
  getRPCNetworkIds,
1242
1418
  isSolanaNetwork,
1419
+ toAdminNetworkId,
1420
+ fromAdminNetworkId,
1243
1421
  nativeTokenSymbol,
1244
1422
  AdminClient,
1245
1423
  createPendingSession,
@@ -1256,6 +1434,8 @@ export {
1256
1434
  resolveAppId,
1257
1435
  resolveAuthToken,
1258
1436
  adminClientFromFlags,
1437
+ hasAuthLoginToken,
1438
+ gasManagerClientFromFlags,
1259
1439
  resolveX402,
1260
1440
  resolveX402Client,
1261
1441
  resolveWalletKey,
@@ -2,7 +2,7 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  isJSONMode
5
- } from "./chunk-2BALTY22.js";
5
+ } from "./chunk-46LMXT54.js";
6
6
 
7
7
  // src/lib/interaction.ts
8
8
  import { stdin, stdout } from "process";
@@ -2,7 +2,7 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  getBaseDomain
5
- } from "./chunk-2BALTY22.js";
5
+ } from "./chunk-46LMXT54.js";
6
6
 
7
7
  // src/lib/auth.ts
8
8
  import { createHash, randomBytes } from "crypto";
@@ -2,7 +2,7 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  isRevealMode
5
- } from "./chunk-2BALTY22.js";
5
+ } from "./chunk-46LMXT54.js";
6
6
 
7
7
  // src/lib/secrets.ts
8
8
  function maskSecret(value) {
@@ -12,6 +12,7 @@ import {
12
12
  errInvalidAPIKey,
13
13
  errInvalidAccessKey,
14
14
  errInvalidArgs,
15
+ errLoginRequired,
15
16
  errNetwork,
16
17
  errNetworkNotEnabled,
17
18
  errNoActiveSession,
@@ -26,7 +27,7 @@ import {
26
27
  exitWithError,
27
28
  isReplMode,
28
29
  setReplMode
29
- } from "./chunk-2BALTY22.js";
30
+ } from "./chunk-46LMXT54.js";
30
31
  export {
31
32
  CLIError,
32
33
  EXIT_CODES,
@@ -39,6 +40,7 @@ export {
39
40
  errInvalidAPIKey,
40
41
  errInvalidAccessKey,
41
42
  errInvalidArgs,
43
+ errLoginRequired,
42
44
  errNetwork,
43
45
  errNetworkNotEnabled,
44
46
  errNoActiveSession,