> ## Documentation Index
> Fetch the complete documentation index at: https://docs.factory.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Droid Exec (Headless)

> 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.

<Tip>
  Explore the [Droid Exec cookbooks](/guides/droid-exec/code-review).
</Tip>

## Summary and goals

Droid Exec is a one-shot task runner designed to:

* Produce readable logs, and structured artifacts when requested
* Enforce opt-in for mutations/command execution (secure-by-default)
* Fail fast on permission violations with clear errors
* Support simple composition for batch and parallel work

<CardGroup cols={2}>
  <Card title="Non-Interactive" icon="terminal">
    Single run execution that writes to stdout/stderr for CI/CD integration
  </Card>

  <Card title="Secure by Default" icon="lock">
    Read-only by default with explicit opt-in for mutations via autonomy levels
  </Card>

  <Card title="Composable" icon="puzzle">
    Designed for shell scripting, parallel execution, and pipeline integration
  </Card>

  <Card title="Clean Output" icon="file-export">
    Structured output formats and artifacts for automated processing
  </Card>
</CardGroup>

## Execution model

* 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):

```
Usage: droid exec [options] [prompt]

Execute a single command (non-interactive mode)

Arguments:
  prompt                          The prompt to execute

Options:
  -o, --output-format <format>    Output format (default: "text")
  --input-format <format>         Input format: stream-jsonrpc 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
```

Use any [available model ID](/models) with `--model` or `--spec-model`. For custom models, see [Bring Your Own Key (BYOK)](/cli/byok/overview).

## Installation

