Working with Autohand
Dynamic Meta-Tools
Create custom tools on-the-fly that persist across sessions. Meta-tools let you extend Autohand's capabilities without writing code.
What are meta-tools?
Meta-tools are custom tools you can create during a session that become available in future sessions. They're useful for:
- Repetitive tasks: Create a tool once, use it forever
- Project-specific workflows: Encode your project's unique commands
- Team standardization: Share tools across your organization
Meta-tools are stored as JSON files in ~/.autohand/tools/ and automatically loaded on startup.
Creating a meta-tool
Use the create_meta_tool action to define a new tool:
# Ask Autohand to create a tool
"Create a tool called deploy_staging that runs our staging deployment script"
# Autohand will use create_meta_tool internally to create:
# ~/.autohand/tools/deploy_staging.json
The tool definition includes:
- Name: Unique identifier for the tool
- Description: What the tool does (shown in tool listings)
- Parameters: Input values the tool accepts
- Handler: The command or action to execute
Tool structure
Meta-tools are stored as JSON files with this structure:
{
"name": "deploy_staging",
"description": "Deploy the application to the staging environment",
"parameters": {
"branch": {
"type": "string",
"description": "Git branch to deploy",
"default": "main"
},
"skip_tests": {
"type": "boolean",
"description": "Skip running tests before deploy",
"default": false
}
},
"handler": {
"type": "command",
"template": "npm run deploy:staging -- --branch {{branch}} {{#if skip_tests}}--skip-tests{{/if}}"
}
}
Handler templates
Handler templates support parameter substitution using {{param}} syntax:
| Syntax | Description | Example |
|---|---|---|
{{param}} | Insert parameter value | git checkout {{branch}} |
{{#if param}}...{{/if}} | Conditional block | {{#if verbose}}--verbose{{/if}} |
{{#each items}}...{{/each}} | Iterate over array | {{#each files}}{{this}} {{/each}} |
Parameters are automatically escaped to prevent command injection.
Handler types
Meta-tools support different handler types:
Command handler
Executes a shell command:
{
"handler": {
"type": "command",
"template": "npm run {{script}} -- {{args}}"
}
}
File handler
Creates or modifies a file:
{
"handler": {
"type": "file",
"action": "write",
"path": "src/components/{{name}}/index.tsx",
"template": "export { {{name}} } from './{{name}}';"
}
}
Composite handler
Runs multiple actions in sequence:
{
"handler": {
"type": "composite",
"steps": [
{"type": "command", "template": "npm run build"},
{"type": "command", "template": "npm run test"},
{"type": "command", "template": "npm run deploy"}
]
}
}
Security
Meta-tools include security measures to prevent misuse:
- Parameter escaping: All parameter values are escaped to prevent injection
- Dangerous pattern detection: Commands like
rm -rf /are blocked - Permission inheritance: Meta-tools respect your permission settings
- Audit logging: All meta-tool executions are logged
Blocked patterns include:
rm -rf /
sudo rm
:(){:|:&};:
> /dev/sda
mkfs.
dd if=
Managing meta-tools
View and manage your meta-tools:
# List all meta-tools
ls ~/.autohand/tools/
# View a specific tool
cat ~/.autohand/tools/deploy_staging.json
# Delete a tool
rm ~/.autohand/tools/deploy_staging.json
Meta-tools are loaded on Autohand startup. To reload after changes, restart your session.
Example meta-tools
Database migration tool
{
"name": "db_migrate",
"description": "Run database migrations with optional rollback",
"parameters": {
"direction": {
"type": "string",
"enum": ["up", "down"],
"default": "up"
},
"steps": {
"type": "number",
"description": "Number of migrations to run",
"default": 1
}
},
"handler": {
"type": "command",
"template": "npx prisma migrate {{direction}} --steps {{steps}}"
}
}
Component generator
{
"name": "create_component",
"description": "Generate a new React component with tests",
"parameters": {
"name": {
"type": "string",
"description": "Component name (PascalCase)"
}
},
"handler": {
"type": "composite",
"steps": [
{
"type": "file",
"action": "write",
"path": "src/components/{{name}}/{{name}}.tsx",
"template": "export function {{name}}() {\n return {{name}};\n}"
},
{
"type": "file",
"action": "write",
"path": "src/components/{{name}}/{{name}}.test.tsx",
"template": "import { {{name}} } from './{{name}}';\n\ntest('renders', () => {\n // TODO\n});"
}
]
}
}