axexec 1.7.0 → 2.0.1

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.
package/README.md CHANGED
@@ -18,6 +18,12 @@ axexec is **not** a security boundary. It does not restrict filesystem or networ
18
18
  npm install -g axexec
19
19
  ```
20
20
 
21
+ ## Prerequisites
22
+
23
+ - Node.js 22.14+
24
+ - npx (included with Node.js) for one-off runs; pnpm (optional) for local development workflows
25
+ - jq for JSONL pipeline examples
26
+
21
27
  ## Requirements
22
28
 
23
29
  Install the agent CLIs you plan to use:
@@ -45,40 +51,53 @@ export AXEXEC_COPILOT_PATH=/opt/copilot/bin/copilot
45
51
  ```bash
46
52
  # Run a prompt with an agent
47
53
  axexec --agent claude "Add error handling to auth.ts"
48
- axexec -a codex "Fix the bug in main.ts"
49
- axexec -a gemini "Refactor the utils module"
50
- axexec -a opencode "Add logging"
51
- axexec -a copilot "Write tests"
54
+ axexec --agent codex "Fix the bug in main.ts"
55
+ axexec --agent gemini "Refactor the utils module"
56
+ axexec --agent opencode "Add logging"
57
+ axexec --agent copilot "Write tests"
52
58
 
53
59
  # Run with explicit credentials JSON (from axauth export)
54
- axexec -a claude --credentials-file ./creds.json "Review this PR"
60
+ axexec --agent claude --credentials-file ./creds.json "Review this PR"
55
61
 
56
62
  # Specify a model
57
- axexec -a claude --model opus "Review this PR"
58
- axexec -a gemini --model gemini-2.5-pro "Refactor utils"
63
+ axexec --agent claude --model opus "Review this PR"
64
+ axexec --agent gemini --model gemini-2.5-pro "Refactor utils"
59
65
 
60
66
  # Set permissions
61
- axexec -a claude --allow 'read,glob,bash:git *' "Check git history" # best-effort
67
+ axexec --agent claude --allow 'read,glob,bash:git *' "Check git history" # best-effort
62
68
 
63
69
  # Output normalized JSONL event stream
64
- axexec -a claude -f jsonl "Add tests" | jq 'select(.type == "tool.call")'
70
+ axexec --agent claude --format jsonl "Add tests" | jq 'select(.type == "tool.call")'
65
71
 
66
72
  # List available agents
67
73
  axexec --list-agents
68
74
  ```
69
75
 
76
+ Examples use long flags for clarity; short flags like `-a`, `-m`, and `-f` are still supported.
77
+
78
+ ## Output Formats
79
+
80
+ axexec supports `--format jsonl|tsv`:
81
+
82
+ - `jsonl`: one JSON object per line (machine-friendly)
83
+ - `tsv`: tab-separated values (human-friendly)
84
+ - Default is TSV; when stdout is a TTY and `--format` is omitted, output is truncated for readability
85
+ - Use `--format tsv` to force full TSV (not applicable to `--list-agents`, which always outputs TSV)
86
+ - Always set `--format` explicitly in pipelines
87
+ - TSV output starts with `time` and `event type` as the first two columns for all events
88
+
70
89
  ## Pipeline Examples
71
90
 
72
91
  ### Count event types
73
92
 
74
93
  ```bash
75
- axexec -a claude "Summarize the change" | cut -f2 | sort | uniq -c | sort -rn
94
+ axexec --agent claude --format tsv "Summarize the change" | cut -f2 | sort | uniq -c | sort -rn
76
95
  ```
77
96
 
78
97
  ### Filter tool calls
79
98
 
80
99
  ```bash
