# ffleet.toml — per-project Forge Fleet configuration. # # A personal dev-tool preference, not team config: `ffleet init` writes this by # default to `~/.forge-fleet/{project-id}/ffleet.toml` ("home mode", specs/017), # not into the repo it configures, so nothing about it needs to be shared, # committed, or even visible to a teammate cloning the same repo. In-repo # ("local mode") is still supported as an explicit opt-in for projects that want # it (e.g. forge-fleet's own dev loop) — that's the case this example file # serves; `source_dir` may be omitted in local mode, since it's derived from # where the file lives. Format mirrors `wt.toml`, with one deliberate # difference: the per-coding-agent flag list is called `extra_args` (not `args`) # to make clear it is appended to the coding-agent command, not the whole command # to run. # # Copy to `ffleet.toml` in your repo root and edit, or run `ffleet init` to # generate one (home or local). Values left commented fall back to the default # shown. # --- Repository / environment (global) --------------------------------------- # Logical project name; used to name containers and worktrees. Required. project_name = "creator-ai" # Absolute path to the source repository on the host. Required in home mode. # Optional in local mode (this file's own location, resolved via git, is used # instead) — set it explicitly only if this file isn't colocated with the repo # it configures. source_dir = "/path/to/repo" # Where per-environment git worktrees are created (absolute, or relative to the # repo root). Required. worktree_root = ".forge-fleet/worktrees" # Docker image the coding-agent container runs. Default (pulled from GHCR on # first use): ghcr.io/grzegorz-aniol/forge-fleet-python:latest # Use the Go-dev variant to develop the Go port (published to GHCR): # image = "ghcr.io/grzegorz-aniol/forge-fleet-go:latest" image = "ghcr.io/grzegorz-aniol/forge-fleet-python:latest" # Git integration mode: auto | off | worktree | clone. Default: auto git_mode = "auto" # Use a local `main` branch as base; keep completion local-only (no push/PR). # Default: false git_local_main = false # Let the agent inside the container drive the host Docker daemon (binds the # host docker socket; agent-started containers become siblings). Default: false docker_host_bind = false # Shared uv cache mounted into the container. Default: ~/.cache/uv uv_cache_dir = "~/.cache/uv" # Extra bind mounts as `source:target` entries. Target must be an absolute # container path; a relative source resolves against the repo root; ~ expands # to the host home directory. extra_mounts = [ "~/.agents:/home/buddy/.agents", "~/.ssh:/home/buddy/.ssh", ] # Extra host-to-address mappings passed to `docker run --add-host`, letting processes # in the container resolve names to host (or arbitrary) addresses. Each entry is # `host:address`; `host-gateway` resolves to the host itself. Default: empty (the key # may be omitted entirely). extra_hosts = ["host.docker.internal:host-gateway"] # Additional env file passed to `docker run --env-file` (runtime secrets/keys). # A relative path resolves against this config file's own directory (home- or # repo-based), not the current working directory. # docker_env_file = "docker.env" # Gitignored files to snapshot from the main repo into each *new* worktree, so a # working environment has them at the same relative path (e.g. `.env` appears at # `/workspace/.env` in the container). Entries are relative to the main checkout # (globs allowed). This is a one-time copy at creation — not a live link — so # later edits on either side don't sync, and the agent can't clobber your real # file. Prefer this over a mount for env/local-config files. Default: none. # copy_files = [".env", "config/local.json"] # --- Coding-agent selection -------------------------------------------------- # Which coding-agent (the assistant launched in the container) `ffleet up` runs # when none is named on the command line (--coding-agent / CODING_AGENT). Must be # one of the [section] names below. (Same key as wt.toml's `default`.) default = "claude" # --- Issue tracker for `-t` templates ---------------------------------------- # Where `ffleet up -t ` fetches the issue from. Valid values: # github (default) - fetch via the `gh` CLI (must be installed/authenticated) # linear - fetch via the Linear API (needs LINEAR_API_KEY; e.g. in # .env.forge-fleet); refs may be a UUID or human id (ENG-123) # none - don't fetch; the raw is exposed as {id} # On any fetch failure ffleet warns and continues as if pm=none. # pm = "github" # --- Git identity (injected into the container) ------------------------------ # Both must be set together; otherwise identity resolves from host git config. # [git] # user_name = "Jane Developer" # user_email = "jane@example.com" # --- Per-coding-agent configuration ------------------------------------------ [claude] # Host directory mounted as the coding-agent's Claude config/credentials. dir = "~/.claude" # Credential source Forge Fleet injects into the container: # auto - try keychain, then token, then api-key, then # credentials-file, first one available wins (default) # keychain - macOS only; pin the Keychain-derived credential # (fails fast if the Keychain lookup fails) # token - pin CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`) # api-key - pin ANTHROPIC_API_KEY (API billing, not subscription) # credentials-file - pin the ~/.claude mount's .credentials.json (Linux only) # external - skip the auth preflight entirely (you provide # credentials another way, e.g. --docker-env-file) # auth = "auto" # Override the binary invoked in the container (default: the section name). # cmd = "claude" # Extra flags appended to the claude launch command, after Forge Fleet's own # --dangerously-skip-permissions / -p / --session-id. E.g. pick a subagent: extra_args = ["--agent", "myagent"] [codex] dir = "~/.codex" # cmd = "codex" # extra_args = ["--model", "gpt-5"] # --- Prompt templates --------------------------------------------------------- # `ffleet create -t ` looks up `[templates.]`, fetches the issue # `` from the configured `pm` source (see above), derives the short name # from the issue title, and renders `prompt_template` with the issue's fields: # {number}, {title}, {body}, {url}, and {id} (the raw ref). Extra `key=value` # tokens on the command line add/override template variables, e.g. # `ffleet up -t task 100 priority=high` makes {priority} available. # [templates.task] # prompt_template = """ # Work on issue #{number}: {title} # # {body} # # Issue URL: {url} # """ # Optional: subagent to run for envs seeded from this template. Translated to the # coding-agent's own subagent flag and appended to its launch command (Claude # only: `--agent `; using it with another coding-agent errors). # subagent = "code-reviewer"