Non-interactive execution mode for CI/CD pipelines and automation scripts.
Droid Exec is Factory’s headless execution mode designed for automation workflows. Unlike the interactive CLI, droid exec runs as a one-shot command that completes a task and exits, making it ideal for CI/CD pipelines, shell scripts, and batch processing.
Non-interactive single run that writes to stdout/stderr.
Default is spec-mode: the agent is only allowed to execute read-only operations.
Add --auto to enable edits and commands; risk tiers gate what can run.
CLI help (excerpt):
Copy
Usage: droid exec [options] [prompt]Execute a single command (non-interactive mode)Arguments: prompt The prompt to executeOptions: -o, --output-format <format> Output format (default: "text") --input-format <format> Input format: stream-json for multi-turn sessions -f, --file <path> Read prompt from file --auto <level> Autonomy level: low|medium|high --skip-permissions-unsafe Skip ALL permission checks - allows all permissions (unsafe) -s, --session-id <id> Existing session to continue (requires a prompt) -m, --model <id> Model ID to use -r, --reasoning-effort <level> Reasoning effort (defaults per model) --spec-model <id> Model ID to use for spec mode --use-spec Start in spec mode --enabled-tools <ids> Enable specific tools (comma or space separated list) --disabled-tools <ids> Disable specific tools (comma or space separated list) --list-tools List available tools for the selected model and exit --cwd <path> Working directory path -h, --help display help for command
Supported models (examples):
claude-opus-4-5-20251101 (default)
claude-sonnet-4-5-20250929
claude-haiku-4-5-20251001
gpt-5.1-codex
gpt-5.1
gemini-3-pro-preview
glm-4.6
See the model table for the full list of available models and their costs.
Droid exec uses a tiered autonomy system to control what operations the agent can perform. By default, it runs in read-only mode, requiring explicit flags to enable modifications.
✅ Directory listing: ls, find (without -delete or -exec)
❌ No modifications to files or system
Use case: Safe for reviewing what changes would be made
Copy
# Analyze and plan refactoring without making changesdroid exec "Analyze the authentication system and create a detailed plan for migrating from session-based auth to OAuth2. List all files that would need changes and describe the modifications required."# Review code quality and generate reportdroid exec "Review the codebase for security vulnerabilities, performance issues, and code smells. Generate a prioritized list of improvements needed."# Understand project structuredroid exec "Analyze the project architecture and create a dependency graph showing how modules interact with each other."
Operations that may have significant side effects, but these side effects are typically harmless and straightforward to recover from.
Adds common development tasks to low-risk operations:
Commands that may have security implications such as data transfers between untrusted sources or execution of unknown code, or major side effects such as irreversible data loss or modifications of production systems/deployments.
Irreversible actions to production deployments, database migrations, or other sensitive operations
Commands that access or modify sensitive information like passwords or keys
❌ Still blocks: sudo rm -rf /, system-wide changes
Use case: CI/CD pipelines, automated deployments
Copy
# Full workflow automationdroid exec --auto high "fix bug, test, commit, and push to main"droid exec --auto high "deploy to staging after running tests"
DANGEROUS: This mode allows ALL operations without confirmation. Only use in completely isolated environments like Docker containers or throwaway VMs.
⚠️ Allows ALL operations without confirmation
⚠️ Can execute irreversible operations
Cannot be combined with —auto flags
Use case: Isolated environments
Copy
# In a disposable Docker container for CI testingdocker run --rm -v $(pwd):/workspace alpine:latest sh -c " apk add curl bash && curl -fsSL https://app.factory.ai/cli | sh && droid exec --skip-permissions-unsafe 'Install all system dependencies, modify system configs, run integration tests that require root access, and clean up test databases'"# In ephemeral GitHub Actions runner for rapid iteration# where the runner is destroyed after each jobdroid exec --skip-permissions-unsafe "Modify /etc/hosts for test domains, install custom kernel modules, run privileged container tests, and reset network interfaces"# In a temporary VM for security testingdroid exec --skip-permissions-unsafe "Run penetration testing tools, modify firewall rules, test privilege escalation scenarios, and generate security audit reports"
Human-readable output for direct consumption or logs:
Copy
$ droid exec --auto low "create a python file that prints 'hello world'"Perfect! I've created a Python file named `hello_world.py` in your home directory that prints 'hello world' when executed.
Streaming JSONL messages showing the agent’s execution in real-time. Each line is a separate JSON event that can be parsed independently:
Copy
$ droid exec "run ls command" --output-format stream-json{"type":"system","subtype":"init","cwd":"/path/to/dir","session_id":"abc-123","tools":["Read","Execute",...],"model":"claude-sonnet-4-5-20250929"}{"type":"message","role":"user","id":"msg-1","text":"run ls command","timestamp":1762517060816,"session_id":"abc-123"}{"type":"message","role":"assistant","id":"msg-2","text":"I'll run the ls command to list the contents...","timestamp":1762517062000,"session_id":"abc-123"}{"type":"tool_call","id":"call-1","messageId":"msg-2","toolId":"Execute","toolName":"Execute","parameters":{"command":"ls -la"},"timestamp":1762517062500,"session_id":"abc-123"}{"type":"tool_result","id":"call-1","messageId":"msg-3","toolId":"Execute","isError":false,"value":"total 16\ndrwxr-xr-x@ 8 user staff...","timestamp":1762517063000,"session_id":"abc-123"}{"type":"completion","finalText":"The ls command has been executed successfully. Here are the directory contents...","numTurns":1,"durationMs":3000,"session_id":"abc-123","timestamp":1762517064000}
The debug format is a deprecated alias for stream-json and works identically.
# Process files in parallel (GNU xargs -P)find src -name "*.ts" -print0 | xargs -0 -P 4 -I {} \ droid exec --auto low "Refactor file: {} to use modern TS patterns"
Background job parallelization:
Copy
# Process multiple directories in parallel with job controlfor path in packages/ui packages/models apps/factory-app; do ( cd "$path" && droid exec --auto low "Run targeted analysis and write report.md" ) &donewait # Wait for all background jobs to complete
Chunked inputs:
Copy
# Split large file lists into manageable chunksgit diff --name-only origin/main...HEAD | split -l 50 - /tmp/files_for f in /tmp/files_*; do list=$(tr '\n' ' ' < "$f") droid exec --auto low "Review changed files: $list and write to review.json"donerm /tmp/files_* # Clean up temporary files
Workflow Automation (CI/CD):
Copy
# Dead code detection and cleanup suggestionsname: Code Cleanup Analysison: schedule: - cron: '0 1 * * 0' # Weekly on Sundays workflow_dispatch:jobs: cleanup-analysis: strategy: matrix: module: ['src/components', 'src/services', 'src/utils', 'src/hooks'] steps: - uses: actions/checkout@v4 - run: droid exec --cwd "${{ matrix.module }}" --auto low "Identify unused exports, dead code, and deprecated patterns. Generate cleanup recommendations in cleanup-report.md"