The CLI is published on npm (npm i -g @aex-lang/cli). APIs are experimental and may change before v1.0. Roadmap →
Skip to content

The aex CLI keeps contracts tidy, validated, and auditable. Commands compose cleanly in CI pipelines.

Installation ​

bash
npm install -g @aex-lang/cli

Or use without installing:

bash
npx @aex-lang/cli check tasks/fix-test.aex

aex init ​

Scaffold policies and task contracts.

aex init --policy ​

Create a .aex/policy.aex file with a starter security boundary:

bash
aex init --policy

aex init --task ​

Scaffold a starter task contract, inputs, and policy files:

bash
aex init --task fix-test

Creates tasks/fix-test.aex, tasks/fix-test.inputs.json, and tasks/fix-test.policy.json.

aex check ​

Validate syntax and semantics. Errors include machine-readable codes.

bash
aex check tasks/fix-test.aex

aex fmt ​

Reformat contracts deterministically. Use --check to fail CI when files drift.

bash
aex fmt tasks/fix-test.aex
aex fmt tasks/*.aex --check

aex compile ​

Emit the JSON IR that adapters and runtimes consume.

bash
aex compile tasks/fix-test.aex > tasks/fix-test.ir.json

aex run ​

Execute a contract locally with optional inputs, policies, and confirmation handlers.

bash
aex run tasks/fix-test.aex \
  --inputs tasks/fix-test.inputs.json \
  --policy tasks/fix-test.policy.json \
  --auto-confirm

Options ​

FlagDescription
--inputs <file>Path to an inputs JSON file
--policy <file>Path to a runtime policy JSON file
--auto-confirmAutomatically approve confirmation gates
--model <provider>Model provider for make steps (openai, anthropic)
--model-handler <path>Path to a custom model handler module
--registry <url>URL of a remote tool registry
--log-jsonOutput structured log events as JSON
--otlp-endpoint <url>OpenTelemetry collector endpoint for trace export

Model providers ​

Set the model provider for make steps:

bash
# Use OpenAI (requires OPENAI_API_KEY)
aex run task.aex --model openai

# Use Anthropic (requires ANTHROPIC_API_KEY)
aex run task.aex --model anthropic

# Use a custom handler
aex run task.aex --model-handler ./my-handler.ts

Remote tool registries ​

Load tool definitions from an HTTP endpoint:

bash
aex run task.aex --registry https://tools.example.com/registry

The registry must return JSON with a tools object mapping tool names to { url, sideEffect } definitions.

Structured logging ​

bash
# JSON event log to stdout
aex run task.aex --log-json

# Export traces to an OpenTelemetry collector
aex run task.aex --otlp-endpoint http://localhost:4318/v1/traces

aex effective ​

Preview the merged permissions when a policy and task contract are combined.

bash
# Policy only
aex effective

# Policy + task contract
aex effective --contract tasks/fix-test.aex

Options ​

FlagDescription
--contract <file>Path to a task contract to merge with the policy
--policy <file>Explicit path to a policy file (otherwise auto-discovered)

Output ​

Policy:   .aex/policy.aex
Contract: tasks/fix-test.aex

Allowed:
  file.read
  file.write
  tests.run

Denied:
  network.*
  secrets.read

Confirmation required:
  file.write

Budget:
  calls=20

The allow list is the intersection (only tools both policy and task agree on), deny is the union (everything either blocks), and budget is the minimum.

aex proxy ​

Start an MCP stdio proxy that gates every tool call against your policy.

bash
# Preferred: everything after -- is the upstream command
aex proxy -- npx -y your-mcp-server --flag "hello world"

# Legacy: --upstream with a quoted string
aex proxy -- your-mcp-server

Options ​

FlagDescription
-- <cmd...>Everything after -- is the upstream command (preferred)
--upstream <cmd>Quoted upstream command string (legacy, deprecated)
--contract <file>Optional task contract for additional constraints
--policy <file>Explicit policy file (otherwise auto-discovered)
--auto-confirmAutomatically approve confirmation gates

The proxy auto-discovers .aex/policy.aex in the working directory. It sits between your MCP client (Claude Code, Codex CLI) and the upstream server, enforcing allow/deny rules, confirmation gates, and budgets on every tools/call request.

See the Claude Code and Codex integration guides for full setup.

Meta-Tools ​

The proxy exposes four meta-tools through the MCP protocol. These are handled locally — never forwarded to upstream:

ToolDescription
aex.checkpointSave session state (audit log, budget, tool history) to disk
aex.resumeLoad a checkpoint and restore budget state
aex.list_tasksList available contracts and checkpoints
aex.review_taskReview a contract's permissions without executing

Meta-tools bypass policy — they manage AEX itself. They appear automatically in tools/list responses. See the Meta-Tools Reference for input schemas and examples.

aex gate ​

Claude Code PreToolUse hook that evaluates every tool call against your AEX policy.

bash
# Configured as a Claude Code hook, not run directly
# In .claude/settings.json:
# { "hooks": { "PreToolUse": [{ "matcher": ".*", "command": "aex gate" }] } }

Options ​

FlagDescription
--contract <file>Optional task contract for additional constraints
--policy <file>Explicit policy file (otherwise auto-discovered from cwd in hook input)
--allow-no-policyAllow all tool calls when no policy is found (default: deny all)

Behavior ​

  • Reads JSON from stdin (Claude Code hook protocol)
  • Maps Claude Code tool names to AEX capabilities (e.g., Write → file.write)
  • Evaluates against allow/deny/confirm/budget rules
  • Responds with permissionDecision: "allow", "deny", or "ask"
  • Fails closed if no policy is found (denies all calls); pass --allow-no-policy to allow all
  • Tracks budget state across calls via .aex/.gate-budget.json

Tool Name Mapping ​

Claude CodeAEX Capability
Read, Glob, Grep, LSfile.read
Write, Edit, MultiEditfile.write
Bashshell.exec
WebFetchnetwork.fetch
WebSearchnetwork.search
Agentagent.spawn

aex draft ​

Generate a draft AEX task contract from a natural language prompt.

bash
aex draft "<prompt>" [options]

The command calls an LLM to produce a valid AEX contract, validates it, and saves it to .aex/runs/.

Options ​

FlagDescription
--model <provider>Model provider (openai, anthropic, or provider:model like openai:gpt-4o)
--out <file>Output file path (defaults to .aex/runs/<timestamp>-<name>.aex)
--name <name>Task name in snake_case (derived from prompt if omitted)
--policy <file>Policy file to constrain against (auto-discovers .aex/policy.aex)
--from-plan <file>Read plan text from file instead of prompt
--max-retries <n>Max retries on validation failure (default: 1)

Examples ​

bash
# Generate a contract using Anthropic
aex draft "fix the failing test in src/foo.ts" --model anthropic

# Specify output path and name
aex draft "review this PR" --model openai --name review_pr --out tasks/review.aex

# Use a specific model version
aex draft "update dependency" --model openai:gpt-4o

The drafted contract is validated against the active policy. If validation fails, the LLM is retried with error feedback.

aex review ​

Review an AEX task contract and optionally execute it.

bash
aex review <file> [options]

Options ​

FlagDescription
--jsonOutput machine-readable JSON summary
--runPrompt for approval then execute the task
--yesSkip approval prompt (with --run)
--policy <file>Policy file (auto-discovers if omitted)
--model <provider>Model provider for make steps (with --run)
--model-handler <path>Custom model handler (with --run)
--inputs <file>Inputs JSON file (with --run)
--auto-confirmAuto-approve confirmation gates during execution

Output ​

The review shows: task name, goal, requested tools, denied tools, effective permissions, checks, model-generated steps, and whether the task runs under current policy.

Examples ​

bash
# Review a drafted contract
aex review .aex/runs/20260502-153012-fix-test.aex

# Review and run with approval
aex review .aex/runs/fix-test.aex --run

# Machine-readable output
aex review tasks/fix-test.aex --json

aex classify ​

Classify a prompt as exploratory or contract-requiring.

bash
aex classify "<prompt>"

Output ​

json
{ "mode": "contract_recommended", "reason": "prompt implies file modifications" }

Modes: exploratory, contract_recommended, contract_required. Uses keyword heuristics, no LLM call.

aex sign and aex verify ​

Generate and validate provenance metadata using an HMAC secret.

bash
aex sign tasks/fix-test.aex --id release-bot --key-file ./keys/aex.hmac
aex verify tasks/fix-test.aex \
  --signature tasks/fix-test.aex.signature.json \
  --key-file ./keys/aex.hmac

CI Integration ​

Hook the commands into CI:

yaml
- run: npx @aex-lang/cli fmt tasks/*.aex --check
- run: npx @aex-lang/cli check tasks/*.aex
- run: npm test

Or use the setup-aex GitHub Action:

yaml
- uses: harsh-nod/aex/action@main
  with:
    version: latest
- run: aex check tasks/*.aex

Note: The action is at action/action.yml in the repo, so the uses: path includes the /action subdirectory.

Prompts are not permissions. Plans are not contracts.