axauth 2.1.0 → 3.1.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 (48) hide show
  1. package/README.md +10 -4
  2. package/dist/auth/adapter.d.ts +60 -20
  3. package/dist/auth/agents/claude-install.d.ts +11 -0
  4. package/dist/auth/agents/claude-install.js +80 -0
  5. package/dist/auth/agents/claude-storage.d.ts +13 -5
  6. package/dist/auth/agents/claude-storage.js +11 -16
  7. package/dist/auth/agents/claude.js +14 -89
  8. package/dist/auth/agents/codex-auth-check.d.ts +6 -5
  9. package/dist/auth/agents/codex-auth-check.js +34 -20
  10. package/dist/auth/agents/codex-install.js +1 -2
  11. package/dist/auth/agents/codex-storage.d.ts +0 -1
  12. package/dist/auth/agents/codex-storage.js +4 -5
  13. package/dist/auth/agents/codex.js +4 -4
  14. package/dist/auth/agents/copilot-install.js +2 -3
  15. package/dist/auth/agents/copilot.js +11 -6
  16. package/dist/auth/agents/gemini-install.d.ts +1 -1
  17. package/dist/auth/agents/gemini-install.js +3 -3
  18. package/dist/auth/agents/gemini.js +19 -17
  19. package/dist/auth/agents/opencode-credentials.d.ts +25 -37
  20. package/dist/auth/agents/opencode-credentials.js +48 -122
  21. package/dist/auth/agents/opencode-remove-provider.d.ts +25 -0
  22. package/dist/auth/agents/opencode-remove-provider.js +86 -0
  23. package/dist/auth/agents/opencode-storage.js +18 -22
  24. package/dist/auth/agents/opencode.d.ts +1 -1
  25. package/dist/auth/agents/opencode.js +59 -41
  26. package/dist/auth/build-refreshed-credentials.d.ts +6 -4
  27. package/dist/auth/build-refreshed-credentials.js +34 -19
  28. package/dist/auth/extract-creds-from-directory.d.ts +7 -3
  29. package/dist/auth/extract-creds-from-directory.js +4 -1
  30. package/dist/auth/refresh-credentials.d.ts +38 -12
  31. package/dist/auth/refresh-credentials.js +51 -18
  32. package/dist/auth/registry.d.ts +18 -15
  33. package/dist/auth/registry.js +35 -18
  34. package/dist/auth/resolve-refresh-credentials.d.ts +11 -8
  35. package/dist/auth/resolve-refresh-credentials.js +12 -48
  36. package/dist/auth/types.d.ts +3 -35
  37. package/dist/auth/types.js +2 -47
  38. package/dist/auth/wait-for-refreshed-credentials.d.ts +5 -1
  39. package/dist/auth/wait-for-refreshed-credentials.js +7 -4
  40. package/dist/commands/auth-export.js +24 -46
  41. package/dist/commands/auth.js +13 -3
  42. package/dist/commands/copy-to-clipboard.d.ts +6 -0
  43. package/dist/commands/copy-to-clipboard.js +48 -0
  44. package/dist/commands/vault.js +16 -15
  45. package/dist/index.d.ts +2 -2
  46. package/dist/index.js +2 -2
  47. package/dist/vault/vault-client.js +21 -2
  48. package/package.json +7 -7
@@ -72,12 +72,11 @@ function checkAllAuth() {
72
72
  return getAllAdapters().map((adapter) => adapter.checkAuth());
73
73
  }
74
74
  /**
75
- * Extract raw credentials for an agent.
75
+ * Find credentials for an agent.
76
76
  *
77
- * Checks credentials from all available sources:
78
- * - Environment variables
79
- * - Keychain (macOS)
80
- * - File storage
77
+ * Checks environment variables first (e.g., ANTHROPIC_API_KEY), then falls
78
+ * back to local storage (keychain or file) if no environment credentials
79
+ * are found. This allows easy overrides in CI/CD environments.
81
80
  *
82
81
  * Note: The `data` field format is agent-specific and not standardized.
83
82
  * Use {@link getAccessToken} to extract the token in a uniform way.
@@ -85,12 +84,22 @@ function checkAllAuth() {
85
84
  * For vault credentials, use {@link fetchVaultCredentials} from the vault module
86
85
  * or the `axauth vault fetch` CLI command.
87
86
  *
87
+ * **Multi-provider agents** (OpenCode):
88
+ * - `options.provider` is required - throws if not specified
89
+ *
88
90
  * @example
89
- * const creds = extractRawCredentials("codex");
90
- * if (creds) { await exportCredentials(creds); }
91
+ * const creds = findCredentials("codex");
92
+ * const creds = findCredentials("opencode", { provider: "anthropic" });
91
93
  */
