Skip to content

Latest commit

 

History

History
3316 lines (2596 loc) · 158 KB

File metadata and controls

3316 lines (2596 loc) · 158 KB

Autohand Configuration Reference

Complete reference for all configuration options in ~/.autohand/config.json (or .toml/.yaml/.yml).

Tip: Most settings below can be changed interactively using the /settings command instead of editing the file manually.

Localized references:

Table of Contents

For local repository scanning and credential reuse during workflow uploads, see Repository discovery.


Configuration File Location

Autohand looks for configuration in this order:

  1. AUTOHAND_CONFIG environment variable (custom path)
  2. ~/.autohand/config.toml
  3. ~/.autohand/config.yaml
  4. ~/.autohand/config.yml
  5. ~/.autohand/config.json (default)

You can also override the base directory:

export AUTOHAND_HOME=/custom/path  # Changes ~/.autohand to /custom/path

Profiles and One-Run Overrides

A profile is a partial config stored under profiles.<name> and selected with --profile <name>. --set key=value overrides one setting with a dotted path; repeat it for several. Values are parsed as JSON when they parse (true, 50, ["a","b"]) and kept as text otherwise.

{
  "provider": "openrouter",
  "profiles": {
    "review": {
      "provider": "autohandai",
      "autohandai": { "model": "moa" },
      "permissions": { "mode": "restricted" },
      "ui": { "showThinking": true }
    }
  }
}
autohand --profile review
autohand --set ui.theme=aurora --set agent.maxIterations=50
autohand doctor --profile review --json

Precedence, lowest first: config file, workspace .autohand overlays, environment variables, profile, --set. Both layers exist for the run only: nothing is written to the config file, and a save triggered during the run (for example by /model or /theme) restores the file's own value under every layered path unless you changed that setting during the run, in which case your change is kept. Neither a profile nor --set can touch auth or profiles. An unknown profile name stops startup with the list of defined profiles.


Environment Variables

Variable Description Example
AUTOHAND_HOME Base directory for all Autohand data /custom/path
AUTOHAND_CONFIG Custom config file path /path/to/config.toml
AUTOHAND_PROVIDER Select provider for this process, overriding global and workspace selection autohandai
AUTOHAND_MODELS_CATALOG Custom provider model catalog path /path/to/models.json
AUTOHAND_API_URL API endpoint (overrides config) https://api.autohand.ai
AUTOHAND_AUTH_URL Sign-in and account-sync website origin (independent of AUTOHAND_API_URL) https://autohand.ai
AUTOHAND_AUTH_API_URL Canonical CLI device-auth API base; normally leave unset https://api.autohand.ai/v1/auth
AUTOHAND_SECRET Company/team secret key sk-xxx
AUTOHAND_PERMISSION_CALLBACK_URL URL for permission callback (experimental) http://localhost:3000/callback
AUTOHAND_PERMISSION_CALLBACK_TIMEOUT Timeout for permission callback in ms 5000
AUTOHAND_NON_INTERACTIVE Run in non-interactive mode 1
AUTOHAND_YES Auto-confirm all prompts 1
AUTOHAND_NO_BANNER Disable startup banner 1
AUTOHAND_STREAM_TOOL_OUTPUT Stream tool output in real-time 1
AUTOHAND_DEBUG Enable debug logging 1
AUTOHAND_THINKING_LEVEL Set reasoning depth level normal
AUTOHAND_CLIENT_NAME Client/editor identifier (set by ACP extensions) zed
AUTOHAND_CLIENT_VERSION Client version (set by ACP extensions) 0.169.0
AUTOHAND_CODE Environment detection flag (set automatically) 1
AUTOHAND_CODE_SIMPLE Enable bare mode without passing --bare 1
AUTOHAND_DISABLE_STATEFUL_READ Emergency opt-out for all stateful-read experiments 1

Process provider selection

Set AUTOHAND_PROVIDER=autohandai to select Autohand AI for this process even when the global configuration or .autohand/settings.local.json selects another provider. Supply inference credentials through AUTOHAND_AI_API_KEY, AUTOHAND_AI_BASE_URL, and AUTOHAND_AI_PLAN; normal account authentication still applies. Existing feature gates remain in effect.

The override accepts the normal built-in, custom:<id>, and extension:<id> provider names. An empty or unsupported explicit value fails startup. Omitting the variable preserves normal saved-provider selection. Incidental settings saves retain the saved provider selection and its configuration section, including credentials, instead of writing process-only values to disk. For custom or extension providers, their configuration map is retained from disk.

Thinking Level

The AUTOHAND_THINKING_LEVEL environment variable controls the depth of reasoning the model uses:

Value Description
none Direct responses without visible reasoning
normal Standard reasoning depth (default)
extended Deep reasoning for complex tasks, shows more detailed thought process

This is typically set by ACP client extensions (like Zed) through the config dropdown.

# Example: Use extended thinking for complex tasks
AUTOHAND_THINKING_LEVEL=extended autohand --prompt "refactor this module"

Bare Mode

Bare mode starts Autohand with only explicitly requested context and runtime integrations. Enable it with either:

autohand --bare
AUTOHAND_CODE_SIMPLE=1 autohand

When --bare is passed, Autohand also sets AUTOHAND_CODE_SIMPLE=1 for the running process.

Bare mode disables automatic startup and interactive integrations:

  • hooks and hook notifications
  • LSP startup
  • plugin sync, plugin auto-loading, and meta-tool auto-loading
  • attribution, telemetry, session sync, auto-reporting, and background pings
  • automatic memory/session bootstrap context
  • background prompt suggestions, update checks, feature flag fetches, and model metadata prefetches
  • keychain and browser OAuth authentication fallback
  • automatic AGENTS.md and provider-instruction discovery
  • all slash commands, including a bare / typed in the prompt

Slash-shaped absolute file paths, such as /Users/alex/project/file.ts, are still treated as normal prompt text. Command-shaped slash input, such as /help, /model, or /mcp, prints Slash commands are disabled in bare mode. and is not executed.

Authentication in bare mode is explicit only. Autohand reads AUTOHAND_API_KEY first, then auth.apiKeyHelper if configured. It does not read keychain credentials or start OAuth/browser login. Third-party providers continue to use their provider-specific API keys and configuration.

These explicit inputs remain available in bare mode:

Input Description
--system-prompt <value> Replace the system prompt with inline text or a path-like value
--system-prompt-file <path> Replace the system prompt with file contents
--append-system-prompt <value> Append inline text or a path-like value to the system prompt
--append-system-prompt-file <path> Append file contents to the system prompt
--add-dir <path...> Add explicit directories to workspace scope
--mcp-config <path> Load an explicit MCP config file
--settings Open settings directly from the CLI flag
--config <path> Use an explicit Autohand config file
--agents <json|path> Load explicit inline agents JSON or an explicit agents directory
--plugin-dir <path> Load an explicit plugin/meta-tool directory

Provider Settings

features.autohand_inference

Autohand-hosted inference (the autohandai provider, Fantail/Moa) is enabled by default. Set this to false to hide it — for example, to keep a workspace pinned to a different provider without it appearing in /model.

{
  "features": {
    "autohand_inference": false
  }
}

An environment override is also supported:

AUTOHAND_FEATURE_AUTOHAND_INFERENCE=0 autohand

When disabled, Autohand is hidden from setup and /model, Fantail/Moa are hidden from ACP and JSON-RPC model discovery, and autohandai provider config resolves as unavailable.

provider

Active LLM provider to use.

Value Description
"autohandai" Autohand AI Cloud or Local
"openrouter" OpenRouter API (default)
"anthropic" Anthropic Messages API
"ollama" Local Ollama instance
"llamacpp" Local llama.cpp server
"openai" OpenAI API directly
"mlx" MLX on Apple Silicon (local)
"llmgateway" LLM Gateway unified API
"deepseek" DeepSeek API
"zai" Z.ai GLM API
"sakana" Sakana.AI Fugu API
"bedrock" AWS Bedrock
"custom:<id>" User-defined OpenAI-compatible provider from customProviders
"extension:<id>" Provider registered by a trusted runtime extension and configured in extensionProviders

Provider model catalog

Autohand stores bundled provider model lists in src/providers/models.json and copies that file to dist/providers/models.json in packaged builds. Provider pickers, ACP/RPC model discovery, and static provider fallbacks read from this catalog instead of hardcoded TypeScript arrays. At normal startup the CLI also checks https://code.autohand.ai/cli/models.json for a validated Pi-compatible update when the last successful check is at least four hours old.

To add or update bundled model choices, edit the relevant provider entry in models.json:

{
  "providers": {
    "nvidia": {
      "defaultModel": "z-ai/glm-5.1",
      "models": [
        "z-ai/glm-5.1",
        { "id": "nvidia/new-model", "displayName": "New Model" }
      ]
    }
  }
}

For a local override without changing the installed package, create ~/.autohand/models.json or set AUTOHAND_MODELS_CATALOG=/path/to/models.json. Local override entries are merged ahead of the last valid downloaded catalog, which is merged ahead of bundled entries; all layers are deduplicated by model ID. OpenRouter and other providers with live model APIs still try live discovery first, then merge or fall back to catalog entries.

Use autohand update --models or autohand upgrade --models to force an immediate refresh. Use autohand --offline or AUTOHAND_OFFLINE=1 to disable automatic startup checks. AUTOHAND_MODELS_URL can select another compatible endpoint for development. See Model catalog updates for the cache, validation, fallback, and publication contracts.

autohandai

Autohand AI provider configuration. Cloud mode uses Autohand-hosted OpenAI-compatible inference at https://inference.autohand.ai/v1 (a saved https://api.autohand.ai/v1 is migrated automatically; private gateways are left alone). Completions stream, so the first tokens appear while the answer is still being generated. Local mode uses Apple Silicon MLX inference.

Requires features.autohand_inference: true or AUTOHAND_FEATURE_AUTOHAND_INFERENCE=1.

{
  "autohandai": {
    "plan": "cloud",
    "authMode": "account",
    "baseUrl": "https://inference.autohand.ai/v1",
    "model": "moa",
    "contextWindow": 1000000,
    "reasoningEffort": "high"
  }
}
Field Type Required Default Description
plan "cloud" or "local" Yes "cloud" Hosted Autohand AI or local MLX inference
authMode "account" or "api-key" Cloud "account" in CLI when logged in CLI can use account auth; SDK Cloud must use API key
apiKey string SDK Cloud/API-key Cloud - Autohand AI API key
baseUrl string No https://inference.autohand.ai/v1 OpenAI-compatible API endpoint
model string Yes fantail fantail, moa, or a selected local MLX coding model
contextWindow number No 262144 for Fantail, 1000000 for Moa, 256000 for Local Model context window
reasoningEffort "medium", "high", or "xhigh" Moa Cloud "high" during setup Moa thinking effort level

Cloud model context and output limits come from the active models.json catalog. The catalog is authoritative over stale persisted contextWindow values, so existing Fantail configurations automatically adopt its 256k input window and 16k output ceiling without requiring users to rewrite ~/.autohand/config.json.

| port | number | Local | 8080 | Local MLX server port | | localModelPath | string | No | - | Downloaded local coding model path | | serverCommand | string | No | - | Local server start command |

Cloud configurations persisted with a retired model ID are automatically migrated to fantail before a request is sent. Cloud mode currently accepts only the catalog's fantail and moa IDs.

openrouter

OpenRouter provider configuration.

{
  "openrouter": {
    "apiKey": "sk-or-v1-xxx",
    "baseUrl": "https://openrouter.ai/api/v1",
    "model": "your-modelcard-id-here",
    "contextWindow": 262144
  }
}
Field Type Required Default Description
apiKey string Yes - Your OpenRouter API key
baseUrl string No https://openrouter.ai/api/v1 API endpoint
model string Yes - Model identifier (e.g., your-modelcard-id-here)
contextWindow number No Auto Exact model context window. Autohand fills this from OpenRouter when known.

anthropic

Native Anthropic Messages API configuration. Autohand sends system prompts, tool definitions, tool uses, and tool results using Anthropic's native request format.

{
  "anthropic": {
    "apiKey": "sk-ant-xxx",
    "baseUrl": "https://api.anthropic.com",
    "model": "claude-sonnet-5",
    "contextWindow": 1000000
  }
}
Field Type Required Default Description
apiKey string Yes - Your Anthropic Console API key
baseUrl string No https://api.anthropic.com Anthropic API origin; /v1/messages is appended
model string Yes claude-sonnet-5 Native Anthropic model identifier
contextWindow number No Catalog value Model context window used by Autohand accounting
reasoningEffort string No Provider default Native output effort (low through xhigh)

zai

Z.ai provider configuration.

{
  "zai": {
    "apiKey": "your-zai-api-key",
    "baseUrl": "https://api.z.ai/api/paas/v4",
    "model": "glm-5.2",
    "contextWindow": 1000000
  }
}
Field Type Required Default Description
apiKey string Yes - Your Z.ai API key
baseUrl string No https://api.z.ai/api/paas/v4 API endpoint
model string Yes glm-5.2 Model identifier, for example glm-5.2, glm-5.1, or glm-4.5
contextWindow number No Auto Exact model context window. Autohand infers 1M for GLM-5.2 and 200K for GLM-5.1.

sakana

Sakana.AI provider configuration. The API is OpenAI-compatible and uses https://api.sakana.ai/v1 as its base URL.

{
  "sakana": {
    "apiKey": "your-sakana-api-key",
    "baseUrl": "https://api.sakana.ai/v1",
    "model": "fugu",
    "contextWindow": 1000000
  }
}
Field Type Required Default Description
apiKey string Yes - Your Sakana API key
baseUrl string No https://api.sakana.ai/v1 API endpoint
model string Yes fugu Model identifier, for example fugu or fugu-ultra
contextWindow number No Auto Exact model context window. Autohand infers 1M for Fugu models.

