Complete reference for all configuration options in ~/.autohand/config.json (or .toml/.yaml/.yml).
Tip: Most settings below can be changed interactively using the
/settingscommand instead of editing the file manually.
Localized references:
- English
- 日本語
- 简体中文
- 繁體中文
- 한국어
- Deutsch
- Español
- Français
- Italiano
- Polski
- Русский
- Português (Brasil)
- Türkçe
- Čeština
- Magyar
- हिन्दी
- Bahasa Indonesia
For local repository scanning and credential reuse during workflow uploads, see Repository discovery.
- Configuration File Location
- Environment Variables
- Bare Mode
- Provider Settings
- Workspace Settings
- UI Settings
- Agent Settings
- Concurrent Session Awareness
- Local Peer Communication
- Permissions Settings
- Patch Mode
- Network Settings
- Required Ports and Agent Transports
- Telemetry Settings
- Agent Trace Settings
- External Agents
- Skills System
- API Settings
- Authentication Settings
- Community Skills Settings
- Share Settings
- Settings Sync
- Hooks Settings
- MCP Settings
- Chrome Extension Settings
- Complete Example
Autohand looks for configuration in this order:
AUTOHAND_CONFIGenvironment variable (custom path)~/.autohand/config.toml~/.autohand/config.yaml~/.autohand/config.yml~/.autohand/config.json(default)
You can also override the base directory:
export AUTOHAND_HOME=/custom/path # Changes ~/.autohand to /custom/pathA 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 --jsonPrecedence, 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.
| 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 |
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.
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 starts Autohand with only explicitly requested context and runtime integrations. Enable it with either:
autohand --bare
AUTOHAND_CODE_SIMPLE=1 autohandWhen --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.mdand 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 |
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 autohandWhen 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.
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 |
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.
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 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. |
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) |
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.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. |
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. |
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 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) |
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 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 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 |
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-turboclaude-3-5-haiku-20241022 - Google:
gemini-1.5-pro,gemini-1.5-flash
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 |
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:0provider = "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": {
"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 |
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 && autohandSee Workspace Safety for full details.
{
"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 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.
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.
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.
| 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 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 falseChoose 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-composerYou can toggle rotating activity verbs without editing the file:
autohand config set verbs activity true
autohand config set verbs activity falseCustomize 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 falseWhen 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
}
}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 autohandNote: This feature is experimental and may have edge cases. The default ora-based UI remains stable and fully functional.
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 trueThis 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 falseTerminal 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.
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 codexEvery 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.
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
updateCheckIntervalhours (default: 24) - Non-blocking: startup continues even if check fails
To disable:
{
"ui": {
"checkForUpdates": false
}
}Or via environment variable:
export AUTOHAND_SKIP_UPDATE_CHECK=1Control 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) |
{
"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 |
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, andfind_grep - Intent-matched tools for editing, verification, git, browser, web, dependency, or project-tracking work
- Tools requested through recent
tool_searchcalls 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.
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.
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):
- CLI flag:
autohand -dorautohand --debug - Environment variable:
AUTOHAND_DEBUG=1 - Config file: Set
agent.debug: true
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
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.
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
}
}| Value | Description |
|---|---|
"interactive" |
Prompt for approval on dangerous operations (default) |
"unrestricted" |
No prompts, allow everything |
"restricted" |
Deny all dangerous operations |
Array of tool patterns that never require approval.
["run_command:npm *", "run_command:bun test"]Array of tool patterns that are always blocked.
["run_command:rm -rf /", "run_command:sudo *"]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 |
| Type | Default | Description |
|---|---|---|
| boolean | true |
Remember approval decisions for the session |
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.jsonto.gitignoreto 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)
You can view your current permission settings in two ways:
CLI Flag (Non-interactive):
autohand --permissionsThis 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 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
# 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.patchWhen --patch is specified:
- Auto-confirm: All confirmations are automatically accepted (
--yesimplied) - No prompts: No approval prompts are shown (
--unrestrictedimplied) - Preview only: Changes are captured but NOT written to disk
- Security enforced: Blacklisted operations (
.env, SSH keys, dangerous commands) are still blocked
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.patchThe 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);| Code | Meaning |
|---|---|
0 |
Success, patch generated |
1 |
Error (missing --prompt, permission denied, etc.) |
# 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# 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"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": {
"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 |
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. |
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.
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.
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 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.
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 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.
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) |
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.
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 |
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
| 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 |
| 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:
- Phase 1 - Analyze + Rank + Audit: Scans your project structure, audits installed skills for redundancy/conflicts, and ranks community skills by relevance (0-100).
- 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.
The --auto-skill CLI flag generates skills without the interactive advisor flow:
autohand --auto-skillThis will:
- Analyze your project structure (package.json, requirements.txt, etc.)
- Detect languages, frameworks, and patterns
- Generate 3 relevant skills using LLM
- 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
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 = 4teams.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.
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.baseUrlAUTOHAND_SECRET→api.companySecret
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) |
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 |
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 |
share:
enabled: trueIf 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.
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) |
# Disable sync for this session
autohand --sync-settings=false
# Enable sync (default for logged users)
autohand --sync-settingsBy 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/)
- Device ID (
device-id) - Unique per device - Error logs (
error.log) - Local only - Version cache (
version-*.json) - Local cache files
These items require explicit opt-in in your config:
- Telemetry data - Set
sync.includeTelemetry: trueto sync - Feedback data - Set
sync.includeFeedback: trueto sync
{
"sync": {
"enabled": true,
"includeTelemetry": true,
"includeFeedback": true
}
}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.
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
passwordfield
- On startup: If you're logged in, the sync service starts automatically
- Every 5 minutes: Settings are compared with cloud storage
- Cloud wins: Remote changes are downloaded first
- Local uploads: New local changes are uploaded
- On exit: Sync service stops gracefully
You can exclude specific files or patterns from sync:
{
"sync": {
"enabled": true,
"exclude": ["custom-local-config.json", "temp/*"]
}
}sync:
enabled: true
interval: 300000
exclude: []
includeTelemetry: false
includeFeedback: falseConfigure 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
}
]
}
}- Type:
boolean - Default:
true - Description: Enable or disable all MCP support. When
false, no servers are connected at startup and MCP tools are unavailable.
- Type:
McpServerConfigEntry[] - Default:
[] - Description: Array of MCP server configurations.
| 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
/mcpto manage servers interactively, or/mcp addto browse the community registry or add custom servers.
For full MCP documentation, see docs/mcp.md.
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
}
]
}
}| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Enable/disable all hooks globally |
hooks |
array | [] |
Array of hook definitions |
| 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.
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"]
}
}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 |
| 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.
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.
autohand import claude --categories hooks
autohand import codex --categories hooks
autohand import cursor --categories hooks
autohand import grok --categories hooksInside 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.
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 |
autohand --browser # Start with browser bridge enabled
autohand --no-browser # Start with browser bridge disabled/browser # Open browser integration panel
/browser disconnect # Close the browser bridge connection
{
"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
}
}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: falseprovider = "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 = trueAutohand 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
These flags override config file settings:
| 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 |
| 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 |
| 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) |
| 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) |
| 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) |
| 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) |
| 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) |
| Flag | Description |
|---|---|
--add-dir <path...> |
Add additional directories to workspace scope (can be used multiple times) |
| 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.
| 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 |
| Flag | Description |
|---|---|
--browser |
Enable browser integration (same as /browser) |
--no-browser |
Disable browser integration |
| 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 |
| 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.
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.
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.
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.
| Command | Description |
|---|---|
/model |
Switch or configure LLM model |
/cc |
Compact context manually |
| 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 |
| 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 |
| Command | Description |
|---|---|
/skills |
List and manage skills |
/skills-new |
Create new skill |
/learn |
Learn and install recommended skills |
| 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 |
| Command | Description |
|---|---|
/permissions |
Manage tool permissions |
/hooks |
Manage lifecycle hooks |
| Command | Description |
|---|---|
/login |
Authenticate with Autohand API |
/logout |
Log out of Autohand account |
| 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 |
| Command | Description |
|---|---|
/ide |
Detect and connect to running IDEs |
| Command | Description |
|---|---|
/mcp |
Interactive MCP server manager |
| Command | Description |
|---|---|
/automode |
Start autonomous coding mode |
/repeat |
Schedule recurring jobs |
/yolo |
Toggle yolo mode (auto-approve tools) |
| Command | Description |
|---|---|
/browser |
Enable browser integration |
| 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.
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.
| 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)
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.
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
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
When both flags are provided:
--sys-prompttakes full precedence--append-sys-promptis ignored
# --append-sys-prompt is ignored in this case
autohand --sys-prompt "Custom only" --append-sys-prompt "This is ignored"| 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 |
| Scenario | Behavior |
|---|---|
| Empty value | Error |
| File not found | Treated as inline string |
| Empty file | Error |
| File > 1MB | Error |
| Permission denied | Error |
| Directory path | Error |
# 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"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.
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 --unrestrictedUse /add-dir during an interactive session:
/add-dir # Show current directories
/add-dir /path/to/dir # Add a new directory
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)

