# Theme Export

Theme export is the compile-to-deliverable step. Everything before it happens inside Divine: you build in worktrees, preview, review, and deploy into the app theme. Export takes that finished theme and packages it as a single self-contained zip a client can install on their own WordPress, with no Divine plugin anywhere on the destination site.

## Why A Self-Contained Bundle

The whole point of export is to break the dependency on Divine. While you build, Divine supplies Blockstudio conventions, media helpers, Tailwind class composition, and performance behavior. If the exported theme relied on those services still being present, a client could only run it on a machine that also ran Divine, which defeats the purpose of handing over a normal WordPress theme.

So export bundles the runtime into the theme itself. The zip contains the theme files plus a copy of the Divine runtime, and a small marker in `functions.php` loads that runtime when the theme boots. The result installs and activates like any other WordPress theme. The runtime travels with it.

## Running An Export

The plainest path is the `dv` CLI, which works against theme files directly:

```bash
dv export [theme-path] [--output <dir-or-file>] [--worktree <id>] [--json]
```

The path argument defaults to the current directory, so `dv export .` from a theme exports that theme. `--output` chooses where the zip lands: pass a directory to drop the generated filename there, or a `.zip` path to write a specific file. `--worktree <id>` exports a sibling or registered worktree of the resolved app instead of the app theme itself. `--json` prints a compact machine-readable result instead of just the path:

```json
{
  "path": "/abs/path/to/theme-20260625-120000-abcd123456.zip",
  "sha256": "…",
  "size": 1048576
}
```

This CLI path is file-based. It does not need a running WordPress site, an app registration, or admin access; it operates on the theme directory you point it at. The same export is also available over the admin and REST surface for an app or a worktree, which returns the theme slug, artifact filename, download URL, file size, and SHA-256 checksum, and writes the zip under `wp-content/uploads/divine-exports/` behind a deny-all guard. Both paths build the same self-contained bundle.

## What The Bundle Contains

An exported zip is a complete, installable theme.

| Item | Purpose |
| --- | --- |
| Theme files | Every normal theme file: templates, `pages/`, `blocks/`, `patterns/`, assets, PHP, `style.css`, and `divine.json`. |
| `divine-runtime/` | The bundled standalone runtime, including the scoped Blockstudio build and runtime frontend assets for preloading and media. |
| `functions.php` marker | A small wrapped block that loads the bundled runtime when the theme boots. |
| `divine-runtime/provenance.json` | Records the Divine version, bundled Blockstudio version, scoped namespace, and a generation timestamp. |
| `divine-runtime/THIRD-PARTY.md` | Records the bundled component licenses. |

The marker injected into `functions.php` is wrapped in comments and only loads the runtime when the bundled file is present:

```php
/* BEGIN Divine standalone runtime */
if ( file_exists( __DIR__ . '/divine-runtime/src/Runtime/theme-bootstrap.php' ) ) {
	require_once __DIR__ . '/divine-runtime/src/Runtime/theme-bootstrap.php';
}
/* END Divine standalone runtime */
```

Injection is idempotent. Re-exporting a theme that already carries the marker does not add a second copy.

## What The Bundle Excludes

Export ships a theme, not a development checkout, so it leaves behind everything that belongs to building rather than running.

| Excluded | Why |
| --- | --- |
| Harness admin code | The exported theme has no admin app, workspace REST routes, or worktree machinery. |
| `.git` and git state | The deliverable is files, not a repository. |
| `node_modules` | Build-time dependencies are not runtime dependencies. |
| `tests/` and `fixtures/` | Test inputs are not part of a shipped theme. |
| `.cache`, `.turbo`, `.DS_Store` | Development caches and OS cruft are dropped. |
| The `.divine` directory and prior `divine-runtime/` copies | Workspace state and stale runtime copies are excluded so the fresh runtime is the only one bundled. |

## The Deployment Model

The exported theme runs on the client's WordPress with no Divine plugin installed. The bundled `divine-runtime/` boots from the theme's own `functions.php`, so Blockstudio conventions, media helpers, Tailwind composition, and `divine.json` performance behavior all keep working from inside the theme. Divine is the build and authoring environment; the finished theme is a self-contained artifact that no longer depends on it.

The provenance manifest inside each zip records what was bundled: Divine is AGPL-3.0-or-later, the scoped Blockstudio build is GPL-2.0-or-later under the `Divine\Lib` namespace, and `THIRD-PARTY.md` carries the matching license notice. That record travels with the deliverable so the client always knows what is inside it.

## Requirements

Export needs the PHP `zip` extension. The admin and REST path also needs a writable uploads directory, where it writes the artifact and a deny-all guard. Source checkouts must have the scoped runtime libraries built before export; packaged plugin builds already ship those files in place. If the runtime is missing a required file, export fails with a message naming what to build rather than producing an incomplete zip.

## Installing An Exported Theme

Install the generated zip through Appearance, Themes, Add New, or unzip it into `wp-content/themes/` by hand, then activate it like any other theme. The bundled runtime boots from the theme's `functions.php` on the first request. Nothing about installation is Divine-specific, and the destination site never needs the Divine plugin.
