# restore_version

Bring back an old version of one of the shooter's themes or layouts by saving its content as the newest version.

## What it is for

`restore_version` makes an old version of one of the shooter's themes or layouts the newest again. It does this by saving the old version's content as a new version, so history only grows and nothing is deleted ([the family page](appearance.md)). It is the undo for `edit_theme` and `edit_layout`. It does not choose which version to undo, and it does not change what any device shows.

## What to know first

**It works on a theme or a layout: say which in `kind`.** The record is found by `id` (an id, or a name only one record of that kind has). A built-in is answered as if it did not exist; a built-in has no versions to restore.

**Write the version only in `version`.** A number after the name in `id` (`Dusk@3`) is accepted, and `version` is compared with it, not with the newest: equal means nothing is saved and the reply says `is already at v3`, even if the newest is higher. Otherwise `version` is restored.

**The old version's name comes back with it.** The tool does not find which version to undo. `get_theme` or `get_layout` lists the versions with where each was saved and its note; to undo Claude's last change, restore the version before the newest one saved by Claude.

**Restoring the newest version changes nothing,** when `id` has no number: the reply says the record is already at that version and saves nothing.

## Generated table

**Tool:** `restore_version` · **Family:** Appearance · **Scope:** `appearance` · **Save scope:** none · **Changes:** records · **Runs:** no solver work in the connector

**Description** (what the connector sends to an assistant, word for word):

```text
Bring back an old version of one of the shooter's themes or layouts by saving its content as the newest version. To keep an old look as a second theme or layout use create_theme or create_layout. Saves a new version, so history is kept; needs the appearance permission. To undo Claude's last change, read the versions with get_theme or get_layout and restore the one before the newest that Claude saved. Give the number only in version, not after the id. Guide: restore_version.
```

**Inputs** (4; read from the input schema the connector sends):

| Input | Type | Required | Bounds | Field |
|---|---|---|---|---|
| `kind` | `"theme"` or `"layout"` | yes | - | - (selects a record) |
| `id` | text | yes | - | - (selects a record) |
| `version` | integer | yes | >= 1 | - (selects a record) |
| `request` | text | yes | 1 to 300 characters | `note` (theme), `note` (layout) |

