# Agent Sync

Agent Sync mirrors the records of some SleekWP products into JSON files in the
active theme. The files stay in step with their WordPress records, so they can
be reviewed, versioned, deployed or edited by a coding agent. It works the
same in the suite and in a standalone plugin.

## Which products support it

| Product    | Directory      | Records                                |
| ---------- | -------------- | -------------------------------------- |
| SleekAI    | `sleek/ai/`    | `chatbots/`, `agents/`, `agent-modes/` |
| SleekPixel | `sleek/pixel/` | `images/`                              |
| SleekRank  | `sleek/rank/`  | `page-groups/`                         |
| SleekView  | `sleek/view/`  | `views/`, `pages/` (Admin Pages)       |

The other products do not sync records to files.

## Turning it on

Agent Sync is opt-in for each product. Create the product's directory inside a
`sleek` directory of the active theme, for example for SleekAI:

```text
wp-content/themes/your-theme/sleek/ai/
```

A `sleek` directory on its own enables nothing: a product syncs only while its
own directory exists. With a child theme, the directory belongs in the child
theme. Removing the directory stops the sync and leaves the records in place.

On the next WordPress request, which can be any page, admin screen, REST call
or WP-CLI command, the product writes its existing records into the
directory:

```text
sleek/
├── ai/
│   ├── chatbots/
│   │   ├── AGENTS.md
│   │   └── support-bot.json
│   ├── agents/
│   └── agent-modes/
├── pixel/
│   └── images/
├── rank/
│   └── page-groups/
└── view/
    ├── pages/
    └── views/
```

Each record is a file named after its slug, such as `support-bot.json`. A
record without a slug is named after its title, or `item-<ID>.json` without
either.

## AGENTS.md

Every record directory also gets an `AGENTS.md`, which tells a coding agent
what the records are and how to edit them, followed by the JSON schema of the
record's `data`. The product writes it from its own instructions and schema
and rewrites it when they change with an update, so do not edit it by hand.

## JSON format

Every file holds sync metadata, WordPress post fields and the product's data:

```json
{
  "sync": {
    "key": "7f7cc7d8-2f7e-4f6c-bd66-5f80a7c9fef4",
    "updatedAt": "2026-07-19T08:15:00.000Z",
    "version": 1
  },
  "post": {
    "title": "City Pages",
    "status": "publish"
  },
  "data": {
    "basePageId": 123,
    "urlPattern": "services/{slug}"
  }
}
```

- `sync.key` ties the file to its record, so the record keeps its identity
  when the file is renamed; the record's slug then follows the file name.
- `sync.updatedAt` is a UTC timestamp with milliseconds and decides which side
  is newer.
- `post` holds the title and the status. A missing title is made from the file
  name, and an unknown status becomes `draft`.
- `data` holds the product's configuration of that record.

A file that lacks part of this shape, such as the `sync` block, is imported
and then rewritten in full.

## How changes travel

**From the site to the files.** Saving a record, in the workspace or anywhere
else, rewrites its file at the end of that request with a new `updatedAt`.

**From the files to the site.** Early in every request the product checks
whether any of its files changed since it last looked, by name and
modification time. A changed file is imported when its `sync.updatedAt` is
**later** than the record's. When the record is newer, the record wins and the
file is rewritten from it; when both are the same, nothing is imported.

So a file edit takes effect only together with a new `updatedAt`: set it to
the current time when you or an agent change a file, or remove `updatedAt`,
which imports the file as of now. A new file with a slug the site does not
have yet creates a new record.

Developers can edit and deploy files while editors keep working in the admin;
whichever side changed last wins.

## Deletion safeguards

Agent Sync is careful with destructive changes:

- A missing file does not delete its record. The record is written out again.
- A file whose `data` is empty does not overwrite the record. The file is
  rewritten from the record.
- Moving a record to the trash keeps its file, renamed to
  `<slug>__trashed.json` with the status `trash`. Restoring the record writes
  `<slug>.json` again.
- Deleting a record permanently deletes its file. If the file is still in
  version control, deploying it again recreates the record, so delete it from
  the repository too.

These rules keep a temporary branch, an incomplete agent edit or a missing
file from silently erasing valid configuration.

## Recommended workflow

1. Create `sleek/<product>/` in the active theme for each product to sync.
2. Load the site once, or run any WP-CLI command, to write the existing
   records.
3. Commit the files with the theme.
4. Let a coding agent edit the files; `AGENTS.md` tells it how.
5. Review the diff and deploy it. The next request on the site imports every
   file whose `updatedAt` moved forward.

SleekAI also has WP-CLI commands that run the import right away and write the
exports its own WP-CLI process has queued; its [WP-CLI page](/docs/ai/cli.md)
lists them.
