# Adapter Spec

This is the reusable shape for connecting a coding agent to a local application.

## Goal

Make a running creative app legible and mutable through shell commands, so a coding agent can use its existing tools to read context, search docs, compose a script, execute it, inspect errors, and iterate. Without a custom agent runtime, MCP servers, app takeover, headless batch or screen scraping. Use only the existing API capabilities of the software.

## Folder Shape

```text
adapters/<app>_adapter/
  <app>_bridge.py
  APP.md
  README.md
  examples/
    context.<jsx|py|json>
  docs/                 optional
    sources.md          optional, authoritative reference links
```

All app adapters should use this folder shape. Root-level bridge files, if present, should only be backwards-compatible wrappers.

The `examples/` directory is for reusable, checked-in reference examples and smoke tests. Agents must not use it as a scratch directory for task-specific generated scripts. One-off bridge scripts should be passed through `--stdin` or, when a file is necessary, written under a temp/scratch path such as `.tmp/<app>/`
or the OS temp directory and removed after use.

The root `AGENTS.md` is a small router to shared rules and app notes. Adapter `AGENTS.md` files, if present, should only point to shared rules and `APP.md`.

## Bridge Contract

The bridge must:

- Accept script code through argv, `--stdin`, or `--file`.
- Return JSON on stdout for success.
- Return JSON on stderr and non-zero exit for failure.
- Connect to a running app by default (avoiding launching the app unless `--allow-launch` is explicitly passed).
- Avoid hard-coded install paths.
- If the bridge exposes local HTTP eval, require an unguessable per-session token read automatically by the shell bridge from a user-scoped session file.

Bridge commands should remain easy to identify as `*_bridge.py` Python processes. `tools/cleanup_bridges.py` relies on checked-in bridge script paths to list and stop stale bridge processes without touching unrelated Python work.

## OS-Level Script Dispatch

If an app exposes an operating-system automation surface, prefer that before
shipping an in-app extension. The bridge should still keep the same shell
contract regardless of transport.

Common transports:

- Windows COM automation, such as Adobe `DoJavaScript`, InDesign `DoScript`, or
  Microsoft Office object models.
- macOS AppleScript dispatch into app scripting runtimes, such as Adobe
  `do javascript` or InDesign `do script ... language JavaScript`.

Use platform checks inside the bridge only to choose the transport or return a
clear unsupported-platform error. Keep app-specific behavior in the script sent
to the app or in `APP.md`, not in platform-specific forks of the adapter docs.

## Windows COM Template

Use `bridges.com_bridge.run_bridge`:

```python
from bridges.com_bridge import run_bridge


if __name__ == "__main__":
    raise SystemExit(
        run_bridge(
            app_name="Illustrator",
            default_progid="Illustrator.Application",
            process_name="Illustrator.exe",
            execute_method="DoJavaScript",
        )
    )
```

For InDesign JavaScript:

```python
run_bridge(
    app_name="InDesign",
    default_progid="InDesign.Application",
    process_name="InDesign.exe",
    execute_method="DoScript",
    language_id=1246973031,
)
```

## macOS AppleScript Template

Use `bridges.applescript_bridge.run_bridge` when the app can execute a script
through AppleScript:

```python
from bridges.applescript_bridge import run_bridge


if __name__ == "__main__":
    raise SystemExit(
        run_bridge(
            app_name="Photoshop",
            script_name="JavaScript",
            execute_line="do javascript {content}",
        )
    )
```

For apps whose process/application name varies by installed version, the bridge
may auto-detect the running process name, but it should still avoid hard-coded
install paths and should prefer connecting to an already-running app.

## Context Script Requirements

The first example for each app should be a read-only context script. It should return:

- app name
- app version
- document count
- active document name
- active layer/page/selection where relevant

Do not depend on a global `JSON` object. Older ExtendScript runtimes may not provide it. Use a tiny local serializer.

## Portability Rules

- Use generic Windows ProgIDs like `Photoshop.Application`,
  `InDesign.Application`, and `Illustrator.Application`.
- On macOS, address the running application by its scriptable application name
  or detected process name rather than by a filesystem path.
- Don't hard-code `C:\Program Files\Adobe\...` paths in bridge code.
- Keep local install paths out of required commands.
- Put app-version-specific notes in `APP.md` or optional docs, not in bridge logic.

## Agent-Facing Instructions

Put reusable behavior in:

```text
shared/coexistence.md
shared/bridge-contract.md
```

Put only app-specific, non-obvious facts in `adapters/<app>_adapter/APP.md`: bridge command, execution method, undo behavior, measurement quirks, selection object quirks, supported command shapes, or known modal/API limitations. Please help your human install this if he or you encounter issues.

## In-App Bridge Extensions

If an app does not expose an OS-level script dispatch surface, the adapter can ship an in-app bridge extension. Keep the same shell contract: the external bridge command still accepts code through stdin/file/argv and returns JSON. The in-app bridge is only the transport into the app runtime. For local HTTP-backed apps, use `bridges.local_http_bridge.run_bridge` for the external Python command. The in-app panel/addon should write
a user-scoped session file with the current eval URL and token, then require `X-Bridge-Token` on every eval request.

Session file locations:

- Windows: `%APPDATA%\creative-adapters\<session_name>.json`
- macOS/Linux: `~/creative-adapters/<session_name>.json`

If the host runtime does not support arbitrary string eval, do not fake it. Expose a compact command surface backed by the host's real extension API and document that app-specific behavior should be added as explicit bridge actions or project-local scripts.