81
- axexec -a claude -f jsonl "Audit dependencies" | jq 'select(.type == "tool.call")'
100
+ axexec --agent claude --format jsonl "Audit dependencies" | jq 'select(.type == "tool.call")'
82
101
  ```
83
102
 
84
103
  ### Filter available agents by package
@@ -98,7 +117,7 @@ axexec --list-agents | tail -n +2 | awk -F'\t' '$3 ~ /openai/ {print $1}'
98
117
  --provider <provider> Provider for OpenCode (e.g., anthropic, openai, google, opencode)
99
118
  --allow <perms> Allow permissions (best-effort, comma-separated)
100
119
  --deny <perms> Deny permissions (best-effort, comma-separated)
101
- -f, --format <fmt> Output format: jsonl, tsv (default: tsv, truncated on TTY)
120
+ -f, --format <fmt> Output format: jsonl, tsv (default: tsv; if stdout is TTY and --format is omitted, output is truncated)
102
121
  --raw-log <file> Write raw agent output to file
103
122
  --debug Enable debug mode (logs unknown events)
104
123
  --verbose Show agent stderr output
@@ -110,15 +129,14 @@ axexec --list-agents | tail -n +2 | awk -F'\t' '$3 ~ /openai/ {print $1}'
110
129
 
111
130
  ## Supported Agents
112
131
 
113
- | Agent | Package | API Key Env Var |
114
- | -------- | ------------------------- | ----------------------- |
115
- | claude | @anthropic-ai/claude-code | ANTHROPIC_API_KEY |
116
- | codex | @openai/codex | OPENAI_API_KEY |
117
- | gemini | @google/gemini-cli | GEMINI_API_KEY |
118
- | opencode | opencode-ai | AX_OPENCODE_CREDENTIALS |
119
- | copilot | @github/copilot | GITHUB_TOKEN |
132
+ `axexec` supports: `claude`, `codex`, `gemini`, `opencode`, `copilot`.
133
+
134
+ Canonical references:
120
135
 
121
- OpenCode requires `AX_OPENCODE_CREDENTIALS` with provider-specific credentials (see [CI/CD Credentials](#cicd-credentials)).
136
+ - Agent/package metadata: `axshared` (`axshared/README.md`)
137
+ - Credential environment variable mapping: `axauth/README.md`
138
+
139
+ OpenCode requires `AX_OPENCODE_CREDENTIALS` with provider-specific credentials (see [CI/CD Usage](#cicd-usage)).
122
140
 
123
141
  ## Event Stream
124
142
 
@@ -138,7 +156,8 @@ axexec normalizes all agent output to a standard event stream:
138
156
 
139
157
  ### Using Credential Environment Variables
140
158
 
141
- For CI/CD pipelines, credentials can be passed via environment variables:
159
+ For CI/CD pipelines, credentials can be passed via `AX_*_CREDENTIALS` environment variables.
160
+ Canonical variable names are documented in `axauth/README.md`.
142
161
 
143
162
  ```bash
144
163
  # Export credentials locally (one-time setup)
@@ -150,23 +169,15 @@ axauth export --agent claude --output creds.json --no-password
150
169
  axexec --agent claude --prompt "Review this PR"
151
170
  ```
152
171
 
153
- | Agent | Credential Env Var |
154
- | -------- | ----------------------- |
155
- | claude | AX_CLAUDE_CREDENTIALS |
156
- | codex | AX_CODEX_CREDENTIALS |
157
- | gemini | AX_GEMINI_CREDENTIALS |
158
- | opencode | AX_OPENCODE_CREDENTIALS |
159
- | copilot | AX_COPILOT_CREDENTIALS |
160
-
161
172
  ### Using Standard API Keys
162
173
 
163
174
  You can also use standard environment variables directly:
164
175
 
165
176
  ```bash
166
- ANTHROPIC_API_KEY=sk-... axexec -a claude "Review code"
167
- OPENAI_API_KEY=sk-... axexec -a codex "Fix bug"
168
- GEMINI_API_KEY=... axexec -a gemini "Refactor"
169
- GITHUB_TOKEN=ghp_... axexec -a copilot "Write tests"
177
+ ANTHROPIC_API_KEY=sk-... axexec --agent claude "Review code"
178
+ OPENAI_API_KEY=sk-... axexec --agent codex "Fix bug"
179
+ GEMINI_API_KEY=... axexec --agent gemini "Refactor"
180
+ GITHUB_TOKEN=ghp_... axexec --agent copilot "Write tests"
170
181
  ```
171
182
 
172
183
  For Claude, `CLAUDE_CODE_OAUTH_TOKEN` (generated via `claude setup-token`) also works.
@@ -179,15 +190,15 @@ field must match your `--provider` flag:
179
190
  ```bash
180
191
  # Anthropic
181
192
  AX_OPENCODE_CREDENTIALS='{"agent":"opencode","type":"api-key","provider":"anthropic","data":{"apiKey":"sk-ant-..."}}' \