customProviders

Custom providers let users bring an OpenAI-compatible endpoint without a code change or a new bundled provider. Add the provider under customProviders, then select it with provider: "custom:<id>". The same flow is available from /model with New provider.... During setup, Autohand verifies the base URL, authentication, and selected model through the OpenAI-compatible /models endpoint before saving the provider.

{
  "provider": "custom:acme",
  "customProviders": {
    "acme": {
      "id": "acme",
      "displayName": "Acme AI",
      "apiFormat": "openai-compatible",
      "baseUrl": "https://api.acme.example/v1",
      "apiKey": "acme-api-key",
      "apiKeyRequired": true,
      "model": "acme-code-1",
      "contextWindow": 256000,
      "reasoningEffort": "high",
      "models": [
        {
          "id": "acme-code-1",
          "label": "Acme Code 1",
          "contextWindow": 256000,
          "reasoningEffort": "high"
        }
      ]
    }
  }
}

For local OpenAI-compatible servers that do not require auth, set apiKeyRequired to false and omit apiKey.

Field Type Required Default Description
id string Yes - Stable provider id. It must match the object key and is selected as custom:<id>.
displayName string Yes - Name shown in /model and provider settings.
apiFormat string Yes - Must be openai-compatible.
baseUrl string Yes - Endpoint root such as https://api.example.com/v1. Autohand verifies /models and calls /chat/completions.
apiKey string Conditional - Bearer token for hosted endpoints. Required when apiKeyRequired is true.
apiKeyRequired boolean No true Set false for local or already-authenticated gateways.
model string Yes - Active model id.
contextWindow number No Auto Exact context window for token budgeting, status, telemetry, and sync metadata.
reasoningEffort string No - Optional none, low, medium, high, or xhigh. Sent as reasoning_effort for custom OpenAI-compatible requests.
models array No - Optional model picker entries with per-model context and reasoning metadata.

extensionProviders

Trusted runtime extensions can register providers in the extension: namespace. Install and review the owning extension with --trust, select its exact provider id, and place provider-owned configuration under the same key:

{
  "provider": "extension:company-release",
  "extensionProviders": {
    "extension:company-release": {
      "model": "release-model",
      "apiKey": "company-api-key",
      "baseUrl": "https://models.example.com"
    }
  }
}

model is required. Other fields are defined by the extension provider. Keep credentials in user config or environment variables rather than the extension package. Removing or disabling the extension makes its provider unavailable; it does not delete saved provider configuration.

ollama

Ollama provider configuration.

{
  "ollama": {
    "baseUrl": "http://localhost:11434",
    "port": 11434,
    "model": "llama3.2"
  }
}
Field Type Required Default Description
baseUrl string No http://localhost:11434 Ollama server URL
port number No 11434 Server port (alternative to baseUrl)
model string Yes - Model name (e.g., llama3.2, codellama)

llamacpp

llama.cpp server configuration.

{
  "llamacpp": {
    "baseUrl": "http://localhost:8080",
    "port": 8080,
    "model": "default"
  }
}
Field Type Required Default Description
baseUrl string No http://localhost:8080 llama.cpp server URL
port number No 8080 Server port
model string Yes - Model identifier

openai

OpenAI API configuration.

{
  "openai": {
    "authMode": "api-key",
    "apiKey": "sk-xxx",
    "baseUrl": "https://api.openai.com/v1",
    "model": "gpt-5.4"
  }
}

OpenAI can also use your ChatGPT subscription via Autohand's built-in OpenAI sign-in flow:

{
  "openai": {
    "authMode": "chatgpt",
    "baseUrl": "https://api.openai.com/v1",
    "contextWindow": 1050000,
    "model": "gpt-5.4",
    "chatgptAuth": {
      "accessToken": "...",
      "refreshToken": "...",
      "accountId": "..."
    }
  }
}
Field Type Required Default Description
authMode string No api-key Authentication mode: api-key or chatgpt
apiKey string Yes for api-key mode - OpenAI API key
baseUrl string No https://api.openai.com/v1 API endpoint
model string Yes - Model name (e.g., gpt-5.4, gpt-5.4-mini)
contextWindow number No Auto Exact model context window. Set this to override stale local assumptions.
chatgptAuth object Yes for chatgpt mode - Stored ChatGPT/Codex auth tokens and account id

When using direct API-key authentication with a gpt-5.6* model, Chat Completions does not permit non-none reasoning_effort alongside function tools. Autohand automatically sends reasoning_effort: "none" for those tool turns.

mlx

MLX provider for Apple Silicon Macs (local inference).

{
  "mlx": {
    "baseUrl": "http://localhost:8080",
    "port": 8080,
    "model": "mlx-community/Llama-3.2-3B-Instruct-4bit"
  }
}
Field Type Required Default Description
baseUrl string No http://localhost:8080 MLX server URL
port number No 8080 Server port
model string Yes - MLX model identifier

llmgateway

LLM Gateway unified API configuration. Provides access to multiple LLM providers through a single API.

{
  "llmgateway": {
    "apiKey": "your-llmgateway-api-key",
    "baseUrl": "https://api.llmgateway.io/v1",
    "model": "gpt-4o"
  }
}
Field Type Required Default Description
apiKey string Yes - LLM Gateway API key
baseUrl string No https://api.llmgateway.io/v1 API endpoint
model string Yes - Model name (e.g., gpt-4o, claude-3-5-sonnet-20241022)

Getting an API Key: Visit llmgateway.io/dashboard to create an account and get your API key.

Supported Models: LLM Gateway supports models from multiple providers including:

  • OpenAI: gpt-4o, gpt-4o-mini, gpt-4-turbo claude-3-5-haiku-20241022
  • Google: gemini-1.5-pro, gemini-1.5-flash

deepseek

DeepSeek provider configuration. The API is OpenAI-compatible and uses https://api.deepseek.com as its base URL.

{
  "deepseek": {
    "apiKey": "your-deepseek-api-key",
    "baseUrl": "https://api.deepseek.com",
    "model": "deepseek-v4-flash"
  }
}
Field Type Required Default Description
apiKey string Yes - DeepSeek API key
baseUrl string No https://api.deepseek.com API endpoint
model string Yes - Model name, for example deepseek-v4-flash or deepseek-v4-pro

bedrock

AWS Bedrock provider configuration. converse is the default mode and uses the AWS SDK credential chain. OpenAI-compatible modes use Bedrock API keys and Bedrock OpenAI-compatible endpoints.

{
  "bedrock": {
    "apiMode": "converse",
    "authMode": "aws-credentials",
    "profile": "enterprise-prod",
    "region": "us-east-1",
    "model": "anthropic.claude-3-5-sonnet-20241022-v2:0"
  }
}
provider: bedrock
bedrock:
  apiMode: openai-chat
  authMode: bedrock-api-key
  apiKey: bedrock-api-key
  region: us-east-1
  model: openai.gpt-oss-120b-1:0
provider = "bedrock"

[bedrock]
apiMode = "openai-responses"
authMode = "bedrock-api-key"
apiKey = "bedrock-api-key"
region = "us-west-2"
endpoint = "https://vpce-abc123.bedrock-runtime.us-west-2.vpce.amazonaws.com/openai/v1"
model = "arn:aws:bedrock:us-west-2:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0"
Field Type Required Default Description
model string Yes - Bedrock model ID, inference profile ID, or ARN
region string Yes AWS_REGION, then AWS_DEFAULT_REGION, then us-east-1 in setup AWS region
apiMode string No converse converse, openai-chat, or openai-responses
authMode string No aws-credentials for converse, bedrock-api-key for OpenAI-compatible modes Authentication mode
profile string No - Optional AWS profile for credential-chain auth
endpoint string No Derived from mode and region Custom/private Bedrock endpoint
apiKey string Yes for OpenAI-compatible modes - Bedrock API key. Do not use OpenAI API keys.

Run aws configure sso or set AWS_PROFILE=enterprise-prod autohand for profile-based AWS auth. IAM role, container, and instance metadata credentials are supported by the AWS SDK. Enable model access in the AWS console before using a model.


Workspace Settings

{
  "workspace": {
    "defaultRoot": "/path/to/projects",
    "allowDangerousOps": false
  }
}
Field Type Default Description
defaultRoot string Current directory Default workspace when none specified
allowDangerousOps boolean false Allow destructive operations without confirmation

Workspace Safety

Autohand automatically blocks operation in dangerous directories to prevent accidental damage:

  • Filesystem roots (/, C:\, D:\, etc.)
  • Home directories (~, /Users/<user>, /home/<user>, C:\Users\<user>)
  • System directories (/etc, /var, /System, C:\Windows, etc.)
  • WSL Windows mounts (/mnt/c, /mnt/c/Users/<user>)

This check cannot be bypassed. If you try to run autohand in a dangerous directory, you'll see an error and must specify a safe project directory.

# This will be blocked
cd ~ && autohand
# Error: Unsafe Workspace Directory

# This works
cd ~/projects/my-app && autohand

See Workspace Safety for full details.


UI Settings

{
  "ui": {
    "theme": "aurora",
    "customThemes": {
      "company": {
        "colors": {
          "accent": "#7c3aed",
          "success": "#22c55e"
        }
      }
    },
    "autoConfirm": false,
    "readFileCharLimit": 300,
    "silentToolOutput": false,
    "taskListPosition": "above-composer",
    "activityVerbs": ["Compiling", "Parsing", "Reviewing"],
    "activityVerbsEnabled": true,
    "activitySymbol": "✳",
    "statusLine": {
      "showProviderModel": true,
      "showContext": true,
      "showCommandHint": true,
      "showPullRequest": true,
      "showSessionLines": false,
      "showQueue": true,
      "showActiveStatus": true,
      "showActiveMetrics": true,
      "showCancelHint": true
    },
    "showCompletionNotification": true,
    "showThinking": false,
    "terminalBell": true,
    "checkForUpdates": true,
    "updateCheckInterval": 24
  }
}
Field Type Default Description
theme string "aurora" Color theme for terminal output. Built-ins include aurora, dark, light, dracula, sandy, tui, tuatara, github-dark, cappadocia, rio, and australia. Legacy turkey and brazil values still load as aliases.
customThemes object {} Inline custom theme definitions keyed by theme name. Set theme to the same key to use one.
autoConfirm boolean false Skip confirmation prompts for safe operations
readFileCharLimit number 300 Max characters to display from read/find tool output (full content is still sent to the model)
silentToolOutput boolean false Hide tool output blocks in the terminal while still preserving tool results for the model/session
taskListPosition "up" or "above-composer" "above-composer" Place the live task list above the status line or directly above the composer
activityVerbs string or string[] built-in pool Custom activity verb or verb pool for the working indicator, rendered as Verb...
activityVerbsEnabled boolean true Show rotating activity verbs like Compiling... while the agent is working
activitySymbol string "✳" Symbol shown before the activity verb in activity indicator output
showTips boolean true Rotate tips about slash commands, the / @ $ ! : ? triggers and shortcuts beside the idle composer
enterWhileWorking string select While a turn runs, Enter queues a draft; select a queued message with the arrow keys, press Enter to edit it, then Enter to steer or Shift+Enter to save it in the queue. steer and queue retain the earlier direct steering shortcuts for configured sessions
statusLine.showProviderModel boolean true Show the active provider and model in the composer status line
statusLine.showContext boolean true Show the context percentage in the composer status line
statusLine.showCommandHint boolean true Show command, mention, skill, and terminal-entry hints in the composer status line
statusLine.showPullRequest boolean true Show the associated pull request number, or PR #123 when no PR is associated
statusLine.showSessionLines boolean false Show lines added and removed during the current session
statusLine.showQueue boolean true Show queued request counts in the status line
statusLine.showActiveStatus boolean true Show active turn status text while the agent is working
statusLine.showActiveMetrics boolean true Show elapsed time and token metrics while the agent is working
statusLine.showCancelHint boolean true Show the Esc cancel hint while the agent is working
completionReportEnabled boolean true Ask the model to include a concise completion report after completed action turns
showCompletionNotification boolean true Show system notification when task completes
showThinking boolean false Display LLM's reasoning/thought process
renderMarkdown boolean true Render assistant markdown in the terminal: headings, emphasis, inline and fenced code, lists, task lists, quotes, rules, links, and tables. Set false to show the markdown as written. Toggle it in /settings under UI & Display, or run /settings render_markdown off
mouseComposerCursor boolean on, except iTerm2 Enable click-to-position editing in the Ink composer
keybindingProfile string "autohand" Shortcut profile for the composer: autohand, claude-code, codex, cursor, antigravity, devin or factory. See Keyboard Shortcut Profiles
terminalBell boolean true Ring terminal bell when task completes (shows badge on terminal tab/dock)
checkForUpdates boolean true Check for CLI updates on startup
updateCheckInterval number 24 Hours between update checks (uses cached result within interval)

Aurora theme

Aurora is the default theme for new configurations and when no theme is selected. It combines charcoal surfaces, cool off-white text, soft periwinkle accents, and restrained mint, rose, and amber status colours. Existing saved theme selections are preserved.

Aurora in the built CLI, showing a sample response, coloured diff, and charcoal composer.

Select aurora from /theme, or set "ui": { "theme": "aurora" } in your config. Switching takes effect immediately and persists across sessions.

Role Colour
Focus and headings #9b9ef5 periwinkle
Main text #e4e5ec cool pearl
Secondary text and comments #a4a6b2 slate
Input background #222326 charcoal
Success and additions #86cfa3 mint
Errors and removals #ed9a9a rose
Warnings and numbers #e2be80 amber

Use a dark terminal background; #111216 is the reference background. Autohand styles its input and tool surfaces while leaving the terminal background setting to you. Text, syntax, and status colours are tested for at least 4.5:1 contrast on the reference background and theme surfaces; input text exceeds 7:1. Truecolor preserves the palette, with fallback conversion for 256-colour and 16-colour terminals. Status labels and diff markers also work without colour.

