# Images

Images is a neutral, English App Coder App for creating and editing images with prompts, optional reference images, and user-managed templates.

## Runtime modes

- In Homepage `full` and `inline` embeds, the App sends a named request to `/api/images`. Homepage resolves credential id `openai-image` server-side. The raw key never enters the App. The handshake publishes the non-sensitive `api:images` capability in `homepage/app/config`; its `available` and `state` values drive inline guidance and disable generation while the credential is missing.
- In direct standalone mode, the App asks the user for an OpenAI key in its own Preferences and stores that key in the App's Local Storage. No key is shipped in this package.
- `file://` use is a local diagnostic mode. It can render and inspect the App, but hosted API calls require a same-origin server.

Embedded presentation follows the host surface rather than introducing another chrome layer:

- `full` mode fills the available surface edge to edge and adds only internal safe-area padding.
- `inline` mode fills its inline surface with no App-level outer padding; the surrounding Homepage surface owns that spacing.
- Embedded panels are flat and transparent, with generous spacing and subtle separators. Homepage theme variables supplied through the bridge control the App background, surfaces, text, borders, and controls.

## Storage ownership

The App owns its data in versioned Local Storage records:

- `app.images.history.v1`
- `app.images.references.v1`
- `app.images.templates.v1`
- `app.images.selected-template.v1`
- `app.images.preferences.v1`
- `app.images.metadata.v1`
- `app.images.openai-key.v1`
- `app.images.field-history.v1`
- `app.images.prompt.v1`

The session-only template values key is `app.images.template-values.v1`. Template field editing is controlled by `fieldsPreferences` in `config.js`. When it is `false`, the app exposes the selected template's saved field values below the Description. When it is `true`, the same fields are contributed to Homepage Preferences and are available in the standalone Preferences panel.

Template definitions use ordered field objects with `key`, `value`, `description`, and `order`. Older key/value pairs are migrated to the order users currently see, with empty descriptions. Template imports accept both pair arrays and field objects; exports use field objects. See [Template field metadata and order](requirements/Template-field-metadata.md).

On first open, Images migrates these Local Storage keys:

| Previous key | New key |
|---|---|
| `app.image-generator.history.v1` | `app.images.history.v1` |
| `app.image-generator.references.v1` | `app.images.references.v1` |
| `app.image-generator.templates.v1` | `app.images.templates.v1` |
| `app.image-generator.selected-template.v1` | `app.images.selected-template.v1` |
| `app.image-generator.preferences.v1` | `app.images.preferences.v1` |
| `app.image-generator.metadata.v1` | `app.images.metadata.v1` |
| `app.image-generator.openai-key.v1` | `app.images.openai-key.v1` |
| `app.image-generator.field-history.v1` | `app.images.field-history.v1` |
| `app.image-generator.prompt.v1` | `app.images.prompt.v1` |

It also migrates the session-only key `app.image-generator.template-values.v1` to `app.images.template-values.v1`. For each key, Images copies the stored string, verifies the destination matches, and only then removes the old key. If the destination already contains different data, both copies are left untouched for manual reconciliation. If a read, write, verification, or removal fails, Images keeps the source whenever possible and retries on the next open; a verified destination is retained even if removing the old key fails.

History entries include compressed image data, prompt, options, favorites, and a complete template snapshot. Reference images are stored separately and referenced by ID so a history item can restore the builder without changing the current template catalog.

Homepage may consume only the declared history extension after the host implements it. The App remains the canonical owner and publishes revision-only history change notifications. The host may read history, preview/download, copy prompts, favorite, delete, and clear through the reviewed adapter.

## Host-side work still required

Homepage must provide the named image route, credential resolution, and the App-specific history adapter. The App Coder package does not edit Homepage files.

The request is `POST /api/images` with `operation: "generate" | "edit"`, prompt, optional `sourceImage`, optional ordered `referenceImages`, and a provider-shaped `options` object containing `model`, `output_format`, `size`, `quality`, and `background`. The App resolves the selected model policy and always sends the selected file format as `options.output_format`. The normalized response should use Homepage's `{ ok, data, error }` envelope and return one base64 image.

The declared App-specific bridge messages are:

- `homepage/app/config` — host to App, with the instance-scoped capability snapshot. The Images capability is `api:images`, backed by resource `images` and credential `openai-image`.
- `homepage/app/preferences-request` — App to host. App-owned generation settings use `sectionId: "output"`; when `fieldsPreferences` is enabled, the Fields button requests `sectionId: "images-fields"`; the credential setup action uses only `capabilityId: "api:images"` so Homepage resolves the global APIs target.
- `homepage/app/images-preferences-sync` — App to host after template selection, carrying the selected template's Output values while preserving the File format currently selected in Output preferences. This message is not sent for ordinary manual preference changes.

When JPEG is the selected file format, template and history settings that request a transparent background are normalized to opaque so the selected format remains valid.
- `homepage/app/toast-action` — host to App. The App accepts only the `open-api-preferences` action for issue `openai-image-credential` and the active instance.
- `homepage/app/images/history-changed` — App to host, with schema version and revision only.
- `homepage/app/images/history-command` — host to App with `refresh`, `select`, or `open`.

Template export and import use the `images-template-bundle` kind and the `images` app slug. Older `image-generator` bundles are not accepted.

Homepage owns the initial missing-capability Toast and its issue lifecycle. The App does not emit a duplicate initial Toast. The App may still report provider or route failures through `homepage/app/api-status`.

The host must validate the exact slug, instance ID, same-origin source, declared capability/resource allowlist, and declared Local Storage schema before using the extension. Capability availability means that the named credential is configured; provider validity and runtime availability remain API-status concerns.
