axauth 3.1.6 → 3.2.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.
@@ -0,0 +1,12 @@
1
+ import type { AgentCli } from "axshared";
2
+ import type { AuthAdapter, FindStoredCredentialsOptions, InstallOptions, OperationResult, TokenOptions } from "./adapter.js";
3
+ import type { Credentials } from "./types.js";
4
+ interface AccessTokenDependencies {
5
+ adapter: AuthAdapter;
6
+ installCredentials: (agentId: AgentCli, creds: Credentials, options?: InstallOptions) => OperationResult;
7
+ }
8
+ declare function findCredentialsWithEnvironmentPriority(adapter: AuthAdapter, options?: FindStoredCredentialsOptions): Credentials | undefined;
9
+ type AccessTokenGetter = (agentId: AgentCli, creds: Credentials, options?: TokenOptions) => Promise<string | undefined>;
10
+ declare function getAgentAccessTokenFromStoredCredentials(agentId: AgentCli, adapter: AuthAdapter, options: TokenOptions | undefined, getAccessToken: AccessTokenGetter): Promise<string | undefined>;
11
+ declare function getAccessTokenWithRefresh(agentId: AgentCli, creds: Credentials, options: TokenOptions | undefined, dependencies: AccessTokenDependencies): Promise<string | undefined>;
12
+ export { findCredentialsWithEnvironmentPriority, getAccessTokenWithRefresh, getAgentAccessTokenFromStoredCredentials, };
@@ -0,0 +1,47 @@
1
+ import { isCredentialExpired, isTokenExpired } from "./is-token-expired.js";
2
+ import { refreshAndPersist } from "./refresh-credentials.js";
3
+ function findCredentialsWithEnvironmentPriority(adapter, options) {
4
+ const environmentCredentials = adapter.getEnvironmentCredentials?.();
5
+ if (environmentCredentials)
6
+ return environmentCredentials;
7
+ const stored = adapter.findStoredCredentials(options);
8
+ return stored?.credentials;
9
+ }
10
+ function shouldRefreshToken(token, creds, options) {
11
+ if (creds.type === "api-key")
12
+ return false;
13
+ if (options?.skipRefresh)
14
+ return false;
15
+ let expired = isTokenExpired(token);
16
+ if (expired === undefined) {
17
+ expired = isCredentialExpired(creds.data);
18
+ }
19
+ return expired === true;
20
+ }
21
+ async function getAgentAccessTokenFromStoredCredentials(agentId, adapter, options, getAccessToken) {
22
+ const stored = adapter.findStoredCredentials({
23
+ provider: options?.provider,
24
+ });
25
+ if (!stored)
26
+ return undefined;
27
+ return getAccessToken(agentId, stored.credentials, {
28
+ ...options,
29
+ storage: options?.storage ?? stored.source,
30
+ });
31
+ }
32
+ async function getAccessTokenWithRefresh(agentId, creds, options, dependencies) {
33
+ const token = dependencies.adapter.getAccessToken(creds, options);
34
+ if (!token)
35
+ return undefined;
36
+ if (!shouldRefreshToken(token, creds, options)) {
37
+ return token;
38
+ }
39
+ const result = await refreshAndPersist(agentId, creds, (resolvedAgentId, refreshedCreds, installOptions) => dependencies.installCredentials(resolvedAgentId, refreshedCreds, installOptions), {
40
+ timeout: options?.refreshTimeout,
41
+ provider: options?.provider,
42
+ storage: options?.storage,
43
+ });
44
+ const finalCreds = result.ok ? result.credentials : result.staleCredentials;
45
+ return dependencies.adapter.getAccessToken(finalCreds, options);
46
+ }
47
+ export { findCredentialsWithEnvironmentPriority, getAccessTokenWithRefresh, getAgentAccessTokenFromStoredCredentials, };
@@ -9,9 +9,8 @@ import { codexAdapter } from "./agents/codex.js";
9
9
  import { copilotAdapter } from "./agents/copilot.js";
10
10
  import { geminiAdapter } from "./agents/gemini.js";
11
11
  import { opencodeAdapter } from "./agents/opencode.js";