Tuatara theme

Select tuatara from /theme, or set "ui": { "theme": "tuatara" } in your config. The selection takes effect immediately and persists across sessions.

Tuatara uses lichen green for focus, warm stone for text, mist blue for functions and links, amber for warnings and numbers, and clay red for errors and removed lines. Its restrained palette draws on the olive, brown, and orange-red colouring of New Zealand's tuatara.

Tuatara in the built CLI, showing a sample response, coloured diff, and dark olive composer.

Role Colour
Focus and headings #b7c98a lichen
Main text #dfdfcf warm stone
Secondary text and comments #9da992 sage grey
Input background #303c2d dark olive
Success and additions #9cba91 fern
Errors and removals #e69a83 clay
Warnings and numbers #d9bd7b amber

Use a dark terminal background; #171c17 is the reference background. Autohand styles its own input and tool surfaces but leaves the terminal's background setting to you. Tests check at least 4.5:1 contrast for text, syntax, and status colours against the reference background and these surfaces, and at least 7:1 for input text. These use the W3C contrast calculation; terminal palettes, transparency, and font rendering can affect the displayed result. Truecolor preserves the full palette; 256-colour and 16-colour terminals use the existing fallback conversion. Status labels and diff +/- markers remain readable when colour output is disabled.

Custom themes

Custom themes can override any semantic color token. Missing tokens are inherited from the dark theme:

{
  "ui": {
    "theme": "company",
    "customThemes": {
      "company": {
        "vars": {
          "brand": "#7c3aed",
          "brandSoft": "#a78bfa"
        },
        "colors": {
          "accent": "brand",
          "borderAccent": "brandSoft",
          "mdHeading": "brand"
        }
      }
    }
  }
}

Note: readFileCharLimit and silentToolOutput only affect terminal display. Full content is still sent to the model and stored in tool messages. When tool output is visible in the interactive Ink UI, non-ignored file changes inside the active workspace are captured around every LLM tool batch and rendered as Added, Edited, or Deleted diffs, including changes made by shell, meta, and MCP tools.

You can toggle silent tool output without editing the file:

autohand config set silent_tool_output true
autohand config set silent_tool_output false

Task List Position

Choose UI & Display → Task list position in /settings. up places live tasks above the working status line; above-composer keeps them directly above the composer and is the default.

Set it directly during an interactive session:

/settings task_list position up
/settings task_list position above-composer

above composer is also accepted. Omit the value to open the position picker directly. The preference is saved and takes effect when the composer returns, without restarting.

You can also set the position from the command line:

autohand config set task_list position up
autohand config set task_list position above-composer

You can toggle rotating activity verbs without editing the file:

autohand config set verbs activity true
autohand config set verbs activity false

Customize the verbs in the config file when you want a fixed status label or a small project-specific rotation:

{
  "ui": {
    "activityVerbs": "Compiling"
  }
}
{
  "ui": {
    "activityVerbs": ["Indexing", "Reviewing", "Testing"],
    "activitySymbol": ">"
  }
}

activityVerbs accepts either a single string or a non-empty string array. When activityVerbsEnabled is false, Autohand falls back to Working... instead of rotating through custom or built-in verbs. While no turn is running, a tip rotates every 30 seconds at the right end of the row above the composer, beside the Completed in … summary. Tips cover slash commands, the / @ $ ! : ? composer triggers, keyboard shortcuts and your installed skills; only tips that fit the remaining width are drawn, and they hide while the agent works. Set showTips to false, or toggle Idle tips in /settings, to turn them off.

You can toggle completion reports, including the structured SITREP prompt, without editing the file:

autohand config set sitrep true
autohand config set sitrep false

Terminal Bell

When terminalBell is enabled (default), Autohand rings the terminal bell (\x07) when a task completes. This triggers:

  • Badge on terminal tab - Shows a visual indicator that work is done
  • Dock icon bounce - Gets your attention when terminal is in background (macOS)
  • Sound - If terminal sounds are enabled in your terminal settings

Terminal-specific settings:

  • macOS Terminal: Preferences > Profiles > Advanced > Bell (Visual/Audible)
  • iTerm2: Preferences > Profiles > Terminal > Notifications
  • VS Code Terminal: Settings > Terminal > Integrated: Enable Bell

To disable:

{
  "ui": {
    "terminalBell": false
  }
}

Ink Renderer

Autohand uses the Ink 7 + React 19 renderer by default for interactive terminals. The legacy ui.useInkRenderer config field is ignored so old config files cannot force the plain terminal composer. Ink provides:

  • Flicker-free output: All UI updates are batched through React reconciliation
  • Working queue feature: Type instructions while the agent works
  • Better input handling: No conflicts between readline handlers
  • Composable UI: Foundation for future advanced UI features

Emergency fallback for terminal compatibility:

AUTOHAND_LEGACY_UI=1 autohand

Note: This feature is experimental and may have edge cases. The default ora-based UI remains stable and fully functional.

Mouse Composer Cursor

mouseComposerCursor is on by default except in iTerm2, where terminal mouse reporting makes the viewport jump when it is switched around scroll-wheel events. The option is left unset in config.json so this per-terminal default applies; to force it on everywhere, run:

autohand config set ui.mouseComposerCursor true

This lets you place the blinking composer cursor by clicking text, including wrapped lines and Unicode text. To turn it off everywhere, run:

autohand config set ui.mouseComposerCursor false

Terminal mouse reporting can change native selection and scroll-wheel behavior. During active work, click a live command to expand or compact its output; clicks in the composer continue to position its cursor. Mouse reporting is always restored when Autohand exits. Terminal-specific modifier keys, commonly Shift, may bypass mouse reporting for native selection.

Keyboard Shortcut Profiles

If you already use another coding agent, the composer can follow its shortcuts. Pick a profile during setup (offered when Autohand detects the agent on your machine), in /settings → UI → Keyboard shortcuts, or directly:

autohand config set ui.keybindingProfile codex

Every profile keeps Autohand's fixed keys: Enter submits (while a turn runs it queues drafts; select a queued message and submit it to steer, see ui.enterWhileWorking), Esc interrupts, Shift+Tab cycles interaction modes, Ctrl+C clears the input and exits on a second press, ? on an empty composer shows the shortcuts panel, and Ctrl+O, Ctrl+T and Ctrl+G expand command output and toggle the team and goals panels. Profiles add what the other agent binds on top:

Profile Newline Exit History
autohand Shift+Enter, Alt+Enter Ctrl+C twice /whatityped
claude-code Shift+Enter, Alt+Enter, Ctrl+J Ctrl+D Ctrl+R
codex Shift+Enter, Alt+Enter, Ctrl+J Ctrl+D Ctrl+R
cursor Shift+Enter, Alt+Enter, Ctrl+J Ctrl+D /whatityped
antigravity Shift+Enter, Alt+Enter, Ctrl+J Ctrl+D /whatityped
devin Shift+Enter, Alt+Enter, Ctrl+J Ctrl+D Ctrl+R
factory Shift+Enter, Alt+Enter Ctrl+C twice /whatityped

Ctrl+D exits only when the composer is empty. Ctrl+R opens the same history view as /whatityped. The ? panel always lists the chords of the active profile, so it is the quickest way to check what is bound.

Two agents let you remap their own shortcuts in a file, and Autohand honours those remaps for the actions it shares. With claude-code, bindings in ~/.claude/keybindings.json for chat:newline, chat:cycleMode, app:exit, app:toggleTranscript, app:toggleTodos and history:search are applied, including null to unbind. With codex, insert_newline and history_search under [tui.keymap.composer] and exit under [tui.keymap.global] in ~/.codex/config.toml replace the profile's chords. Chords with more than one keystroke are ignored, and a malformed file leaves the profile defaults in place. Extension keybindings can never take a chord that the active profile uses.

Which chords actually arrive depends on the terminal, not on the profile:

  • Shift+Enter needs a terminal that encodes modified keys through the kitty keyboard protocol, which Autohand requests at start: Ghostty, kitty, WezTerm and iTerm2 3.5 or later do; Terminal.app does not.
  • Alt+Enter needs Option configured as Meta in macOS terminals.
  • Ctrl+J is a plain control byte and works on any tty, including tmux, which is why every non-default profile includes it.

Import during setup. When setup detects Claude Code, Codex, Cursor, Gemini, Cline, Continue, Augment, OpenCode, Kimi or Grok, it also offers to bring your memories, sessions and skills across. Accepting runs the same import as autohand import --all --categories memory,sessions,skills; you can decline and run /import later, and a failed import never blocks setup.

Update Check

When checkForUpdates is enabled (default), Autohand checks for new releases on startup:

> Autohand v0.6.8 (abc1234) ✓ Up to date

If an update is available:

> Autohand v0.6.7 (abc1234) ⬆ Update available: v0.6.8
  ↳ Run: curl -fsSL https://autohand.ai/install.sh | sh

How it works:

  • Fetches latest release from GitHub API
  • Caches result in ~/.autohand/version-check.json
  • Only checks once per updateCheckInterval hours (default: 24)
  • Non-blocking: startup continues even if check fails

To disable:

{
  "ui": {
    "checkForUpdates": false
  }
}

Or via environment variable:

export AUTOHAND_SKIP_UPDATE_CHECK=1

Agent Settings

Control agent behavior and iteration limits.

{
  "agent": {
    "maxIterations": 100,
    "enableRequestQueue": true,
    "toolSelectionCache": true,
    "autoMemory": true,
    "goalAutoMode": true,
    "idleLogoutEnabled": true,
    "idleTimeoutMs": 14400000,
    "debug": false
  }
}
Field Type Default Description
maxIterations number 100 Maximum tool iterations per user request before stopping
enableRequestQueue boolean true Allow users to type and queue requests while agent is working
toolSelectionCache boolean true Cache local per-turn tool schema selection for equivalent tool-selection input
autoMemory boolean true Extract and save durable user/project memories after completed interactive turns, including evidence-backed lessons from failures and cancellations
goalAutoMode boolean true Put the session in auto mode while a goal is active (autonomous turns, no tool approval prompts)
idleLogoutEnabled boolean true End authenticated interactive sessions after the idle timeout
idleTimeoutMs number 14400000 Milliseconds of inactivity before ending an authenticated session (4 hours)
budget object unset Limits for one run, shared with in-process sub-agents: maxRequests (model requests), maxTokens (reported prompt plus completion tokens; requests that report no usage are counted but their tokens are unknown), maxDurationSeconds (wall time). A request the budget no longer covers is refused before it is sent and the turn fails with the limit named. --max-requests, --max-tokens, and --max-duration override these for a run
sessionRetryLimit number 3 Times a failed turn is re-run after a retryable error before the turn is reported as failed
sessionRetryDelay number unset Milliseconds before the first re-run, growing 1.5× per attempt. When unset, provider outages (5xx, network, timeout) wait 5 s, 15 s, 45 s and other errors 1 s, 1.5 s, 2.25 s; a provider retry-after always wins
debug boolean false Enable verbose debug output (logs agent internal state to stderr)

Concurrent Session Awareness

{
  "sessions": {
    "awareness": "warn"
  }
}
Field Type Default Description
awareness string "warn" passive shows peers, warn also reports risky git and file collisions, and coordinate asks before writing a path claimed by another live session

Tool Schema Selection

Autohand does not send every full tool schema on every LLM request. The system prompt includes a compact tool capability catalog, and each request exposes only a small set of concrete schemas selected from:

  • Core discovery tools such as tool_search, read_file, fff_find, and find_grep
  • Intent-matched tools for editing, verification, git, browser, web, dependency, or project-tracking work
  • Tools requested through recent tool_search calls or explicitly mentioned by name

This avoids the large upfront context cost of sending all tool schemas before the user intent is known. toolSelectionCache controls only the local selector cache for equivalent turns; it does not perform a pre-user LLM warmup and does not force a large cached prompt prefix.

To disable the local selector cache:

{
  "agent": {
    "toolSelectionCache": false
  }
}

To keep authenticated long-running agent sessions alive while they wait for work:

{
  "agent": {
    "idleLogoutEnabled": false
  }
}

For a single process, use autohand --no-idle-logout or set AUTOHAND_NO_IDLE_LOGOUT=1.

Set idleTimeoutMs to a positive duration in milliseconds to change the idle period. The default is 14400000 (4 hours); invalid values fall back to the default.

Goals and auto mode

A goal is a standing instruction to keep working, so starting one switches the session into auto mode: the agent drives its own turns and stops asking for tool approval until the goal is complete. Setting a new goal while one is active queues it, and the queue advances automatically as each goal completes. After a goal reaches its budget limit, a new approved objective can start without clearing the old goal. The exhausted goal and its usage remain in terminal history; starting fresh does not resume or increase the exhausted goal's budget. Completion is saved before resolving the next queued template. If that template is missing or invalid, completion still succeeds, queueError describes the queue-start failure, and the item stays queued for an explicit retry. After repairing the template, /goal resume, --goal resume, or start_queued_goal starts the queued item without restarting the finished goal. Interactive goals created through the goal writer or agent tools use the same auto-mode policy as slash commands, including template starts and explicit resumes. The non-interactive --goal and RPC management APIs persist goals but do not silently launch an autonomous run or change interaction permissions. If a migration or interrupted session leaves queued work without a live owner, bare /goal starts the next item instead of leaving the backlog stranded.

Use /goals or /goals view (/goal view also works) to inspect compact goal summaries and edit full objectives. Close the panel with Ctrl+G (Cmd+G on macOS). Esc clears a goal selection or cancels its unsaved edit; it does not close the panel. Closing the view does not pause the goal; use /goals pause for that. See viewing and managing goals for keyboard controls and the queue, edit, resume, complete, and clear commands.

