Gears¶
Gears are Axium's privileged automation extension system — structured components with enhanced capabilities beyond regular Spokes.
Overview¶
While Spokes provide lightweight plugins for commands and event handlers, Gears offer more powerful capabilities:
- Long-running job execution with tmux pane management
- Filesystem access with fine-grained read/write permissions
- IPC operations for daemon-level actions
- Background process spawning with environment context
- Prefix rule registration with conflict detection
- Enhanced security with explicit permission manifests
Gears vs Spokes¶
| Feature | Spokes | Gears |
|---|---|---|
| CLI commands | ✓ | ✓ |
| Event system | ✓ | ✓ |
| Permissions required | Basic | Explicit manifest |
| Filesystem access | Limited | Fine-grained |
| IPC operations | Read-only | Privileged actions |
| Tmux pane control | ✗ | ✓ |
| Background processes | ✗ | ✓ |
| Prefix registration | ✗ | ✓ |
| Security model | Permissive | Sandboxed |
When to use Gears: - Need to spawn long-running processes in tmux panes - Require filesystem read/write access - Want to register command prefixes dynamically - Need privileged IPC operations (HUD updates, notifications)
When to use Spokes: - Simple CLI commands - Event handlers without side effects - Read-only operations - Quick integrations
Directory Structure¶
Gears live in ~/.config/axium/gears/:
~/.config/axium/gears/
.gear_metadata.json # Installation tracking
ansible/
gear.yaml # Manifest with permissions
main.py # Entry module with register()
ansible_runner.py # Additional modules
terraform/
gear.yaml
main.py
Gear Manifest¶
Every Gear requires a gear.yaml manifest defining metadata and permissions:
name: ansible
version: 1.0.0
description: Ansible automation gear with tmux integration
author: Axium Team
entrypoint: main:register
permissions:
# Execute commands in subprocesses
exec: true
# Send notifications via daemon
notify: true
# Network access
net: false
# IPC actions this gear can perform
ipc:
- tmux_split_run # Create tmux panes and run commands
- hud_update # Update HUD segments
- notify # Send system notifications
- read_file # Read files via daemon
- write_file # Write files via daemon
# Filesystem read permissions (glob patterns)
fs_read:
- ~/.ansible/**
- ~/.ssh/config
- ~/ansible/**
# Filesystem write permissions
fs_write:
- ~/.ansible/tmp/**
- ~/ansible/logs/**
# Optional: Register command prefix rules
prefixes:
- command: ansible-playbook
wrapper: axium ansible-run
Manifest Fields¶
- name: Unique identifier (must match directory name)
- version: Semantic version string
- description: Short description for
axium gear list - author: Gear author
- entrypoint: Python module and function (format:
module:function) - permissions: Permission declarations (see below)
- prefixes: Optional prefix rules to register
Permission System¶
Gears use an explicit permission model for security:
Boolean Permissions¶
- exec: Execute commands in subprocesses
- notify: Send notifications to user
- net: Make network requests
IPC Permissions¶
List of IPC actions the gear can perform via axium.core.api:
tmux_split_run- Create tmux panes and execute commandshud_update- Update HUD status segmentsnotify- Send system notificationsread_file- Read files through daemonwrite_file- Write files through daemonget_env_data- Access environment configuration
Filesystem Permissions¶
Glob patterns for filesystem access:
permissions:
fs_read:
- ~/.ansible/** # Read all ansible config
- ~/.ssh/config # Read SSH config
- ~/playbooks/** # Read playbook files
fs_write:
- ~/.ansible/tmp/** # Write to tmp directory
- ~/playbooks/logs/** # Write log files
Permission Overrides¶
Users can override gear permissions in ~/.config/axium/overrides/permissions/<gear>.yaml:
# Override for ansible gear
exec: true # Allow execution
notify: false # Disable notifications
fs_read:
- ~/.ansible/**
- /company/ansible/** # Add company directory
ipc:
- tmux_split_run
- hud_update
# Removed: notify (disabled above)
Commands¶
# View effective permissions
axium gear perms-show ansible
# Edit permission overrides
axium gear perms-edit ansible
Loading Lifecycle¶
- Discovery - Daemon scans
~/.config/axium/gears/forgear.yamlfiles - Manifest Loading - Parse
gear.yamlfor metadata and permissions - Permission Merging - Combine base permissions with user overrides
- Registration - Import module and call
register(app, events) - Prefix Registration - Register any prefix rules from manifest
- Activation - Gear commands and handlers become available
- Event Emission - Emit
gear_loadedevent
Loading at Startup¶
Gears load automatically when: - Daemon starts (after Spokes) - CLI commands are invoked (for command registration)
# In daemon startup
from axium.core import gears
discovered = gears.discover_gears()
for gear_name in discovered:
gears.load_gear(gear_name, app, events, daemon_permissions)
Sandboxing¶
Gears operate in a security sandbox:
- No direct imports between gears
- Communication via EventBus only
- All privileged operations require explicit permissions
- No shared global state between gears
- IPC permission checks on every API call
Example:
# ✓ ALLOWED: Gear calls API with permission check
from axium.core import api
result = api.tmux_split_run("ansible", "ansible-playbook site.yml", height=20)
# Daemon checks: does "ansible" gear have "tmux_split_run" IPC permission?
# ✗ NOT ALLOWED: Direct import between gears
from other_gear import helper # ImportError - other_gear not in sys.path
Prefix Conflict Detection¶
When gears register prefix rules, Axium detects conflicts:
# gear1/gear.yaml
prefixes:
- command: terraform
wrapper: axium tf-wrapper
# gear2/gear.yaml
prefixes:
- command: terraform # ⚠️ CONFLICT
wrapper: axium other-wrapper
Behavior: - First gear to register wins - Conflict logged as warning - User can resolve by disabling one gear or removing prefix
Metadata Tracking¶
Gear installation is tracked in .gear_metadata.json:
{
"ansible": {
"name": "ansible",
"version": "1.0.0",
"description": "Ansible automation gear",
"entrypoint": "main:register",
"source": "local:~/dev/gear-ansible",
"install_mode": "symlink",
"installed_at": "2025-10-13T15:30:00Z",
"last_loaded": "2025-10-13T16:45:00Z",
"status": "active"
}
}
Status values:
- active - Successfully loaded and running
- error - Failed to load (see logs)
- not-loaded - Installed but not loaded yet
CLI Commands¶
# List installed gears
axium gear list
# View effective permissions for a gear
axium gear perms-show ansible
# Edit permission overrides
axium gear perms-edit ansible
Example Gear¶
Minimal gear that adds a command and uses tmux:
# ~/.config/axium/gears/example/main.py
def register(app, events):
"""
Register gear commands and event handlers.
Args:
app: Typer application for CLI commands
events: EventBus for event subscriptions
"""
from axium.core import api
@app.command("example-run")
def example_run():
"""Run example command in tmux pane."""
# Requires: ipc: [tmux_split_run]
result = api.tmux_split_run(
"example",
"echo 'Hello from gear!' && sleep 5",
height=20
)
if result["ok"]:
print("✓ Command running in pane")
else:
print(f"✗ Failed: {result.get('error')}")
@app.command("example-notify")
def example_notify():
"""Send a test notification."""
# Requires: ipc: [notify]
api.notify_send_cli(
"example",
"Test Notification",
"This is from the example gear"
)
# React to environment changes
def on_env_change(new_env, old_env):
print(f"[example] Environment changed: {old_env} → {new_env}")
events.on("env_change", on_env_change)
With manifest:
# ~/.config/axium/gears/example/gear.yaml
name: example
version: 0.1.0
description: Example gear demonstrating capabilities
author: Your Name
entrypoint: main:register
permissions:
exec: false
notify: true
net: false
ipc:
- tmux_split_run
- notify
fs_read: []
fs_write: []
Usage:
See Also¶
- Writing Gears - Complete guide to gear development
- Spokes - Lightweight plugin system
- Permissions - Permission system details
- API Reference - Gear API documentation