# AI Edit Photoshop CEP panel for image generation. It sends text prompts to your own image API, previews the result, and places generated PNGs into the active document as new masked layers. ## Architecture | Layer | File | Role | | --- | --- | --- | | Panel UI | `src/panels/ImageGenerator.jsx` | React + Tailwind, runs in the CEP CEF panel | | Bridge | `src/cep.js` | Node file/network access and `evalScript` calls | | Host | `cep/host/host.jsx` | ExtendScript: masked layer placement, file and prompt dialogs | | Manifest | `cep/CSXS/manifest.xml` | CEP extension declaration | Node runs in the panel (`--enable-nodejs --mixed-context`), so temp files and HTTP both go through Node rather than UXP storage or `fetch`. ## Styling Tailwind CSS 3, compiled by PostCSS into `dist/styles/panel.css`. Utility classes carry the exact pixel values from the original design, so arbitrary values (`h-[47px]`, `bg-[#2f2f2f]`) are used throughout rather than the default scale. - `tailwind.config.js` — accent color, the rounded font stack, and the `narrow` (max 340px) breakpoint - `src/index.css` — Tailwind entry plus base rules for `html`, `body`, and `#root` `src/styles.css` and `src/panels/ImageGenerator.css` are the pre-Tailwind originals. Nothing imports them; they are kept as the reference for the original pixel values. ## Prompt Input The prompt box is a `contentEditable` div. CEF does not reliably receive IME composition events, so the button above 词库 opens a native Photoshop ScriptUI window for typing Chinese. Text crosses `evalScript` as `escape()`-encoded ASCII in both directions. ## API Shape The default request is compatible with OpenAI-style image endpoints: ```json { "model": "gpt-image-2", "prompt": "your prompt", "n": 1, "size": "1024x1024", "response_format": "b64_json" } ``` Accepted response shapes: ```json { "data": [{ "b64_json": "..." }] } ``` ```json { "data": [{ "url": "https://..." }] } ``` `output` and `images` arrays are also tolerated for gateway variants. ## Photoshop Placement Generated images first appear only in the panel's thumbnail list. Clicking a thumbnail places it as an embedded smart-object layer with a new layer mask. The selection that existed when generation started is saved as a temporary alpha channel, so the mask still uses the original selection even if the user changes the selection before clicking. Without a selection, the layer gets a reveal-all mask. When a selection exists, its merged visible pixels are exported as the first reference image. Uploaded reference files follow it. The panel sends these images as data URLs in the request body's `images` array. The request size is read from Photoshop: the full canvas dimensions are used without a selection, and the selection bounds are used when a selection exists. ## Build ```bash npm install npm run build ``` Output goes to `dist`, which is the extension folder itself (`dist/CSXS/manifest.xml`). ## Install ```bash npm run cep:setup ``` This enables `PlayerDebugMode` for CSXS 9–12 and links `dist` into the Adobe extensions folder. On Windows it writes to `HKCU\Software\Adobe\CSXS.*` and creates a directory junction; on macOS it uses `defaults write` and a symlink. Restart Photoshop, then open the panel from `Plugins`. ## Development ```bash npm run watch ``` Reload the panel from its flyout menu, or open `http://localhost:8088` for Chrome DevTools (the port comes from `cep/.debug`).