Goal token usage follows the goal and session that owned the turn when it started. If completion starts the next queued goal during that turn, the final usage remains on the completed goal. A turn started without a goal is not charged retroactively to a newly created goal. Only reported provider usage is counted; unavailable usage is not estimated. Active elapsed time includes short turns and objective edits, and stops while the goal is paused or complete.

Goal storage does not treat malformed, unreadable, or unsupported snapshots as empty state. Mutations stop without overwriting the stored file. Successful writes also refresh .autohand/goals.local.json.backup; if that refresh fails, the goal remains saved and a warning explains that the backup may be older.

Use /goal repair or --goal repair to restore a validated backup explicitly. The damaged bytes are retained in a goals.local.json.corrupt-* file, created with mode 0600 where supported. Windows does not implement Unix owner/group permission distinctions through Node's file-mode API; see the Node filesystem documentation. Recovered active goals are paused and must be resumed deliberately. Recovery refuses newer schema versions and backups owned by another live session. If no valid backup exists, the original files remain untouched for manual recovery.

Goal tools and RPC accept optional acceptance_criteria: 1–20 unique criteria approved by the user. Goals with criteria require completion_evidence when completing: a summary and checks, each with the exact criterion, a status of passed, and non-empty evidence (a result or artifact reference). Missing, failed, unrun, duplicate, and mismatched checks prevent completion. Spending floors remain separate requirements, not proof. Legacy goals without criteria retain their existing completion behavior.

/goal complete <JSON evidence> and --goal 'complete <JSON evidence>' accept the same evidence object. Receipts survive queue advancement and appear in get_goal, command output, and history. They are explicitly reported evidence, not independently verified results. Reopening a completed goal removes its current receipt and requires new evidence before completing again.

Goals may be blocked by an obstacle or waiting for an external condition. Both states require stop_reason and resume_when through tools/RPC, and stop automatic continuation and elapsed-time accrual. An optional checkpoint stores a summary, nextStep, and up to 20 artifacts references. A checkpoint alone saves progress without pausing. Explicit /goal resume preserves it and clears the stop details; it does not automatically verify the condition.

The command equivalents accept JSON (camelCase field names):

/goal waiting {"stopReason":"CI running","resumeWhen":"CI completes","checkpoint":{"summary":"Patch ready","nextStep":"Inspect CI"}}
/goal checkpoint {"summary":"Tests prepared","artifacts":["test-report.log"]}

Use /goal blocked with the same fields for an obstacle. A slow command alone does not automatically mark a goal blocked. Invalid supplied statuses reject the entire update without silently applying other edits.

/goal recover opens an offline-session picker; /goal recover <session-id> selects an exact owner directly. Recovery restores the original conversation, not just the goal text, and leaves work stopped until /goal resume. Live owners, unknown conversations, and cross-workspace sessions are refused. Canceling the picker changes nothing. Pause your current active goal first.

Recovery preserves saved usage instead of charging unobservable offline time. If conversation restoration fails after preparation, the original goal remains safely stopped and can be retried. --goal recover only lists actionable offline choices; it does not open a picker or start autonomous work. Use /goal repair instead when the goal-storage file itself is damaged.

The /goals panel (also Ctrl+G) refreshes across terminals approximately once per second, including elapsed time and owner liveness. It shows the current owner, token/time budgets, stop details, checkpoint, and latest reported completion evidence. Panel refreshes do not call a model or modify storage. Unchanged snapshots do not trigger redraws; closing the CLI releases monitoring.

Queue updates preserve the selected goal by identity and keep an edit draft intact. If the edited goal disappears, Enter cannot send its draft as a new agent instruction; Escape cancels the edit. Storage errors are shown alongside the last valid view until storage can be read again. Nothing is reset or repaired automatically.

To keep the normal turn-by-turn loop while goals are active:

{
  "agent": {
    "goalAutoMode": false
  }
}

An idle timeout ends the interactive session and exits; it does not sign you out. Your credential is stored in the shared ~/.autohand config, so revoking it would sign you out of every other terminal tab and every later run. Signing out stays an explicit /logout.

Debug Mode

Enable debug mode to see verbose logging of agent internal state (react loop iterations, prompt building, session details). Output goes to stderr to avoid interfering with normal output.

Three ways to enable debug mode (in order of precedence):

  1. CLI flag: autohand -d or autohand --debug
  2. Environment variable: AUTOHAND_DEBUG=1
  3. Config file: Set agent.debug: true

Request Queue

When enableRequestQueue is enabled, you can continue typing messages while the agent processes a previous request. Your input will be queued and processed automatically when the current task completes.

  • Type your message and press Enter to add it to the queue
  • The status line shows how many requests are queued
  • Requests are processed in FIFO (first-in, first-out) order
  • Maximum queue size is 10 requests

Local Peer Communication

Communication is independent of sessions.awareness and defaults off. Enable it to address other local sessions and published workers with the : composer or peer tools. Peer communication uses local Unix-domain sockets on macOS/Linux and requires no TCP or UDP port. See Required Ports and Agent Transports for agent IPC, local model servers, browser integration, and optional HTTP listeners.

{
  "sessions": {
    "communication": {
      "enabled": true,
      "scope": "workspace",
      "idleBehavior": "notify",
      "alias": "builder"
    }
  }
}
Option Default Behavior
enabled false Start authenticated local IPC and peer tools.
scope workspace Maximum authorized scope: workspace, repository, or machine. Both peer policies must allow it.
idleBehavior notify Notify while idle; auto explicitly allows peer-triggered turns within existing budgets.
alias Generated Up to 64 letters, digits, dashes and underscores; starts with a letter.
coordinationDirectory AUTOHAND_HOME Shared discovery/resource namespace; private inboxes stay in each profile.
allowResourceControl false Permit explicit controller policy installation and resource grants.
resourceWaitTimeoutMs 300000 Maximum parked command-admission wait.
limits Built-in bounded limits Positive integer overrides documented in the protocol reference.

Use /peers list workspace, /peers list repository, or /peers list machine to choose a directory. The listing includes your own ID for controller setup. /peers send, /peers inbox, /peers reply, and /peers status expose delivery without requiring the user to relay model-to-model messages. Leading :peer message sends immediately; an inline selected :peer supplies an exact reference to the local model.

See the user guide, resource coordination, the technical reference, and the two-session lab. The Unix IPC adapter is implemented for macOS/Linux. Windows communication remains unavailable until private pipe and process-job adapters are implemented; keep communication disabled there. Changing auto-confirmation never bypasses an enabled resource policy.

Permissions Settings

Fine-grained control over tool permissions.

{
  "permissions": {
    "mode": "interactive",
    "whitelist": [
      "run_command:npm *",
      "run_command:bun *",
      "run_command:git status"
    ],
    "blacklist": ["run_command:rm -rf *", "run_command:sudo *"],
    "rules": [
      {
        "tool": "run_command",
        "pattern": "npm test",
        "action": "allow"
      }
    ],
    "rememberSession": true
  }
}

mode

Value Description
"interactive" Prompt for approval on dangerous operations (default)
"unrestricted" No prompts, allow everything
"restricted" Deny all dangerous operations

whitelist

Array of tool patterns that never require approval.

["run_command:npm *", "run_command:bun test"]

blacklist

Array of tool patterns that are always blocked.

["run_command:rm -rf /", "run_command:sudo *"]

rules

Fine-grained permission rules.

| Field | Type | Description | | --------- | --------- | ------------------------------------------- | ---------- | -------------- | | tool | string | Tool name to match | | pattern | string | Optional pattern to match against arguments | | action | "allow" | "deny" | "prompt" | Action to take |

rememberSession

Type Default Description
boolean true Remember approval decisions for the session

Local Project Permissions

Each project can have its own permission settings that override the global config. These are stored in .autohand/settings.local.json in your project root.

When you approve a file operation (edit, write, delete), it's automatically saved to this file so you won't be asked again for the same operation in this project.

{
  "version": 1,
  "permissions": {
    "whitelist": [
      "apply_patch:src/components/Button.tsx",
      "write_file:package.json",
      "run_command:bun test"
    ]
  }
}

How it works:

  • When you approve an operation, it's saved to .autohand/settings.local.json
  • Next time, the same operation will be auto-approved
  • Local project settings are merged with global settings (local takes priority)
  • Add .autohand/settings.local.json to .gitignore to keep personal settings private

Project config overlays:

Both .autohand/config.{json,toml,yaml,yml} (shareable) and .autohand/settings.local.json (personal) are read at startup and layered over the global config, in that order. Only hooks and mcp are read from the shared project config file, because a repository can commit it. settings.local.json supports hooks, mcp, permissions, agent, network, telemetry, provider, and model. Hooks and MCP servers are appended to the global list, with a project entry replacing a global one that has the same identity (hook script name or event plus description/command; MCP server name). Permissions, telemetry, provider, and every other section in the shared project config file are ignored, so a cloned repository cannot switch on unrestricted mode or redirect session sync, and a config written by autohand mcp add --scope project cannot replace your real provider. Overlays are read from the workspace the invocation targets (--path, else the current directory), and saving settings never copies project hooks, MCP servers, or overridden fields into the file being saved. Project hooks and MCP servers from either file only apply after you trust the workspace; see Workspace trust in the hooks documentation. Trust decisions live in ~/.autohand/trusted-workspaces.json.

Pattern format:

  • tool_name:path - For file operations (e.g., apply_patch:src/file.ts)
  • tool_name:command args - For commands (e.g., run_command:npm test)

Viewing Permissions

You can view your current permission settings in two ways:

CLI Flag (Non-interactive):

autohand --permissions

This displays:

  • Current permission mode (interactive, unrestricted, restricted)
  • Workspace and config file paths
  • All approved patterns (whitelist)
  • All denied patterns (blacklist)
  • Summary statistics

Interactive Command:

/permissions

In interactive mode, the /permissions command provides the same information plus options to:

  • Remove items from the whitelist
  • Remove items from the blacklist
  • Clear all saved permissions

Patch Mode

Patch mode allows you to generate a shareable git-compatible patch without modifying your workspace files. This is useful for:

  • Code review before applying changes
  • Sharing AI-generated changes with team members
  • Creating reproducible change sets
  • CI/CD pipelines that need to capture changes without applying them

Usage

# Generate patch to stdout
autohand --prompt "add user authentication" --patch

# Save to file
autohand --prompt "add user authentication" --patch --output auth.patch

# Pipe to file (alternative)
autohand --prompt "refactor api handlers" --patch > refactor.patch

Behavior

When --patch is specified:

  • Auto-confirm: All confirmations are automatically accepted (--yes implied)
  • No prompts: No approval prompts are shown (--unrestricted implied)
  • Preview only: Changes are captured but NOT written to disk
  • Security enforced: Blacklisted operations (.env, SSH keys, dangerous commands) are still blocked

Applying Patches

Recipients can apply the patch using standard git commands:

# Check what would be applied (dry-run)
git apply --check changes.patch

# Apply the patch
git apply changes.patch

# Apply with 3-way merge (handles conflicts better)
git apply -3 changes.patch

# Apply and stage changes
git apply --index changes.patch

# Reverse a patch
git apply -R changes.patch

Patch Format

The generated patch follows git's unified diff format:

diff --git a/src/auth.ts b/src/auth.ts
new file mode 100644
--- /dev/null
+++ b/src/auth.ts
@@ -0,0 +1,15 @@
+export function authenticate(user: string, password: string) {
+  // Implementation here
+}

diff --git a/src/index.ts b/src/index.ts
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,7 @@
 import express from 'express';
+import { authenticate } from './auth';

 const app = express();
+app.use(authenticate);

Exit Codes

Code Meaning
0 Success, patch generated
1 Error (missing --prompt, permission denied, etc.)

Combining with Other Flags

# Use specific model
autohand --prompt "optimize queries" --patch --model gpt-4o

# Specify workspace
autohand --prompt "add tests" --patch --path ./my-project

# Use custom config
autohand --prompt "refactor" --patch --config ~/.autohand/work.json

Team Workflow Example

# Developer A: Generate patch for a feature
autohand --prompt "implement user dashboard with charts" --patch --output dashboard.patch

# Share via git (create PR with just the patch file)
git checkout -b patch/dashboard
git add dashboard.patch
git commit -m "Add dashboard feature patch"
git push

# Developer B: Review and apply
git fetch origin patch/dashboard
git apply dashboard.patch
# Run tests, review code, then commit
git add -A && git commit -m "feat: add user dashboard with charts"

Shell Settings

Control what shell commands started by Autohand can see. This covers the run_command tool, ! terminal commands, and streaming or interactive shells. Hook commands and MCP server processes have their own launchers and are not affected.

{
  "shell": {
    "env": {
      "inherit": "essential",
      "include": ["NODE_*", "NVM_DIR"],
      "exclude": ["*_TOKEN", "AWS_*"],
      "set": { "CI": "1" }
    }
  }
}
Field Type Default Description
env.inherit string all all passes the whole parent environment; essential keeps PATH, HOME, USER, SHELL, TMPDIR, locale and terminal variables (plus their Windows equivalents); none starts empty
env.include string[] [] Variable names or globs to add back on top of the inherited set
env.exclude string[] [] Variable names or globs removed after inheritance and includes
env.set object {} Values pinned for every command; applied last

Variables Autohand needs to run its own tooling (AUTOHAND_*, AUTOHAND_CLI, AUTOHAND_HOME, CODEX_HOME) are always present. Explicit per-command overrides supplied by a tool call still win over the policy.

Network Settings

{
  "network": {
    "maxRetries": 3,
    "timeout": 30000,
    "retryDelay": 1000
  }
}
Field Type Default Max Description
maxRetries number 3 5 Retry attempts for failed API requests
timeout number 30000 - Request timeout in milliseconds
retryDelay number 1000 - Delay between retries in milliseconds

Required Ports and Agent Transports

