# Optional local artwork helper

The portable plugin bundles the reviewed helper source at `scripts/artwork-prep/` inside this skill. It includes `artwork-prep.mjs`, `artwork-prep.test.mjs`, `package.json` and its pinned `package-lock.json`; it does not include installed dependencies or binaries. Node **20.9.0 or newer** is required by the pinned Sharp dependency. Read the source and dependency manifest before running it. Checksums establish matching package bytes, not a security audit of downloaded native binaries.

Get the owner's explicit consent before installing dependencies with `npm ci` and before executing this downloaded helper. Explain the selected local directory, npm network access and the native sharp dependency; combine these into one permission request when both are missing. Installation of the instructions alone authorizes neither `npm ci` nor helper execution. Reuse valid consent for this version and job instead of asking before every inspect/prepare/pack command. Use the owner's existing compatible Node installation; installing or upgrading Node requires separate permission. Do not run lifecycle scripts, install global tools or grant broader filesystem access as an implied part of reading the skill. If the runtime cannot install native dependencies safely, use an existing trusted local application or request a source export.

After consent, in the installed skill's `scripts/artwork-prep` directory:

```sh
npm ci --workspaces=false --ignore-scripts
npm test --workspaces=false
node artwork-prep.mjs inspect --input original.png --width-in 2 --height-in 3
node artwork-prep.mjs prepare --input original.png --output ready.png --width-in 2 --height-in 3 --target agent-api > ready.receipt.json
node artwork-prep.mjs pack --input ready.png --output sheet.png --width-in 2 --height-in 3 --copies 3 --sheet-width-in 12 --sheet-height-in 22 --margin-in 0.5 --gap-in 0.25 > sheet.receipt.json
```

Paths are examples; select owner-approved input/output locations. Preserve originals and use new output paths. Read current shop sheet dimensions and spacing before packing. `--copies` is the total copies, including the original; printed sheet quantity remains a separate order choice.

The command prints one JSON receipt to stdout; it does **not** create a receipt file unless you redirect or save that output. Use new receipt paths too: shell redirection can overwrite an existing receipt. Check the exit status and `ok` before treating a receipt as successful. `npm test` runs bundled synthetic fixtures in temporary directories and performs no uploads; it is optional after installation and useful when validating an update, not required on every order.

The CLI supervises processing in a child process with a 120-second wall-clock timeout and bounded response size. A timeout stops that child and reports `PROCESSING_TIMEOUT`; no success is confirmed. Inspect any partially written output and select a new path before retrying. Direct module consumers must use `runBounded` or their own process isolation; `run` alone does not supply a wall-clock boundary. File/pixel limits remain enforced in both interfaces.

### Attachment location and transfer

Use a returned `workspace_path` directly when it exists; only use `download_url` when it is non-null and the provider documents that route. Check the actual execution host and transfer capability before installing dependencies or asking the owner to resend a file. Do not assume an environment alias proves which computer it is. Hash identical reattachments: a changed filename does not add resolution.

If Windows Library materialization fails because required provenance/extended-attribute handling is unsupported (for example `os.setxattr` is absent), stop that transfer and report a provider compatibility failure. The shop workspace does not fix this provider bug. Input must materialize through a supported provider route preserving required metadata, or the owner must explicitly download/select the actual file through a supported file picker. Verify the actual bytes against the original SHA-256 before processing or uploading. Do not use sidecars, skip metadata, private endpoints or guessed download routes as workarounds. Cloud preparation permission applies to the specific approved job and processing location; reuse valid permission within that scope, never treat it as universal. Without supported transfer and verified bytes, local preparation remains unverified.

The helper byte-detects single-page PNG, JPEG, TIFF and WebP. Preparation writes oriented sRGB PNG at 300 PPI and refuses distorted dimensions, blank or opaque artwork. It automatically downsamples excess pixels with Lanczos3; the older `--allow-downsample` flag remains accepted but is unnecessary. For conventional cubic enlargement up to 2× per axis, select `--allow-upscale` under the existing preparation authorization and the [resizing rules](artwork.md). More than 2× is rejected with `UPSCALE_LIMIT`, even with that flag. Without the flag, enlargement returns `LOW_PPI`. The flag enables a local operation; it does not approve the artwork or place an order.

For a 600 × 600 source requested at 3 × 3 inches:

```sh
node artwork-prep.mjs prepare --input original.png --output enlarged.png --width-in 3 --height-in 3 --allow-upscale --target agent-api > enlarged.receipt.json
```

Output is 900 × 900 at 300 PPI, while the receipt retains 200 source PPI, the 1.5× scale, interpolation method and a quality warning. `effectivePPI` always describes the input at the requested print size; `outputPPI` describes the new output. Preserve this preparation receipt when packing or uploading; inspecting the prepared file cannot recover its original resolution history. Profile conversion needs `--convert-srgb` within the owner's preparation scope plus visual color approval in the final review. Inspect reports metadata and does not establish transparency suitability. Preparation checks visible content and some real transparency in both input and output, but cannot establish that every intended background was removed.

`density` is a compatibility alias of `decoderDensity`: neither proves the source contained an embedded DPI tag, because a decoder may supply a default such as 72. Source PPI comes from actual pixels divided by requested inches. `colorInterpretation` discloses when an untagged source was assumed to be sRGB; this does not recover an unknown profile. `sourceAlpha` reports partial transparency and visible-ink bounds in the oriented source canvas. Size the canvas consistently with the approved job and disclose large margins or ink touching its edges; do not silently trim it. These facts support visual review, not automatic artwork approval.

Packing accepts prepared transparent sRGB PNG at exactly the requested pixel size and density. It does not rotate or resize copies; it rejects overflow and verifies decoded sheet pixels against the copies and transparent background. Defaults are not shop specifications. Input is limited to 64 MiB and 100 million decoded/output pixels; copy count is 1–500. Outputs are created exclusively and include JSON hashes, dimensions and placement receipts. Re-open and visually compare output at final print size on light and dark backgrounds.

For **one individual design destined for the browser workspace or Assistant API**, use `prepare --target agent-api`. It checks the output against **25 million pixels and 25 MiB before writing**, while allowing a larger supported source to be downsampled. A packed preview is a separate sheet file; this target is intentionally unavailable for `pack` so it cannot be mistaken for the single-image upload. Server validation remains authoritative and must still succeed. Other local workflows retain the helper's broader limits; they do not imply acceptance by a shop endpoint.

SVG, PDF, EPS, PSD, AI and CDR are **not converted by this helper**. Use a capable licensed source application to verify complete pages/artboards, fonts, linked images, clipping and effects, then export transparent sRGB PNG at sufficient actual detail. Embedded previews and thumbnails do not establish faithful conversion. The helper does not remove backgrounds or recover detail. Direct finished-sheet intake accepts a single-page PDF at the ordered sheet size or a transparent PNG at exactly 300 pixels per inch of that sheet; confirm the actual pixel size before uploading, or use the shop builder.

Execution is local after dependency installation; the helper has no upload, account, checkout or payment capability. Automated helper tests do not establish actual Dot execution or successful shop submission. Report failures and unsupported files honestly.