92
- function extractRawCredentials(agentId) {
93
- return ADAPTERS[agentId].extractRawCredentials();
94
+ 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
103
  }
95
104
  /**
96
105
  * Extract raw credentials from custom directories.
@@ -100,17 +109,17 @@ function extractRawCredentials(agentId) {
100
109
  *
101
110
  * @example
102
111
  * // For agents without separation (Claude, Codex, Gemini, Copilot)
103
- * const creds = extractRawCredentialsFromDirectory("claude", { configDir: "/tmp/config" });
112
+ * const creds = findCredentialsFromDirectory("claude", { configDir: "/tmp/config" });
104
113
  *
105
114
  * // For agents with separation (OpenCode)
106
- * const creds = extractRawCredentialsFromDirectory("opencode", {
115
+ * const creds = findCredentialsFromDirectory("opencode", {
107
116
  * configDir: "/tmp/config",
108
117
  * dataDir: "/tmp/data",
109
118
  * });
110
119
  */
111
- function extractRawCredentialsFromDirectory(agentId, options) {
120
+ function findCredentialsFromDirectory(agentId, options) {
112
121
  const adapter = ADAPTERS[agentId];
113
- return adapter.extractRawCredentialsFromDirectory?.(options);
122
+ return adapter.loadCredentialsFromDirectory?.(options);
114
123
  }
115
124
  /**
116
125
  * Install credentials for an agent.
@@ -171,6 +180,7 @@ async function getAccessToken(creds, options) {
171
180
  const result = await refreshAndPersist(creds, installCredentials, {
172
181
  timeout: options?.refreshTimeout,
173
182
  provider: options?.provider,
183
+ storage: options?.storage,
174
184
  });
175
185
  const finalCreds = result.ok ? result.credentials : result.staleCredentials;
176
186
  return ADAPTERS[creds.agent].getAccessToken(finalCreds, options);
@@ -179,16 +189,23 @@ async function getAccessToken(creds, options) {
179
189
  * Get access token for an agent by ID.
180
190
  *
181
191
  * Convenience function that extracts credentials and gets the token.
182
- * Automatically refreshes expired OAuth tokens.
192
+ * Automatically refreshes expired OAuth tokens, preserving the original
193
+ * storage location (keychain or file).
183
194
  *
184
195
  * @example
185
196
  * const token = await getAgentAccessToken("claude");
186
197
  */
187
198
  async function getAgentAccessToken(agentId, options) {
188
- const creds = extractRawCredentials(agentId);
189
- if (!creds)
199
+ const stored = ADAPTERS[agentId].findStoredCredentials({
200
+ provider: options?.provider,
201
+ });
202
+ if (!stored)
190
203
  return undefined;
191
- return getAccessToken(creds, options);
204
+ // Pass the source to getAccessToken so refresh preserves storage location
205
+ return getAccessToken(stored.credentials, {
206
+ ...options,
207
+ storage: options?.storage ?? stored.source,
208
+ });
192
209
  }
193
210
  /**
194
211
  * Convert credentials to environment variables.
@@ -239,4 +256,4 @@ function installCredentialsFromEnvironmentVariable(agent, options) {
239
256
  dataDir: options?.dataDir,
240
257
  });
241
258
  }
242
- export { checkAllAuth, checkAuth, credentialsToEnvironment, extractRawCredentials, extractRawCredentialsFromDirectory, getAccessToken, getAdapter, getAgentAccessToken, getAllAdapters, getCapabilities, getCredentialsEnvironmentVariableName, installCredentials, installCredentialsFromEnvironmentVariable, removeCredentials, };
259
+ export { checkAllAuth, checkAuth, credentialsToEnvironment, findCredentials, findCredentialsFromDirectory, getAccessToken, getAdapter, getAgentAccessToken, getAllAdapters, getCapabilities, getCredentialsEnvironmentVariableName, installCredentials, installCredentialsFromEnvironmentVariable, removeCredentials, };
@@ -1,18 +1,21 @@
1
1
  /**
2
- * Resolve which credentials to use for refresh and how to merge results.
2
+ * Resolve which credentials to use for refresh.
3
+ *
4
+ * OpenCode credentials are always per-provider (bundled format removed).
3
5
  */
4
6
  import type { Credentials } from "./types.js";
5
- interface RefreshProviderOptions {
6
- provider?: string;
7
- }
8
7
  type RefreshResolution = {
9
8
  ok: true;
10
9
  credentials: Credentials;
11
- mergeProvider?: string;
12
10
  } | {
13
11
  ok: false;
14
12
  error: string;
15
13
  };
16
- declare function resolveRefreshCredentials(creds: Credentials, options?: RefreshProviderOptions): RefreshResolution;
17
- declare function mergeOpenCodeBundle(original: Credentials, refreshed: Credentials, mergeProvider?: string): Credentials;
18
- export { mergeOpenCodeBundle, resolveRefreshCredentials };
14
+ /**
15
+ * Resolve credentials for refresh.
16
+ *
17
+ * All credential types are passed through directly since OpenCode
18
+ * credentials are always per-provider format.
19
+ */
20
+ declare function resolveRefreshCredentials(creds: Credentials): RefreshResolution;
21
+ export { resolveRefreshCredentials };
@@ -1,51 +1,15 @@
1
1
  /**
2
- * Resolve which credentials to use for refresh and how to merge results.
2
+ * Resolve which credentials to use for refresh.
3
+ *
4
+ * OpenCode credentials are always per-provider (bundled format removed).
3
5
  */
4
- import { extractProviderCredentials, splitToPerProviderCredentials, } from "./agents/opencode-credentials.js";
5
- function resolveRefreshCredentials(creds, options) {
6
- if (creds.agent !== "opencode") {
7
- return { ok: true, credentials: creds };
8
- }
9
- if (creds.provider) {
10
- return { ok: true, credentials: creds };
11
- }
12
- if (options?.provider) {
13
- const providerCreds = extractProviderCredentials(creds, options.provider);
14
- if (!providerCreds) {
15
- return {
16
- ok: false,
17
- error: `No credentials found for provider '${options.provider}'`,
18
- };
19
- }
20
- return {
21
- ok: true,
22
- credentials: providerCreds,
23
- mergeProvider: providerCreds.provider,
24
- };
25
- }
26
- const perProvider = splitToPerProviderCredentials(creds);
27
- const refreshCreds = perProvider.find((cred) => cred.type === "oauth-credentials") ??
28
- perProvider.at(0);
29
- if (!refreshCreds) {
30
- return { ok: false, error: "No provider credentials found for opencode" };
31
- }
32
- return {
33
- ok: true,
34
- credentials: refreshCreds,
35
- mergeProvider: refreshCreds.provider,
36
- };
37
- }
38
- function mergeOpenCodeBundle(original, refreshed, mergeProvider) {
39
- if (original.agent !== "opencode")
40
- return refreshed;
41
- if (original.provider)
42
- return refreshed;
43
- if (!mergeProvider)
44
- return refreshed;
45
- const mergedData = { ...original.data, ...refreshed.data };
46
- if ("_source" in original.data) {
47
- mergedData._source = original.data._source;
48
- }
49
- return { ...refreshed, data: mergedData };
6
+ /**
7
+ * Resolve credentials for refresh.
8
+ *
9
+ * All credential types are passed through directly since OpenCode
10
+ * credentials are always per-provider format.
11
+ */
12
+ function resolveRefreshCredentials(creds) {
13
+ return { ok: true, credentials: creds };
50
14
  }
51
- export { mergeOpenCodeBundle, resolveRefreshCredentials };
15
+ export { resolveRefreshCredentials };
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Shared types for auth module.
3
3
  */
4
- import { type AgentCli } from "axshared";
5
- import { z } from "zod";
4
+ import type { AgentCli } from "axshared";
5
+ export { parseCredentials, parseCredentialsOrArray } from "axshared";
6
+ export type { Credentials } from "axshared";
6
7
  /** Auth status for an agent */
7
8
  interface AuthStatus {
8
9
  agentId: AgentCli;
@@ -11,37 +12,4 @@ interface AuthStatus {
11
12
  /** Additional details (e.g., provider list for opencode) */
12
13
  details?: Record<string, unknown>;
13
14
  }
14
- /** Extracted credential data schema */
15
- declare const Credentials: z.ZodObject<{
16
- agent: z.ZodEnum<{
17
- claude: "claude";
18
- codex: "codex";
19
- gemini: "gemini";
20
- opencode: "opencode";
21
- copilot: "copilot";
22
- }>;
23
- type: z.ZodEnum<{
24
- "api-key": "api-key";
25
- "oauth-token": "oauth-token";
26
- "oauth-credentials": "oauth-credentials";
27
- }>;
28
- provider: z.ZodOptional<z.ZodString>;
29
- data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
30
- }, z.core.$strip>;
31
- type Credentials = z.infer<typeof Credentials>;
32
- /**
33
- * Parse and validate credentials from unknown input.
34
- *
35
- * @returns Validated Credentials or undefined if invalid
36
- */
37
- declare function parseCredentials(input: unknown): Credentials | undefined;
38
- /**
39
- * Parse and validate credentials that may be a single object or an array.
40
- *
41
- * Used by encrypt/decrypt commands to handle OpenCode's multi-provider export format.
42
- *
43
- * @returns Validated Credentials or Credentials[] or undefined if invalid
44
- */
45
- declare function parseCredentialsOrArray(input: unknown): Credentials | Credentials[] | undefined;
46
15
  export type { AuthStatus };
47
- export { Credentials, parseCredentials, parseCredentialsOrArray };
@@ -1,50 +1,5 @@
1
1
  /**
2
2
  * Shared types for auth module.
3
3
  */
4
- import { AGENT_CLIS, CredentialType } from "axshared";
5
- import { z } from "zod";
6
- /** Zod schema for AgentCli */
7
- const AgentCliSchema = z.enum(AGENT_CLIS);
8
- /** Extracted credential data schema */
9
- const Credentials = z.object({
10
- agent: AgentCliSchema,
11
- type: CredentialType,
12
- /** Provider identifier for multi-provider agents like OpenCode (trimmed, non-empty if present) */
13
- provider: z.string().trim().min(1).optional(),
14
- data: z.record(z.string(), z.unknown()),
15
- });
16
- /**
17
- * Parse and validate credentials from unknown input.
18
- *
19
- * @returns Validated Credentials or undefined if invalid
20
- */
21
- function parseCredentials(input) {
22
- const result = Credentials.safeParse(input);
23
- return result.success ? result.data : undefined;
24
- }
25
- /**
26
- * Parse and validate credentials that may be a single object or an array.
27
- *
28
- * Used by encrypt/decrypt commands to handle OpenCode's multi-provider export format.
29
- *
30
- * @returns Validated Credentials or Credentials[] or undefined if invalid
31
- */
32
- function parseCredentialsOrArray(input) {
33
- // Try single credential first
34
- const singleResult = Credentials.safeParse(input);
35
- if (singleResult.success)
36
- return singleResult.data;
37
- // Try array of credentials
38
- if (Array.isArray(input)) {
39
- const parsed = [];
40
- for (const item of input) {
41
- const result = Credentials.safeParse(item);
42
- if (!result.success)
43
- return undefined;
44
- parsed.push(result.data);
45
- }
46
- return parsed;
47
- }
48
- return undefined;
49
- }
50
- export { Credentials, parseCredentials, parseCredentialsOrArray };
4
+ // Re-export credential types from axshared for convenience
5
+ export { parseCredentials, parseCredentialsOrArray } from "axshared";
@@ -3,5 +3,9 @@
3
3
  */
4
4
  import type { ExecutionDirectories } from "axexec";
5
5
  import type { Credentials } from "./types.js";
6
- declare function waitForRefreshedCredentials(agent: Credentials["agent"], directories: ExecutionDirectories, deadlineMs: number): Promise<Credentials | undefined>;
6
+ interface WaitOptions {
7
+ /** Provider ID for multi-provider agents (OpenCode) */
8
+ provider?: string;
9
+ }
10
+ declare function waitForRefreshedCredentials(agent: Credentials["agent"], directories: ExecutionDirectories, deadlineMs: number, options?: WaitOptions): Promise<Credentials | undefined>;
7
11
  export { waitForRefreshedCredentials };
@@ -3,14 +3,17 @@
3
3
  */
4
4
  const CREDENTIAL_POLL_INTERVAL_MS = 200;
5
5
  function delay(ms) {
6
- return new Promise((resolve) => setTimeout(resolve, ms));
6
+ return new Promise((resolve) => {
7
+ setTimeout(resolve, ms);
8
+ });
7
9
  }
8
- async function waitForRefreshedCredentials(agent, directories, deadlineMs) {
9
- const { extractRawCredentialsFromDirectory } = await import("./registry.js");
10
+ async function waitForRefreshedCredentials(agent, directories, deadlineMs, options) {
11
+ const { findCredentialsFromDirectory } = await import("./registry.js");
10
12
  for (;;) {
11
- const refreshedCredentials = extractRawCredentialsFromDirectory(agent, {
13
+ const refreshedCredentials = findCredentialsFromDirectory(agent, {
12
14
  configDir: directories.config,
13
15
  dataDir: directories.data,
16
+ provider: options?.provider,
14
17
  });
15
18
  if (refreshedCredentials)
16
19
  return refreshedCredentials;
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Auth export command handler.
3
3
  */
4
- import { execFileSync } from "node:child_process";
5
4
  import { renameSync, unlinkSync, writeFileSync } from "node:fs";
6
5
  import promptPassword from "@inquirer/password";
7
- import { extractRawCredentials } from "../auth/registry.js";
8
- import { extractProviderCredentials, splitToPerProviderCredentials, } from "../auth/agents/opencode.js";
6
+ import { findCredentials } from "../auth/registry.js";
7
+ import { getAllStoredCredentials, getStoredCredentialsForProvider, } from "../auth/agents/opencode.js";
9
8
  import { DEFAULT_PASSWORD, encrypt, toBase64 } from "../crypto.js";
9
+ import { copyToClipboard } from "./copy-to-clipboard.js";
10
10
  import { validateAgent } from "./validate-agent.js";
11
11
  /** Handle auth export command */
12
12
  async function handleAuthExport(options) {
@@ -19,13 +19,16 @@ async function handleAuthExport(options) {
19
19
  const agentId = validateAgent(options.agent);
20
20
  if (!agentId)
21
21
  return;
22
- const rawCreds = extractRawCredentials(agentId);
23
- if (!rawCreds) {
22
+ // OpenCode handles credential fetching separately in resolveExportData
23
+ // (it reads from disk with its own functions)
24
+ // For other agents, fetch credentials here
25
+ const rawCreds = agentId === "opencode" ? undefined : findCredentials(agentId);
26
+ if (agentId !== "opencode" && !rawCreds) {
24
27
  console.error(`Error: No credentials found for ${agentId}`);
25
28
  process.exitCode = 1;
26
29
  return;
27
30
  }
28
- // Handle per-provider export for OpenCode
31
+ // Handle per-provider export for OpenCode, or use rawCreds for others
29
32
  const exportData = resolveExportData(agentId, rawCreds, options.provider);
30
33
  if (!exportData)
31
34
  return;
@@ -44,24 +47,30 @@ async function handleAuthExport(options) {
44
47
  /** Resolve export data based on agent and provider options */
45
48
  function resolveExportData(agentId, rawCreds, provider) {
46
49
  if (agentId === "opencode") {
47
- if (provider) {
48
- // Export single provider
49
- const providerCreds = extractProviderCredentials(rawCreds, provider);
50
- if (!providerCreds) {
50
+ // Validate if provider was specified (check undefined, not falsy - empty string is an error)
51
+ if (provider !== undefined) {
52
+ if (provider.trim().length === 0) {
53
+ console.error("Error: Provider cannot be empty");
54
+ process.exitCode = 2;
55
+ return undefined;
56
+ }
57
+ // Export single provider (reads from disk)
58
+ const creds = getStoredCredentialsForProvider(provider);
59
+ if (!creds) {
51
60
  console.error(`Error: No credentials found for provider '${provider}'`);
52
61
  process.exitCode = 1;
53
62
  return undefined;
54
63
  }
55
- return providerCreds;
64
+ return creds;
56
65
  }
57
- // Export all providers as array
58
- const allCreds = splitToPerProviderCredentials(rawCreds);
59
- if (allCreds.length === 0) {
66
+ // Export all providers as array (reads from disk)
67
+ const creds = getAllStoredCredentials();
68
+ if (creds.length === 0) {
60
69
  console.error(`Error: No valid credentials found for ${agentId}`);
61
70
  process.exitCode = 1;
62
71
  return undefined;
63
72
  }
64
- return allCreds;
73
+ return creds;
65
74
  }
66
75
  // Non-OpenCode agents: export single credential
67
76
  if (provider) {
@@ -118,35 +127,4 @@ function writeOutput(output, isStdout, json) {
118
127
  return false;
119
128
  }
120
129
  }
121
- /** Copy text to system clipboard */
122
- function copyToClipboard(text) {
123
- try {
124
- switch (process.platform) {
125
- case "darwin": {
126
- execFileSync("pbcopy", [], { input: text });
127
- break;
128
- }
129
- case "linux": {
130
- execFileSync("xclip", ["-selection", "clipboard"], { input: text });
131
- break;
132
- }
133
- case "win32": {
134
- execFileSync("clip", [], { input: text });
135
- break;
136
- }
137
- default: {
138
- throw new Error(`Clipboard not supported on ${process.platform}. ` +
139
- `Use --output to write to a file instead.`);
140
- }
141
- }
142
- console.error(`Credentials copied to clipboard`);
143
- }
144
- catch (error) {
145
- console.error(`Failed to copy to clipboard: ${error.message}`);
146
- if (process.platform === "linux") {
147
- console.error("Hint: Ensure 'xclip' is installed.");
148
- }
149
- process.exitCode = 1;
150
- }
151
- }
152
130
  export { handleAuthExport };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Auth commands - manage agent credentials.
3
3
  */
4
- import { checkAllAuth, extractRawCredentials, getAccessToken, removeCredentials, } from "../auth/registry.js";
4
+ import { checkAllAuth, findCredentials, getAccessToken, removeCredentials, } from "../auth/registry.js";
5
5
  import { removeProviderCredentials } from "../auth/agents/opencode.js";
6
6
  import { validateAgent } from "./validate-agent.js";
7
7
  export { handleAuthInstall } from "./install-credentials.js";
@@ -20,9 +20,19 @@ async function handleAuthToken(options) {
20
20
  const agentId = validateAgent(options.agent);
21
21
  if (!agentId)
22
22
  return;
23
- const creds = extractRawCredentials(agentId);
23
+ // OpenCode requires --provider
24
+ if (agentId === "opencode" && !options.provider) {
25
+ console.error("Error: --provider is required for opencode");
26
+ console.error("Hint: Use 'axauth auth list' to see available providers");
27
+ process.exitCode = 1;
28
+ return;
29
+ }
30
+ const creds = findCredentials(agentId, { provider: options.provider });
24
31
  if (!creds) {
25
- console.error(`Error: No credentials found for ${agentId}`);
32
+ const providerHint = agentId === "opencode" && options.provider
33
+ ? ` for provider '${options.provider}'`
34
+ : "";
35
+ console.error(`Error: No credentials found for ${agentId}${providerHint}`);
26
36
  process.exitCode = 1;
27
37
  return;
28
38
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Clipboard utility for copying text to system clipboard.
3
+ */
4
+ /** Copy text to system clipboard */
5
+ declare function copyToClipboard(text: string): void;
6
+ export { copyToClipboard };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Clipboard utility for copying text to system clipboard.
3
+ */
4
+ import { execFileSync } from "node:child_process";
5
+ /** Copy text to system clipboard */
6
+ function copyToClipboard(text) {
7
+ try {
8
+ switch (process.platform) {
9
+ case "darwin": {
10
+ execFileSync("pbcopy", [], { input: text });
11
+ break;
12
+ }
13
+ case "linux": {
14
+ execFileSync("xclip", ["-selection", "clipboard"], { input: text });
15
+ break;
16
+ }
17
+ case "win32": {
18
+ execFileSync("clip", [], { input: text });
19
+ break;
20
+ }
21
+ case "aix":
22
+ case "android":
23
+ case "freebsd":
24
+ case "haiku":
25
+ case "openbsd":
26
+ case "sunos":
27
+ case "cygwin":
28
+ case "netbsd": {
29
+ throw new Error(`Clipboard not supported on ${process.platform}. ` +
30
+ `Use --output to write to a file instead.`);
31
+ }
32
+ // Default case for any unknown/future platforms not in Node.js type definition
33
+ default: {
34
+ throw new Error(`Clipboard not supported on ${process.platform}. ` +
35
+ `Use --output to write to a file instead.`);
36
+ }
37
+ }
38
+ console.error(`Credentials copied to clipboard`);
39
+ }
40
+ catch (error) {
41
+ console.error(`Failed to copy to clipboard: ${error.message}`);
42
+ if (process.platform === "linux") {
43
+ console.error("Hint: Ensure 'xclip' is installed.");
44
+ }
45
+ process.exitCode = 1;
46
+ }
47
+ }
48
+ export { copyToClipboard };
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Vault commands - fetch and push credentials to axvault server.
3
3
  */
4
- import { credentialsToEnvironment, extractRawCredentials, installCredentials, } from "../auth/registry.js";
5
- import { extractProviderCredentials } from "../auth/agents/opencode.js";
4
+ import { credentialsToEnvironment, findCredentials, installCredentials, } from "../auth/registry.js";
5
+ import { getStoredCredentialsForProvider } from "../auth/agents/opencode.js";
6
6
  import { fetchVaultCredentials, pushVaultCredentials, } from "../vault/vault-client.js";
7
7
  import { getVaultConfig } from "../vault/vault-config.js";
8
8
  import { validateAgent } from "./validate-agent.js";
@@ -133,12 +133,18 @@ async function handleVaultPush(options) {
133
133
  const agentId = validateAgent(options.agent);
134
134
  if (!agentId)
135
135
  return;
136
- // Validate --provider is only used with opencode
136
+ // Validate provider flag usage
137
137
  if (options.provider && agentId !== "opencode") {
138
138
  console.error("Error: --provider flag is only supported for opencode agent");
139
139
  process.exitCode = 2;
140
140
  return;
141
141
  }
142
+ if (agentId === "opencode" && !options.provider) {
143
+ console.error("Error: --provider is required for opencode");
144
+ console.error("Hint: Use 'axauth auth list' to see available providers");
145
+ process.exitCode = 1;
146
+ return;
147
+ }
142
148
  // Check vault is configured
143
149
  const vaultConfig = getVaultConfig();
144
150
  if (!vaultConfig) {
@@ -147,19 +153,14 @@ async function handleVaultPush(options) {
147
153
  return;
148
154
  }
149
155
  // Extract local credentials
150
- const rawCredentials = extractRawCredentials(agentId);
151
- if (!rawCredentials) {
152
- console.error(`Error: No credentials found for ${agentId}`);
153
- console.error("Hint: Authenticate with the agent first, or use 'axauth list' to check status");
154
- process.exitCode = 1;
155
- return;
156
- }
157
- // Handle per-provider extraction for OpenCode
158
- const credentials = options.provider
159
- ? extractProviderCredentials(rawCredentials, options.provider)
160
- : rawCredentials;
156
+ const credentials = agentId === "opencode" && options.provider
157
+ ? getStoredCredentialsForProvider(options.provider)
158
+ : findCredentials(agentId);
161
159
  if (!credentials) {
162
- console.error(`Error: No credentials found for provider '${options.provider}'`);
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 auth list' to check status`;
163
+ console.error(`Error: ${hint}`);
163
164
  process.exitCode = 1;
164
165
  return;
165
166
  }
package/dist/index.d.ts CHANGED
@@ -34,8 +34,8 @@ export type { AgentCli } from "axshared";
34
34
  export { AGENT_CLIS } from "axshared";
35
35
  export type { AdapterCapabilities, AuthAdapter, InstallOptions, OperationResult, RemoveOptions, } from "./auth/adapter.js";
36
36
  export type { AuthStatus, Credentials } from "./auth/types.js";
37
- export { checkAllAuth, checkAuth, credentialsToEnvironment, extractRawCredentials, extractRawCredentialsFromDirectory, getAccessToken, getAgentAccessToken, getCredentialsEnvironmentVariableName, installCredentials, installCredentialsFromEnvironmentVariable, removeCredentials, getAdapter, getAllAdapters, getCapabilities, type ExtractOptions, type InstallFromEnvironmentOptions, } from "./auth/registry.js";
37
+ export { checkAllAuth, checkAuth, credentialsToEnvironment, findCredentials, findCredentialsFromDirectory, getAccessToken, getAgentAccessToken, getCredentialsEnvironmentVariableName, installCredentials, installCredentialsFromEnvironmentVariable, removeCredentials, getAdapter, getAllAdapters, getCapabilities, type ExtractOptions, type FindStoredCredentialsOptions, type InstallFromEnvironmentOptions, } from "./auth/registry.js";
38
38
  export { getVaultConfig, isVaultConfigured, type VaultConfig, } from "./vault/vault-config.js";
39
39
  export { fetchVaultCredentials, type VaultFailureReason, type VaultFetchOptions, type VaultResult, } from "./vault/vault-client.js";
40
40
  export { extractExpiryDate, extractExpiryTimestamp, isCredentialExpired, isRefreshable, isTokenExpired, type RefreshableCredentials, } from "./auth/is-token-expired.js";
41
- export { refreshAndPersist, refreshCredentials, type RefreshAndPersistResult, type RefreshOptions, type RefreshResult, } from "./auth/refresh-credentials.js";
41
+ export { refreshAndPersist, refreshBlob, refreshCredentials, type RefreshAndPersistResult, type RefreshBlobResult, type RefreshOptions, type RefreshResult, } from "./auth/refresh-credentials.js";
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ export { AGENT_CLIS } from "axshared";
34
34
  // Registry - unified entry point for all operations
35
35
  export {
36
36
  // Core operations
37
- checkAllAuth, checkAuth, credentialsToEnvironment, extractRawCredentials, extractRawCredentialsFromDirectory, getAccessToken, getAgentAccessToken, getCredentialsEnvironmentVariableName, installCredentials, installCredentialsFromEnvironmentVariable, removeCredentials,
37
+ checkAllAuth, checkAuth, credentialsToEnvironment, findCredentials, findCredentialsFromDirectory, getAccessToken, getAgentAccessToken, getCredentialsEnvironmentVariableName, installCredentials, installCredentialsFromEnvironmentVariable, removeCredentials,
38
38
  // Adapter access
39
39
  getAdapter, getAllAdapters, getCapabilities, } from "./auth/registry.js";
40
40
  // Vault utilities
@@ -42,4 +42,4 @@ export { getVaultConfig, isVaultConfigured, } from "./vault/vault-config.js";
42
42
  export { fetchVaultCredentials, } from "./vault/vault-client.js";
43
43
  // Token/credential utilities
44
44
  export { extractExpiryDate, extractExpiryTimestamp, isCredentialExpired, isRefreshable, isTokenExpired, } from "./auth/is-token-expired.js";
45
- export { refreshAndPersist, refreshCredentials, } from "./auth/refresh-credentials.js";
45
+ export { refreshAndPersist, refreshBlob, refreshCredentials, } from "./auth/refresh-credentials.js";