12
+ import { findCredentialsWithEnvironmentPriority, getAccessTokenWithRefresh, getAgentAccessTokenFromStoredCredentials, } from "./get-access-token-with-refresh.js";
12
13
  import { installCredentialsFromEnvironmentCore } from "./install-from-environment.js";
13
- import { isCredentialExpired, isTokenExpired } from "./is-token-expired.js";
14
- import { refreshAndPersist } from "./refresh-credentials.js";
15
14
  /** Registry of all adapters by agent ID */
16
15
  const ADAPTERS = {
17
16
  claude: claudeCodeAdapter,
@@ -92,14 +91,7 @@ function checkAllAuth() {
92
91
  * const creds = findCredentials("opencode", { provider: "anthropic" });
93
92
  */
94
93
  function findCredentials(agentId, options) {
95
- const adapter = ADAPTERS[agentId];
96
- // Check environment credentials first (allows easy overrides in CI/CD)
97
- const environmentCredentials = adapter.getEnvironmentCredentials?.();
98
- if (environmentCredentials)
99
- return environmentCredentials;
100
- // Fall back to stored credentials (keychain/file)
101
- const stored = adapter.findStoredCredentials(options);
102
- return stored?.credentials;
94
+ return findCredentialsWithEnvironmentPriority(ADAPTERS[agentId], options);
103
95
  }
104
96
  /**
105
97
  * Extract raw credentials from custom directories.
@@ -158,32 +150,10 @@ function removeCredentials(agentId, options) {
158
150
  * const token = await getAccessToken(creds, { skipRefresh: true });
159
151
  */
160
152
  async function getAccessToken(agentId, creds, options) {
161
- const token = ADAPTERS[agentId].getAccessToken(creds, options);
162
- // No token found
163
- if (!token)
164
- return undefined;
165
- // API keys don't expire
166
- if (creds.type === "api-key")
167
- return token;
168
- // Skip refresh if requested
169
- if (options?.skipRefresh)
170
- return token;
171
- // Check if token is expired (try JWT first, then credential fields)
172
- let expired = isTokenExpired(token);
173
- if (expired === undefined) {
174
- // Token isn't a JWT - check credential's explicit expiry fields
175
- expired = isCredentialExpired(creds.data);
176
- }
177
- if (expired !== true)
178
- return token; // Valid or no expiry info
179
- // Refresh and persist
180
- const result = await refreshAndPersist(agentId, creds, (aid, c, installOptions) => installCredentials(aid, c, installOptions), {
181
- timeout: options?.refreshTimeout,
182
- provider: options?.provider,
183
- storage: options?.storage,
153
+ return getAccessTokenWithRefresh(agentId, creds, options, {
154
+ adapter: ADAPTERS[agentId],
155
+ installCredentials,
184
156
  });
185
- const finalCreds = result.ok ? result.credentials : result.staleCredentials;
186
- return ADAPTERS[agentId].getAccessToken(finalCreds, options);
187
157
  }
188
158
  /**
189
159
  * Get access token for an agent by ID.
@@ -196,16 +166,7 @@ async function getAccessToken(agentId, creds, options) {
196
166
  * const token = await getAgentAccessToken("claude");
197
167
  */
198
168
  async function getAgentAccessToken(agentId, options) {
199
- const stored = ADAPTERS[agentId].findStoredCredentials({
200
- provider: options?.provider,
201
- });
202
- if (!stored)
203
- return undefined;
204
- // Pass the source to getAccessToken so refresh preserves storage location
205
- return getAccessToken(agentId, stored.credentials, {
206
- ...options,
207
- storage: options?.storage ?? stored.source,
208
- });
169
+ return getAgentAccessTokenFromStoredCredentials(agentId, ADAPTERS[agentId], options, getAccessToken);
209
170
  }
210
171
  /**
211
172
  * Convert credentials to environment variables.
package/dist/cli.js CHANGED
@@ -9,7 +9,8 @@ import packageJson from "../package.json" with { type: "json" };
9
9
  import { handleAuthExport, handleAuthInstall, handleAuthList, handleAuthRemove, handleAuthToken, } from "./commands/auth.js";
10
10
  import { handleDecrypt } from "./commands/decrypt.js";
11
11
  import { handleEncrypt } from "./commands/encrypt.js";
12
- import { handleVaultFetch, handleVaultPush } from "./commands/vault.js";
12
+ import { handleVaultFetch } from "./commands/vault-fetch.js";
13
+ import { handleVaultPush } from "./commands/vault-push.js";
13
14
  import { AGENT_CLIS } from "axshared";
14
15
  // Handle SIGINT gracefully
15
16
  process.on("SIGINT", () => {
@@ -198,6 +199,8 @@ vault
198
199
  .requiredOption("-a, --agent <agent>", `Agent to push credentials from (${AGENT_CLIS.join(", ")})`)
199
200
  .requiredOption("-n, --name <name>", "Credential name in vault (e.g., ci, prod)")
200
201
  .option("-p, --provider <provider>", "Provider to push (opencode only; pushes single provider instead of all)")
202
+ .option("--display-name <name>", "Human-readable display name for this credential (e.g., 'Claude (Work)')")
203
+ .option("--notes <text>", "Additional notes about this credential")
201
204
  .addHelpText("after", String.raw `
202
205
  Environment variables (option 1 - single JSON):
203
206
  AXVAULT JSON config: {"url":"...","apiKey":"..."}
@@ -210,6 +213,9 @@ Examples:
210
213
  # Push local Claude credentials to vault as "ci"
211
214
  axauth vault push --agent claude --name ci
212
215
 
216
+ # Push with a display name for multi-instance identification
217
+ axauth vault push --agent claude --name work-claude --display-name "Claude (Work)"
218
+
213
219
  # Push a single OpenCode provider to vault
214
220
  axauth vault push --agent opencode --provider anthropic --name ci-anthropic
215
221
 
@@ -0,0 +1,4 @@
1
+ import type { VaultFailureReason } from "../vault/vault-client.js";
2
+ /** Human-readable error messages for vault failures */
3
+ declare const FAILURE_MESSAGES: Record<VaultFailureReason, string>;
4
+ export { FAILURE_MESSAGES };
@@ -0,0 +1,12 @@
1
+ /** Human-readable error messages for vault failures */
2
+ const FAILURE_MESSAGES = {
3
+ "not-configured": "Vault not configured. Set AXVAULT (JSON) or AXVAULT_URL + AXVAULT_API_KEY.",
4
+ unreachable: "Vault server is unreachable. Check vault URL and network.",
5
+ unauthorized: "Invalid API key. Check apiKey in vault config.",
6
+ forbidden: "Access denied. API key doesn't have required access to this credential.",
7
+ "not-found": "Credential not found in vault.",
8
+ "legacy-credential": "Credential uses legacy encryption. Re-upload it to vault.",
9
+ "client-error": "Invalid request. Check credential name and try again.",
10
+ "server-error": "Vault server error. Check server logs.",
11
+ };
12
+ export { FAILURE_MESSAGES };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Vault commands - fetch and push credentials to axvault server.
2
+ * Vault fetch command - download credentials from axvault server.
3
3
  */
4
4
  interface VaultFetchOptions {
5
5
  agent: string;
@@ -19,17 +19,4 @@ interface VaultFetchOptions {
19
19
  * - Outputs shell export commands with --env flag (for eval/source)
20
20
  */
21
21
  declare function handleVaultFetch(options: VaultFetchOptions): Promise<void>;
22
- interface VaultPushOptions {
23
- agent: string;
24
- name: string;
25
- provider?: string;
26
- }
27
- /**
28
- * Handle vault push command.
29
- *
30
- * Reads local credentials for an agent and pushes them to the vault server
31
- * in raw (unencrypted) format. This allows the vault to handle encryption
32
- * and automatic token refresh.
33
- */
34
- declare function handleVaultPush(options: VaultPushOptions): Promise<void>;
35
- export { handleVaultFetch, handleVaultPush };
22
+ export { handleVaultFetch };
@@ -1,22 +1,11 @@
1
1
  /**
2
- * Vault commands - fetch and push credentials to axvault server.
2
+ * Vault fetch command - download credentials from axvault server.
3
3
  */
4
- import { credentialsToEnvironment, findCredentials, installCredentials, } from "../auth/registry.js";
5
- import { getStoredCredentialsForProvider } from "../auth/agents/opencode.js";
6
- import { fetchVaultCredentials, pushVaultCredentials, } from "../vault/vault-client.js";
4
+ import { credentialsToEnvironment, installCredentials, } from "../auth/registry.js";
5
+ import { fetchVaultCredentials } from "../vault/vault-client.js";
7
6
  import { getVaultConfig } from "../vault/vault-config.js";
7
+ import { FAILURE_MESSAGES } from "./vault-failure-messages.js";
8
8
  import { validateAgent } from "./validate-agent.js";
9
- /** Human-readable error messages for vault failures */
10
- const FAILURE_MESSAGES = {
11
- "not-configured": "Vault not configured. Set AXVAULT (JSON) or AXVAULT_URL + AXVAULT_API_KEY.",
12
- unreachable: "Vault server is unreachable. Check vault URL and network.",
13
- unauthorized: "Invalid API key. Check apiKey in vault config.",
14
- forbidden: "Access denied. API key doesn't have read access to this credential.",
15
- "not-found": "Credential not found in vault.",
16
- "legacy-credential": "Credential uses legacy encryption. Re-upload it to vault.",
17
- "client-error": "Invalid request. Check credential name and try again.",
18
- "server-error": "Vault server error. Check server logs.",
19
- };
20
9
  /**
21
10
  * Escape a value for safe use in shell export statement.
22
11
  * Uses single quotes and escapes any single quotes in the value.
@@ -66,7 +55,7 @@ async function handleVaultFetch(options) {
66
55
  process.exitCode = 1;
67
56
  return;
68
57
  }
69
- const { credentials, refreshed } = result;
58
+ const { credentials, refreshed, displayName, notes } = result;
70
59
  // Log refresh status to stderr (not stdout, to allow piping)
71
60
  if (refreshed) {
72
61
  console.error("Note: Credentials were auto-refreshed by vault");
@@ -112,71 +101,18 @@ async function handleVaultFetch(options) {
112
101
  }
113
102
  else {
114
103
  // Output credentials as JSON (default)
104
+ const output = {
105
+ ...credentials,
106
+ ...(displayName !== undefined && { displayName }),
107
+ ...(notes !== undefined && { notes }),
108
+ };
115
109
  if (options.json) {
116
- console.log(JSON.stringify(credentials, undefined, 2));
110
+ console.log(JSON.stringify(output, undefined, 2));
117
111
  }
118
112
  else {
119
113
  // Compact JSON for piping
120
- console.log(JSON.stringify(credentials));
114
+ console.log(JSON.stringify(output));
121
115
  }
122
116
  }
123
117
  }
124
- /**
125
- * Handle vault push command.
126
- *
127
- * Reads local credentials for an agent and pushes them to the vault server
128
- * in raw (unencrypted) format. This allows the vault to handle encryption
129
- * and automatic token refresh.
130
- */
131
- async function handleVaultPush(options) {
132
- // Validate agent
133
- const agentId = validateAgent(options.agent);
134
- if (!agentId)
135
- return;
136
- // Validate provider flag usage
137
- if (options.provider && agentId !== "opencode") {
138
- console.error("Error: --provider flag is only supported for opencode agent");
139
- process.exitCode = 2;
140
- return;
141
- }
142
- if (agentId === "opencode" && !options.provider) {
143
- console.error("Error: --provider is required for opencode");
144
- console.error("Hint: Use 'axauth list --json' to see available providers");
145
- process.exitCode = 1;
146
- return;
147
- }
148
- // Check vault is configured
149
- const vaultConfig = getVaultConfig();
150
- if (!vaultConfig) {
151
- console.error(`Error: ${FAILURE_MESSAGES["not-configured"]}`);
152
- process.exitCode = 1;
153
- return;
154
- }
155
- // Extract local credentials
156
- const credentials = agentId === "opencode" && options.provider
157
- ? getStoredCredentialsForProvider(options.provider)
158
- : findCredentials(agentId);
159
- if (!credentials) {
160
- const hint = agentId === "opencode"
161
- ? `No credentials found for provider '${options.provider}'`
162
- : `No credentials found for ${agentId}\nHint: Authenticate with the agent first, or use 'axauth list' to check status`;
163
- console.error(`Error: ${hint}`);
164
- process.exitCode = 1;
165
- return;
166
- }
167
- // Push to vault
168
- const result = await pushVaultCredentials({
169
- agentId,
170
- name: options.name,
171
- credentials,
172
- provider: options.provider,
173
- });
174
- if (!result.ok) {
175
- console.error(`Error: ${FAILURE_MESSAGES[result.reason]}`);
176
- process.exitCode = 1;
177
- return;
178
- }
179
- const label = options.provider ? `${agentId}/${options.provider}` : agentId;
180
- console.error(`Credentials pushed to vault: ${label} → ${options.name}`);
181
- }
182
- export { handleVaultFetch, handleVaultPush };
118
+ export { handleVaultFetch };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Vault push command - upload local credentials to axvault server.
3
+ */
4
+ interface VaultPushOptions {
5
+ agent: string;
6
+ name: string;
7
+ provider?: string;
8
+ displayName?: string;
9
+ notes?: string;
10
+ }
11
+ /**
12
+ * Handle vault push command.
13
+ *
14
+ * Reads local credentials for an agent and pushes them to the vault server
15
+ * in raw (unencrypted) format. This allows the vault to handle encryption
16
+ * and automatic token refresh.
17
+ */
18
+ declare function handleVaultPush(options: VaultPushOptions): Promise<void>;
19
+ export { handleVaultPush };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Vault push command - upload local credentials to axvault server.
3
+ */
4
+ import { findCredentials } from "../auth/registry.js";
5
+ import { getStoredCredentialsForProvider } from "../auth/agents/opencode.js";
6
+ import { pushVaultCredentials } from "../vault/vault-client.js";
7
+ import { getVaultConfig } from "../vault/vault-config.js";
8
+ import { FAILURE_MESSAGES } from "./vault-failure-messages.js";
9
+ import { validateAgent } from "./validate-agent.js";
10
+ /**
11
+ * Handle vault push command.
12
+ *
13
+ * Reads local credentials for an agent and pushes them to the vault server
14
+ * in raw (unencrypted) format. This allows the vault to handle encryption
15
+ * and automatic token refresh.
16
+ */
17
+ async function handleVaultPush(options) {
18
+ // Validate agent
19
+ const agentId = validateAgent(options.agent);
20
+ if (!agentId)
21
+ return;
22
+ // Validate provider flag usage
23
+ if (options.provider && agentId !== "opencode") {
24
+ console.error("Error: --provider flag is only supported for opencode agent");
25
+ process.exitCode = 2;
26
+ return;
27
+ }
28
+ if (agentId === "opencode" && !options.provider) {
29
+ console.error("Error: --provider is required for opencode");
30
+ console.error("Hint: Use 'axauth list --json' to see available providers");
31
+ process.exitCode = 1;
32
+ return;
33
+ }
34
+ // Check vault is configured
35
+ const vaultConfig = getVaultConfig();
36
+ if (!vaultConfig) {
37
+ console.error(`Error: ${FAILURE_MESSAGES["not-configured"]}`);
38
+ process.exitCode = 1;
39
+ return;
40
+ }
41
+ // Extract local credentials
42
+ const credentials = agentId === "opencode" && options.provider
43
+ ? getStoredCredentialsForProvider(options.provider)
44
+ : findCredentials(agentId);
45
+ if (!credentials) {
46
+ const hint = agentId === "opencode"
47
+ ? `No credentials found for provider '${options.provider}'`
48
+ : `No credentials found for ${agentId}\nHint: Authenticate with the agent first, or use 'axauth list' to check status`;
49
+ console.error(`Error: ${hint}`);
50
+ process.exitCode = 1;
51
+ return;
52
+ }
53
+ // Push to vault
54
+ const result = await pushVaultCredentials({
55
+ agentId,
56
+ name: options.name,
57
+ credentials,
58
+ provider: options.provider,
59
+ displayName: options.displayName,
60
+ notes: options.notes,
61
+ });
62
+ if (!result.ok) {
63
+ console.error(`Error: ${FAILURE_MESSAGES[result.reason]}`);
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+ const label = options.provider ? `${agentId}/${options.provider}` : agentId;
68
+ console.error(`Credentials pushed to vault: ${label} → ${options.name}`);
69
+ }
70
+ export { handleVaultPush };
@@ -14,6 +14,8 @@ type VaultResult = {
14
14
  ok: true;
15
15
  credentials: Credentials;
16
16
  refreshed: boolean;
17
+ displayName: string | undefined;
18
+ notes: string | undefined;
17
19
  } | {
18
20
  ok: false;
19
21
  reason: VaultFailureReason;
@@ -61,6 +63,10 @@ interface VaultPushOptions {
61
63
  credentials: Credentials;
62
64
  /** Provider for multi-provider agents (e.g., "anthropic" for OpenCode) */
63
65
  provider?: string;
66
+ /** Human-readable display name for this credential */
67
+ displayName?: string;
68
+ /** Additional notes about this credential */
69
+ notes?: string;
64
70
  }
65
71
  /**
66
72
  * Push credentials to the axvault server.
@@ -11,6 +11,14 @@ import { getVaultConfig } from "./vault-config.js";
11
11
  const VaultCredentialResponse = z.object({
12
12
  name: z.string(),
13
13
  credential: z.record(z.string(), z.unknown()),
14
+ displayName: z
15
+ .string()
16
+ .nullish()
17
+ .transform((value) => value ?? undefined),
18
+ notes: z
19
+ .string()
20
+ .nullish()
21
+ .transform((value) => value ?? undefined),
14
22
  updatedAt: z.string(),
15
23
  });
16
24
  /**
@@ -84,6 +92,8 @@ async function fetchVaultCredentials(options) {
84
92
  ok: true,
85
93
  credentials: body.credential,
86
94
  refreshed: wasRefreshed,
95
+ displayName: body.displayName,
96
+ notes: body.notes,
87
97
  };
88
98
  }
89
99
  catch {
@@ -133,6 +143,10 @@ async function pushVaultCredentials(options) {
133
143
  type: options.credentials.type,
134
144
  data: options.credentials.data,
135
145
  ...(options.provider !== undefined && { provider: options.provider }),
146
+ ...(options.displayName !== undefined && {
147
+ displayName: options.displayName,
148
+ }),
149
+ ...(options.notes !== undefined && { notes: options.notes }),
136
150
  }),
137
151
  });
138
152
  // Handle error responses
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "axauth",
3
3
  "author": "Łukasz Jerciński",
4
4
  "license": "MIT",
5
- "version": "3.1.6",
5
+ "version": "3.2.0",
6
6
  "description": "Authentication management library and CLI for AI coding agents",
7
7
  "repository": {
8
8
  "type": "git",
@@ -62,31 +62,31 @@
62
62
  "automation",
63
63
  "coding-assistant"
64
64
  ],
65
- "packageManager": "pnpm@10.28.1",
65
+ "packageManager": "pnpm@10.30.1",
66
66
  "engines": {
67
67
  "node": ">=22.14.0"
68
68
  },
69
69
  "dependencies": {
70
70
  "@commander-js/extra-typings": "^14.0.0",
71
- "@inquirer/password": "^5.0.4",
71
+ "@inquirer/password": "^5.0.7",
72
72
  "axconfig": "^3.6.3",
73
- "axexec": "^2.0.0",
73
+ "axexec": "^2.0.1",
74
74
  "axshared": "^5.0.0",
75
- "commander": "^14.0.2",
76
- "zod": "^4.3.5"
75
+ "commander": "^14.0.3",
76
+ "zod": "^4.3.6"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@total-typescript/ts-reset": "^0.6.1",
80
- "@types/node": "^25.0.10",
81
- "@vitest/coverage-v8": "^4.0.17",
82
- "eslint": "^9.39.2",
83
- "eslint-config-axkit": "^1.1.0",
80
+ "@types/node": "^25.3.0",
81
+ "@vitest/coverage-v8": "^4.0.18",
82
+ "eslint": "^10.0.1",
83
+ "eslint-config-axkit": "^1.2.1",
84
84
  "fta-check": "^1.5.1",
85
85
  "fta-cli": "^3.0.0",
86
- "knip": "^5.82.1",
86
+ "knip": "^5.85.0",
87
87
  "prettier": "3.8.1",
88
- "semantic-release": "^25.0.2",
88
+ "semantic-release": "^25.0.3",
89
89
  "typescript": "^5.9.3",
90
- "vitest": "^4.0.17"
90
+ "vitest": "^4.0.18"
91
91
  }
92
92
  }