### Copy and Run Example Axe Agents Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/quick-start.md Shows how to copy an example agent from the examples directory into your Axe configuration and then run it. This is useful for understanding how agents are structured and for quick testing. ```bash # Copy an example agent into your config cp examples/code-reviewer/code-reviewer.toml "$(axe config path)/agents/" cp -r examples/code-reviewer/skills/ "$(axe config path)/skills/" # Set your API key and run export ANTHROPIC_API_KEY="your-key-here" git diff | axe run code-reviewer ``` -------------------------------- ### Install Axe via Binary on Linux Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/installation.md Downloads and installs the pre-built Linux amd64 binary to the system path. This method is suitable for environments where Go is not installed. ```bash curl -L https://github.com/jrswab/axe/releases/latest/download/axe_linux_amd64.tar.gz | tar xz sudo mv axe /usr/local/bin/ ``` -------------------------------- ### Go Integration Test Setup for Read-Only Tools Source: https://github.com/jrswab/axe/blob/master/docs/plans/019_m8_integration_polish_spec.md Code snippet demonstrating the setup for an integration test in Go, specifically for verifying agents configured with read-only tools like 'read_file' and 'list_directory' using a mock server. ```go // Setup mocks and agent config resetRunCmd(t) mockServer := mock.NewMockServer(t) // Mock responses for tool use mockServer.RegisterResponse(t, mock.AnthropicToolUseResponse("", []mock.MockToolCall{ {Name: "read_file", Input: map[string]any{"path": "hello.txt"}}, })) mockServer.RegisterResponse(t, mock.AnthropicResponse("File content: Hello, World!")) // Agent configuration testutil.SetupXDGDirs(t) agentConfig := "model: anthropic/claude-sonnet-4-20250514\ntools: [\"read_file\", \"list_directory\"]" // Temporary workdir with file tempDir := t.TempDir() writeFile(filepath.Join(tempDir, "hello.txt"), "Hello, World!") // Command execution rootCmd.SetArgs([]string{"run", agentConfig, "--workdir", tempDir}) os.Setenv("ANTHROPIC_API_KEY", "test-key") os.Setenv("AXE_ANTHROPIC_BASE_URL", mockServer.URL()) // Execute and assert assert.NoError(t, rootCmd.Execute()) stdout := stdoutCapture.String() assert.Contains(t, stdout, "File content: Hello, World!") assert.Equal(t, 2, mock.RequestCount()) // Assertions on request bodies would follow here... ``` -------------------------------- ### Global Configuration TOML Example Source: https://github.com/jrswab/axe/blob/master/AGENTS.md Example TOML configuration for global Axe settings, defining API keys and base URLs for various providers like Anthropic, OpenAI, Ollama, and Bedrock. ```toml [providers.anthropic] api_key = "sk-ant-..." base_url = "https://api.anthropic.com" [providers.openai] api_key = "sk-..." base_url = "https://api.openai.com" [providers.ollama] base_url = "http://localhost:11434" [providers.bedrock] region = "us-east-1" ``` -------------------------------- ### Build Axe from Source Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/installation.md Clones the repository and compiles the binary locally using the Go toolchain. Requires Go 1.25+ installed on the host. ```bash git clone https://github.com/jrswab/axe.git cd axe go build . ``` -------------------------------- ### Pipe Input to Axe Agents Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/quick-start.md Demonstrates piping standard input to Axe agents. This allows integrating Axe with other command-line tools by feeding their output directly into an agent. ```bash git diff --cached | axe run pr-reviewer cat error.log | axe run log-analyzer ``` -------------------------------- ### Install Axe via Go Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/installation.md Uses the Go toolchain to install the latest version of Axe directly. Requires Go 1.25 or higher. ```bash go install github.com/jrswab/axe@latest ``` -------------------------------- ### Initialize Axe Configuration Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/quick-start.md Initializes the Axe configuration directory and creates a sample skill and default config.toml. This command sets up the necessary files and directories for Axe to function. ```bash axe config init ``` -------------------------------- ### Configure MCP Servers in TOML Source: https://github.com/jrswab/axe/blob/master/docs/plans/027_mcp_tool_support_spec.md Example TOML configuration syntax for defining multiple MCP servers using an array of tables. ```toml [[mcp_servers]] name = "my-tools" url = "https://my-mcp-server.example.com/sse" transport = "sse" [[mcp_servers]] name = "pipedream" url = "https://remote.mcp.pipedream.net" transport = "streamable-http" headers = { Authorization = "Bearer ${PIPEDREAM_TOKEN}" } ``` -------------------------------- ### Implement NewMockLLMServer Function Source: https://github.com/jrswab/axe/blob/master/docs/plans/009_mock_provider_integration_spec.md Initializes and starts a new MockLLMServer. It sets up an httptest.Server with a handler that records requests and serves predefined responses. It also registers a cleanup function to shut down the server. ```go func NewMockLLMServer(t *testing.T, responses []MockLLMResponse) *MockLLMServer { // ... implementation details ... server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // ... request handling logic ... })) t.Cleanup(server.Close) // ... return MockLLMServer instance ... } ``` -------------------------------- ### Define Budget Configuration Template Source: https://github.com/jrswab/axe/blob/master/docs/plans/037_token_budget_limits_spec.md The scaffold template for agent initialization includes a commented-out budget configuration block to guide users on setting token limits. ```toml # [budget] # max_tokens = 0 ``` -------------------------------- ### Repository Setup and Build Commands Source: https://github.com/jrswab/axe/blob/master/CONTRIBUTING.md Commands to clone the repository, configure remotes, and build the project binary from source. ```bash git clone https://github.com/YOUR_USERNAME/axe.git cd axe git remote add upstream https://github.com/jrswab/axe.git go build . ``` -------------------------------- ### Add Commented MCP Server Example to Agent Scaffold Source: https://github.com/jrswab/axe/blob/master/docs/plans/027_mcp_tool_support_spec.md This snippet shows how to add a commented-out example for MCP server connections within the agent's configuration. It is intended to be placed in the `Scaffold()` function in `internal/agent/agent.go` after the `sub_agents_config` section and before the `[memory]` section. ```go package agent // Scaffold initializes the agent's configuration. func Scaffold() (*Config, error) { // ... other configurations ... // MCP server connections (optional) // [[mcp_servers]] // name = "my-tools" // url = "https://my-mcp-server.example.com/sse" // transport = "sse" // headers = { Authorization = "Bearer ${MY_TOKEN}" } // ... other configurations ... return &Config{ /* ... */ }, nil } ``` -------------------------------- ### Update rootCmd Example in Go Source: https://github.com/jrswab/axe/blob/master/docs/plans/003_single_agent_run_spec.md The `rootCmd.Example` field in `cmd/root.go` needs to be updated to include a new example for the `run` command. This addition should be integrated with the existing examples. ```go axe run pr-reviewer Run the pr-reviewer agent ``` -------------------------------- ### Agent TOML Configuration Example Source: https://github.com/jrswab/axe/blob/master/AGENTS.md Example TOML configuration for an Axe agent, specifying agent name, model, description, system prompt, skills, file globs, working directory, tools, sub-agents, memory settings, parameters, and MCP servers. ```toml name = "agent-name" # Required model = "provider/model-name" # Required (e.g., anthropic/claude-sonnet-4-20250514) description = "..." # Optional system_prompt = "..." # Optional skill = "path/to/SKILL.md" # Optional (absolute, relative to config dir, or bare name) files = ["**/*.go", "README.md"] # Optional (glob patterns) workdir = "/path/to/dir" # Optional (default: cwd, supports ~ and $VAR) tools = ["read_file", "write_file"] # Optional (valid: list_directory, read_file, write_file, edit_file, run_command, url_fetch, web_search) sub_agents = ["agent1", "agent2"] # Optional (allowed sub-agent names) [sub_agents_config] max_depth = 3 # Default: 3, Max: 5 parallel = true # Default: true (run sub-agents concurrently) timeout = 120 # Default: 120 seconds [memory] enabled = true # Default: false last_n = 10 # Default: 10 (load last N entries into context) max_entries = 100 # Default: 100 (warn when exceeded) path = "/custom/path" # Optional (default: $XDG_DATA_HOME/axe/memory/{agent-name}.md) [params] temperature = 0.7 # Default: 0 (omitted if 0) max_tokens = 4096 # Default: 0 (provider default) [[mcp_servers]] name = "server-name" transport = "stdio" # or "http", "https" command = "/path/to/server" args = ["--flag"] env = {"KEY" = "value"} [[mcp_servers]] name = "http-server" transport = "https" url = "https://example.com/mcp" headers = {"Authorization" = "Bearer ${API_KEY}"} # ${VAR} expanded from env ``` -------------------------------- ### Bash Script Example with Environment Variable Expansion Source: https://github.com/jrswab/axe/blob/master/docs/plans/021_path_expansion_spec.md Demonstrates the use of environment variable expansion within a bash script, as referenced in the SKILL.md file example. ```bash $HOME/.config/axe/skills/yti/scripts/get_transcript.sh ``` -------------------------------- ### Environment Restriction Examples Source: https://github.com/jrswab/axe/blob/master/docs/plans/035_run_command_sandbox_spec.md Demonstrates how environment variables are handled under restriction, including expansion, stripping, and inheritance, to prevent credential leakage and ensure predictable behavior. ```shell # Environment variable behavior under restriction # $HOME and $TMPDIR expand to workdir # $PATH works normally # $SHELL, $EDITOR, $API_KEY are stripped # env command shows only restricted variables ``` -------------------------------- ### Command Validation Examples Source: https://github.com/jrswab/axe/blob/master/docs/plans/035_run_command_sandbox_spec.md Illustrates various command execution scenarios and their expected validation outcomes, including allowed and rejected commands based on path traversal, absolute paths, and shell features. ```shell # Allowed commands echo hello cat subdir/file.txt cat file~backup cat file..bak ls | grep foo echo hello > output.txt " " ls / # Rejected commands cat /etc/passwd cat ../../etc/passwd cat ~/secrets echo ok; cat /etc/passwd echo hello > /tmp/out FOO=/etc/passwd command "" cat "/etc/passwd" echo `cat /etc/passwd` echo $(cat /etc/passwd) ls /etc/ ``` -------------------------------- ### Integrate MCP Router in Execution Loop Source: https://github.com/jrswab/axe/blob/master/docs/plans/027_mcp_tool_support_spec.md Demonstrates how to initialize the router, register servers, and route tool calls during the command execution process. ```go if len(cfg.MCPServers) > 0 { router := mcpclient.NewRouter() defer router.Close() for _, serverCfg := range cfg.MCPServers { client, _ := mcpclient.Connect(ctx, serverCfg) tools, _ := client.ListTools(ctx) router.Register(client, tools, builtinNames) } } // In executeToolCalls if router != nil && router.Has(tc.Name) { return router.Dispatch(ctx, tc) } ``` -------------------------------- ### Initialize Tool Registry in cmd/run.go Source: https://github.com/jrswab/axe/blob/master/docs/plans/014_list_directory_spec.md Shows how to initialize and populate the tool registry in `cmd/run.go`. It involves creating a new registry and then calling `tool.RegisterAll` to add all defined tools, including `list_directory`, making them resolvable by the system. ```go package main import ( "github.com/jrswab/axe/internal/tool" // ... other imports ) func main() { // ... existing code registry := tool.NewRegistry() tool.RegisterAll(registry) // Register all tools // ... existing code // This call now succeeds for "list_directory" because it's registered. resolvedTools, err := registry.Resolve(cfg.Tools) // ... rest of the main function } ``` -------------------------------- ### Scaffold a New Axe Agent Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/quick-start.md Scaffolds a new agent with the specified name. This command generates the basic structure for a new agent, allowing you to start developing its functionality. ```bash axe agents init my-agent ``` -------------------------------- ### Setup XDG Directories Helper in Go Source: https://github.com/jrswab/axe/blob/master/docs/plans/008_i9n_test_infrastructure_spec.md The `SetupXDGDirs` helper function in Go is designed to manage the XDG configuration home directory for tests. It handles cases where the environment variable is already set by capturing and restoring its original value, or unsetting it if it was not initially present. It also manages temporary directories for test isolation. ```go // SetupXDGDirs manages the XDG configuration home directory for tests. // It captures and restores the original XDG_CONFIG_HOME environment variable. // It creates a temporary directory for test isolation. ``` -------------------------------- ### Pull Axe Docker Image Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/installation.md Downloads the latest Axe container image from the GitHub Container Registry. Useful for isolated execution environments. ```bash docker pull ghcr.io/jrswab/axe:latest ``` -------------------------------- ### Edit an Existing Axe Agent Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/quick-start.md Opens the specified agent for editing. This command is used to modify the configuration and skills associated with an existing agent. ```bash axe agents edit my-agent ``` -------------------------------- ### Run an Axe Agent Source: https://github.com/jrswab/axe/blob/master/docs/src/getting-started/quick-start.md Executes the specified agent. This command invokes the agent to perform its defined task, potentially processing input or generating output. ```bash axe run my-agent ``` -------------------------------- ### Gemini Provider Implementation and Tests Source: https://github.com/jrswab/axe/blob/master/docs/plans/032_gemini_provider_spec.md This section outlines the files involved in creating and testing the Gemini provider. It includes the main provider implementation, its corresponding tests, registry modifications, and mock server helpers for testing responses. ```go internal/provider/gemini.go internal/provider/gemini_test.go internal/provider/registry.go internal/provider/registry_test.go internal/testutil/mockserver.go ``` -------------------------------- ### Setup Isolated XDG Directories for Testing (Go) Source: https://github.com/jrswab/axe/blob/master/docs/plans/008_i9n_test_infrastructure_spec.md Creates a temporary directory structure mimicking XDG_CONFIG_HOME and XDG_DATA_HOME, setting environment variables accordingly. It specifically prepares directories for axe agents and skills. This function is crucial for ensuring tests do not interfere with each other or the host system's configuration. ```go func SetupXDGDirs(t *testing.T) (configDir, dataDir string) // Behavior: // - Call t.Helper(). // - Create a temp directory using t.TempDir(). This is the XDG root. // - Create "/config" and "/data" subdirectories. // - Call t.Setenv("XDG_CONFIG_HOME", "/config"). // - Call t.Setenv("XDG_DATA_HOME", "/data"). // - Create the "axe/agents/" directory tree under "/config/". // - Create the "axe/skills/" directory tree under "/config/". // - Create the "axe/" directory under "/data/". // - Return the axe-level config path ("/config/axe") as configDir. // - Return the axe-level data path ("/data/axe") as dataDir. // Post-conditions: // - xdg.GetConfigDir() returns configDir. // - xdg.GetDataDir() returns dataDir. // - agent.Load() looks for TOML files in configDir/agents/. // - After the test completes, t.Setenv restores original env vars. t.TempDir removes the temp directory. ``` -------------------------------- ### Setup Isolated Environment for Smoke Tests Source: https://github.com/jrswab/axe/blob/master/docs/plans/010_cli_smoke_tests_spec.md The `setupSmokeEnv` function creates a temporary directory structure for XDG configuration and data, mimicking a clean user environment. It returns the paths to these directories and an environment map suitable for passing to child processes, ensuring test isolation. ```go func setupSmokeEnv(t *testing.T) (configDir, dataDir string, env map[string]string) ``` -------------------------------- ### TOML Configuration for MCP Servers Source: https://github.com/jrswab/axe/blob/master/docs/plans/027_mcp_tool_support_spec.md This TOML snippet provides an example of how to configure MCP server connections. It includes fields for the server name, URL, transport protocol, and optional headers. This configuration is used within the agent's setup. ```toml # MCP server connections (optional) [[mcp_servers]] name = "my-tools" url = "https://my-mcp-server.example.com/sse" transport = "sse" headers = { Authorization = "Bearer ${MY_TOKEN}" } ``` -------------------------------- ### Go Mock LLM Responses for Tool Calls Source: https://github.com/jrswab/axe/blob/master/docs/plans/019_m8_integration_polish_spec.md Demonstrates how to simulate LLM responses for tool calls and subsequent text responses using Go test utility functions. This is crucial for testing agent behavior with tools that interact with the filesystem. ```go // Turn 1: LLM requests list_directory testutil.OpenAIToolCallResponse("Let me list the directory.", []testutil.MockToolCall{ {ID: "tc_1", Name: "list_directory", Input: map[string]string{"path": "."}}, }), // Turn 2: LLM receives directory listing, returns final response testutil.OpenAIResponse("Directory listed successfully."), ``` -------------------------------- ### Dockerfile for axe CLI Source: https://github.com/jrswab/axe/blob/master/docs/plans/022_docker_containerization_spec.md A multi-stage Dockerfile to build a minimal and hardened axe CLI container image. It includes build and runtime stages, user setup for security, and baked-in environment variables. Dependencies include golang:1.24-alpine for building and alpine:3.21 for runtime, with ca-certificates installed. ```dockerfile # Build Stage FROM golang:1.24-alpine AS builder WORKDIR /build # Copy go module files and download dependencies first to leverage Docker cache COPY go.mod go.sum ./ RUN go mod download # Copy the rest of the source code COPY . . # Build the axe binary # CGO_ENABLED=0 produces a fully static binary # -trimpath, -ldflags="-s -w" match .goreleaser.yml for minimal binary size RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /build/axe . # Runtime Stage FROM alpine:3.21 # Install only ca-certificates for HTTPS connections RUN apk add --no-cache ca-certificates # Create non-root user and group RUN addgroup -g 10001 -S axe && adduser -u 10001 -S axe -G axe # Create necessary directories and set ownership RUN mkdir -p /home/axe/.config/axe \ /home/axe/.local/share/axe \ /tmp/axe && \ chown -R axe:axe /home/axe /.config /.local /.tmp/axe # Set environment variables for XDG paths ENV HOME=/home/axe XDG_CONFIG_HOME=/home/axe/.config XDG_DATA_HOME=/home/axe/.local/share # Copy the built binary from the build stage COPY --from=builder /build/axe /usr/local/bin/axe # Set the runtime user USER axe # Set the entrypoint to the axe binary ENTRYPOINT ["/usr/local/bin/axe"] # No CMD is set, user provides axe subcommand and arguments directly # OCI Image Labels LABEL org.opencontainers.image.title="axe" LABEL org.opencontainers.image.description="Lightweight CLI for running single-purpose LLM agents" LABEL org.opencontainers.image.source="https://github.com/jrswab/axe" # LABEL org.opencontainers.image.licenses="Value from LICENSE file" ``` -------------------------------- ### JSON Output Mode for Scripting Source: https://context7.com/jrswab/axe/llms.txt Demonstrates how to use the `--json` flag with the `axe run` command to get structured output. The example shows the JSON format, including metadata like model used, token counts, stop reason, duration, and budget information. ```bash axe run my-agent --json # Output: # { # "model": "claude-sonnet-4-20250514", # "content": "Agent response here...", # "input_tokens": 1234, # "output_tokens": 567, # "stop_reason": "end_turn", # "duration_ms": 2340, # "tool_calls": 3, # "tool_call_details": [...], # "refused": false, # "retry_attempts": 0, # "budget_max_tokens": 50000, # "budget_used_tokens": 1801, # "budget_exceeded": false # } ``` -------------------------------- ### Register List Directory Tool in Go Source: https://github.com/jrswab/axe/blob/master/docs/plans/014_list_directory_spec.md Demonstrates how to register the `list_directory` tool in Go using `tool.RegisterAll`. This ensures the tool is available in the registry for use by the system. The `ToolEntry` must have both `Definition` and `Execute` functions set. ```go package tool import ( "github.com/jrswab/axe/internal/provider" "github.com/jrswab/axe/internal/toolname" ) // RegisterAll registers all available tools with the provided registry. func RegisterAll(registry *provider.Registry) { registry.Register(provider.ToolEntry{ Name: toolname.ListDirectory, Definition: ListDirectoryDefinition, Execute: ListDirectoryExecutor, }) // ... other tool registrations } ``` -------------------------------- ### Implement Budget Tracking in Tool Execution Source: https://github.com/jrswab/axe/blob/master/docs/plans/037_token_budget_limits_implement.md Integrates the BudgetTracker into the conversation loop to monitor token consumption and halt execution if limits are exceeded. ```go func runConversationLoop(opts ExecuteOptions) { for { if opts.BudgetTracker != nil && opts.BudgetTracker.Exceeded() { return resp, nil } // ... send request if opts.BudgetTracker != nil { opts.BudgetTracker.Add(resp.InputTokens, resp.OutputTokens) } } } ``` -------------------------------- ### Example TOML Configuration File Source: https://github.com/jrswab/axe/blob/master/docs/plans/004_multi_provider_support_spec.md Provides an example of the expected structure for the global configuration file located at $XDG_CONFIG_HOME/axe/config.toml. ```toml [providers.anthropic] api_key = "sk-ant-..." [providers.openai] api_key = "sk-..." [providers.ollama] base_url = "http://localhost:11434" ``` -------------------------------- ### TOML Configuration Example with Path Expansion Source: https://github.com/jrswab/axe/blob/master/docs/plans/021_path_expansion_spec.md Illustrates how user-supplied paths can be defined in TOML configuration files, leveraging tilde and environment variable expansion for flexibility. ```toml workdir = "~/projects/myapp" skill = "$HOME/.config/axe/skills/review/SKILL.md" files = ["~/notes/*.md"] ``` -------------------------------- ### Verify implementation with Go test and vet Source: https://github.com/jrswab/axe/blob/master/docs/plans/030_html_stripping_implement.md Commands to validate the implementation by running specific unit tests and static analysis tools to ensure code quality. ```bash go test ./internal/tool/ -run TestURLFetch -v -count=1 go test ./internal/tool/ -run TestStripHTML -v -count=1 go vet ./internal/tool/ ``` -------------------------------- ### Update Agent Configuration TOML Example in README Source: https://github.com/jrswab/axe/blob/master/docs/plans/031_readme_mcp_docs_implement.md This snippet demonstrates the TOML configuration required to add MCP server support within the `README.md` file's agent configuration example. It shows how to define an MCP server with its name, URL, transport protocol, and headers. ```toml [[mcp_servers]] name = "my-tools" url = "https://my-mcp-server.example.com/sse" transport = "sse" headers = { Authorization = "Bearer ${MY_TOKEN}" } ``` -------------------------------- ### GET /agents Source: https://github.com/jrswab/axe/blob/master/docs/design/cli-structure.md Manages agent configurations, including listing, showing details, and initialization. ```APIDOC ## GET /agents ### Description Commands to interact with agent configurations. ### Method GET/POST (CLI) ### Commands - **list**: List all configured agents. - **show **: Show agent configuration details. - **init **: Scaffold a new agent TOML file. - **edit **: Open agent TOML in the system editor. ```