axconfig 1.0.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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/bin/axconfig +17 -0
  4. package/dist/agents/claude-code.d.ts +14 -0
  5. package/dist/agents/claude-code.js +98 -0
  6. package/dist/agents/codex.d.ts +15 -0
  7. package/dist/agents/codex.js +164 -0
  8. package/dist/agents/gemini.d.ts +14 -0
  9. package/dist/agents/gemini.js +156 -0
  10. package/dist/agents/opencode.d.ts +14 -0
  11. package/dist/agents/opencode.js +152 -0
  12. package/dist/auth/agents/claude-code.d.ts +9 -0
  13. package/dist/auth/agents/claude-code.js +106 -0
  14. package/dist/auth/agents/codex.d.ts +9 -0
  15. package/dist/auth/agents/codex.js +75 -0
  16. package/dist/auth/agents/gemini.d.ts +9 -0
  17. package/dist/auth/agents/gemini.js +97 -0
  18. package/dist/auth/agents/opencode.d.ts +9 -0
  19. package/dist/auth/agents/opencode.js +62 -0
  20. package/dist/auth/check-auth.d.ts +13 -0
  21. package/dist/auth/check-auth.js +24 -0
  22. package/dist/auth/extract-credentials.d.ts +11 -0
  23. package/dist/auth/extract-credentials.js +20 -0
  24. package/dist/auth/get-access-token.d.ts +35 -0
  25. package/dist/auth/get-access-token.js +116 -0
  26. package/dist/auth/types.d.ts +19 -0
  27. package/dist/auth/types.js +4 -0
  28. package/dist/build-agent-config.d.ts +41 -0
  29. package/dist/build-agent-config.js +79 -0
  30. package/dist/builder.d.ts +19 -0
  31. package/dist/builder.js +27 -0
  32. package/dist/cli.d.ts +10 -0
  33. package/dist/cli.js +79 -0
  34. package/dist/commands/auth.d.ts +19 -0
  35. package/dist/commands/auth.js +87 -0
  36. package/dist/commands/create.d.ts +14 -0
  37. package/dist/commands/create.js +101 -0
  38. package/dist/crypto.d.ts +39 -0
  39. package/dist/crypto.js +78 -0
  40. package/dist/index.d.ts +51 -0
  41. package/dist/index.js +53 -0
  42. package/dist/parse-permissions.d.ts +50 -0
  43. package/dist/parse-permissions.js +125 -0
  44. package/dist/types.d.ts +85 -0
  45. package/dist/types.js +8 -0
  46. package/package.json +93 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Łukasz Jerciński
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # axconfig
2
+
3
+ Configuration management library and CLI for AI coding agents.
4
+
5
+ ## Overview
6
+
7
+ axconfig is the **single source of truth** for all AI coding agent configuration logic. It can be used:
8
+
9
+ 1. **As a library** - imported by [axrun](https://github.com/anthropics/axrun) to build agent configs programmatically
10
+ 2. **As a CLI** - standalone tool for managing, inspecting, and creating agent configs
11
+
12
+ ## Architecture
13
+
14
+ ```
15
+ ┌─────────────────────────────────────────────────────────────┐
16
+ │ axrun │
17
+ │ (Agent execution: spawns agents, streams events) │
18
+ │ │
19
+ │ axrun -a claude-code --allow "read,bash:git *" "prompt" │
20
+ │ │ │
21
+ │ ▼ │
22
+ │ ┌────────────────────────┐ │
23
+ │ │ axconfig │ │
24
+ │ │ (Config translation) │ │
25
+ │ └────────────────────────┘ │
26
+ │ │ │
27
+ │ ▼ │
28
+ │ { env, settings } │
29
+ │ │ │
30
+ │ ▼ │
31
+ │ spawn(claude, { env }) │
32
+ └─────────────────────────────────────────────────────────────┘
33
+ ```
34
+
35
+ ## Core Responsibilities
36
+
37
+ ### Permission Parsing
38
+
39
+ Unified syntax for all agents:
40
+
41
+ ```bash
42
+ # Tool permissions
43
+ read, write, edit, bash, glob, grep, web
44
+
45
+ # Bash command patterns
46
+ bash:git *
47
+ bash:npm run build
48
+
49
+ # Path restrictions (agent-dependent)
50
+ read:src/**
51
+ write:.env
52
+ ```
53
+
54
+ ### Config Translation
55
+
56
+ Translates unified permissions to agent-specific formats:
57
+
58
+ | Agent | Output Format |
59
+ | ----------- | --------------------------------------------------------- |
60
+ | claude-code | JSON `settings.json` with `permissions.allow/deny` arrays |
61
+ | codex | TOML `config.toml` + Starlark `.rules` files |
62
+ | gemini | TOML policy files with `[[rule]]` entries |
63
+ | opencode | JSON with `permission.{edit,bash,webfetch}` |
64
+
65
+ ### Capability Validation
66
+
67
+ Each agent has different capabilities:
68
+
69
+ | Agent | Tool Perms | Bash Patterns | Path Restrictions | Can Deny Read |
70
+ | ----------- | ----------- | ------------- | ----------------- | ------------- |
71
+ | claude-code | ✓ | ✓ | ✓ | ✓ |
72
+ | codex | ✗ (sandbox) | ✓ | ✗ | ✗ |
73
+ | gemini | ✓ | ✓ | ✗ | ✓ |
74
+ | opencode | ✓ | ✓ | ✗ | ✓ |
75
+
76
+ axconfig validates permissions against agent capabilities:
77
+
78
+ - **Unsupported allow rules** → warning, rule dropped (safe: fewer permissions)
79
+ - **Unsupported deny rules** → error, abort (unsafe: can't enforce restriction)
80
+
81
+ ## Library API
82
+
83
+ ```typescript
84
+ import { parsePermissions, getConfigBuilder, buildAgentConfig } from "axconfig";
85
+
86
+ // Parse CLI-style permission strings
87
+ const permissions = parsePermissions(
88
+ ["read,glob,bash:git *"], // allow
89
+ ["bash:rm *"], // deny
90
+ );
91
+
92
+ // Build agent-specific config
93
+ const result = buildAgentConfig({
94
+ agentId: "claude-code",
95
+ allow: "read,glob,bash:git *",
96
+ deny: "bash:rm *",
97
+ output: "/tmp/my-config", // directory for config files
98
+ });
99
+
100
+ if (result.ok) {
101
+ // result.env = { CLAUDE_CONFIG_DIR: "/tmp/my-config" }
102
+ // result.warnings = [...]
103
+ }
104
+ ```
105
+
106
+ ## CLI Commands
107
+
108
+ ```bash
109
+ # List agents and their auth status
110
+ axconfig auth list
111
+ axconfig auth list --json
112
+
113
+ # Export credentials to encrypted file
114
+ axconfig auth export --agent claude-code --output creds.json
115
+ axconfig auth export --agent claude-code --output creds.json --no-password
116
+
117
+ # Create config with permissions (outputs env vars)
118
+ axconfig create --agent claude-code --output /tmp/config \
119
+ --allow "read,glob,bash:git *" \
120
+ --deny "bash:rm *"
121
+
122
+ # Create config with exported credentials
123
+ axconfig create --agent claude-code --output /tmp/config \
124
+ --allow read \
125
+ --with-credentials creds.json
126
+
127
+ # Export for shell usage
128
+ eval $(axconfig create --agent claude-code --output /tmp/config --allow read)
129
+ ```
130
+
131
+ ## Pipeline Examples
132
+
133
+ The CLI outputs TSV format for easy processing with standard Unix tools:
134
+
135
+ ```bash
136
+ # List all agents and their auth status
137
+ axconfig auth list
138
+ # AGENT STATUS METHOD
139
+ # claude-code authenticated OAuth (max)
140
+ # codex authenticated ChatGPT OAuth
141
+ # ...
142
+
143
+ # Filter to show only authenticated agents
144
+ axconfig auth list | tail -n +2 | awk -F'\t' '$2 == "authenticated"'
145
+
146
+ # Count agents by status
147
+ axconfig auth list | tail -n +2 | cut -f2 | sort | uniq -c
148
+
149
+ # Extract agent names as a list
150
+ axconfig auth list | tail -n +2 | cut -f1
151
+
152
+ # Export config as JSON and extract specific fields with jq
153
+ axconfig create --agent claude-code --output /tmp/cfg --allow read --format json | jq '.env'
154
+
155
+ # Check if a specific agent is authenticated
156
+ axconfig auth list --json | jq -e '.[] | select(.agentId == "claude-code") | .authenticated'
157
+ ```
158
+
159
+ ## Module Structure
160
+
161
+ ```
162
+ src/
163
+ ├── types.ts # PermissionRule, AxrunConfig, BuildResult, etc.
164
+ ├── parse-permissions.ts # parseRule, parseRuleList, parsePermissions
165
+ ├── builder.ts # ConfigBuilder registry
166
+ ├── build-agent-config.ts # High-level buildAgentConfig function
167
+ ├── check-auth.ts # Auth status detection for agents
168
+ ├── extract-credentials.ts # Credential extraction for export
169
+ ├── crypto.ts # AES-256-GCM encryption for credentials
170
+ ├── cli.ts # CLI entry point
171
+ └── agents/
172
+ ├── claude-code.ts # Claude Code config builder
173
+ ├── codex.ts # Codex config builder
174
+ ├── gemini.ts # Gemini CLI config builder
175
+ └── opencode.ts # OpenCode config builder
176
+ ```
177
+
178
+ ## Integration with axrun
179
+
180
+ axrun imports axconfig as a dependency:
181
+
182
+ ```typescript
183
+ // In axrun/src/cli.ts
184
+ import { buildAgentConfig } from "axconfig";
185
+
186
+ const configResult = buildAgentConfig({
187
+ agentId: options.agent,
188
+ allow: options.allow,
189
+ deny: options.deny,
190
+ output: "/tmp/axrun-config",
191
+ });
192
+
193
+ if (!configResult.ok) {
194
+ // Handle errors
195
+ }
196
+
197
+ // Spawn agent with config
198
+ spawn(agentBin, args, { env: { ...process.env, ...configResult.env } });
199
+ ```
200
+
201
+ ## Auth Preservation
202
+
203
+ A key requirement is preserving agent authentication when injecting permissions.
204
+
205
+ ### Problem
206
+
207
+ Agents store auth in their config directories. Naively overriding config paths breaks auth:
208
+
209
+ ```bash
210
+ # This breaks auth!
211
+ CLAUDE_CONFIG_DIR=/tmp/custom claude "prompt"
212
+ ```
213
+
214
+ ### Solution
215
+
216
+ Each agent has a preferred method for layering config:
217
+
218
+ | Agent | Method |
219
+ | ----------- | ---------------------------------------------------- |
220
+ | claude-code | `--settings <file>` flag merges with existing config |
221
+ | codex | `CODEX_HOME` with copied/symlinked auth files |
222
+ | gemini | `GEMINI_CLI_SYSTEM_SETTINGS_PATH` for settings |
223
+ | opencode | `OPENCODE_CONFIG` points to merged config |
224
+
225
+ axconfig handles these differences internally.
226
+
227
+ ## Agent Rule
228
+
229
+ Add to your `CLAUDE.md` or `AGENTS.md`:
230
+
231
+ ```markdown
232
+ # Rule: `axconfig` Usage
233
+
234
+ Run `npx -y axconfig --help` to learn available options.
235
+
236
+ Use `axconfig` to manage AI agent configurations with unified permission syntax.
237
+ It translates `--allow` and `--deny` rules to agent-specific formats (Claude Code,
238
+ Codex, Gemini CLI, OpenCode) and handles auth preservation automatically.
239
+ ```
240
+
241
+ ## Development Status
242
+
243
+ 🚧 **Work in Progress**
244
+
245
+ Migrating config logic from axrun to axconfig.
246
+
247
+ ## License
248
+
249
+ MIT
package/bin/axconfig ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point that dynamically imports the compiled TypeScript.
4
+ *
5
+ * Uses top-level await to ensure module evaluation errors are handled
6
+ * properly. Without await, errors during import would surface as unhandled
7
+ * rejections instead of clean CLI failures with appropriate exit codes.
8
+ */
9
+ try {
10
+ await import("../dist/cli.js");
11
+ } catch (error) {
12
+ console.error(
13
+ "Failed to start axconfig:",
14
+ error instanceof Error ? error.message : error,
15
+ );
16
+ process.exitCode = 1;
17
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Claude Code ConfigBuilder.
3
+ *
4
+ * Translates AxrunConfig into Claude Code's settings.json format.
5
+ *
6
+ * Claude Code supports:
7
+ * - Tool permissions via permissions.allow/deny
8
+ * - Bash patterns like "Bash(git:*)"
9
+ * - Path patterns like "Read(src/**)"
10
+ */
11
+ import type { ConfigBuilder } from "../types.js";
12
+ /** Claude Code ConfigBuilder */
13
+ declare const claudeCodeConfigBuilder: ConfigBuilder;
14
+ export { claudeCodeConfigBuilder };
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Claude Code ConfigBuilder.
3
+ *
4
+ * Translates AxrunConfig into Claude Code's settings.json format.
5
+ *
6
+ * Claude Code supports:
7
+ * - Tool permissions via permissions.allow/deny
8
+ * - Bash patterns like "Bash(git:*)"
9
+ * - Path patterns like "Read(src/**)"
10
+ */
11
+ import { mkdirSync, writeFileSync } from "node:fs";
12
+ import path from "node:path";
13
+ import { registerConfigBuilder } from "../builder.js";
14
+ /** Claude Code tool name mapping */
15
+ const TOOL_MAP = {
16
+ read: "Read",
17
+ write: "Write",
18
+ edit: "Edit",
19
+ bash: "Bash",
20
+ glob: "Glob",
21
+ grep: "Grep",
22
+ web: "WebFetch",
23
+ };
24
+ /** Claude Code capabilities */
25
+ const CAPABILITIES = {
26
+ toolPermissions: true,
27
+ bashPatterns: true,
28
+ pathRestrictions: true,
29
+ canDenyRead: true,
30
+ };
31
+ /**
32
+ * Translate a permission rule to Claude Code format.
33
+ */
34
+ function translateRule(rule) {
35
+ switch (rule.type) {
36
+ case "tool": {
37
+ return TOOL_MAP[rule.name];
38
+ }
39
+ case "bash": {
40
+ // Claude Code uses "Bash(pattern:*)" for command patterns
41
+ return `Bash(${rule.pattern}:*)`;
42
+ }
43
+ case "path": {
44
+ // Claude Code uses "Tool(path/**)" for path patterns
45
+ const toolName = rule.tool.charAt(0).toUpperCase() + rule.tool.slice(1);
46
+ return `${toolName}(${rule.pattern})`;
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Build Claude Code configuration.
52
+ */
53
+ function build(config, output) {
54
+ mkdirSync(output, { recursive: true });
55
+ const warnings = [];
56
+ const permissions = config.permissions;
57
+ const settingsPath = path.join(output, "settings.json");
58
+ // If no permissions specified, deny all
59
+ if (!permissions) {
60
+ const settings = {
61
+ permissions: {
62
+ allow: [],
63
+ deny: [],
64
+ },
65
+ };
66
+ writeFileSync(settingsPath, JSON.stringify(settings, undefined, 2));
67
+ return {
68
+ ok: true,
69
+ env: { CLAUDE_CONFIG_DIR: output },
70
+ warnings: [],
71
+ };
72
+ }
73
+ // Claude Code supports all permission types, so no warnings/errors needed
74
+ // All rules can be translated directly
75
+ const allowRules = permissions.allow.map((rule) => translateRule(rule));
76
+ const denyRules = permissions.deny.map((rule) => translateRule(rule));
77
+ const settings = {
78
+ permissions: {
79
+ allow: allowRules,
80
+ deny: denyRules,
81
+ },
82
+ };
83
+ writeFileSync(settingsPath, JSON.stringify(settings, undefined, 2));
84
+ return {
85
+ ok: true,
86
+ env: { CLAUDE_CONFIG_DIR: output },
87
+ warnings,
88
+ };
89
+ }
90
+ /** Claude Code ConfigBuilder */
91
+ const claudeCodeConfigBuilder = {
92
+ agentId: "claude-code",
93
+ capabilities: CAPABILITIES,
94
+ build,
95
+ };
96
+ // Self-register on import
97
+ registerConfigBuilder(claudeCodeConfigBuilder);
98
+ export { claudeCodeConfigBuilder };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Codex ConfigBuilder.
3
+ *
4
+ * Translates AxrunConfig into Codex's config.toml and execpolicy rules.
5
+ *
6
+ * Codex has unique characteristics:
7
+ * - Uses OS-level sandbox for file access (read-only, workspace-write)
8
+ * - Uses execpolicy .rules files for bash command patterns
9
+ * - CANNOT deny read access (sandbox always allows reads)
10
+ * - Does NOT support path restrictions
11
+ */
12
+ import type { ConfigBuilder } from "../types.js";
13
+ /** Codex ConfigBuilder */
14
+ declare const codexConfigBuilder: ConfigBuilder;
15
+ export { codexConfigBuilder };
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Codex ConfigBuilder.
3
+ *
4
+ * Translates AxrunConfig into Codex's config.toml and execpolicy rules.
5
+ *
6
+ * Codex has unique characteristics:
7
+ * - Uses OS-level sandbox for file access (read-only, workspace-write)
8
+ * - Uses execpolicy .rules files for bash command patterns
9
+ * - CANNOT deny read access (sandbox always allows reads)
10
+ * - Does NOT support path restrictions
11
+ */
12
+ import { mkdirSync, writeFileSync } from "node:fs";
13
+ import path from "node:path";
14
+ import { registerConfigBuilder } from "../builder.js";
15
+ /** Codex capabilities */
16
+ const CAPABILITIES = {
17
+ toolPermissions: false, // Uses sandbox mode instead
18
+ bashPatterns: true,
19
+ pathRestrictions: false,
20
+ canDenyRead: false, // Sandbox always allows reads
21
+ };
22
+ /**
23
+ * Infer sandbox mode from permissions.
24
+ *
25
+ * - If write or edit is allowed → workspace-write
26
+ * - Otherwise → read-only
27
+ */
28
+ function inferSandboxMode(permissions) {
29
+ const allowsWrite = permissions.allow.some((r) => r.type === "tool" && (r.name === "write" || r.name === "edit"));
30
+ return allowsWrite ? "workspace-write" : "read-only";
31
+ }
32
+ /**
33
+ * Generate Starlark prefix_rule for execpolicy.
34
+ *
35
+ * @example
36
+ * generatePrefixRule("git", "status", "allow")
37
+ * // Returns: prefix_rule(pattern = ["git", "status"], decision = "allow")
38
+ */
39
+ function generatePrefixRule(pattern, decision) {
40
+ // Split the pattern into tokens
41
+ // "git status" → ["git", "status"]
42
+ // "npm run build" → ["npm", "run", "build"]
43
+ const tokens = pattern.trim().split(/\s+/u);
44
+ // Handle wildcards at the end
45
+ // "git *" → pattern = ["git"], which matches all git subcommands
46
+ const filteredTokens = tokens.filter((t) => t !== "*");
47
+ const patternString = JSON.stringify(filteredTokens);
48
+ return `prefix_rule(pattern = ${patternString}, decision = "${decision}")`;
49
+ }
50
+ /**
51
+ * Build Codex configuration.
52
+ */
53
+ function build(config, output) {
54
+ mkdirSync(output, { recursive: true });
55
+ const warnings = [];
56
+ const errors = [];
57
+ const permissions = config.permissions;
58
+ // Check for unsupported rules
59
+ if (permissions) {
60
+ // Check for --deny "read" which is not possible in Codex
61
+ for (const rule of permissions.deny) {
62
+ if (rule.type === "tool" && rule.name === "read") {
63
+ errors.push({
64
+ rule,
65
+ reason: "Codex sandbox mode always permits file reads",
66
+ suggestions: [
67
+ "Use a different agent that supports denying reads (e.g., claude-code)",
68
+ 'Remove the --deny "read" rule',
69
+ ],
70
+ });
71
+ }
72
+ // Path restrictions not supported
73
+ if (rule.type === "path") {
74
+ errors.push({
75
+ rule,
76
+ reason: "Codex does not support path restrictions",
77
+ suggestions: [
78
+ `Use "${rule.tool}" to deny all ${rule.tool} operations`,
79
+ "Use a different agent that supports path restrictions (e.g., claude-code)",
80
+ ],
81
+ });
82
+ }
83
+ }
84
+ // Path restrictions in allow rules - warn and drop
85
+ for (const rule of permissions.allow) {
86
+ if (rule.type === "path") {
87
+ warnings.push({
88
+ rule,
89
+ reason: "Codex does not support path restrictions",
90
+ suggestions: [
91
+ `Use "${rule.tool}" to allow all ${rule.tool} operations`,
92
+ "Remove the path restriction",
93
+ ],
94
+ });
95
+ }
96
+ }
97
+ // Tool permissions other than read/write/edit - warn as Codex uses sandbox
98
+ const nonFileTools = permissions.allow.filter((r) => r.type === "tool" &&
99
+ !["read", "write", "edit", "bash"].includes(r.name));
100
+ for (const rule of nonFileTools) {
101
+ if (rule.type === "tool") {
102
+ warnings.push({
103
+ rule,
104
+ reason: `Codex does not have a dedicated "${rule.name}" tool permission`,
105
+ suggestions: [
106
+ `Tool "${rule.name}" may not be available in Codex`,
107
+ "Check Codex documentation for available tools",
108
+ ],
109
+ });
110
+ }
111
+ }
112
+ }
113
+ // If there are errors, abort
114
+ if (errors.length > 0) {
115
+ return { ok: false, errors };
116
+ }
117
+ // Create CODEX_HOME directory structure
118
+ const rulesDirectory = path.join(output, "rules");
119
+ mkdirSync(rulesDirectory, { recursive: true });
120
+ // Infer sandbox mode
121
+ const sandboxMode = permissions ? inferSandboxMode(permissions) : "read-only";
122
+ // Generate config.toml
123
+ const configToml = `# Generated by axconfig
124
+ approval_policy = "never"
125
+ sandbox_mode = "${sandboxMode}"
126
+ `;
127
+ writeFileSync(path.join(output, "config.toml"), configToml);
128
+ // Generate execpolicy rules
129
+ const rules = ["# Generated by axconfig"];
130
+ if (permissions) {
131
+ // Collect bash patterns
132
+ const allowBash = permissions.allow
133
+ .filter((r) => r.type === "bash")
134
+ .map((r) => r.pattern);
135
+ const denyBash = permissions.deny
136
+ .filter((r) => r.type === "bash")
137
+ .map((r) => r.pattern);
138
+ // Generate allow rules
139
+ for (const pattern of allowBash) {
140
+ rules.push(generatePrefixRule(pattern, "allow"));
141
+ }
142
+ // Generate deny rules
143
+ for (const pattern of denyBash) {
144
+ rules.push(generatePrefixRule(pattern, "forbidden"));
145
+ }
146
+ }
147
+ // Write rules file
148
+ const rulesPath = path.join(rulesDirectory, "axconfig.rules");
149
+ writeFileSync(rulesPath, rules.join("\n"));
150
+ return {
151
+ ok: true,
152
+ env: { CODEX_HOME: output },
153
+ warnings,
154
+ };
155
+ }
156
+ /** Codex ConfigBuilder */
157
+ const codexConfigBuilder = {
158
+ agentId: "codex",
159
+ capabilities: CAPABILITIES,
160
+ build,
161
+ };
162
+ // Self-register on import
163
+ registerConfigBuilder(codexConfigBuilder);
164
+ export { codexConfigBuilder };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Gemini CLI ConfigBuilder.
3
+ *
4
+ * Translates AxrunConfig into Gemini CLI's TOML policy format.
5
+ *
6
+ * Gemini CLI supports:
7
+ * - Tool permissions via [[rule]] with toolName
8
+ * - Bash patterns via commandPrefix
9
+ * - Does NOT support path restrictions
10
+ */
11
+ import type { ConfigBuilder } from "../types.js";
12
+ /** Gemini CLI ConfigBuilder */
13
+ declare const geminiConfigBuilder: ConfigBuilder;
14
+ export { geminiConfigBuilder };