**Sent with the inputs** (each input's own description, word for word; an input not listed is sent without one):

```text
kind: Which kind id names
id: The theme or layout id, or its name; no @version
version: The version number to bring back
request: The shooter's request in their own words; stored as the version's note, so "undo that" can find it
```

## When to use it, and when not

| The shooter wants | Use | Why |
|---|---|---|
| The last change, or an older look or layout, back | `restore_version` | Saves the old content as the newest version |
| To know which versions there are and who saved them | [get_theme](get_theme.md) / [get_layout](get_layout.md) | They list every version with its note |
| A new change kept | [edit_theme](edit_theme.md) / [edit_layout](edit_layout.md) | Saves the next version from the newest content |
| An old look kept as a second theme | [create_theme](create_theme.md) | Copies `<id>@<version>` into a new theme |
| A device to show the restored one | [set_active](set_active.md) | A save does not change what a device shows |

Ask which version if the shooter names a time or a change and `get_theme` lists more than one candidate.

## The inputs

**`kind`** is `theme` or `layout`; a name or an id of the other kind is answered as no such record of the kind given.

**`id`** selects the record. A number written after it (`Dusk@1`) is not refused. The tool compares `version` with that number to decide whether to answer `is already at` (equal: nothing saved), and copies the saved version's `based_on` from the version it names (read); the content restored is always the one named by `version`, and the number of the saved version is always the record's newest plus one (run). With `id: Dusk@1` and `version: 1` on a theme at version 4 the reply says it is already at v1 and nothing is saved; with `version: 4` it restores v4 as v5, which has the content of the newest.

**`version`** is the number to bring back. It must be a live version of the record: a deleted one, or one that never existed, is answered as `has no v<N>`.

**`request`** is the shooter's words; the note of the new version is `restored v<N> — ` and then the request.

## What it returns

The spoken line is one of: `Restored '<old name>' to v<N>; saved as v<M>.` (saved), or `'<name>' is already at v<N>; nothing to restore.` (nothing saved). The name is the old version's, so a version with another name renames the record back. A stored name of several words is spoken in quotation marks with the stored-text note (run).

| Key | Holds |
|---|---|
| `theme_id` or `layout_id` | The record's id, whichever `kind` was given |
| `version` | The number of the new version, or the version it is already at |
| `restored` | The version brought back (only when something was saved) |
| `unchanged` | `true` when nothing was saved |

## Worked examples

Every example below was run by the documentation generator against a made-up account, never a real one. Numbers are rounded to three places; generated ids and times are shown as placeholders. Two things are printed more briefly than the tool sent them, and nothing else is changed. A list of plain values stands on one line, whole up to 12 entries (a longer one, and a list of objects past 3, ends with a count of the rest). A reply that puts stored text in quotation marks also carries a note saying so, which an example leaves out and marks instead; no reply below carried it.

## When it refuses

| Refusal | Cause | Tell or ask the person |
|---|---|---|
| `No theme ` or `No layout `, then `id` as given and `. list_appearance shows the themes.` or `. list_appearance shows the layouts.` | No record of that kind matches, two share the name, the id is a built-in, or the version written in `id` is not there | Look at `list_appearance`; use the id |
| `has no v` and the number, after the record's name and an apostrophe | The version was deleted or never existed | Say which versions the record has (`get_theme`) |
| `Nothing saved — ` and the server's reason in quotation marks | The server turned the save down | Say nothing was restored |

The input check turns away a `kind` that is neither word, a `version` that is not a whole number of 1 or more, a request of none or of more than 300, and a missing input; the rule is on [the connector overview](connector.md). An input the tool does not have is dropped, and the reply names it (since 2026-10-15). On a link without the scope `appearance` the tool is not offered (run).

## What it reads and changes

**Reads** the account's themes or layouts (the record and the old version). **Saves** one new version of the same record: the record's newest number plus one, `source` Claude, the note above, and the old version's whole content, name included. Every older version stays. The restored content is saved as it was: the tool does not check it again, so a theme whose picture has since left the account is restored with that picture (run). It makes no record, sends no command to a device and changes what no device shows. A device using the record picks up the new version through sync (read).

## Below this page

- [get_theme](get_theme.md) and [get_layout](get_layout.md): the versions to choose from.
- [the connector overview](connector.md), [the family page](appearance.md)

## Worked examples

**1. An earlier version, whose name comes back with it**

Starting point: one theme whose stored versions are 1 (named Dawn, saved in the app), 2 (deleted), 3 (named Dusk, saved by Claude with the note larger text) and 4 (named Dusk, saved in the app); one layout at versions 1 and 2, the second with a title on its first section; and one phone. Link scopes: `read`, `appearance`.

Call:
```json
{"kind":"theme","id":"Dusk","version":1,"request":"back to the first"}
```

Spoken line:
```text
Restored 'Dawn' to v1; saved as v5.
```

Details:
```json
{
 "theme_id": "fixture-theme",
 "version": 5,
 "restored": 1
}
```

Saved the theme at version 5, changed: `base_size_px`, `name`, `note`, `source`.

**2. An earlier version of a layout**

Starting point: one theme whose stored versions are 1 (named Dawn, saved in the app), 2 (deleted), 3 (named Dusk, saved by Claude with the note larger text) and 4 (named Dusk, saved in the app); one layout at versions 1 and 2, the second with a title on its first section; and one phone. Link scopes: `read`, `appearance`.

Call:
```json
{"kind":"layout","id":"Bench","version":1,"request":"back to the first"}
```

Spoken line:
```text
Restored 'Bench' to v1; saved as v3.
```

Details:
```json
{
 "layout_id": "fixture-layout",
 "version": 3,
 "restored": 1
}
```

Saved the layout at version 3, changed: `note`, `sections[]`.

**3. A deleted version, a version past the newest, and the newest**

Starting point: one theme whose stored versions are 1 (named Dawn, saved in the app), 2 (deleted), 3 (named Dusk, saved by Claude with the note larger text) and 4 (named Dusk, saved in the app); one layout at versions 1 and 2, the second with a title on its first section; and one phone. Link scopes: `read`, `appearance`.

Call 1:
```json
{"kind":"theme","id":"Dusk","version":2,"request":"older look"}
```

The tool refuses:
```text
'Dusk' has no v2.
```

Call 2:
```json
{"kind":"theme","id":"Dusk","version":5,"request":"older look"}
```

The tool refuses:
```text
'Dusk' has no v5.
```

Call 3:
```json
{"kind":"theme","id":"Dusk","version":4,"request":"older look"}
```

Spoken line:
```text
'Dusk' is already at v4; nothing to restore.
```

Details:
```json
{
 "theme_id": "fixture-theme",
 "version": 4,
 "unchanged": true
}
```

Saved nothing.

**4. A version written in the id**

Starting point: one theme whose stored versions are 1 (named Dawn, saved in the app), 2 (deleted), 3 (named Dusk, saved by Claude with the note larger text) and 4 (named Dusk, saved in the app); one layout at versions 1 and 2, the second with a title on its first section; and one phone. Link scopes: `read`, `appearance`.

Call 1:
```json
{"kind":"theme","id":"Dusk@1","version":1,"request":"older look"}
```

Spoken line:
```text
'Dawn' is already at v1; nothing to restore.
```

Details:
```json
{
 "theme_id": "fixture-theme",
 "version": 1,
 "unchanged": true
}
```

Saved nothing.

Call 2:
```json
{"kind":"theme","id":"Dusk@1","version":4,"request":"older look"}
```

Spoken line:
```text
Restored 'Dusk' to v4; saved as v5.
```

Details:
```json
{
 "theme_id": "fixture-theme",
 "version": 5,
 "restored": 4
}
```

Saved the theme at version 5, changed: `note`, `source`.

**5. A built-in theme, and a name that is a layout's**

Starting point: one theme whose stored versions are 1 (named Dawn, saved in the app), 2 (deleted), 3 (named Dusk, saved by Claude with the note larger text) and 4 (named Dusk, saved in the app); one layout at versions 1 and 2, the second with a title on its first section; and one phone. Link scopes: `read`, `appearance`.

Call 1:
```json
{"kind":"theme","id":"builtin:dark","version":1,"request":"older look"}
```

The tool refuses:
```text
No theme builtin:dark. list_appearance shows the themes.
```

Call 2:
```json
{"kind":"layout","id":"Dusk","version":1,"request":"older look"}
```

The tool refuses:
```text
No layout Dusk. list_appearance shows the layouts.
```

---

[All reference pages](index.md)