182
- axexec -a opencode --provider anthropic -m claude-sonnet-4 "Hello"
193
+ axexec --agent opencode --provider anthropic --model claude-sonnet-4 "Hello"
183
194
 
184
195
  # OpenAI (provider must be specified in credentials)
185
196
  AX_OPENCODE_CREDENTIALS='{"agent":"opencode","type":"api-key","provider":"openai","data":{"apiKey":"sk-..."}}' \
186
- axexec -a opencode --provider openai -m gpt-4.1 "Hello"
197
+ axexec --agent opencode --provider openai --model gpt-4.1 "Hello"
187
198
 
188
199
  # OpenCode hosted models (provider must be "opencode")
189
200
  AX_OPENCODE_CREDENTIALS='{"agent":"opencode","type":"api-key","provider":"opencode","data":{"apiKey":"..."}}' \
190
- axexec -a opencode --provider opencode -m glm-4.7-free "Hello"
201
+ axexec --agent opencode --provider opencode --model glm-4.7-free "Hello"
191
202
  ```
192
203
 
193
204
  ## Isolation
@@ -19,7 +19,7 @@ function buildExecutionMetadata(agentId, options, credentialResult, credentials,
19
19
  if (credentials) {
20
20
  execution.credentials = {
21
21
  type: credentials.type,
22
- provider: credentials.agent === "opencode" ? credentials.provider : undefined,
22
+ provider: options.provider,
23
23
  };
24
24
  }
25
25
  return execution;
package/dist/cli.js CHANGED
@@ -40,7 +40,7 @@ const program = new Command()
40
40
  .option("--provider <provider>", "Provider for OpenCode (required for OpenCode)")
41
41
  .option("--allow <perms>", "Allow permissions (best-effort, comma-separated)")
42
42
  .option("--deny <perms>", "Deny permissions (best-effort, comma-separated)")
43
- .option("-f, --format <fmt>", "Output format: jsonl, tsv (default: tsv, truncated on TTY)")
43
+ .option("-f, --format <fmt>", "Output format: jsonl, tsv (default when omitted: truncated tsv on TTY, full tsv otherwise)")
44
44
  .option("--raw-log <file>", "Write raw agent output to file")
45
45
  .option("--debug", "Enable debug mode")
46
46
  .option("--verbose", "Show agent stderr output")
@@ -130,7 +130,7 @@ Examples:
130
130
  format = formatResult.format;
131
131
  }
132
132
  // Resolve credentials from --credentials-file if specified.
133
- const credentialsResult = await resolveCredentials(options.credentialsFile, readStdin, options.agent);
133
+ const credentialsResult = await resolveCredentials(options.credentialsFile, readStdin);
134
134
  if (!credentialsResult.ok) {
135
135
  process.stderr.write(`Error: ${credentialsResult.error}\n`);
136
136
  process.exitCode = 2;
@@ -138,7 +138,7 @@ Examples:
138
138
  }
139
139
  const { credentials } = credentialsResult;
140
140
  // Validate provider options
141
- const providerResult = validateProviderOptions(options.agent, options.model, options.provider, credentials);
141
+ const providerResult = validateProviderOptions(options.agent, options.model, options.provider);
142
142
  if (!providerResult.ok) {
143
143
  process.stderr.write(`Error: ${providerResult.error}\n`);
144
144
  process.exitCode = 2;
@@ -4,12 +4,12 @@
4
4
  * Each agent has its own env var requirements. This module extracts
5
5
  * the appropriate values from Credentials and returns them as env vars.
6
6
  */
7
- import type { Credentials } from "axshared";
7
+ import type { AgentCli, Credentials } from "axshared";
8
8
  /**
9
9
  * Gets additional environment variables for credential-based auth.
10
10
  *
11
11
  * Some agents use environment variables for API keys or OAuth tokens
12
12
  * in addition to or instead of file-based credentials.
13
13
  */
14
- declare function getCredentialEnvironment(credentials: Credentials): Record<string, string>;
14
+ declare function getCredentialEnvironment(agentId: AgentCli, credentials: Credentials, provider?: string): Record<string, string>;
15
15
  export { getCredentialEnvironment };
@@ -11,7 +11,7 @@ import { resolveStringField } from "./resolve-string-field.js";
11
11
  * Some agents use environment variables for API keys or OAuth tokens
12
12
  * in addition to or instead of file-based credentials.
13
13
  */
14
- function getCredentialEnvironment(credentials) {
14
+ function getCredentialEnvironment(agentId, credentials, provider) {
15
15
  const environment = {};
16
16
  // Extract API key from credentials data
17
17
  const apiKey = resolveStringField(credentials.data, "apiKey", "key");
@@ -19,7 +19,7 @@ function getCredentialEnvironment(credentials) {
19
19
  // axauth uses "accessToken", but also check legacy "oauthToken" and "token" keys
20
20
  const oauthToken = resolveStringField(credentials.data, "accessToken", "oauthToken") ??
21
21
  resolveStringField(credentials.data, "token", "token");
22
- switch (credentials.agent) {
22
+ switch (agentId) {
23
23
  case "claude": {
24
24
  if (credentials.type === "api-key" && apiKey) {
25
25
  environment["ANTHROPIC_API_KEY"] = apiKey;
@@ -51,7 +51,6 @@ function getCredentialEnvironment(credentials) {
51
51
  }
52
52
  case "opencode": {
53
53
  // OpenCode supports multiple providers, env var depends on provider
54
- const provider = credentials.provider;
55
54
  if (credentials.type === "api-key" && apiKey) {
56
55
  switch (provider) {
57
56
  case "anthropic": {
@@ -71,6 +70,9 @@ function getCredentialEnvironment(credentials) {
71
70
  environment["OPENCODE_API_KEY"] = apiKey;
72
71
  break;
73
72
  }
73
+ case undefined: {
74
+ break;
75
+ }
74
76
  }
75
77
  }
76
78
  break;
@@ -19,7 +19,7 @@ type WarningWriter = (message: string) => void;
19
19
  *
20
20
  * The caller is responsible for cleaning up the temp directory after use.
21
21
  */
22
- declare function installCredentials(agentId: AgentCli, credentials?: Credentials, warn?: WarningWriter): Promise<InstallResult>;
22
+ declare function installCredentials(agentId: AgentCli, credentials?: Credentials, provider?: string, warn?: WarningWriter): Promise<InstallResult>;
23
23
  /**
24
24
  * Cleanup for use in finally blocks.
25
25
  */
@@ -42,7 +42,7 @@ async function createTemporaryDirectories(agentId) {
42
42
  /**
43
43
  * Installs agent-specific credentials to the appropriate directory.
44
44
  */
45
- function installAgentCredentials(agentId, configDirectory, dataDirectory, credentials, warn) {
45
+ function installAgentCredentials(agentId, configDirectory, dataDirectory, credentials, provider, warn) {
46
46
  switch (agentId) {
47
47
  case "claude": {
48
48
  installClaudeCredentials(configDirectory, credentials);
@@ -57,8 +57,8 @@ function installAgentCredentials(agentId, configDirectory, dataDirectory, creden
57
57
  break;
58
58
  }
59
59
  case "opencode": {
60
- if (credentials.agent === "opencode") {
61
- installOpenCodeCredentials(dataDirectory, credentials, warn);
60
+ if (provider) {
61
+ installOpenCodeCredentials(dataDirectory, credentials, provider, warn);
62
62
  }
63
63
  break;
64
64
  }
@@ -78,15 +78,15 @@ function installAgentCredentials(agentId, configDirectory, dataDirectory, creden
78
78
  *
79
79
  * The caller is responsible for cleaning up the temp directory after use.
80
80
  */
81
- async function installCredentials(agentId, credentials, warn) {
81
+ async function installCredentials(agentId, credentials, provider, warn) {
82
82
  const { baseDirectory, configDirectory, dataDirectory } = await createTemporaryDirectories(agentId);
83
83
  try {
84
84
  if (credentials) {
85
- installAgentCredentials(agentId, configDirectory, dataDirectory, credentials, warn);
85
+ installAgentCredentials(agentId, configDirectory, dataDirectory, credentials, provider, warn);
86
86
  }
87
87
  const runtimeEnvironment = buildAgentRuntimeEnvironment(agentId, configDirectory, dataDirectory);
88
88
  const credentialEnvironment = credentials
89
- ? getCredentialEnvironment(credentials)
89
+ ? getCredentialEnvironment(agentId, credentials, provider)
90
90
  : {};
91
91
  return {
92
92
  env: { ...runtimeEnvironment, ...credentialEnvironment },
@@ -54,7 +54,5 @@ declare function installGeminiCredentials(configDirectory: string, credentials:
54
54
  * - oauth-credentials: Written as { [provider]: { type: "oauth", ...data } }
55
55
  * - api-key: Written as { [provider]: { type: "api", key: "..." } }
56
56
  */
57
- declare function installOpenCodeCredentials(dataDirectory: string, credentials: Extract<Credentials, {
58
- agent: "opencode";
59
- }>, warn?: WarningWriter): void;
57
+ declare function installOpenCodeCredentials(dataDirectory: string, credentials: Credentials, provider: string, warn?: WarningWriter): void;
60
58
  export { installClaudeCredentials, installCodexCredentials, installGeminiCredentials, installOpenCodeCredentials, };
@@ -100,9 +100,8 @@ function installGeminiCredentials(configDirectory, credentials) {
100
100
  * - oauth-credentials: Written as { [provider]: { type: "oauth", ...data } }
101
101
  * - api-key: Written as { [provider]: { type: "api", key: "..." } }
102
102
  */
103
- function installOpenCodeCredentials(dataDirectory, credentials, warn = defaultWarningWriter) {
103
+ function installOpenCodeCredentials(dataDirectory, credentials, provider, warn = defaultWarningWriter) {
104
104
  const authPath = path.join(dataDirectory, "auth.json");
105
- const provider = credentials.provider;
106
105
  switch (credentials.type) {
107
106
  case "oauth-credentials": {
108
107
  saveJsonFile(authPath, {
@@ -25,14 +25,6 @@ function parseCredentialsFromEnvironment(agentId) {
25
25
  const parsed = JSON.parse(credEnvironmentValue);
26
26
  const parseResult = parseCredentialsResult(parsed);
27
27
  if (parseResult.ok) {
28
- if (parseResult.value.agent !== agentId) {
29
- return {
30
- ok: false,
31
- exitCode: 2,
32
- message: `Error: ${credEnvironmentVariable} agent mismatch. ` +
33
- `Expected ${agentId}, got ${parseResult.value.agent}.`,
34
- };
35
- }
36
28
  return { ok: true, credentials: parseResult.value };
37
29
  }
38
30
  return {
@@ -67,7 +59,6 @@ function parseApiKeyFromEnvironment(agentId) {
67
59
  return {
68
60
  ok: true,
69
61
  credentials: {
70
- agent: agentId,
71
62
  type: "oauth-token",
72
63
  data: { oauthToken },
73
64
  },
@@ -102,7 +93,6 @@ function parseApiKeyFromEnvironment(agentId) {
102
93
  return {
103
94
  ok: true,
104
95
  credentials: {
105
- agent: agentId,
106
96
  type: "api-key",
107
97
  data: { apiKey },
108
98
  },
@@ -9,5 +9,5 @@ type ReadCredentialsResult = {
9
9
  ok: false;
10
10
  error: string;
11
11
  };
12
- declare function readCredentialsFile(path: string, readStdin: () => Promise<string>, expectedAgent: string): Promise<ReadCredentialsResult>;
12
+ declare function readCredentialsFile(path: string, readStdin: () => Promise<string>): Promise<ReadCredentialsResult>;
13
13
  export { readCredentialsFile };
@@ -4,7 +4,7 @@
4
4
  import { readFile } from "node:fs/promises";
5
5
  import { parseCredentialsResult } from "axshared";
6
6
  import { formatZodError } from "./format-zod-error.js";
7
- async function readCredentialsFile(path, readStdin, expectedAgent) {
7
+ async function readCredentialsFile(path, readStdin) {
8
8
  let raw;
9
9
  try {
10
10
  raw = path === "-" ? await readStdin() : await readFile(path, "utf8");
@@ -28,12 +28,6 @@ async function readCredentialsFile(path, readStdin, expectedAgent) {
28
28
  error: `Invalid credentials format: ${formatZodError(parseResult.error)}`,
29
29
  };
30
30
  }
31
- if (parseResult.value.agent !== expectedAgent) {
32
- return {
33
- ok: false,
34
- error: `Credentials agent mismatch. Expected ${expectedAgent}, got ${parseResult.value.agent}.`,
35
- };
36
- }
37
31
  return { ok: true, credentials: parseResult.value };
38
32
  }
39
33
  export { readCredentialsFile };
@@ -14,8 +14,7 @@ type ResolveCredentialsResult = {
14
14
  *
15
15
  * @param credentialsFile - Path to credentials file or "-" for stdin
16
16
  * @param readStdin - Function to read stdin
17
- * @param agentId - Expected agent ID for validation
18
17
  * @returns Credentials or undefined if no file specified
19
18
  */
20
- declare function resolveCredentials(credentialsFile: string | undefined, readStdin: () => Promise<string>, agentId: string): Promise<ResolveCredentialsResult>;
19
+ declare function resolveCredentials(credentialsFile: string | undefined, readStdin: () => Promise<string>): Promise<ResolveCredentialsResult>;
21
20
  export { resolveCredentials };
@@ -7,14 +7,13 @@ import { readCredentialsFile } from "./read-credentials-file.js";
7
7
  *
8
8
  * @param credentialsFile - Path to credentials file or "-" for stdin
9
9
  * @param readStdin - Function to read stdin
10
- * @param agentId - Expected agent ID for validation
11
10
  * @returns Credentials or undefined if no file specified
12
11
  */
13
- async function resolveCredentials(credentialsFile, readStdin, agentId) {
12
+ async function resolveCredentials(credentialsFile, readStdin) {
14
13
  if (!credentialsFile) {
15
14
  return { ok: true, credentials: undefined };
16
15
  }
17
- const result = await readCredentialsFile(credentialsFile, readStdin, agentId);
16
+ const result = await readCredentialsFile(credentialsFile, readStdin);
18
17
  if (!result.ok) {
19
18
  return { ok: false, error: result.error };
20
19
  }
package/dist/run-agent.js CHANGED
@@ -83,32 +83,6 @@ async function runAgent(agentId, options) {
83
83
  }
84
84
  // Credentials are optional; isolation still applies even when none are found.
85
85
  const credentials = credentialsResult.credentials;
86
- if (credentials && credentials.agent !== validation.agentId) {
87
- diagnostics.error("Error: Credentials agent mismatch. " +
88
- `Expected ${validation.agentId}, got ${credentials.agent}.`);
89
- setExitCode(2);
90
- return {
91
- events: [],
92
- success: false,
93
- execution: { agent: validation.agentId, model: options.model },
94
- };
95
- }
96
- // Validate OpenCode credentials provider matches the requested provider.
97
- // This duplicates validation in validateOpenCodeOptions() (CLI layer) but is
98
- // necessary for programmatic API consumers who call runAgent() directly.
99
- if (validation.agentId === "opencode" &&
100
- credentials?.agent === "opencode" &&
101
- options.provider &&
102
- credentials.provider.toLowerCase() !== options.provider.toLowerCase()) {
103
- diagnostics.error("Error: Credentials provider mismatch. " +
104
- `Expected ${options.provider}, got ${credentials.provider}.`);
105
- setExitCode(2);
106
- return {
107
- events: [],
108
- success: false,
109
- execution: { agent: validation.agentId, model: options.model },
110
- };
111
- }
112
86
  // Normalize provider to lowercase for OpenCode (all OpenCode provider IDs are lowercase).
113
87
  // This ensures consistent behavior for both CLI and programmatic API users.
114
88
  const normalizedOptions = validation.agentId === "opencode" && options.provider
@@ -117,7 +91,7 @@ async function runAgent(agentId, options) {
117
91
  // Always create isolated runtime directories; install credentials if provided.
118
92
  let credentialResult;
119
93
  try {
120
- credentialResult = await installCredentials(validation.agentId, credentials, diagnostics.warn);
94
+ credentialResult = await installCredentials(validation.agentId, credentials, normalizedOptions.provider, diagnostics.warn);
121
95
  }
122
96
  catch (error) {
123
97
  const message = error instanceof Error ? error.message : String(error);
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Validate OpenCode-specific CLI options.
3
3
  */
4
- import type { Credentials } from "axshared";
5
4
  type ProviderValidationResult = {
6
5
  ok: true;
7
6
  normalizedProvider: string | undefined;
@@ -13,7 +12,7 @@ type ProviderValidationResult = {
13
12
  * Validate provider usage and OpenCode-specific options.
14
13
  *
15
14
  * - For non-OpenCode agents: provider must not be specified
16
- * - For OpenCode: validates model format, requires provider, checks credentials
15
+ * - For OpenCode: validates model format, requires provider
17
16
  */
18
- declare function validateProviderOptions(agentId: string, model: string | undefined, provider: string | undefined, credentials: Credentials | undefined): ProviderValidationResult;
17
+ declare function validateProviderOptions(agentId: string, model: string | undefined, provider: string | undefined): ProviderValidationResult;
19
18
  export { validateProviderOptions };
@@ -5,9 +5,9 @@
5
5
  * Validate provider usage and OpenCode-specific options.
6
6
  *
7
7
  * - For non-OpenCode agents: provider must not be specified
8
- * - For OpenCode: validates model format, requires provider, checks credentials
8
+ * - For OpenCode: validates model format, requires provider
9
9
  */
10
- function validateProviderOptions(agentId, model, provider, credentials) {
10
+ function validateProviderOptions(agentId, model, provider) {
11
11
  // --provider is only valid for OpenCode
12
12
  if (provider && agentId !== "opencode") {
13
13
  return {
@@ -20,9 +20,9 @@ function validateProviderOptions(agentId, model, provider, credentials) {
20
20
  return { ok: true, normalizedProvider: undefined };
21
21
  }
22
22
  // OpenCode-specific validation
23
- return validateOpenCodeOptions(model, provider, credentials);
23
+ return validateOpenCodeOptions(model, provider);
24
24
  }
25
- function validateOpenCodeOptions(model, provider, credentials) {
25
+ function validateOpenCodeOptions(model, provider) {
26
26
  // Require --provider for OpenCode
27
27
  if (!provider) {
28
28
  // If model contains "/" and no provider given, suggest they might be using
@@ -45,14 +45,6 @@ function validateOpenCodeOptions(model, provider, credentials) {
45
45
  // Normalize to lowercase to match OpenCode's provider ID format.
46
46
  // OpenCode stores all provider IDs in lowercase (anthropic, openai, etc).
47
47
  const normalizedProvider = provider.toLowerCase();
48
- // Validate credentials provider matches
49
- if (credentials?.agent === "opencode" &&
50
- credentials.provider.toLowerCase() !== normalizedProvider) {
51
- return {
52
- ok: false,
53
- error: `Credentials provider mismatch. Expected ${normalizedProvider}, got ${credentials.provider}.`,
54
- };
55
- }
56
48
  return { ok: true, normalizedProvider };
57
49
  }
58
50
  export { validateProviderOptions };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "axexec",
3
3
  "author": "Łukasz Jerciński",
4
4
  "license": "MIT",
5
- "version": "1.7.0",
5
+ "version": "2.0.1",
6
6
  "description": "Unified CLI runner for AI coding agents with normalized event streaming",
7
7
  "repository": {
8
8
  "type": "git",
@@ -59,27 +59,27 @@
59
59
  "automation",
60
60
  "coding-assistant"
61
61
  ],
62
- "packageManager": "pnpm@10.28.0",
62
+ "packageManager": "pnpm@10.28.1",
63
63
  "engines": {
64
64
  "node": ">=22.14.0"
65
65
  },
66
66
  "dependencies": {
67
67
  "@commander-js/extra-typings": "^14.0.0",
68
68
  "axconfig": "^3.6.3",
69
- "axshared": "^4.0.0",
69
+ "axshared": "^5.0.0",
70
70
  "commander": "^14.0.2",
71
71
  "zod": "^4.3.5"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@total-typescript/ts-reset": "^0.6.1",
75
- "@types/node": "^25.0.9",
75
+ "@types/node": "^25.0.10",
76
76
  "@vitest/coverage-v8": "^4.0.17",
77
77
  "eslint": "^9.39.2",
78
78
  "eslint-config-axkit": "^1.1.0",
79
79
  "fta-check": "^1.5.1",
80
80
  "fta-cli": "^3.0.0",
81
- "knip": "^5.82.0",
82
- "prettier": "3.8.0",
81
+ "knip": "^5.82.1",
82
+ "prettier": "3.8.1",
83
83
  "semantic-release": "^25.0.2",
84
84
  "typescript": "^5.9.3",
85
85
  "vitest": "^4.0.17"