Unified configuration management for AI coding agents - common API for permissions, settings, and config across Claude Code, Codex, Gemini CLI, GitHub Copilot CLI, and OpenCode
npm install axconfigUnified configuration management for AI coding agents — common API for permissions, settings, and config across Claude Code, Codex, Gemini CLI, GitHub Copilot CLI, and OpenCode.
Different AI coding agents each have their own config formats, permission syntaxes, and settings locations. If you want to control what an agent can do or configure its behavior, you'd need to learn each agent's specific configuration format and file locations.
axconfig solves this by providing:
1. Unified permission syntax — One way to express permissions (--allow read,bash:git *) that works across all agents
2. Common config access — Get and set configuration properties using a consistent API, regardless of agent
3. Translation to agent-specific formats — Converts unified config into whatever format each agent expects
4. Capability validation — Knows what each agent supports and warns/errors appropriately
It can be used:
- As a library — integrate into your own tools and scripts
- As a CLI — standalone tool for managing agent configs
Unified syntax for all agents:
``bashTool permissions
read, write, bash, glob, grep, webfetch
$3
Translates unified permissions to agent-specific formats:
| Agent | Output Format |
| -------- | --------------------------------------------------------- |
| claude | JSON
settings.json with permissions.allow/deny arrays |
| codex | TOML config.toml + Starlark .rules files |
| copilot | JSON config.json (no pre-configured permissions) |
| gemini | JSON settings.json + TOML policy files in policies/ |
| opencode | JSON with permission.{edit,bash,webfetch} |$3
Each agent has different capabilities:
| Agent | Tool Perms | Bash Patterns | Path Restrictions | Can Deny Read | Notes |
| -------- | ----------- | ------------- | ----------------- | ------------- | -------------------------------------------- |
| claude | ✓ | ✓ | ✓ | ✓ | Permissions + OS-level sandbox |
| codex | ✗ (sandbox) | ✓ | ✗ | ✗ | OS-level sandbox (Landlock+seccomp/Seatbelt) |
| copilot | ✗ | ✗ | ✗ | ✗ | Runtime prompts only (no pre-config) |
| gemini | ✓ | ✓ | ✗ | ✓ | Permissions only (no sandbox) |
| opencode | ✓ | ✓ | ✓ | ✓ | UX-only permissions (no sandbox) |
Security notes:
- Claude Code manages application-level permissions; OS-level sandbox settings (network filtering, filesystem isolation) are configured separately
- Copilot CLI does not support pre-configured permissions; all actions require runtime approval prompts
- OpenCode permissions are UX-only to keep users informed; they do not provide security isolation
axconfig validates permissions against agent capabilities:
- Unsupported allow rules → warning, rule dropped (safe: fewer permissions)
- Unsupported deny rules → error, abort (unsafe: can't enforce restriction)
Library API
`typescript
import {
buildAgentConfig,
getConfigReader,
parsePermissions,
resolveConfigPath,
} from "axconfig";// Parse CLI-style permission strings
const permissions = parsePermissions(
["read,glob,bash:git *"], // allow
["bash:rm *"], // deny
);
// Build agent-specific config
const result = buildAgentConfig({
agentId: "claude",
allow: "read,glob,bash:git *",
deny: "bash:rm *",
output: "/tmp/my-config", // directory for config files
});
if (result.ok) {
// result.env = { CLAUDE_CONFIG_DIR: "/tmp/my-config" }
// result.warnings = [...]
}
// Read existing config
const reader = getConfigReader("claude");
const configDir = resolveConfigPath("claude"); // ~/.claude/
const perms = reader.readPermissions(configDir);
if (perms.ok && perms.value) {
console.log(perms.value.allow); // PermissionRule[]
}
// Read/write raw config values
const raw = reader.readRaw(configDir, "permissions.allow");
reader.writeRaw(configDir, "customSetting", { foo: "bar" });
`CLI Commands
$3
`bash
Create config with permissions (outputs env vars)
axconfig create --agent claude --output /tmp/config \
--allow "read,glob,bash:git *" \
--deny "bash:rm *"Export for shell usage
eval $(axconfig create --agent claude --output /tmp/config --allow read)Export as JSON for parsing
axconfig create --agent claude --output /tmp/cfg --allow read --format json | jq '.env'
`$3
`bash
Get current settings (uses agent's default config location)
axconfig get --agent claude allow
Output: read,glob,bash:git *
axconfig get --agent claude deny
Output: bash:rm *
axconfig get --agent claude model
Output: sonnet
Get settings as JSON
axconfig get --agent claude allow --format json
Output: ["Read", "Glob", {"Bash": {"command": "git", "args": "*"}}]
Set settings (merge with existing by default)
axconfig set --agent claude allow "read,glob"
axconfig set --agent claude deny "bash:rm *"
axconfig set --agent claude model "claude-sonnet-4-20250514"Replace instead of merge (for allow/deny)
axconfig set --agent claude allow "read,glob" --replaceSet with custom config path
axconfig set --agent claude --path /tmp/cfg allow "read,glob"
`$3
`bash
Get raw config value by dotted path
axconfig get-raw --agent claude permissions.allow
Output: ["Read", "Glob"]
Get raw value as JSON
axconfig get-raw --agent claude permissions --format jsonSet raw config value (JSON or string)
axconfig set-raw --agent claude permissions.allow '["Read", "Glob"]'
axconfig set-raw --agent opencode permission.edit allow
`$3
`bash
Capture settings in shell variables
ALLOW=$(axconfig get --agent claude allow)
MODEL=$(axconfig get --agent claude model)Extract allow rules as JSON and filter with jq
axconfig get --agent claude allow --format json | jq '.'List all bash permissions, one per line
axconfig get --agent claude allow | tr ',' '\n' | grep 'bash:'Count unique bash command prefixes
axconfig get --agent claude allow \
| tr ',' '\n' | grep 'bash:' \
| cut -d: -f2 | cut -d' ' -f1 | sort | uniq -c | sort -rnCompare permissions between agents
diff <(axconfig get -a claude allow) <(axconfig get -a gemini allow)Check if a specific permission exists
axconfig get --agent claude allow | grep -q 'bash:git' && echo "git allowed"Add a new permission to existing allow list
CURRENT=$(axconfig get --agent claude allow)
axconfig set --agent claude allow "$CURRENT,write" --replace
`Module Structure
`
src/
├── types.ts # PermissionRule, ConfigReader, BuildResult, etc.
├── parse-permissions.ts # parseRule, parseRuleList, parsePermissions
├── builder.ts # ConfigBuilder registry
├── reader.ts # ConfigReader registry
├── resolve-config-path.ts # Resolve agent config directory
├── build-agent-config.ts # High-level buildAgentConfig function
├── cli.ts # CLI entry point
├── commands/
│ ├── create.ts # Create command handler
│ ├── get.ts # Get unified settings
│ ├── set.ts # Set unified settings
│ ├── get-raw.ts # Get raw config values
│ └── set-raw.ts # Set raw config values
└── agents/
├── claude.ts # Claude Code config builder + reader
├── codex.ts # Codex config builder + reader
├── copilot.ts # GitHub Copilot CLI config builder + reader
├── gemini.ts # Gemini CLI config builder + reader
└── opencode.ts # OpenCode config builder + reader
`Agent Rule
Add to your
CLAUDE.md or AGENTS.md:`markdown
Rule:
axconfig UsageRun
npx -y axconfig --help to learn available options.Use
axconfig to manage AI agent configurations with unified permission syntax.
It translates --allow and --deny rules to agent-specific formats (Claude Code,
Codex, Gemini CLI, GitHub Copilot CLI, OpenCode).
``MIT