Autohand Code has no single required inbound TCP port. Normal cloud inference uses outbound HTTPS, usually TCP 443. Local agent communication does not open a TCP listener. Additional ports depend on the provider and optional features you enable. The network settings above control retries and timeouts; they do not configure a listener, peer port, or firewall rule.

Feature Connection and default port Configuration and when it is needed
Peer messages, discovery queries, receipts, and resource coordination Local Unix-domain sockets; no TCP/UDP port Opt in with sessions.communication.enabled. Each root session owns a private socket, normally under <coordinationDirectory>/peer-runtime/; the directory defaults to AUTOHAND_HOME. Long paths use a verified private temporary directory. There is no sessions.communication.port setting.
In-process subagents and teammate communication In-process calls or parent/child stdio; no TCP/UDP port Workers use their owning root's peer runtime. Running more agents does not require allocating a port per agent. Their model requests still use the selected provider's connection.
RPC and ACP agent interfaces JSON messages over stdin/stdout; no TCP/UDP port The embedding application launches the CLI and owns its stdio pipes. These modes do not start an HTTP or WebSocket server.
MCP tools over stdio Child-process stdin/stdout; no CLI transport port Configure mcp.servers[].command and args. A tool server may make its own network connections.
MCP tools over http or sse Outbound to mcp.servers[].url; HTTPS 443, HTTP 80, or the explicit URL port Autohand is the client. A local MCP server must already listen on the port in its URL; there is no fixed Autohand MCP listener.
Cloud inference, account sign-in/sync, downloads, and enabled online services Outbound HTTPS, normally TCP 443 Use the selected provider's baseUrl and the relevant service URL. api.baseUrl / AUTOHAND_API_URL select the account API; AUTOHAND_AUTH_URL selects the sign-in origin. Custom URLs can use other ports.
Ollama CLI connects to http://localhost:11434; TCP 11434 ollama.baseUrl, or ollama.port when no explicit base URL is set. Only required when using that server.
llama.cpp server CLI connects to http://localhost:8080; TCP 8080 llamacpp.baseUrl, or llamacpp.port when no explicit base URL is set. Setup can discover an existing server on another port, including 80.
MLX server CLI connects to http://localhost:8080; TCP 8080 mlx.baseUrl, or mlx.port when no explicit base URL is set. The server must use the same address and port.
Autohand AI Local Local model server, normally http://127.0.0.1:8080; TCP 8080 autohandai.baseUrl and autohandai.port. Setup may start the chosen model on the next port, normally 8081, if a reachable server is serving another model; it saves the resulting endpoint.
OpenAI ChatGPT browser sign-in Temporary callback listener on 127.0.0.1:1455; TCP 1455 If occupied, the CLI asks the OS for a free port. The browser uses the actual http://localhost:<port>/auth/callback redirect. No public inbound rule is needed; the listener closes after sign-in or failure. Device-code sign-in does not use this listener.
autohand review serve HTTP listener on 127.0.0.1; OS-assigned port by default --port 0 selects a free port; --port <1–65535> selects a fixed one. Use the URL printed by the command. The host stays loopback-only.
Chrome extension / native messaging bridge Native messaging and local IPC; no fixed TCP port chrome settings and --browser enable the integration. This is separate from the browser-profile search fallback below.
Browser-profile search's headless Chrome fallback Browser debugging TCP port randomly selected from 9222–10221 Used when this fallback launches Chrome with --remote-debugging-port. There is no CLI setting to pin that port. It is unrelated to agent messaging; the browser also needs outbound access to the search site.
Optional Squad runtime Separate runtime; CLI fallback URL is http://127.0.0.1:19821 Check the separate runtime's status for its actual listener. /squad forwards --host and --port; AUTOHAND_SQUAD_FIXED_PORT is passed through runtime configuration. Core CLI peer messaging does not depend on Squad or port 19821.

Peer communication across sessions and profiles

Peers communicate on the same machine, under the same OS user. The workspace, repository, and machine scopes control which local peers can discover and address each other; machine does not enable LAN or cross-host communication. No router forwarding, public inbound rule, or reserved TCP port is required for peers.

Profiles using different AUTOHAND_HOME directories must set the same sessions.communication.coordinationDirectory to discover one another. Each profile retains its private inbox in its own home. The runtime requires a private local directory and access to its Unix sockets; a shared network folder or opened firewall port does not create cross-host peer support. Windows peer communication is currently unavailable.

Choosing ports and diagnosing conflicts

For a local provider, an explicit baseUrl takes precedence over the provider's port. Change the server's listening port and the matching CLI URL together. For example, after starting Ollama on port 11435, use:

{
  "provider": "ollama",
  "ollama": {
    "baseUrl": "http://127.0.0.1:11435",
    "model": "your-installed-model"
  },
  "sessions": {
    "communication": {
      "enabled": true,
      "scope": "workspace"
    }
  }
}

For a predictable review URL, run autohand review serve --port 4173. If that port is occupied, choose another or use --port 0. Local providers that default to 8080 need distinct ports when running as separate servers at the same time. Optional local listeners should remain reachable only where you intend to use them.

On macOS/Linux, lsof -nP -iTCP:11434 -sTCP:LISTEN identifies the process listening on a model port; substitute the port you are diagnosing. For peer failures, use /peers list and check communication enablement, scope, the shared coordination directory, and socket permissions instead of opening a TCP port. Project dev servers, hooks, external tools, and third-party MCP servers can need additional ports defined by those programs. --offline suppresses startup network refreshes; it is not a firewall and does not force a cloud provider or tool to run locally.


Telemetry Settings

Product telemetry is disabled by default. Full cloud session sync is a separate content-bearing consent and is also disabled by default.

{
  "telemetry": {
    "enabled": false,
    "apiBaseUrl": "https://api.autohand.ai",
    "enableSessionSync": false,
    "companySecret": ""
  },
  "autoReport": {
    "enabled": true
  }
}
Field Type Default Description
enabled boolean false Queue and send pseudonymous product telemetry
apiBaseUrl string https://api.autohand.ai Product telemetry and session-sync API base
enableSessionSync boolean false Upload full saved session messages and metadata; requires telemetry and account authentication
companySecret string "" Optional company secret used by the telemetry transport

Product telemetry includes the active provider/model, runtime/device envelope, tool names and outcomes, commands without free-form arguments, skill/goal/context lifecycle, and path-sanitized errors. Error strings can still contain sensitive text. Session sync includes message content, workspace path and session metadata. autoReport.enabled is an independent diagnostic-report switch and defaults to true; it does not follow telemetry.enabled. See Data collection, telemetry, and agent traces for the exact payloads and privacy boundaries.


Agent Trace Settings

Agent traces are disabled by default and independent of product telemetry. The local mode reads supported coding-agent session stores, maintains a content-free local index, and powers the aggregate Work Map.

{
  "traces": {
    "enabled": false,
    "cloudSync": false,
    "contentMode": "metadata",
    "discoveryMap": true,
    "pollIntervalMs": 60000,
    "apiBaseUrl": "https://api.autohand.ai"
  }
}
Field Type Default Description
enabled boolean false Start local trace monitoring and allow Work Map scans
cloudSync boolean false Upload changed normalized traces to the authenticated account
contentMode metadata | full metadata Metadata excludes messages; full adds bounded, redacted message/tool content
discoveryMap boolean true Allow aggregate Work Map output for discovery and the agent
pollIntervalMs integer 60000 Monitor interval from 1,000 through 3,600,000 ms
apiBaseUrl string api.baseUrl or https://api.autohand.ai HTTPS trace API base; HTTP is accepted only for localhost development

Cloud sync requires enabled, cloudSync, and a signed-in account. Full mode can contain prompts, responses, tool data, source text, and paths after bounded heuristic redaction, so it requires an explicit separate choice. Local-only mode never enables cloud upload. Setting enabled to false stops the companion and deletes its derived Work Map and checkpoints, without modifying any native agent session store.


External Agents

Load custom agent definitions from external directories.

{
  "externalAgents": {
    "enabled": true,
    "paths": ["~/.autohand/agents", "/team/shared/agents"]
  }
}
Field Type Default Description
enabled boolean false Enable external agent loading
paths string[] [] Directories to load agents from

Skills System

Skills are instruction packages that provide specialized instructions to the AI agent. They work like on-demand AGENTS.md files that can be activated for specific tasks.

Skill Discovery Locations

Skills are discovered from multiple locations, with later sources taking precedence:

Location Source ID Description
~/.codex/skills/**/SKILL.md codex-user User-level Codex skills (recursive)
~/.claude/skills/*/SKILL.md claude-user User-level Claude skills (one level)
~/.autohand/skills/**/SKILL.md autohand-user User-level Autohand skills (recursive)
<project>/.claude/skills/*/SKILL.md claude-project Project-level Claude skills (one level)
<project>/.autohand/skills/**/SKILL.md autohand-project Project-level Autohand skills (recursive)

Auto-Copy Behavior

Skills discovered from Codex or Claude locations are automatically copied to the corresponding Autohand location:

  • ~/.codex/skills/ and ~/.claude/skills/ → ~/.autohand/skills/
  • <project>/.claude/skills/ → <project>/.autohand/skills/

Existing skills in Autohand locations are never overwritten.

SKILL.md Format

Skills use YAML frontmatter followed by markdown content:

---
name: my-skill-name
description: Brief description of the skill
license: MIT
compatibility: Works with Node.js 18+
allowed-tools: read_file write_file run_command
metadata:
  author: your-name
  version: "1.0.0"
---

# My Skill

Detailed instructions for the AI agent...
Field Required Max Length Description
name Yes 64 chars Lowercase alphanumeric with hyphens only
description Yes 1024 chars Brief description of the skill
license No - License identifier (e.g., MIT, Apache-2.0)
compatibility No 500 chars Compatibility notes
allowed-tools No - Space-delimited list of allowed tools
metadata No - Additional key-value metadata

Input Prefixes

Autohand supports special prefixes in the input prompt:

Prefix Description Example
/ Slash commands /help, /model, /quit, /exit
@ File mentions (autocomplete) @src/index.ts
$ Skill mentions (autocomplete) $frontend-design, $code-review
! Run terminal commands directly ! git status, ! ls -la

Skill Mentions ($):

  • Type $ followed by characters to see available skills with autocomplete
  • Tab accepts the top suggestion (e.g., $frontend-design)
  • Skills are discovered from ~/.autohand/skills/ and <project>/.autohand/skills/
  • Activated skills are attached to the prompt as special instructions for the current session
  • Preview panel shows skill metadata (name, description, activation state)

Shell Commands (!):

  • Commands run in your current working directory
  • Output displays directly in terminal
  • Does not go to the LLM
  • 30 second timeout
  • Returns to prompt after execution

Slash Commands

/skills - Package Manager

Command Description
/skills List all available skills
/skills use <name> Activate a skill for the current session
/skills deactivate <name> Deactivate a skill
/skills info <name> Show detailed skill information
/skills install Browse and install from community registry
/skills install @<slug> Install a community skill by slug
/skills search <query> Search the community skills registry
/skills trending Show trending community skills
/skills remove <slug> Uninstall a community skill
/skills new Create a new skill interactively
/skills feedback <slug> <1-5> Rate a community skill

/learn - LLM-Powered Skill Advisor

Command Description
/learn Analyze project and recommend skills (quick scan)
/learn deep Deep-scan project (reads source files) for more targeted results
/learn update Re-analyze project and regenerate outdated LLM-generated skills

/learn uses a two-phase LLM flow:

  1. Phase 1 - Analyze + Rank + Audit: Scans your project structure, audits installed skills for redundancy/conflicts, and ranks community skills by relevance (0-100).
  2. Phase 2 - Generate (conditional): If no community skill scores above 60, offers to generate a custom skill tailored to your project.

Generated skills include metadata (agentskill-source: llm-generated, agentskill-project-hash) so /learn update can detect when your codebase changes and regenerate stale skills.

Auto-Skill Generation (--auto-skill)

The --auto-skill CLI flag generates skills without the interactive advisor flow:

autohand --auto-skill

This will:

  1. Analyze your project structure (package.json, requirements.txt, etc.)
  2. Detect languages, frameworks, and patterns
  3. Generate 3 relevant skills using LLM
  4. Save skills to <project>/.autohand/skills/

For a more targeted, interactive experience, use /learn inside a session instead.

Detected patterns include:

  • Languages: TypeScript, JavaScript, Python, Rust, Go
  • Frameworks: React, Next.js, Vue, Express, Flask, Django
  • Patterns: CLI tools, testing, monorepo, Docker, CI/CD

Multi-agent Session Limits

features.multi_agent_v2.max_concurrent_threads_per_session sets the total number of simultaneous threads in a session, including the main agent. The default is 9: one main agent plus up to eight subagents. Choose an integer from 1 to 64. Setting 1 keeps the main agent available and disables delegation.

Open /settings → Teams → Session thread limit (main agent included), or set it directly:

/settings features.multi_agent_v2.max_concurrent_threads_per_session 4
/settings max_agents 4

The non-interactive equivalent is autohand config set features.multi_agent_v2.max_concurrent_threads_per_session 4. Settings are persisted in the existing configuration format:

{
  "features": {
    "multi_agent_v2": {
      "max_concurrent_threads_per_session": 4
    }
  }
}
features:
  multi_agent_v2:
    max_concurrent_threads_per_session: 4
[features.multi_agent_v2]
max_concurrent_threads_per_session = 4

teams.maxTeammates remains a separate, narrower teammate limit. Raising it does not bypass the session-wide thread budget. Lower limits can reduce simultaneous provider usage, but this setting is not a token or spending cap.

Teammate tools are authorized by the lead session's current tool capabilities, permission rules, and hooks. Headless teammates never silently approve an unresolved interactive request: authorize a specific rule in the lead session or perform that operation in the lead. Existing explicit automatic-approval settings remain subject to policy and hook denials. Missing authorization, a disconnected lead, or a stale task attempt fails closed.

