Skip to content
DocsSettings

Settings

Where settings.toml lives, per-key precedence, captain init, and how bad values are handled.

Captain Barbossa reads optional settings from .captain/settings.toml. There is no required configuration: with no file anywhere, every setting falls back to the built-in default and nothing warns about it.

Where the files live#

Settings file locations
FileScope
<project>/.captain/settings.tomlThis project only. Commit it to share the settings with the repo, or ignore it to keep them yours.
~/.captain/settings.tomlEvery project on this machine.
captain_barbossa/defaults.tomlThe shipped defaults, inside the installed package. The bottom layer, not meant to be edited.

defaults.toml is the single source of the shipped defaults: the tier table the code resolves against is read from it, and captain init writes it back out with the values commented, so the defaults, the code, and the template cannot drift apart.

The project root is the one the rest of the CLI uses: $CAPTAIN_PROJECT when a captain set it, otherwise the enclosing git repository, otherwise the current directory.

Precedence#

Settings resolve per key, not per file or per table:

text
project key  >  global key  >  defaults.toml

A file that sets one key overrides only that key. Everything it leaves out keeps falling back. So these two files:

~/.captain/settings.toml
[captain]
model = "strong"

[models.claude]
cheap = "sonnet"
<project>/.captain/settings.toml
[models.claude]
cheap = "fable"

resolve to [captain] model = "strong" (only the global file sets it), [models.claude] cheap = "claude-fable-5-1" (the project file wins), and mid/strong still on their built-in defaults (neither file mentions them). CLI flags still win over settings for one invocation.

captain init#

shell
captain init            # writes <project>/.captain/settings.toml
captain init --global   # writes ~/.captain/settings.toml

init writes a template with every setting commented out at its current default, so a freshly written file changes nothing until you uncomment a line. It creates the .captain directory if needed and prints the path it wrote. --global is the only flag, and init needs no Herdr pane, so it works from any shell.

What can be configured#

Setting tables
TableCovers
[captain]The captain's CLI and optional starting model.
[crew]The default crew model and wait timeout.
[dashboard]Automatic launch, refresh interval, pane ratio, context limit, and price-file override. See dashboard.
[placement]The captain-tab and crew-tab shapes. See placement.
[models.<provider>]The model behind each provider-neutral tier. See models.
  • An empty [captain] model passes no model flag, leaving the choice to the native CLI.
  • pi has no fixed catalogue: its tiers are ranked from pi --list-models, and overrides use the provider/model IDs pi prints.
  • Dashboard prices_file expands ~. Changing interval needs no captain restart, because the dashboard reads it in its own process.

The commented list of every shipped key and default is exactly what captain init writes, so the authoritative reference is the file on your own disk.

Unknown and invalid values#

How bad values are handled
SituationWhat happens
A tier value in [models.<provider>] matching no known modelKept literally and passed to that CLI as written, so a model newer than this release still works.
[captain] model matching no known modelThe launch fails, naming the options: No claude model matches 'gigantic'. Tiers: cheap, mid, strong.
[captain] agent outside claude, codex, pi, grokThe launch fails naming them, rather than trying to run it.
A value of the wrong type (model = 123, enabled = "true")Ignored, falling back to the shipped default. Nothing is coerced across types. The one latitude is an int where a float is wanted, so interval = 5 works.
A malformed [placement] shapeThe one exception: it fails loudly. See placement validation.
An unknown table or keyIgnored.

The difference between the first two rows is deliberate. A [models.*] tier is a pass-through to the CLI, while [captain] model is resolved up front, so a typo fails loudly at launch instead of silently starting the wrong model.

Malformed files#

A file that is not valid TOML is an error naming the file, and no command runs with half-read settings:

text
captain: Could not read settings from /path/to/.captain/settings.toml: Expected ']'
at the end of a table declaration (at line 1, column 9)

An unreadable file — permissions, or a directory in its place — reports the same way. A file that simply does not exist is not an error: that is the normal case.