Skip to content

Latest commit

 

History

History
220 lines (185 loc) · 22.8 KB

File metadata and controls

220 lines (185 loc) · 22.8 KB

Config reference

beflow reads its configuration from $XDG_CONFIG_HOME/beflow/config.json (fallback ~/.config/beflow/config.json). Running beflow doctor creates the file automatically on first run — open it, fill in your workspace details, and re-run.

The file holds the tracker connection, the workspace + project registry, the agent definitions, and global defaults. The shipped config.example.json includes a $schema pointing at the published JSON schema for editor validation. API keys never live in this file — they are read from environment variables (see Secrets).


Top level

Key Required Description
tracker yes Active tracker: "plane" or "linear".
trackers yes Per-tracker connection settings (see Trackers).
agent yes Default agent name (a key under agents). See Run defaults.
runMode yes Default run mode: autonomous or supervised. See Run defaults.
workspace yes { id, slug } of the tracker workspace.
projects yes Map of project key → project config (see Projects).
agents no Map of agent name → agent config (see Agents).
worktrees no { dir } where --auto runs create per-issue git worktrees. ~ expands; default $XDG_DATA_HOME/beflow/worktrees (fallback ~/.local/share/beflow/worktrees).
runs no { dir } where run records persist for resume. Default $XDG_STATE_HOME/beflow/runs (fallback ~/.local/state/beflow/runs).
decisions no { dir, comment }dir is the append-only policy decision log (default $XDG_STATE_HOME/beflow/decisions, fallback ~/.local/state/beflow/decisions); comment (default true) posts a receipt of each decision on the tracker issue, set false to opt out. The receipt body is the overridable decision-receipt.md template.
tools no { acpx } — the command array beflow spawns to run acpx. Default ["bunx", "acpx"].
prompts no { dir } of user prompt-template overrides. See prompts.
mcp no { enabled } — inject a .mcp.json cascade into agent runs. Default off. See mcp.

Trackers

"trackers": {
  "plane": {
    "baseUrl": "https://api.plane.so",
    "workspaceSlug": "your-workspace",
    "apiKeyEnv": "PLANE_API_KEY"
  },
  "linear": {
    "apiKeyEnv": "LINEAR_API_KEY"
  }
}

Only the active tracker (tracker) needs to be present. apiKeyEnv names the environment variable that holds the API key.

Run defaults

These top-level keys set the defaults a run resolves against; every project may override any of them under projects.<KEY>.<same-key>. agent and runMode are the two required ones (listed in Top level); the rest are optional.

Key Required Description
assignee no Tracker user id; beflow assigns the item to this user when it picks it up.
onManualMove no yield (default) lets a live run finish but skips writeback if a human moved the card; abort also cancels the agent.
linkedContext no Inline parent-epic + attachment context into the agent task. Default on.
deadLetter no { maxAttempts } — failed attempts (crash-resume + CI-rework combined) before an item is quarantined to Needs Input. Default 3.
inputQuality no { minBodyChars } — a fresh autonomous dispatch of a too-thin issue is parked to Needs Input instead of running. Off when 0/absent.
qualityGate no { commands, maxRework, baselineTestGlobs } — check command(s) run in the worktree before an implement done opens a PR. On red, beflow auto-reworks the agent up to maxRework times (integer, default 1; 0 = no auto-rework), then fails. baselineTestGlobs pins matching changed test files to the target branch so a change cannot self-grade against tests it weakened (beflow-owned runs only).
review no { enabled, postToPr } — opt-in PR review assist in watch.
advisor no { enabled, agents, maxNudges } — opt-in deputy reviewer for --auto runs. After each agent run it reviews the committed work against the ticket's contract and re-dispatches a correction on drift, escalating to Needs Input after maxNudges ignored corrections (default 3). agents names config.agents entries (v1 uses the first). Off by default. See Advisor.
routing no { triage, spec, implement } — route a job kind to a specific agent name.
sla no { needsInputMinutes, inReviewMinutes } — re-ping the escalation channel when an item ages past the threshold.
telemetry no { inComment }inComment: true appends a compact token/cost line to the writeback comment. Default off.
policy no Global default policy gate (see PR ownership and policy). A present projects.<KEY>.policy replaces this block wholesale for that project. Sub-keys: evaluator ("globs" | "command" | "agentowners" | "off"; default "off"), rules, agentownersPath, command, onBlock ("comment"; default). Builtin: evaluator "off", onBlock "comment".

Selectable job kinds: only triage, spec, and implement exist (JobKind = "triage" | "spec" | "implement"). The routing keys map these same three values to agent names. review is a separate top-level command (beflow review <key>), not a job kind — it cannot be set via a label or meta block. task and continuation do not exist in the schema; they are not internal names either. When no CLI flag or per-issue meta sets jobKind, autoDetectJobKind derives it from the issue type and state group (see resolution).

Projects

Each entry maps a project key (e.g. MYAPP) to a tracker project (a Plane project or a Linear team) and the local repos its work lands in.

