id = "factory-droid" name = "Droid" homepage = "https://factory.ai" description = "Use the Droid CLI to run Factory from your terminal, editor, tests, and Git workflow." # Factory's own mark, the SVG favicon its site serves. icon = "https://factory.ai/favicon.svg" executables = ["droid"] [dotfiles] # https://docs.factory.ai/cli/configuration/settings names the user-level # settings file: "~/.factory/settings.json" on macOS and Linux, # "%USERPROFILE%\.factory\settings.json" on Windows — the same path, since a # Windows user profile root is the home directory, so it is written once. # The page's example holds model, reasoningEffort, outputStyle, diffMode and # the notification sounds, and also names ~/.factory/output-styles/ as the # directory custom output styles are discovered in. # # https://docs.factory.ai/cli/configuration/mcp: MCP servers are configured # at three levels, the user-level one being "~/.factory/mcp.json". # https://docs.factory.ai/cli/configuration/custom-commands: personal slash # commands live in "~/.factory/commands" — "Private or cross-project # shortcuts available across sessions". paths = [ "~/.factory/settings.json", "~/.factory/mcp.json", "~/.factory/commands/", "~/.factory/output-styles/", ] # The settings page calls settings.local.json "machine-specific overrides", # which is the file's whole purpose: it exists so that what is in it stays on # one machine. ~/.factory/worktrees is the default parent directory for git # worktrees droid creates — checkouts, not configuration. exclude = [ "~/.factory/settings.local.json", "~/.factory/worktrees/", ] # No whole-file credential is documented under ~/.factory: the MCP page says # OAuth tokens are held in the system keyring rather than on disk, and the # files named above are settings and command definitions. secret = [] # The MCP page is explicit that credentials do not belong in mcp.json — # "Never put secrets there: header auth tokens (such as `Authorization`), # `oauth.clientSecret`, or API keys" — and offers ${NAME} expansion instead. # A rule is still worth having, because the file is exactly where an inlined # token ends up when someone skips that advice, and syncing it would carry the # token in the clear. The three key paths are the three places the page says a # credential can appear: the stdio server's env block, the http/sse server's # headers, and the OAuth client secret. [[dotfiles.secret_paths]] file = "~/.factory/mcp.json" match = { key_path = [ "mcpServers.*.env.*", "mcpServers.*.headers.*", "mcpServers.*.oauth.clientSecret", ] } [commands] format = 1 label = "Chat with Droid" description = "Start the Droid coding agent with an optional first prompt, or run a task headlessly with the exec subcommand." quality = "ai-draft" parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = true, short_bundles = false } [[commands.source]] id = "docs" kind = "manual" url = "https://docs.factory.ai/reference/cli-reference" revision = "2026-10-27" evidence = """ From https://docs.factory.ai/reference/cli-reference (Droid CLI commands and flags tables) droid | Start interactive REPL | droid | droid "query" | Start REPL with initial prompt | droid "explain this project" | droid exec "query" | Execute task without interactive mode | droid exec "summarize src/auth" | droid exec -f prompt.md | Load prompt from file | droid exec -f .factory/prompts/review.md | -f, --file | Read prompt from a file | droid exec -f plan.md | -m, --model | Select a specific model ID | droid exec -m claude-opus-5-5 | -s, --session-id | Continue an existing session | droid exec -s session-abc123 | --auto | Set autonomy level (low, medium, high) | droid exec --auto medium "run tests" | --list-tools | Print available tools and exit | droid exec --list-tools | -o, --output-format | Output format (text, json, stream-json, stream-jsonrpc) | droid exec -o json "document API" | -r, --resume [sessionId] | Resume a previous session. In interactive mode, -r is --resume; in droid exec, -r is --reasoning-effort. | droid -r | -r, --reasoning-effort | Override reasoning effort; valid levels are model-dependent (see /models). In droid exec, -r maps to this flag. | droid exec -r high "debug flaky test" | --use-spec | Start in specification mode (plan before executing) | droid exec --use-spec "add user profiles" | --skip-permissions-unsafe | Skip all permission prompts; command blocks still apply (unsafe) | droid exec --skip-permissions-unsafe | --cwd | Execute from a specific working directory (use an absolute path) | droid exec --cwd "$PWD/service" --auto medium "run tests" | --append-system-prompt | Append custom text to the end of the system prompt | droid --append-system-prompt "Always run tests." | --append-system-prompt-file | Append the contents of a file to the end of the system prompt | droid --append-system-prompt-file .factory/system.md | """ [[commands.field]] id = "prompt" label = "Prompt" description = "Initial prompt. Leave empty to start with an empty chat." type = "string" position = 0 sources = ["docs"] [[commands.field]] id = "append_system_prompt" label = "Append to system prompt" type = "string" option = ["--append-system-prompt"] sources = ["docs"] [[commands.field]] id = "append_system_prompt_file" label = "Append system prompt from file" type = "path" option = ["--append-system-prompt-file"] path = { kind = "file", role = "input", must_exist = true } sources = ["docs"] [[commands.group]] id = "basic" label = "Basic" fields = ["prompt"] [[commands.group]] id = "advanced" label = "Advanced" fields = ["append_system_prompt", "append_system_prompt_file"] [[commands.subcommand]] path = ["exec"] label = "Run a task headlessly" description = "Run one prompt non-interactively with droid exec. Mission mode, tool allow/deny lists, spec mode and session tagging are left out." [[commands.subcommand.source]] id = "docs" kind = "manual" url = "https://docs.factory.ai/reference/cli-reference" revision = "2026-10-27" evidence = """ From https://docs.factory.ai/reference/cli-reference (Droid CLI commands and flags tables) droid | Start interactive REPL | droid | droid "query" | Start REPL with initial prompt | droid "explain this project" | droid exec "query" | Execute task without interactive mode | droid exec "summarize src/auth" | droid exec -f prompt.md | Load prompt from file | droid exec -f .factory/prompts/review.md | -f, --file | Read prompt from a file | droid exec -f plan.md | -m, --model | Select a specific model ID | droid exec -m claude-opus-5-5 | -s, --session-id | Continue an existing session | droid exec -s session-abc123 | --auto | Set autonomy level (low, medium, high) | droid exec --auto medium "run tests" | --list-tools | Print available tools and exit | droid exec --list-tools | -o, --output-format | Output format (text, json, stream-json, stream-jsonrpc) | droid exec -o json "document API" | -r, --resume [sessionId] | Resume a previous session. In interactive mode, -r is --resume; in droid exec, -r is --reasoning-effort. | droid -r | -r, --reasoning-effort | Override reasoning effort; valid levels are model-dependent (see /models). In droid exec, -r maps to this flag. | droid exec -r high "debug flaky test" | --use-spec | Start in specification mode (plan before executing) | droid exec --use-spec "add user profiles" | --skip-permissions-unsafe | Skip all permission prompts; command blocks still apply (unsafe) | droid exec --skip-permissions-unsafe | --cwd | Execute from a specific working directory (use an absolute path) | droid exec --cwd "$PWD/service" --auto medium "run tests" | --append-system-prompt | Append custom text to the end of the system prompt | droid --append-system-prompt "Always run tests." | --append-system-prompt-file | Append the contents of a file to the end of the system prompt | droid --append-system-prompt-file .factory/system.md | """ [[commands.subcommand.field]] id = "prompt" label = "Prompt" description = "Leave empty when reading the prompt from a file." type = "string" position = 0 sources = ["docs"] [[commands.subcommand.field]] id = "file" label = "Prompt file" type = "path" option = ["--file", "-f"] path = { kind = "file", role = "input", must_exist = true } sources = ["docs"] [[commands.subcommand.field]] id = "model" label = "Model ID" type = "string" option = ["--model", "-m"] sources = ["docs"] [[commands.subcommand.field]] id = "auto" label = "Autonomy level" description = "Omit for read-only. Low allows safe edits, medium local development, high push and deploy." type = "enum" option = ["--auto"] choices = [{ value = "low", label = "Low (safe edits)" }, { value = "medium", label = "Medium (local development)" }, { value = "high", label = "High (CI/CD, push, deploy)" }] sources = ["docs"] [[commands.subcommand.field]] id = "output_format" label = "Output format" type = "enum" option = ["--output-format", "-o"] choices = [{ value = "text", label = "Text" }, { value = "json", label = "JSON" }, { value = "stream-json", label = "Stream JSON" }] sources = ["docs"] [[commands.subcommand.field]] id = "session_id" label = "Continue session" type = "string" option = ["--session-id", "-s"] sources = ["docs"] [[commands.subcommand.field]] id = "cwd" label = "Working directory" type = "path" option = ["--cwd"] path = { kind = "directory", role = "input", must_exist = true } sources = ["docs"] [[commands.subcommand.field]] id = "reasoning_effort" label = "Reasoning effort" description = "Valid levels depend on the model." type = "string" option = ["--reasoning-effort", "-r"] sources = ["docs"] [[commands.subcommand.field]] id = "use_spec" label = "Plan first (spec mode)" type = "boolean" option = ["--use-spec"] sources = ["docs"] [[commands.subcommand.field]] id = "list_tools" label = "List available tools" type = "boolean" option = ["--list-tools"] sources = ["docs"] [[commands.subcommand.field]] id = "skip_permissions" label = "Skip all permission prompts" description = "Unsafe: only in disposable sandboxes." type = "boolean" option = ["--skip-permissions-unsafe"] effect = "exec" sources = ["docs"] [[commands.subcommand.task]] id = "review" label = "Read-only analysis" fields = ["prompt", "model", "output_format", "cwd"] required = ["prompt"] [[commands.subcommand.task]] id = "edit" label = "Make changes (medium autonomy)" fields = ["prompt", "model", "auto", "cwd"] required = ["prompt"] set = { auto = ["medium"] } [[commands.subcommand.group]] id = "basic" label = "Basic" fields = ["prompt", "file", "model", "auto", "output_format", "cwd"] [[commands.subcommand.group]] id = "advanced" label = "Advanced" fields = ["session_id", "reasoning_effort", "use_spec", "list_tools", "skip_permissions"]