# Edit theme files: change sets, backups and undo

By the end of this page you know how an agent edits the active theme’s files, what is recorded for every write, and how to take a change back.

These tools are in the **Theme files** group. It starts off, and it needs the `edit_theme_options` and `edit_themes` capabilities.

## What the tools can touch

- Only the active theme’s folder. With a child theme active, that is the child theme.
- Only `.html`, `.css`, `.js` and `.scss` files, and `theme.json` at the theme root. PHP files, images and fonts are out of reach.
- Paths are relative to the theme, such as `templates/front-page.html`. A path cannot start with a slash or a dot, or contain `..`. A symlink is never followed for a write.

`btm.theme-list-files` lists the theme and marks each file `editable` or not.

## Every update needs the hash of what was read

`btm.theme-read-file` returns the file’s contents and a `hash` of the bytes on disk. To change the file, the agent sends the complete new contents and that hash as `expectedHash`.

If the file changed in between, because you edited it or another agent did, the write is refused with a 409:

```
The file has changed since it was read: expectedHash does not match the current contents. Read it again and retry with the new hash.
```

Nothing is overwritten blindly. The agent reads again and decides what to do with the newer version.

## One file or many

- `btm.theme-create-file` adds a new file. It fails if anything already exists at that path.
- `btm.theme-update-file` replaces one existing file.
- `btm.theme-apply-changes` creates or replaces many files in one call. Every item is checked first. If one fails, nothing is written. If a write fails part-way, the files already written are put back.
- `btm.theme-delete-file` removes a file after backing it up. Root `style.css`, `theme.json` and `templates/index.html` cannot be deleted, because the theme needs them.

One call can touch at most 100 files and 5 MB of contents, and a single file at most 2 MB.

## Change sets

Every write is recorded as a change set, whether it touched one file or fifty. The result of each write carries a `changeSetId`.

`btm.theme-list-change-sets` lists them, newest first. Each has a status:

- `applied`: every file was written.
- `rolled_back`: a write failed and everything was undone. There is nothing to revert.
- `partial`: a write failed and some files could not be put back.
- `applying`: the write was interrupted, for example because the PHP process stopped.

An agent can pass a `label` to `btm.theme-apply-changes`, such as “Rename hero classes”, so the set is easy to find later.

The records are kept in `wp-content/block-theme-mcp/changesets/`, one folder per theme. The newest 50 per theme are kept.

## Backups

Before a file is replaced or deleted, the old version is copied to `wp-content/block-theme-mcp/backups/`, outside the theme. The newest 10 backups per file are kept, plus any backup a kept change set still needs.

`btm.theme-list-backups` lists the backups of one file. `btm.theme-restore-file` puts one back, the newest by default. It can also bring back a deleted file.

Backups of a file that no longer exists in the theme are removed 30 days after they were taken, unless a kept change set still needs them.

## Undo

`btm.theme-revert-change-set` undoes a whole change set as one unit. Updated files go back to their earlier contents, created files are removed, and deleted files come back. The revert is itself recorded as a new change set, so it can be undone too.

A revert only goes ahead if every file is still exactly as the change set left it. If a file was edited since, nothing is written and the agent gets the list of conflicts:

```
One or more files changed after this change set, so nothing was reverted. See conflicts; revert again with force to overwrite them.
```

Passing `force: true` overwrites those later edits. A careful agent reads the conflicting files and asks you first.

You can also undo a change set yourself, without an agent: the **Activity** tab lists the theme’s change sets with a **Revert** button. See [Activity: see what an agent did and revert it](https://w4dev.com/docs/block-theme-mcp/activity-log-and-revert/).

## When a template edit does not show on the site

A template saved in the Site Editor is stored in the database and takes precedence over the theme file of the same name. An agent can edit `templates/single.html` correctly and the site still shows the saved version.

The tools report this. `btm.theme-read-file` returns `templateOverride` for files in `templates/` and `parts/`, and `btm.theme-apply-changes` returns `templateOverrides` for the files it wrote. The edit becomes visible once the saved version is reset. See [Site Editor templates](https://w4dev.com/docs/block-theme-mcp/site-editor-templates/).

## Search before you change

`btm.theme-search` finds text or a regular expression across the theme, in file and line order. It also searches `.php` and `.json` files and marks those matches `editable: false`. With `wholeWord: true` a hyphen counts as part of a word, so a search for `hero-title` does not match `hero-title-large`. Folders named `node_modules`, `vendor`, `vendor-dev` and `bower_components` are skipped.

## Good to know

- Two writes to the same theme at the same time do not race. The second gets a 409, “Another change to this theme is in progress. Try again in a moment.”
- A theme update from its author replaces the theme’s files, including files an agent edited. Edit a theme you own, or a child theme.
- Backups and change sets stay on disk when the plugin is uninstalled. Delete `wp-content/block-theme-mcp/` by hand when you no longer want them.

Source: https://w4dev.com/docs/block-theme-mcp/theme-files-change-sets-backups-undo/