"projects": {
  "MYAPP": {
    "name": "My App",
    "plane_project_id": "00000000-0000-0000-0000-000000000000",
    "root": "/path/to/your/project",
    "default_repo": "main_repo",
    "repos": {
      "main_repo": "/path/to/your/project/main_repo",
      "website": "/path/to/your/project/website"
    },
    "module_repo_map": {
      "Backend": "main_repo",
      "Frontend": "website"
    },
    "limits": { "inReview": 5, "inProgress": 3 }
  }
}
Key Required Description
name yes Human-readable project name.
default_repo yes Repo key (from repos) used when a run resolves no specific repo.
repos yes Map of repo key → absolute path on disk.
module_repo_map yes Map of board module name → repo key. Modules become Plane modules; they route work to a repo.
root yes Absolute path to the project root.
plane_project_id no The Plane project UUID (Plane only; Linear maps the key to a team).
limits no WIP caps and a per-run time limit (see sub-keys below).
agent no Agent name overriding the global default for this project.
runMode no Run mode overriding the global default for this project.
ci no { autoReworkOnRed } — re-dispatch rework when an In-Review PR's CI goes red.
routing no Per-project job-kind → agent routing.
scheduling no { activeCycleOnly } — only dispatch Todo items in the active cycle.
pr no Project-level PR mechanics. Replaces the global pr block wholesale. Same sub-keys as the global pr (owner, baseBranch). See PR ownership and policy.
policy no Project-level policy gate. Replaces the global policy block wholesale. Same sub-keys as the global policy. See PR ownership and policy.

limits sub-keys

Sub-key Type Description
inReview number Maximum number of items allowed in In Review simultaneously for this project. Watch skips dispatch when the cap is reached.
inProgress number Maximum number of items allowed In Progress simultaneously. Watch skips dispatch when the cap is reached.
maxRunMinutes number Wall-clock limit per agent run in minutes. beflow terminates the run and parks the issue as failed if this threshold is exceeded.

Per-project deadLetter, inputQuality, qualityGate, review, advisor, sla, and telemetry mirror their Run defaults counterparts and override them.

Repos: one project, several repositories

A beflow project is a single board, but the work on it often lands in more than one git repository — say a backend service, a marketing site, and a shared library. repos is the map from a short repo key to that repository's absolute path on disk; it is the set of repositories a run is allowed to touch. (root is just the common parent directory; beflow doctor checks that root and every repos path exist.)

When beflow runs a work item it resolves which repo the agent works in, then runs the agent in a git worktree of that repo:

  1. --repo <key> on the command line wins, if given.
  2. otherwise module_repo_map routes by the item's module — the board module maps to a repo key.
  3. otherwise default_repo is the fallback.

See resolution for the full cascade.

"MYAPP": {
  "name": "My App",
  "root": "/home/you/projects/app",
  "default_repo": "api",
  "repos": {
    "api": "/home/you/projects/app/api",
    "web": "/home/you/projects/app/web",
    "shared": "/home/you/projects/app/shared"
  },
  "module_repo_map": {
    "Backend": "api",
    "Frontend": "web",
    "Shared Library": "shared"
  }
}

With the above, a work item filed under the Backend module runs in api, a Frontend item in web, and a Shared Library item in shared. An item with no module (or one not in the map) falls back to default_repo (api). Override per run with beflow run <KEY>-42 --repo web.

When — and only when — you opt into the agentowners policy gate (policy.evaluator = "agentowners"), beflow setup/update scaffold a starter AGENTOWNERS file into each of these repos paths (at agentownersPath; existing files are left untouched). With any other evaluator, including the default off, beflow writes nothing into your repos. See scaffolding the file.

Agents

Each entry defines how to launch one coding-agent CLI.

"agents": {
  "claude": {
    "command": "claude",
    "args": ["--dangerously-skip-permissions"],
    "acpCommand": "bunx",
    "acpArgs": ["@agentclientprotocol/claude-agent-acp"],
    "model": "claude-opus-4-8"
  }
}
Key Required Description
command yes Interactive CLI binary used by --open (direct spawn).
args no Extra args for the --open spawn (before the task).
acpCommand no ACP-server binary for --auto/--attend via acpx. Defaults to command.
acpArgs no Args for the ACP server. beflow runs acpx --agent "<acpCommand ?? command> <acpArgs…>".
model no acpx --model for --auto/--attend.

Secrets

API keys are read from the environment, never from config.json. Set them in your shell profile (~/.zshrc or ~/.bashrc) and reload:

# zsh:
echo 'export PLANE_API_KEY=...' >> ~/.zshrc  && source ~/.zshrc
# bash:
echo 'export PLANE_API_KEY=...' >> ~/.bashrc && source ~/.bashrc
# Windows PowerShell:
[System.Environment]::SetEnvironmentVariable("PLANE_API_KEY","your_token","User")
# Use LINEAR_API_KEY instead if you are on Linear.

The variable names are whatever each tracker's apiKeyEnv points at.