Metadata-Version: 2.4
Name: iconmage
Version: 0.1.0
Summary: Create, render, compile, and verify Apple icon bundles
Author-email: Jeremy Howard <github@jhoward.fastmail.fm>
License: Apache-2.0
Project-URL: Homepage, https://github.com/AnswerDotAI/iconmage
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: python-fastllm>=0.0.34
Provides-Extra: dev
Requires-Dist: fastship; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# iconmage

`iconmage` creates Apple Icon Composer documents from SVG artwork, renders every Apple appearance with `ictool`, compiles app resources with `actool`, and verifies the finished bundle. Its optional GPT workflow writes and critiques the SVG for you.

The package carries a native-created `.icon` template, so neither automated builds nor icon generation need to open Icon Composer.

## Requirements

`iconmage` runs on macOS with a recent Xcode selected by `xcode-select`. It uses Icon Composer's bundled `ictool`, plus `actool`, `assetutil`, and `codesign` from Xcode and macOS.

Icon Composer 1.6 or later is required: earlier versions rendered through a positional `--export-preview` form rather than the `--export-image` options `iconmage` passes.

The default agent model is `codex/gpt-5.6-terra`, which uses the Codex credentials already stored on the machine. Pass another fastllm model with `--model`; provider API keys then follow fastllm's usual configuration.

## Generate an icon

Give the agent a concrete visual brief:

```bash
iconmage generate \
  'App icon for a local-first notebook app. A folded sheet forming a lowercase n. Bold centered silhouette, cobalt and warm white, no outline, no text, readable at 32 px.' \
  AppIcon.icon
```

The default workflow generates four SVG candidates, renders Apple appearance and 32-pixel previews, asks the model to choose and revise the strongest candidate, compares the revision with its source, and writes:

```text
AppIcon.icon/             Icon Composer document
AppIcon-renders/          Six PNGs: Default, Dark, Tinted Light/Dark, Clear Light/Dark
AppIcon-generation.json   Brief, selected SVG, critiques, and model
```

Use `--candidates` and `--rounds` to change the search budget. `--background '#fff2d5'` sets the Icon Composer background. `--overwrite` replaces an existing destination document.

## Use existing SVG artwork

Artwork must use a `0 0 1024 1024` view box. Keep it flat; Icon Composer supplies the material, shadows, refraction, masks, and appearance variants.

```bash
iconmage create artwork.svg AppIcon.icon --background '#fff2d5'
iconmage render AppIcon.icon previews
```

`render` writes Default, Dark, Tinted Light/Dark, and Clear Light/Dark PNGs. Use repeated `--rendition` options to render a subset.

These renders show the full square canvas. `actool` adds the transparent margin and macOS applies the rounded-rectangle mask at display time, so a render looks larger and squarer than the installed icon. Compare renders with each other rather than with the Dock.

## Compile and install

Compile resources without modifying an app:

```bash
iconmage compile AppIcon.icon MyApp.app/Contents/Resources --target 14.0
```

The command creates `Assets.car` and `AppIcon.icns`, then prints the plist entries that the application builder must merge before signing.

That ICNS is the fallback for macOS releases before 26, and `actool` generates it from the same document. Its appearance is Apple's to decide: Xcode 26.1 removed the undocumented flag that let a project substitute a hand-made legacy icon.

`install` performs that merge for an existing bundle. Passing a signing identity signs the finished bundle after every resource is final:

```bash
iconmage install AppIcon.icon MyApp.app --target 14.0 --identity '-'
iconmage verify MyApp.app
```

Use a Developer ID identity instead of `-` for a distributable application. `verify` checks the ICNS fallback, asset catalog records, plist metadata, strict code signature, and designated requirement.

## Python API

```python
from iconmage import create_icon, render_icon, compile_icon, install_icon, verify_app

icon = create_icon('artwork.svg', 'AppIcon.icon', background='#fff2d5')
renders = render_icon(icon, 'previews')
plist_entries = compile_icon(icon, 'MyApp.app/Contents/Resources', '14.0')
```

The agent API is asynchronous:

```python
from iconmage import generate_icon

result = await generate_icon('A bold geometric weather icon', 'AppIcon.icon')
```

Application builders should call `compile_icon()` before their existing signing step. `install_icon()` is for complete bundles whose plist already exists.

## Development

The integration test exercises the real Apple tools and a temporary signed app:

```bash
pytest -q
chkstyle iconmage tests
```

Live model calls are not part of the test suite. They depend on credentials and spend tokens; the CLI and `generate_icon()` are the executable integration surface.
