Skip to content

cwp config set

shipped 1.0.0
cwp config set <key> <value> [flags]

Local only: it acts on no environment.

ArgumentWhat it isDefault
<key>dotted path, e.g. pull.uploads
<value>new value; a comma-separated list for list keys
FlagWhat it doesDefault
--because <text>why this value, recorded beside the line
--until <condition>when the reason is spent: cwp:B-, cwp>=, plugin:>=, stage:, or a date
--with-agentwith —dry-run on a host with no shell: install and remove the PHP agent so the plan is realoff

Plus the shared flags --json, -v, --verbose, -q, --quiet and --dry-run.

What it does

config set writes one key to whichever layer owns it: cwp.yml for project keys, ~/.config/cwp/config.yml for machine keys.

Example

cwp config set pull.uploads sync
cwp config set defaults.uploads sync
cwp config set pull.keep_roles administrator,editor
cwp config set pull.uploads sync --dry-run

The reason goes beside the line

A value without its reason is a riddle in three months, and a reason that no longer holds stays where you wrote it. --because records why, --until records when it is spent, and cwp adds the date and its own name:

cwp config set pull.uploads sync --because "Bricks checks is_file(), B-147" --until cwp:B-147
# because: Bricks checks is_file(), B-147 | until: cwp:B-147 | since: 2026-09-05 | by: cwp config set
uploads: sync

The line above the key is a comment a person reads and cwp parses. A comment you wrote yourself stays above it. Where a grammar line already stands, cwp merges into it: --because alone renews a reason and keeps its until. The command also records a reason on a value that already stands.

--until takes one of five forms:

formspent when
cwp:B-147the running cwp lists the bug as fixed
cwp>=2.1the running cwp is at least that version
plugin:bricks>=2.5inventory.yml names the slug at least at that version
stage:livethe environment reached that stage, or one past it
2026-12-01the date has passed

cwp refuses anything else and names the five forms. cwp status and cwp doctor name every reason that no longer holds:

! pull.uploads — the reason no longer holds: B-147 is fixed in 2.0.0. Change the value, or renew it: cwp config set pull.uploads <value> --because "…"

A reason belongs to the project file. A machine key takes none.

php lands in two files, because the container reads the other one

cwp.yml declares the PHP version, and .ddev/config.yaml is what the container runs. cwp config set php 8.5 writes both and says that the container needs a restart:

✓ php — 8.3 → 8.5 (project)
✓ php_version — 8.3 → 8.5 (.ddev/config.yaml) — run `ddev restart` to pick it up

.ddev/config.yaml keeps everything else it holds. cwp edits around the services, hooks and settings a project adds to it, not through them.

No other key does this. cwp reads every other key from the file it writes it to.

What it does not do

It does not pin defaults into your file. It writes back your file with one key changed, never a serialised copy of the parsed config. Otherwise every schema default would freeze into the file the first time you set anything, and a default cwp later corrects would never reach you.

It changes no value but the one you named, and your comments survive. cwp edits the YAML document in place rather than re-serialising it. Every other key keeps its value, and every comment you wrote is still there afterwards.

Where a comment sits is not guaranteed. An inline comment can end up on its own line. The YAML library can normalise spacing you chose for alignment. So a write to one key sometimes shows up as a diff of a few lines rather than one. You lose nothing and no value moves. The YAML library tidies your formatting; cwp does not edit what you did not ask it to.

It deletes no keys, creates no environments and contacts nothing.