<Steps>
  <Step title="Install Droid CLI">
    <CodeGroup>
      ```bash macOS/Linux theme={null}
      curl -fsSL https://app.factory.ai/cli | sh
      ```

      ```powershell Windows theme={null}
      irm https://app.factory.ai/cli/windows | iex
      ```
    </CodeGroup>
  </Step>

  <Step title="Get Factory API Key">
    Generate your API key from the [Factory Settings Page](https://app.factory.ai/settings/api-keys)
  </Step>

  <Step title="Set Environment Variable">
    Export your API key as an environment variable:

    ```bash theme={null}
    export FACTORY_API_KEY=fk-...
    ```
  </Step>
</Steps>

## Quickstart

* Direct prompt:
  * `droid exec "analyze code quality"`
  * `droid exec "fix the bug in src/main.js" --auto low`
* From file:
  * `droid exec -f prompt.md`
* Pipe:
  * `echo "summarize repo structure" | droid exec`
* Session continuation:
  * `droid exec --session-id <session-id> "continue with next steps"`

## Autonomy Levels

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.

### DEFAULT (no flags) - Read-only Mode

The safest mode for reviewing planned changes without execution:

* ✅ Reading files or logs: cat, less, head, tail, systemctl status
* ✅ Display commands: echo, pwd
* ✅ Information gathering: whoami, date, uname, ps, top
* ✅ Git read operations: git status, git log, git diff
* ✅ Directory listing: ls, find (without -delete or -exec)
* ❌ No modifications to files or system
* **Use case:** Safe for reviewing what changes would be made

```bash theme={null}
# Analyze and plan refactoring without making changes
droid 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 report
droid exec "Review the codebase for security vulnerabilities, performance issues, and code smells. Generate a prioritized list of improvements needed."

# Understand project structure
droid exec "Analyze the project architecture and create a dependency graph showing how modules interact with each other."
```

### `--auto low` - Low-risk Operations

Enables basic file operations while blocking system changes:

* ✅ File creation/editing in project directories
* ❌ No system modifications or package installations
* **Use case:** Documentation updates, code formatting, adding comments

```bash theme={null}
# Safe file operations
droid exec --auto low "add JSDoc comments to all functions"
droid exec --auto low "fix typos in README.md"
```

### `--auto medium` - Development Operations

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:

* Installing packages from trusted sources: npm install, pip install (without sudo)
* Network requests to trusted endpoints: curl, wget to known APIs
* Git operations that modify local repositories: git commit, git checkout, git pull (but not git push)
* Building code with tools like make, npm run build, mvn compile
* ❌ No git push, sudo commands, or production changes
* **Use case:** Local development, testing, dependency management

```bash theme={null}
# Development tasks
droid exec --auto medium "install deps, run tests, fix issues"
droid exec --auto medium "update packages and resolve conflicts"
```

### `--auto high` - Production 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.

* Running arbitrary/untrusted code: curl | bash, eval, executing downloaded scripts
* Exposing ports or modifying firewall rules that could allow external access
* Git push operations that modify remote repositories: git push, git push --force
* 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

```bash theme={null}
# Full workflow automation
droid exec --auto high "fix bug, test, commit, and push to main"
droid exec --auto high "deploy to staging after running tests"
```

### `--skip-permissions-unsafe` - Bypass All Checks

<Warning>
  DANGEROUS: This mode allows ALL operations without confirmation. Only use in completely isolated environments like Docker containers or throwaway VMs.
</Warning>

* ⚠️ Allows ALL operations without confirmation
* ⚠️ Can execute irreversible operations
* Cannot be combined with --auto flags
* **Use case:** Isolated environments

```bash theme={null}
# In a disposable Docker container for CI testing
docker 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 job
droid 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 testing
droid exec --skip-permissions-unsafe "Run penetration testing tools, modify firewall rules, test privilege escalation scenarios, and generate security audit reports"
```

### Fail-fast Behavior

If a requested action exceeds the current autonomy level, droid exec will:

1. Stop immediately with a clear error message
2. Return a non-zero exit code
3. Not perform any partial changes

This ensures predictable behavior in automation scripts and CI/CD pipelines.

## Output formats and artifacts

Droid exec supports three output formats for different use cases:

### text (default)

Human-readable output for direct consumption or logs:

```bash theme={null}
$ 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.
```

### json

Structured JSON output for parsing in scripts and automation:

```bash theme={null}
$ droid exec "summarize this repository" --output-format json
{
  "type": "result",
  "subtype": "success",
  "is_error": false,
  "duration_ms": 5657,
  "num_turns": 1,
  "result": "This is a Factory documentation repository containing guides for CLI tools, web platform features, and onboarding procedures...",
  "session_id": "8af22e0a-d222-42c6-8c7e-7a059e391b0b"
}
```

Use JSON format when you need to:

* Parse the result in a script
* Check success/failure programmatically
* Extract session IDs for continuation
* Process results in a pipeline

### Build custom flows on raw JSON-RPC

For custom integrations, you can run Droid as a long-lived subprocess and drive the full JSON-RPC control surface over stdin/stdout:

```bash theme={null}
droid exec --input-format stream-jsonrpc --output-format stream-jsonrpc --auto low
```

This is the lowest-level integration path for building your own interaction model around Droid. Your process can send turns, stream assistant output, handle permissions, update settings, manage MCP/tools, interrupt work, and resume or fork sessions.

Each stdin line is one JSON-RPC request. Each stdout line is a JSON-RPC response, server request, or notification. A custom client typically:

* Spawns `droid exec` with the project `cwd` and desired flags
* Writes newline-delimited JSON-RPC requests with unique IDs
* Starts with `droid.initialize_session` or `droid.load_session`
* Sends turns with `droid.add_user_message`
* Reads stdout line-by-line and matches responses by `id`
* Handles `droid.session_notification` events for assistant text deltas, tool events, token usage, errors, and turn completion
* Responds to server-to-client requests such as `droid.request_permission` and `droid.ask_user`
* Calls other session methods to interrupt work, update settings, manage MCP servers/tools, inspect context, fork sessions, or compact history
* Implements timeouts, process cleanup, and session persistence

You can build on top of raw stdin/stdout to create custom interaction flows such as:

* Web, desktop, or IDE agent experiences with your own UX and controls
* Chat or copiloting surfaces that route user actions into Droid turns
* CI and workflow runners that execute Droid tasks and surface progress in build logs
* Orchestrators that queue work, resume sessions, fork conversations, and persist results
* Policy layers that approve, deny, transform, or audit tool permission requests
* Bridges from Droid events into your own protocol, message bus, telemetry, or storage layer

For protocol reference and implementation patterns, see the low-level client and process transport in the [TypeScript SDK](https://github.com/Factory-AI/droid-sdk-typescript).

Prefer an SDK when possible:

* **TypeScript**: [`@factory/droid-sdk`](https://github.com/Factory-AI/droid-sdk-typescript) for Node.js apps, streaming, multi-turn sessions, structured output, permissions, tool controls, and SDK-backed MCP tools
* **Python**: [`droid-sdk`](https://github.com/Factory-AI/droid-sdk-python) for asyncio apps, streaming, direct client control, notifications, permissions, and typed event handling

For automated pipelines, you can also direct the agent to write specific artifacts:

```bash theme={null}
droid exec --auto low "Analyze dependencies and write to deps.json"
droid exec --auto low "Generate metrics report in CSV format to metrics.csv"
```

## Working directory

* Use `--cwd` to scope execution:

```
droid exec --cwd /home/runner/work/repo "Map internal packages and dump graphviz DOT to deps.dot"
```

## Models and reasoning effort

Choose a model with `-m` and adjust reasoning with `-r`. See the [Available Models](/models) for available models.

```bash theme={null}
droid exec -m claude-sonnet-4-5-20250929 -r medium -f plan.md
```

Use `--use-spec` to start in specification mode, where the agent plans before executing:

```bash theme={null}
droid exec --use-spec --auto low "refactor the auth module"
```

You can also use a different model for the spec phase:

```bash theme={null}
droid exec --use-spec --spec-model claude-haiku-4-5-20251001 --auto medium "implement feature X"
```

### Tool controls

List available tools for a model:

```bash theme={null}
droid exec --list-tools
droid exec --model gpt-5-codex --list-tools --output-format json
```

Enable or disable specific tools:

```bash theme={null}
# Enable additional tools
droid exec --enabled-tools ApplyPatch "refactor files"

# Disable specific tools
droid exec --auto medium --disabled-tools execute-cli "run edits only"
```

### Custom models

You can configure custom models to use with droid exec by adding them to your `~/.factory/settings.json` file:

```json theme={null}
{
  "customModels": [
    {
      "model": "gpt-5.1-codex-custom",
      "displayName": "My Custom Model",
      "baseUrl": "https://api.openai.com/v1",
      "apiKey": "your-api-key-here",
      "provider": "openai"
    }
  ]
}
```

To use a custom model, use the `custom:` prefix followed by the display name (with spaces replaced by dashes) and the index:

```bash theme={null}
droid exec --model "custom:My-Custom-Model-0" "analyze this codebase"
```

If you have multiple custom models configured:

```json theme={null}
{
  "customModels": [
    {
      "model": "kimi-k2",
      "displayName": "Kimi K2 [Groq]",
      "baseUrl": "https://api.groq.com/openai/v1",
      "apiKey": "your-groq-key",
      "provider": "generic-chat-completion-api",
      "maxOutputTokens": 16384
    },
    {
      "model": "openai/gpt-oss-20b",
      "displayName": "GPT-OSS-20B [OpenRouter]",
      "baseUrl": "https://openrouter.ai/api/v1",
      "apiKey": "YOUR_OPENROUTER_KEY",
      "provider": "generic-chat-completion-api",
      "maxOutputTokens": 32000
    }
  ]
}
```

You would reference them as:

* `--model "custom:Kimi-K2-[Groq]-0"`
* `--model "custom:GPT-OSS-20B-[OpenRouter]-1"`

The index corresponds to the position in the `customModels` array (0-based).

<Note>
  Reasoning effort (`-r` / `--reasoning-effort`) is not yet supported for custom models, but coming soon.
</Note>

## Batch and parallel patterns

Shell loops (bounded concurrency):

```bash theme={null}
# 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:

```bash theme={null}
# Process multiple directories in parallel with job control
for path in packages/ui packages/models apps/factory-app; do
  (
    cd "$path" &&
    droid exec --auto low "Run targeted analysis and write report.md"
  ) &
done
wait  # Wait for all background jobs to complete
```

Chunked inputs:

```bash theme={null}
# Split large file lists into manageable chunks
git 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"
done
rm /tmp/files_*  # Clean up temporary files
```

Workflow Automation (CI/CD):

```yaml theme={null}
# Dead code detection and cleanup suggestions
name: Code Cleanup Analysis
on:
  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"
```

## Unique usage examples

License header enforcer:

```bash theme={null}
git ls-files "*.ts" | xargs -I {} \
  droid exec --auto low "Ensure {} begins with the Apache-2.0 header; add it if missing"
```

API contract drift check (read-only):

```bash theme={null}
droid exec "Compare openapi.yaml operations to our TypeScript client methods and write drift.md with any mismatches"
```

Security sweep:

```bash theme={null}
droid exec --auto low "Run a quick audit for sync child_process usage and propose fixes; write findings to sec-audit.csv"
```

## Exit behavior

* 0: success
* Non-zero: failure (permission violation, tool error, unmet objective). Treat non-zero as failed in CI.

## Best practices

* Favor `--auto low`; keep mutations minimal and commit/push in scripted steps.
* Avoid `--skip-permissions-unsafe` unless fully sandboxed.
* Ask the agent to emit artifacts your pipeline can verify.
* Use `--cwd` to constrain scope in monorepos.