Background processes belong to the teammate task that started them. Failed or cancelled attempts stop their owned processes before reassignment; successful background servers may remain available until teammate shutdown. Shutdown stops all remaining teammate-owned processes without stopping unrelated processes.

Selecting maximum reasoning shows a usage warning when the configured limit is eight or more. At the default, it identifies nine concurrent threads including up to eight subagents and recommends setting features.multi_agent_v2.max_concurrent_threads_per_session below eight. Reducing the limit blocks new children once capacity is exhausted; it does not interrupt existing work.

Use /agents view to inspect direct and team runs, their live activity, parentage, model/provider, usage, output, and errors. The list updates as workers wait for model responses, read files, search, or run commands. Worker summaries no longer appear on the main screen; ui.taskListPosition continues to control ordinary task lists.

Arrow keys select a run, Enter opens details, m opens its message editor, and c requests cancellation with confirmation. Enter queues a message for that exact worker's next model step; it does not mean the worker has already read it. Escape closes the message editor or returns from details/confirmation to the list; unsent drafts are discarded, but submitted messages are not recalled. Escape from the list restores the main composer and its draft. Finished, stopping, and unavailable workers cannot receive new messages. /squad view displays the native daemon's recorded runs for this workspace; these are independent, read-only sessions with their own budgets, not children charged against this CLI session's limit.

Run details distinguish the execution workspace, original user request (when available), and delegated task. New workers use the currently selected workspace, including worktrees; nested workers and queued team tasks retain the initiating request and its constraints. Queued team tasks are bound to the workspace where they were created and remain pending when no matching worker is available; task_get includes that workspace. Finish or stop existing workers before switching workspaces. New workers cannot start while a workspace switch is in progress. /agents definitions uses the active session configuration, and /squad view follows the selected workspace.

Workers receive a bounded set of saved project lessons from <selected workspace>/.autohand/memory. Lessons are reference data to verify against the current task, not instructions that override it. An authorized worker with save_memory can save a concise, evidence-backed lesson with level="project"; read-only workers and workers without that tool report lesson candidates to the lead. Worker tool allowlists are not expanded, and raw responses, logs, credentials, and speculative conclusions are not automatically stored. Bare mode disables project-memory bootstrap; agent.autoMemory=false does not authorize automatic lesson saving.

For the evidence-driven review, cleanup, and testing commands, see Lifecycle workflows.


API Settings

Backend API configuration for team features.

{
  "api": {
    "baseUrl": "https://api.autohand.ai",
    "companySecret": "sk-team-xxx"
  }
}
Field Type Default Description
baseUrl string https://api.autohand.ai API endpoint
companySecret string - Team/company secret for shared features

api.baseUrl must point to the Autohand control-plane API, not the Autohand website. Saved *.autohand-web.pages.dev website deployment URLs are repaired to the canonical API during config loading. Explicit AUTOHAND_API_URL overrides remain unchanged for development and staging environments.

Can also be set via environment variables:

  • AUTOHAND_API_URL → api.baseUrl
  • AUTOHAND_SECRET → api.companySecret

Authentication Settings

Authentication and user session configuration.

{
  "auth": {
    "token": "your-auth-token",
    "user": {
      "id": "user-id",
      "email": "user@example.com",
      "name": "User Name",
      "avatar": "https://example.com/avatar.png"
    },
    "expiresAt": "2025-12-31T23:59:59Z"
  }
}
Field Type Default Description
token string - Authentication token for API access
user object - Authenticated user information
user.id string - User ID
user.email string - User email address
user.name string - User display name
user.avatar string - User avatar URL (optional)
expiresAt string - Token expiration timestamp (ISO 8601 format)

Community Skills Settings

Configuration for community skills discovery and management.

{
  "communitySkills": {
    "enabled": true,
    "showSuggestionsOnStartup": true,
    "autoBackup": true
  }
}
Field Type Default Description
enabled boolean true Enable community skills features
showSuggestionsOnStartup boolean true Show skill suggestions on startup when no vendor skills exist
autoBackup boolean true Automatically backup discovered vendor skills to API

Share Settings

Configuration for session sharing via /share command. Sessions are hosted at autohand.link.

{
  "share": {
    "enabled": true
  }
}
Field Type Default Description
enabled boolean true Enable/disable the /share command

YAML Format

share:
  enabled: true

Disabling Session Sharing

If you want to disable session sharing for security or privacy reasons:

{
  "share": {
    "enabled": false
  }
}

When disabled, running /share will display:

Session sharing is disabled.
To enable, set share.enabled: true in your config file.

Settings Sync

Autohand can sync your configuration across devices for logged-in users. Settings are stored securely in Cloudflare R2 and encrypted before upload.

{
  "sync": {
    "enabled": true,
    "interval": 300000,
    "exclude": [],
    "includeTelemetry": false,
    "includeFeedback": false
  }
}
Field Type Default Description
enabled boolean true (logged) Enable/disable settings sync
interval number 300000 Sync interval in milliseconds (default: 5 minutes)
exclude string[] [] Glob patterns to exclude from sync
includeTelemetry boolean false Sync telemetry data (requires user consent)
includeFeedback boolean false Sync feedback data (requires user consent)

CLI Flag

# Disable sync for this session
autohand --sync-settings=false

# Enable sync (default for logged users)
autohand --sync-settings

What Gets Synced

By default, these items are synced for logged-in users:

  • Configuration (config.json) - API keys are encrypted before upload
  • Custom agents (agents/)
  • Community skills (community-skills/)
  • User hooks (hooks/)
  • Memory (memory/)
  • Project knowledge (projects/)
  • Session history (sessions/)
  • Shared content (share/)
  • Custom skills (skills/)

What Doesn't Sync (By Default)

  • Device ID (device-id) - Unique per device
  • Error logs (error.log) - Local only
  • Version cache (version-*.json) - Local cache files

Consent-Based Sync

These items require explicit opt-in in your config:

  • Telemetry data - Set sync.includeTelemetry: true to sync
  • Feedback data - Set sync.includeFeedback: true to sync
{
  "sync": {
    "enabled": true,
    "includeTelemetry": true,
    "includeFeedback": true
  }
}

Conflict Resolution

Memory history is handled differently from ordinary files. The canonical memory/events/LOG.jsonl histories are merged by event ID and the merged log is uploaded again; one device never replaces another device's memory history with cloud-wins semantics. Compatibility JSON files remain syncable materialized views. Locks and memory/derived/ summary caches never sync.

The same canonical project log records privacy-safe skill and slash-command usage so future sessions can recognize frequently useful project workflows. These events contain capability name/source, user-or-agent origin, outcome, and timestamp only. Slash-command arguments, output, and skill bodies are not persisted. Learned slash commands can be suggested but are never automatically executed.

For ordinary file conflicts (the same non-memory-log file modified on multiple devices), the cloud version wins. This ensures consistency when logging in on new devices.

Security

API keys and other sensitive data in config.json are encrypted using your authentication token before upload. They can only be decrypted with your credentials.

Remote file names are accepted only as relative POSIX paths inside the enabled sync categories. Sync rejects directory traversal, absolute or Windows-style paths, duplicate or empty segments, and destinations redirected outside an enabled root by symbolic links.

The application login token is sent in the Authorization header only to transfer URLs on the configured sync API origin. Cross-origin presigned HTTPS URLs never receive that token; insecure or malformed cross-origin URLs are rejected.

What's encrypted:

  • Fields named apiKey
  • Fields ending with Key, Token, Secret
  • The password field

How It Works

  1. On startup: If you're logged in, the sync service starts automatically
  2. Every 5 minutes: Settings are compared with cloud storage
  3. Cloud wins: Remote changes are downloaded first
  4. Local uploads: New local changes are uploaded
  5. On exit: Sync service stops gracefully

Excluding Files

You can exclude specific files or patterns from sync:

{
  "sync": {
    "enabled": true,
    "exclude": ["custom-local-config.json", "temp/*"]
  }
}

YAML Format

sync:
  enabled: true
  interval: 300000
  exclude: []
  includeTelemetry: false
  includeFeedback: false

MCP Settings

Configure MCP (Model Context Protocol) servers to extend Autohand with external tools.

{
  "mcp": {
    "enabled": true,
    "servers": [
      {
        "name": "filesystem",
        "transport": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
        "env": {},
        "autoConnect": true
      },
      {
        "name": "context7",
        "transport": "http",
        "url": "https://mcp.context7.com/mcp",
        "headers": {
          "CONTEXT7_API_KEY": "ctx7sk-your-api-key"
        },
        "autoConnect": true
      }
    ]
  }
}

mcp.enabled

  • Type: boolean
  • Default: true
  • Description: Enable or disable all MCP support. When false, no servers are connected at startup and MCP tools are unavailable.

mcp.servers

  • Type: McpServerConfigEntry[]
  • Default: []
  • Description: Array of MCP server configurations.

Server Entry Fields

Field Type Required Default Description
name string Yes - Unique server identifier
transport "stdio" | "sse" | "http" Yes - Transport type
command string Yes (stdio) - Command to start the server process
args string[] No [] Arguments for the command
stdioFraming "content-length" | "newline" No Auto-detect JSON-RPC framing for stdio servers
url string Yes (sse/http) - Server endpoint URL
headers Record<string, string> No {} Custom HTTP headers for http/sse transport (e.g. auth tokens)
env Record<string, string> No {} Environment variables passed to the server
autoConnect boolean No true Whether to auto-connect on startup

Servers connect asynchronously in the background during startup without blocking the prompt. Use /mcp to manage servers interactively, or /mcp add to browse the community registry or add custom servers.

For full MCP documentation, see docs/mcp.md.


Hooks Settings

Configuration for lifecycle hooks that run shell commands on agent events. Open /hooks to browse all events and create a workspace-scoped script in plain English, or /hooks manage for manual controls. Autohand AI also exposes list_hooks, create_hook, and set_hook_enabled. See Hooks Documentation for the workflow, plugin counts, approval behavior, and script storage.

{
  "hooks": {
    "enabled": true,
    "hooks": [
      {
        "event": "pre-tool",
        "command": "echo \"Running tool: $HOOK_TOOL\" >> ~/.autohand/hooks.log",
        "description": "Log all tool executions",
        "enabled": true
      },
      {
        "event": "file-modified",
        "command": "./scripts/on-file-change.sh",
        "description": "Custom file change handler",
        "filter": { "path": ["src/**/*.ts"] }
      },
      {
        "event": "stop",
        "command": "printf '%s\\n' \"$HOOK_TOKENS\" >> token-usage.log",
        "description": "Track token usage",
        "async": true
      }
    ]
  }
}

hooks

Field Type Default Description
enabled boolean true Enable/disable all hooks globally
hooks array [] Array of hook definitions

Hook Definition

Field Type Required Default Description
event string Yes - Event to hook into
command string Yes - Shell command to execute
description string No - Description for /hooks display
enabled boolean No true Whether hook is active
timeout number No 5000 Timeout in milliseconds
async boolean No false Run without blocking
matcher string No - Regular expression for the event's tool name, session type, notification type, or other supported context
filter object No - Filter by tool or path
importedFrom object No - Import-generated source metadata used for compatibility, workspace scope, and deduplication

filter.tool accepts an array of Autohand tool names, and filter.path accepts an array of path globs. Imported hooks also apply their source event's matching rules and success/failure filters. See Matchers for event-specific matching.

Legacy Shape and Template Variables

The original event-keyed shape is still accepted: any key under hooks other than enabled and hooks is treated as an event name whose value is a command string, an array of command strings, or an array of definition objects. Legacy names such as on_file_change, before_tool_call, and on_session_end map onto the lifecycle events, and {{file}}-style placeholders in any command are replaced before it runs. See Legacy Event Names, Config Shape, and Template Variables.

{
  "hooks": {
    "on_file_change": ["eslint {{file}} --fix"]
  }
}

Imported Hook Metadata

The import feature writes importedFrom on each imported definition. Keep this metadata when editing a definition: it selects the source payload adapter and preserves project scope and duplicate detection.

Field Type Description
id string Generated identifier used to skip unchanged definitions on repeat imports
source string claude, codex, cursor, or grok
event string Original source event name, such as PreToolUse or preToolUse
configPath string Path of the source configuration file
workspaceRoot string, optional Restricts a project hook to its original workspace
workingDirectory string, optional Retains a source-specific working directory, including Cursor user hooks

Hook Events

Event When Fired
pre-tool Before any tool executes
post-tool After tool completes
file-modified When file is created/modified/deleted
pre-prompt Before prompt preparation and model calls in interactive, command, ACP, and JSON-RPC turns
stop After the agent finishes a turn, including configured ACP stop hooks
post-response Backward-compatible alias for stop
session-start When a session starts, resumes, or is cleared
session-end When a session ends
pre-clear Before memory extraction on /clear or /new
permission-request Before a permission prompt
notification When a notification is sent to the user
session-error When error occurs
rate-limit When a rate limit ends the turn
mode-change When permission mode changes, with previous and current modes
pre-learn Before a learn operation, including /learn analysis
post-learn After a learn operation, with its success state
autoresearch:decision When an experiment decision is persisted
autoresearch:replay When an isolated candidate replay completes
autoresearch:rescore When stored measurements are rescored
autoresearch:prune When artifact retention is previewed or applied

This table lists common events and the recent wiring additions. Use /hooks list or the complete event catalog for all automode, autoresearch, team, review, and context events. Autoresearch decision, replay, rescore, and prune hooks also support matchers.

A pre-prompt hook can prevent model work with a JSON decision of deny or block, continue: false, or exit code 2. Supported additionalContext is added to the conversation. Running prompt hooks can be canceled with Escape in the interactive CLI or through protocol cancellation. See control flow responses for response fields and event-specific behavior.

Environment Variables

When hooks execute, these environment variables are available:

