Config config

Per-user default values for command options, stored in a local SQLite database
Pixelbadger Toolkit — pbtk config — ← all topics

Overview

The config topic sets, shows and removes per-user default values for command options. Set a default once at a topic, group or action level and every command at or below that level uses it unless you pass the option on the command line.

$ pbtk config <topic> [<group>…] [<action>] [--option value …]

The command tree of config mirrors every other topic, group and action. An option that a command accepts is configurable under the same path and with the same name, except the options listed in What can't be configured. The topic, group and action words select the level you are configuring.

Defaults are per user. They apply to every pbtk invocation that runs as the same user.

Usage

Set a topic-wide default

This sets --model for every llm action that has a --model option:

$ pbtk config llm --model claude-sonnet-5-5
Set llm --model = claude-sonnet-5-5

Override it for one action

A default set on an action wins over the default set on its topic, so chat uses gpt-6-luna while the other llm actions keep claude-sonnet-5-5:

$ pbtk config llm chat --model gpt-6-luna
Set llm chat --model = gpt-6-luna

Show the effective values

Run a level with no options to list the values it resolves to. Each line names the level the value comes from.

$ pbtk config llm chat
--model = gpt-6-luna (from: llm chat)
$ pbtk config llm
--model = claude-sonnet-5-5 (from: llm)

A level with nothing configured prints No configured defaults for <level>.

Remove a default

--unset removes the value stored at that level only. The levels above it are not affected. It is repeatable, and the leading dashes on the name are optional:

$ pbtk config llm chat --unset model
Unset llm chat --model

After that, pbtk config llm chat falls back to the topic-level value:

--model = claude-sonnet-5-5 (from: llm)

Removing a name that is not set at that level prints llm chat --model was not set and exits 0. A name that is not configurable at that level is an error (see What can't be configured).

Help shows the configured defaults

Once a default is set, the action's --help shows it as [default: …], so you can see the value the command will use before running it:

$ pbtk llm chat --help
Description:
  Chat with an LLM maintaining conversation history

Usage:
  Pixelbadger.Toolkit llm chat [options]

Options:
  --message <message> (REQUIRED)         The message to send to the LLM
  --session-id <session-id>              Session ID to continue a previous conversation (omit to start a new session)
  --model <model>                        The model to use (defaults to the provider's default model) [default: gpt-6-luna]
  --provider <claude|openai>             The LLM provider to use (supported: openai, claude) [default: openai]
  --reasoning-effort <reasoning-effort>  Reasoning effort level (supported values depend on --provider)
  -?, -h, --help                         Show help and usage information

Validation

Values are parsed and checked by the same option definitions the real command uses. For example, --provider accepts only openai and claude:

$ pbtk config llm chat --provider nope
Error: Argument 'nope' not recognized. Must be one of:
	'openai'
	'claude'

On an error, the command exits with status 1 and nothing is written. When one command sets several values and one of them is invalid, none of them are stored.

Provider-dependent values are checked late. --reasoning-effort accepts any token when you run config, because its allowed values depend on --provider, which config does not see. The value is stored, and the error appears when a command that uses it runs. For example, after pbtk config llm --reasoning-effort ultra:
$ pbtk llm chat --message hi
Error: Invalid reasoning effort 'ultra' for provider 'openai'. Supported values:
low, medium, high

Precedence

For each option, the value that is used is the first one found in this order:

  1. The value given on the command line.
  2. The default configured at the action level (for example llm chat).
  3. The default configured at the group level (for example oauth profile).
  4. The default configured at the topic level (for example llm).
  5. The built-in default of the option.

Each level is checked only at that level's own path. For example, a default set on oauth applies to oauth profile add unless the group or the action sets its own value.

Here is a worked example with a real server. The built-in --port default of web serve-html is 8080:

$ pbtk config web --port 9000
$ pbtk config web serve-html --port 9100
$ pbtk web serve-html --help
  --port <port>             Port to bind the server to [default: 9100]

With --port 9100 stored on the action, starting the server without --port binds 9100. Passing --port 9200 on the command line binds 9200 instead. Unsetting the action value makes the topic value, 9000, apply again.

What can't be configured

These cannot be set through config. Passing one to config fails as an unknown argument:

A stored entry for a required option is not used. Commands report it as an unknown entry and ignore it. See Storage.

Storage

Defaults live in a SQLite database. Its location is:

The database has one table per topic, named after the topic. Each row holds the action path (empty for the topic level, otherwise words such as chat or profile add), the option name, and the value. A topic only reads and writes its own table.

The database is created on the first set. A missing database is treated as having no defaults.

Bad config

If the database cannot be read, every command that reads defaults fails with:

Error: config database <path> is unreadable: <reason>

A stored value that no longer validates fails only the actions that use it, and only when the option falls back to that default. Passing the option on the command line avoids the stored value. For example:

Configured default for web serve-html --port is invalid: Cannot parse argument 'abc' for option '--port' as expected type 'System.Int32'.

An entry that does not match a configurable option at its level is ignored. Each command of that topic prints a warning to stderr for it. The row stays in the database until you unset it:

Warning: ignoring unknown config entry web nope --port

Command Reference

Command Required options Optional options Output
config <level> --<option> <value> None Any configurable option of the level, repeatable Set <level> --<option> = <value>
config <level> None None Effective values with (from: <level>), or No configured defaults for <level>
config <level> --unset <option> None --unset (repeatable, dashes optional) Unset <level> --<option> or <level> --<option> was not set