Variable Description
HOOK_EVENT Event name
HOOK_WORKSPACE Workspace root path
HOOK_TOOL Tool name (tool events)
HOOK_ARGS JSON-encoded tool args
HOOK_SUCCESS true/false (post-tool)
HOOK_PATH File path (file-modified)
HOOK_TOKENS Tokens used (stop)
HOOK_PREVIOUS_MODE Previous permission mode (mode-change)
HOOK_MODE Current permission mode (mode-change)

Hooks also receive JSON on stdin. Mode changes include previous_mode and mode. See the complete environment-variable reference and source adapter notes for imported hooks.

Import Hooks from Another Coding Agent

autohand import claude --categories hooks
autohand import codex --categories hooks
autohand import cursor --categories hooks
autohand import grok --categories hooks

Inside a session, use /import claude --categories hooks (or another source name). The slash command persists definitions and updates the current hook manager. The standalone CLI respects --path, --config, and AUTOHAND_CONFIG, including JSON, TOML, and YAML destination configs. Use --dry-run to scan without writing, or --all --categories hooks to restrict an all-source import to hooks.

Imported command hooks are saved with enabled: false. Review their scripts, then enable selected entries through /hooks manage. The global hooks.enabled switch still applies. Importing does not execute commands, copy scripts, install dependencies, or inherit another agent's trust approvals. Unchanged repeat imports are skipped and preserve the enabled state of existing definitions.

The importer reads user and current-project configurations for Claude Code, Codex, Cursor, and Grok. Codex supports both hooks.json and nested TOML hook definitions; Grok import currently handles hooks only. Project hooks retain their workspace scope. Source timeout values are converted from seconds to Autohand's milliseconds.

Only compatible command hooks are translated. Unsupported source HTTP, prompt/agent, async, and failClosed handlers are reported as skipped, along with events that require unavailable behavior such as turn continuation or pre-compaction. Legacy Codex notify commands are detected and reported for manual porting because they receive JSON in argv. Source-specific payloads and tool schemas are not fully reproduced.

See hook import compatibility for source file locations, event mappings, timeout defaults, supported responses, and manual-porting limits.


Chrome Extension Settings

Control the Autohand Chrome extension integration. See the full guide at Autohand in Chrome.

{
  "chrome": {
    "extensionId": "your-extension-id",
    "enabledByDefault": false,
    "browser": "auto",
    "userDataDir": "/path/to/chrome/user-data",
    "profileDirectory": "Default",
    "installUrl": "https://autohand.ai/chrome"
  }
}
Key Type Default Description
extensionId string — Installed Chrome extension ID for direct handoff
enabledByDefault boolean false Start browser bridge automatically with the CLI
browser string "auto" Preferred Chromium browser: auto, chrome, chromium, brave, edge
userDataDir string — Browser user data directory to target the correct profile
profileDirectory string — Browser profile directory name (e.g., "Default", "Profile 1")
installUrl string — Fallback URL when the extension ID is not configured

CLI Flags

autohand --browser          # Start with browser bridge enabled
autohand --no-browser       # Start with browser bridge disabled

Slash Commands

/browser                   # Open browser integration panel
/browser disconnect        # Close the browser bridge connection

Complete Example

JSON Format (~/.autohand/config.json)

{
  "provider": "openrouter",
  "openrouter": {
    "apiKey": "sk-or-v1-your-key-here",
    "baseUrl": "https://openrouter.ai/api/v1",
    "model": "your-modelcard-id-here"
  },
  "ollama": {
    "baseUrl": "http://localhost:11434",
    "model": "llama3.2"
  },
  "workspace": {
    "defaultRoot": "~/projects",
    "allowDangerousOps": false
  },
  "ui": {
    "theme": "aurora",
    "autoConfirm": false,
    "showCompletionNotification": true,
    "showThinking": false,
    "terminalBell": true,
    "checkForUpdates": true,
    "updateCheckInterval": 24
  },
  "agent": {
    "maxIterations": 100,
    "enableRequestQueue": true,
    "toolSelectionCache": true,
    "idleLogoutEnabled": true,
    "idleTimeoutMs": 14400000,
    "debug": false
  },
  "permissions": {
    "mode": "interactive",
    "whitelist": ["run_command:npm *", "run_command:bun *"],
    "blacklist": ["run_command:rm -rf /"],
    "rememberSession": true
  },
  "network": {
    "maxRetries": 3,
    "timeout": 30000,
    "retryDelay": 1000
  },
  "telemetry": {
    "enabled": false,
    "apiBaseUrl": "https://api.autohand.ai",
    "enableSessionSync": false
  },
  "traces": {
    "enabled": false,
    "cloudSync": false,
    "contentMode": "metadata",
    "discoveryMap": true
  },
  "autoReport": {
    "enabled": true
  },
  "externalAgents": {
    "enabled": false,
    "paths": []
  },
  "api": {
    "baseUrl": "https://api.autohand.ai"
  },
  "auth": {
    "token": "your-auth-token",
    "user": {
      "id": "user-id",
      "email": "user@example.com",
      "name": "User Name"
    }
  },
  "communitySkills": {
    "enabled": true,
    "showSuggestionsOnStartup": true,
    "autoBackup": true
  },
  "share": {
    "enabled": true
  },
  "sync": {
    "enabled": true,
    "interval": 300000,
    "includeTelemetry": false,
    "includeFeedback": false
  }
}

YAML Format (~/.autohand/config.yaml)

provider: openrouter

openrouter:
  apiKey: sk-or-v1-your-key-here
  baseUrl: https://openrouter.ai/api/v1
  model: your-modelcard-id-here

ollama:
  baseUrl: http://localhost:11434
  model: llama3.2

workspace:
  defaultRoot: ~/projects
  allowDangerousOps: false

ui:
  theme: aurora
  autoConfirm: false
  showCompletionNotification: true
  showThinking: false
  terminalBell: true
  checkForUpdates: true
  updateCheckInterval: 24

agent:
  maxIterations: 100
  enableRequestQueue: true
  toolSelectionCache: true
  idleLogoutEnabled: true
  idleTimeoutMs: 14400000
  debug: false

permissions:
  mode: interactive
  whitelist:
    - "run_command:npm *"
    - "run_command:bun *"
  blacklist:
    - "run_command:rm -rf /"
  rememberSession: true

network:
  maxRetries: 3
  timeout: 30000
  retryDelay: 1000

telemetry:
  enabled: false
  apiBaseUrl: https://api.autohand.ai
  enableSessionSync: false

traces:
  enabled: false
  cloudSync: false
  contentMode: metadata
  discoveryMap: true

autoReport:
  enabled: true

externalAgents:
  enabled: false
  paths: []

api:
  baseUrl: https://api.autohand.ai

auth:
  token: your-auth-token
  user:
    id: user-id
    email: user@example.com
    name: User Name

communitySkills:
  enabled: true
  showSuggestionsOnStartup: true
  autoBackup: true

share:
  enabled: true

sync:
  enabled: true
  interval: 300000
  includeTelemetry: false
  includeFeedback: false

TOML Format (~/.autohand/config.toml)

provider = "openrouter"

[openrouter]
apiKey = "sk-or-v1-your-key-here"
baseUrl = "https://openrouter.ai/api/v1"
model = "your-modelcard-id-here"

[ollama]
baseUrl = "http://localhost:11434"
model = "llama3.2"

[workspace]
defaultRoot = "~/projects"
allowDangerousOps = false

[ui]
theme = "aurora"
autoConfirm = false
showCompletionNotification = true
showThinking = false
terminalBell = true
checkForUpdates = true
updateCheckInterval = 24

[ui.customThemes.company.vars]
brand = "#7c3aed"
brandSoft = "#a78bfa"

[ui.customThemes.company.colors]
accent = "brand"
borderAccent = "brandSoft"
mdHeading = "brand"

[agent]
maxIterations = 100
enableRequestQueue = true
toolSelectionCache = true
idleLogoutEnabled = true
idleTimeoutMs = 14400000
debug = false

[permissions]
mode = "interactive"
whitelist = ["run_command:npm *", "run_command:bun *"]
blacklist = ["run_command:rm -rf /"]
rememberSession = true

Directory Structure

Autohand stores data in ~/.autohand/ (or $AUTOHAND_HOME):

~/.autohand/
├── config.json          # Main configuration
├── config.toml          # Alternative TOML config
├── config.yaml          # Alternative YAML config
├── device-id            # Unique device identifier
├── error.log            # Error log
├── feedback.log         # Feedback submissions
├── sessions/            # Session history
├── projects/            # Project knowledge base
├── memory/              # User-level memory
│   ├── events/
│   │   └── LOG.jsonl    # Canonical append-only history
│   ├── derived/
│   │   └── summaries/   # Rebuildable local outline cache
│   ├── index.json       # Rebuildable compatibility index
│   └── <memory-id>.json # Rebuildable latest-state compatibility view
├── commands/            # Custom commands
├── agents/              # Agent definitions
├── tools/               # Custom meta-tools
├── feedback/            # Feedback state
└── telemetry/           # Telemetry data
    ├── queue.json
    └── session-sync-queue.json

Project-level directory (in your workspace root):

<project>/.autohand/
├── config.json          # Shareable project overlay: hooks and mcp only
├── settings.local.json  # Personal overlay: hooks, mcp, permissions, agent, network, telemetry, provider, model (gitignore this)
├── memory/              # Project-specific memory
│   ├── events/
│   │   └── LOG.jsonl    # Canonical append-only project history
│   ├── derived/
│   │   └── summaries/   # Rebuildable local outline cache
│   ├── index.json       # Rebuildable compatibility index
│   └── <memory-id>.json # Rebuildable latest-state compatibility view
├── skills/              # Project-specific skills
└── tools/               # Project-specific meta-tools

CLI Flags (Override Config)

These flags override config file settings:

Core Flags

Flag Description
-v, --version Output the current version
-p, --prompt [text] Run a single instruction in command mode
--output-schema <file> Command mode only: the final answer must be one JSON document valid against this JSON Schema file. The answer is validated locally; one repair turn is attempted; the run exits 1 with the violations if it still fails. With --json local the result content is the canonical JSON text
--path <path> Override workspace root
--config <path> Use custom config file
--model <model> Override model
--provider <provider> Select the provider for this run or resumed session without changing the saved provider
--temperature <n> Set sampling temperature (0-1)
--thinking [level] Set thinking/reasoning depth (none, normal, extended)
-y, --yes Auto-confirm prompts
--dry-run Preview without executing
-d, --debug Enable verbose debug output
--bare Minimal explicit mode; also sets AUTOHAND_CODE_SIMPLE=1 and disables slash commands
--ephemeral Keep the run out of session history: no session directory or index entry, no automatic memory extraction, no session sync. Files the agent writes in the workspace are unaffected. Cannot be combined with --resume or --fork
--profile <name> Layer profiles.<name> from the config onto this run; see Profiles and One-Run Overrides
--set <key=value> Override one setting for this run by dotted path; repeatable; never saved
--answer-only Classified Blueprint answer RPC profile; requires RPC, restricted, and Blueprint context
--setup-only Scoped Autohand device-auth RPC profile; mutually exclusive with --answer-only
--client-context <context> Typed RPC client context: vscode, chrome, or blueprint

Permissions & Safety

Flag Description
--unrestricted No approval prompts
--restricted Deny dangerous operations
--plan Start in read-only plan mode before the first interactive or command prompt
--permissions Display current permission settings and exit
--no-idle-logout Keep authenticated sessions alive past the idle timeout for long-running agents
--yolo [pattern] Auto-approve tool calls matching pattern (e.g., allow:read,write or deny:delete)
--allowed-tools <patterns> Only offer and authorize these tools this run; comma-separated or repeated (e.g. read_file,run_command(git:*)). A run-only restriction on top of every configured policy: never saved, never widened by a local or extension allowlist
--disallowed-tools <patterns> Never offer or authorize these tools this run. Matched on the tool the model names, before capability mapping, so delete_path stays blocked even when unrestricted. Applies to MCP and delegated tools too
--timeout <seconds> Timeout in seconds for auto-approve mode
--max-requests <n> Stop the run after this many model requests, sub-agents included; the turn fails with the limit named and exit code 1 in command mode
--max-tokens <n> Stop the run once reported token usage reaches this total, sub-agents included
--max-duration <seconds> Stop the run after this much wall time; checked before each model request

Git & Worktree

Flag Description
--worktree [name] Run session in isolated git worktree (optional worktree/branch name)
--tmux Launch in a dedicated tmux session (implies --worktree; cannot be used with --no-worktree)
--no-worktree Disable git worktree isolation in auto-mode
-c, --auto-commit Auto-commit changes after completing tasks
--patch Generate git patch without applying changes
--output <file> Output file for patch (used with --patch)

Auto-Mode

Flag Description
--auto-mode [prompt] Enable interactive auto-mode, or start a standalone loop with an inline task
--max-iterations <n> Max auto-mode iterations (default: 50)
--completion-promise <text> Completion marker text (default: "DONE")
--checkpoint-interval <n> Git commit every N iterations (default: 5)
--max-runtime <m> Max runtime in minutes (default: 120)
--max-cost <d> Max API cost in dollars (default: 10)
--interactive-on-complete After auto-mode ends, hand off directly to interactive mode (TTY only)

Skills & Learning

Flag Description
--auto-skill Auto-generate skills based on project analysis (see also /learn for interactive advisor)
--learn Run /learn skill advisor non-interactively (analyze and install recommended skills)
--learn-update Re-analyze project and regenerate outdated LLM-generated skills non-interactively
--skill-install [name] Install a community skill (opens browser if no name provided)
--project Install skill to project level (with --skill-install)

Authentication & Account

Flag Description
--login Sign in to your Autohand account
--logout Sign out of your Autohand account
--sync-settings Enable/disable settings sync (default: true for logged users)

Setup & Info

Flag Description
--setup Run the setup wizard to configure or reconfigure Autohand
--about Show information about Autohand (version, links, contribution info)
--feedback Submit feedback to the Autohand team
--settings Configure Autohand settings (same as /settings in interactive mode)

Workspace & Directories

Flag Description
--add-dir <path...> Add additional directories to workspace scope (can be used multiple times)

Run Modes

Flag Description
--mode <mode> Run mode: interactive (default), rpc, or acp
--acp Shorthand for --mode acp (Agent Client Protocol over stdio)
--teammate-mode <mode> Legacy team display preference; the live team view stays in the lead terminal

To register the native stdio agent in Zed, JetBrains IDEs, JetBrains Air, or another compatible development environment, see the ACP integration guide.

UI & Language

Flag Description
--display-language <locale> Set display language (e.g., en, id, zh-cn, fr, de, ja)
--search-engine <provider> Set web search provider (browser-profile, exa, google, brave, duckduckgo, parallel)
--cc, --context-compact Enable context compaction (default: on)
--no-cc, --no-context-compact Disable context compaction

Browser Integration

Flag Description
--browser Enable browser integration (same as /browser)
--no-browser Disable browser integration

System Prompt

Flag Description
--sys-prompt <value> Replace entire system prompt (inline string or file path)
--append-sys-prompt <value> Append to system prompt (inline string or file path)
--system-prompt <value> Replace entire system prompt (inline string or file path)
--system-prompt-file <path> Replace entire system prompt with file contents
--append-system-prompt <value> Append to system prompt (inline string or file path)
--append-system-prompt-file <path> Append file contents to system prompt
--mcp-config <path> Load an explicit MCP config file
--agents <json|path> Load explicit inline agents JSON or an explicit agents directory
--plugin-dir <path> Load an explicit plugin/meta-tool directory

Experiment Switch Commands

Command Description
autohand experiments list List local and remote feature ids, source, lifecycle stage, and state
autohand experiments status <feature> Show one feature switch, config path or remote metadata, and state
autohand experiments refresh Download remote feature flags from the Autohand API
autohand experiments enable <feature> Enable a config-backed feature switch
autohand experiments disable <feature> Disable a config-backed feature switch

Remote feature flags are fetched from /v1/feature-flags/evaluate, cached at ~/.autohand/feature-flags.json, and refreshed after the API-provided TTL expires. Use features.environment to select a remote flag environment and features.remoteOverrides for local opt-outs of user-overridable remote flags.

cli_usage_v2 is an experimental feature switch for the project token activity dashboard shown by /usage, /usage weekly, and /usage monthly (config path features.cliUsageV2, default on). Disable it with autohand experiments disable cli_usage_v2.

usage_v2 is the legacy model, provider, context, and usage-limits dashboard plus the enhanced /status Usage tab. Enable it with autohand experiments enable usage_v2.

token_usage_status is an experimental feature switch (config path features.tokenUsageStatus, default off) that shows real-time token usage in the working status line — cumulative tokens up (↑) and down (↓) plus context-window occupancy, e.g. ↑15.7k ↓3.2k · context: 6.0% (15.7k/262.1k). The context window is resolved per model across all providers. Enable it with autohand experiments enable token_usage_status.

prompt_caching is an experimental feature switch (config path features.promptCaching, default off) that sends an opaque session-affinity hint on eligible provider requests. The initial candidate is the ChatGPT OAuth Responses transport; standard OpenAI Chat Completions and other providers remain unchanged. Enable it with autohand experiments enable prompt_caching. The OAuth transport remains unverified until a current two-turn live probe confirms accepted controls and provider-reported cache usage, so an independent remote kill switch and exact-field fallback remain active.

automatic_specialists is an experimental feature switch (config path features.automaticSpecialists, default on, restart required after an override) that resolves explicit specialist-team requests before the lead ReAct loop. It renders the selected roster, runs bounded read-only work in parallel, serializes workspace-mutating specialist tasks, and feeds structured results back to the lead. Missing exact catalog matches use one aggregate approval and fail soft to valid local specialists. Disable it with autohand experiments disable automatic_specialists. This switch never starts or queues /squad automatically.

The restart-required stateful-read experiments are ordered and disabled by default:

Feature Config path Behavior
read_state_ledger features.readStateLedger Persists bounded model-visible file coverage in the active session without changing tool results.
read_state_dedup features.readStateDedup Implies the ledger and returns a consume-on-hit stub for an eligible repeated unchanged read.
read_before_write features.readBeforeWrite Implies both earlier increments and requires a complete unchanged read before direct tools mutate an existing regular file.

Enable an increment with autohand experiments enable <feature>. Partial, clamped, invalid-UTF-8, and stale views never authorize a write. Set AUTOHAND_DISABLE_STATEFUL_READ=1 for a process-local emergency rollback without changing the stored flags.


Doctor

autohand doctor checks the installation in one pass: runtime version and executable, config file and provider (custom and extension providers included), required and optional tools, workspace, terminal support, Autohand account status (startup requires a login whatever the inference provider is), every configured MCP server, and extension diagnostics. Each item is marked ok, warning, or failure, and the exit code is 1 when anything fails. Use --json for a structured report, --skip-mcp to avoid connecting to servers, and --path or --config to check another workspace or config file.


Slash Commands

Start directly in planning mode with autohand --plan, or generate a one-shot plan with autohand --plan --prompt "Plan the migration". Planning instructions and read-only tool gating apply from the first model request. Interactive plan acceptance requires a user decision even with --yes or --unrestricted; command and unattended runs leave the plan pending review. Use /plan off or Shift+Tab to change modes interactively.

--plan conflicts with --yolo, --auto-mode, and --auto-commit. It does not change the --mode rpc|acp transport selector.

Autohand provides a rich set of slash commands for interactive use. Type / in the REPL to see suggestions.

Session Management

From the shell, autohand resume opens a picker scoped to the current working directory. Use --path <path> to select another workspace, --all to browse every project, or --last to resume the most recently active session. --last --all selects the most recently active session across projects. Older metadata without a valid activity timestamp falls back to creation time.

autohand resume <reference> accepts a saved session name (set with /rename or --rename, matched case-insensitively), a full session ID, a unique ID prefix, or a saved session directory/file. A name wins over an ID prefix. Ambiguous or missing references exit with an error, and a name shared by several sessions lists their ID prefixes. Explicit references cannot be combined with --last or --all. --config, --model, and --offline remain available; -c continues to mean auto-commit.

The picker loads twenty sessions per page and provides More sessions and Previous sessions navigation. Escape or Ctrl+C cancels without starting an agent. Non-interactive invocations require --last or an explicit reference when saved sessions exist. Empty history exits successfully without starting a session.

Command Description
/quit Exit the current session
/exit Exit the current session
/new Start fresh conversation (with memory extraction)
/clear Clear conversation with automatic memory extraction
/session Show current session details
/sessions List past sessions
/resume Resume a previous session
/history Browse session history with pagination
/undo Revert the last recorded agent file mutation and turn
/export Export session to markdown/JSON/HTML
/share Share current session
/status Show session status and the signed-in Autohand plan
/usage Show Autohand plan limits and project token activity
/upgrade Open the console to upgrade your Autohand plan

/undo never resets or cleans the Git worktree. It preserves unrelated tracked and untracked work, and refuses to overwrite a file that changed after the recorded agent mutation.

Model & Provider

Command Description
/model Switch or configure LLM model
/cc Compact context manually

Project Setup

Command Description
/init Create AGENTS.md file in current directory
/setup Run the setup wizard to configure Autohand
/add-dir Add directories to workspace scope

Agents & Teams

Command Description
/agents Watch active Autohand sessions
/agents definitions List installed sub-agent definitions
/agents view Inspect direct and team runs
/agents provider [agent] Choose and confirm the provider/model default for new teammates, or an override for one sub-agent definition
/agents-new Create a new agent via wizard
/squad Open/manage the standalone Autohand Squad runtime
/team Manage team for parallel work
/tasks Manage tasks in team
/message Send message to teammate

Skills

Command Description
/skills List and manage skills
/skills-new Create new skill
/learn Learn and install recommended skills

Memory & Settings

Command Description
/memory List memory; outline, zoom, forget, rebuild, or delete
/settings Configure Autohand settings
/statusline Configure composer status-line fields
/experiments Toggle experimental feature switches
/sync Sync settings across devices
/import Import sessions, settings, MCP, memory, skills, and hooks from supported agents

Permissions & Hooks

Command Description
/permissions Manage tool permissions
/hooks Manage lifecycle hooks

Authentication

Command Description
/login Authenticate with Autohand API
/logout Log out of Autohand account

Tools & Utilities

Command Description
/search Search the web
/formatters List available code formatters
/lint List available code linters
/completion Generate shell completion scripts
/plan Create implementation plan
/review Perform code review
/pr-review Review a pull request

IDE Integration

Command Description
/ide Detect and connect to running IDEs

MCP (Model Context Protocol)

Command Description
/mcp Interactive MCP server manager

Automation

Command Description
/automode Start autonomous coding mode
/repeat Schedule recurring jobs
/yolo Toggle yolo mode (auto-approve tools)

Browser Integration

Command Description
/browser Enable browser integration

UI & Display

Command Description
/help Display available slash commands and tips
/about Show information about Autohand
/theme Change color theme
/language Change display language
/feedback Send feedback to the Autohand team
/whatsnew View and dismiss active CLI announcements

Published CLI announcements are mandatory per-item notices rather than a configurable channel. The highest-priority active item appears above the composer and cached notices may also appear in the interactive launch output. Press Ctrl+X to dismiss the visible item or use /whatsnew to review all active items. --offline skips announcement network requests while continuing to render the last successful cache.

System Prompt Customization

Autohand allows you to customize the system prompt used by the AI agent. This is useful for specialized workflows, custom instructions, or integration with other systems.

CLI Flags

Flag Description
--sys-prompt <value> Replace the entire system prompt
--append-sys-prompt <value> Append content to the default system prompt

Both flags accept either:

  • Inline string: Direct text content
  • File path: Path to a file containing the prompt (auto-detected)

File Path Detection

A value is treated as a file path if it:

  • Starts with ./, ../, /, or ~/
  • Starts with a Windows drive letter (e.g., C:\)
  • Ends with .txt, .md, or .prompt
  • Contains path separators without spaces

Otherwise, it's treated as an inline string.

--sys-prompt (Complete Replacement)

When provided, this completely replaces the default system prompt. The agent will NOT load:

  • Default Autohand instructions
  • AGENTS.md project instructions
  • User/project memories
  • Active skills
# Inline string
autohand --sys-prompt "You are a Python expert. Be concise." --prompt "Write hello world"

# From file
autohand --sys-prompt ./custom-prompt.txt --prompt "Explain this code"

# Home directory
autohand --sys-prompt ~/.autohand/prompts/python-expert.md --prompt "Debug this function"

Example custom prompt file (custom-prompt.txt):

You are a specialized Python debugging assistant.

Rules:
- Focus only on Python code
- Always explain the root cause
- Suggest fixes with code examples
- Be concise and direct

--append-sys-prompt (Add to Default)

When provided, this appends content to the full default system prompt. The agent will still load:

  • Default Autohand instructions
  • AGENTS.md project instructions
  • User/project memories
  • Active skills

The appended content is added at the very end.

# Inline string
autohand --append-sys-prompt "Always use TypeScript instead of JavaScript" --prompt "Create a function"

# From file
autohand --append-sys-prompt ./team-guidelines.md --prompt "Add error handling"

Example append file (team-guidelines.md):

## Team Guidelines

- Use 2-space indentation
- Prefer functional patterns
- Add JSDoc comments to public APIs
- Run tests before committing

Precedence

When both flags are provided:

  1. --sys-prompt takes full precedence
  2. --append-sys-prompt is ignored
# --append-sys-prompt is ignored in this case
autohand --sys-prompt "Custom only" --append-sys-prompt "This is ignored"

Use Cases

Use Case Recommended Flag
Custom agent persona --sys-prompt
Minimal instructions --sys-prompt
Add team guidelines --append-sys-prompt
Add project conventions --append-sys-prompt
Integration with external systems --sys-prompt
Specialized debugging --sys-prompt

Error Handling

Scenario Behavior
Empty value Error
File not found Treated as inline string
Empty file Error
File > 1MB Error
Permission denied Error
Directory path Error

Examples

# Python expert mode
autohand --sys-prompt "You are a Python expert. Only write Python code." \
  --prompt "Create a web scraper"

# TypeScript enforcement
autohand --append-sys-prompt "Always use TypeScript, never JavaScript." \
  --prompt "Create a REST API"

# CI/CD integration (non-interactive)
autohand --sys-prompt ./ci-prompt.txt \
  --prompt "Fix the failing tests" \
  --unrestricted \
  --patch

# Custom team workflow
autohand --append-sys-prompt ~/.company/coding-standards.md \
  --prompt "Refactor this module"

Multi-Directory Support

Autohand can work with multiple directories beyond the main workspace. This is useful when your project has dependencies, shared libraries, or related projects in different directories.

CLI Flag

Use --add-dir to add additional directories (can be used multiple times):

# Add a single additional directory
autohand --add-dir /path/to/shared-lib

# Add multiple directories
autohand --add-dir /path/to/lib1 --add-dir /path/to/lib2

# With unrestricted mode (auto-approve writes to all directories)
autohand --add-dir /path/to/shared-lib --unrestricted

Interactive Command

Use /add-dir during an interactive session:

/add-dir              # Show current directories
/add-dir /path/to/dir # Add a new directory

Safety Restrictions

The following directories cannot be added:

  • Home directory (~ or $HOME)
  • Root directory (/)
  • System directories (/etc, /var, /usr, /bin, /sbin)
  • Windows system directories (C:\Windows, C:\Program Files)
  • Windows user directories (C:\Users\username)
  • WSL Windows mounts (/mnt/c, /mnt/c/Windows)