AGENTS.md · git:20261102.c601545 · 2026-11-02 · sha256 2b744388fc997120

AGENTS.md git:20261102.c601545A

Immutable. This exact content never changes and is served at /api/v1/blob/2b744388fc997120.

# AGENTS.md — ArtCraft Skills archive

You are a coding agent. This folder is the persistence archive of the
[artcraft-skills](https://github.com/midasmatterhorn/artcraft-skills) project: 16
evidence-verified skills for the ArtCraft desktop apps (14 storytold apps — the 13 craft apps plus
Craft Anything's rebuild workbench and TextureCraft's 3D texture painting — and Tangency Labs'
SolidCraft parametric CAD). If the user asks you to
install, update, or verify these skills, do it for the agent **you** are running as.

## Install (pick your target)

From the packaged release in this folder — the 16 skill folders sit at the zip root
(pick the newest `artcraft-skills-v*.zip`):

```sh
ZIP="$(ls -t releases/artcraft-skills-v*.zip | head -1)"

# Default: OpenAI Codex, ChatGPT desktop, ZCode, Devin, CommandCode, Gemini CLI (~/.agents/skills)
unzip -o "$ZIP" -d ~/.agents/skills/

# Claude Code
unzip -o "$ZIP" -d ~/.claude/skills/

# OpenCode
unzip -o "$ZIP" -d ~/.config/opencode/skills/

# Gemini CLI
unzip -o "$ZIP" -d ~/.gemini/skills/

# Google Antigravity
unzip -o "$ZIP" -d ~/.gemini/config/skills/
```

Windows PowerShell:

```powershell
$zip = Get-ChildItem releases\artcraft-skills-v*.zip | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Expand-Archive $zip -DestinationPath $HOME\.agents\skills   # or .claude\skills / .config\opencode\skills / .gemini\skills / .gemini\config\skills
```

Or from source (latest state):

```sh
git clone https://github.com/midasmatterhorn/artcraft-skills.git && cd artcraft-skills
bash install.sh              # default → ~/.agents/skills/  (add --claude, --opencode, --gemini or --antigravity to retarget)
.\install.ps1                # Windows; -Claude / -OpenCode / -Gemini / -Antigravity switches, -Force to overwrite
```

## Verify

All 16 skill directories must exist under the chosen target — `cadcraft`, `craft-anything`,
`deckcraft`, `designcraft`, `effectcraft`, `figcraft`, `filmcraft`, `gridcraft`, `lightcraft`,
`pdfcraft`, `photocraft`, `solidcraft`, `soundcraft`, `texturecraft`, `vectorcraft`, `wordcraft` — each containing
`SKILL.md` and `agents/openai.yaml`. Print the target directory you used, then tell the
user to restart their agent session so the skills are discovered.

## Windows: driving the GUI apps live

Agents on Windows often spawn processes in a non-interactive window station
(`CREATE_NO_WINDOW`); the ArtCraft GUI apps (egui/DirectX) can exit immediately with code 0
and no window when launched that way. An app that dies before its first frame may also
record the display adapter as bad and leave it out on later starts — VectorCraft writes
`%APPDATA%\VectorCraft\logs\graphics-start.json`, FilmCraft keeps a similar start record —
so the GPU can look "disabled" until that memory is cleared.

**Try the direct launch first.** `CREATE_NO_WINDOW` only hides a console; it does not move
the process to another window station. An agent running in the user's logged-on session (a
terminal, an IDE, a desktop app) can start the GUI itself. The launcher installs apps
per-user by default (`%LOCALAPPDATA%\Programs\ArtCraft\<App>`); apps installed for all
users live at `C:\Program Files\ArtCraft\<App>`:

```cmd
cmd.exe /c start "" "%LOCALAPPDATA%\Programs\ArtCraft\<App>\<app>.exe" --control <port>
```

If no window appears, the agent is in a non-interactive session — a Windows service /
session 0, or a runner that sandboxed its window station. Nothing started from that session
can paint on the user's desktop: use the headless CLI/MCP surface instead, or ask the
**user** to launch the app interactively. As a last resort, an agent that *is* running as
the logged-in user can have Task Scheduler launch the app interactively:

```cmd
schtasks /create /tn "ArtCraft-<App>-<port>" /tr "\"%LOCALAPPDATA%\Programs\ArtCraft\<App>\<app>.exe\" --control <port>" /sc once /st <future-time> /it /f
schtasks /run /tn "ArtCraft-<App>-<port>"
schtasks /delete /tn "ArtCraft-<App>-<port>" /f
```

- `/it` has no effect for tasks run as SYSTEM, and the System account has no interactive
  desktop; from a service, the interactive user has to launch the app.
- `/sc once` refuses a start time already in the past, so `<future-time>` must be later
  today (or create the task with `/sc onlogon` and `/run` it immediately).
- This creates a real scheduled task — an auditable artifact and a known execution
  primitive. Use a unique task name, keep the default limited run level (never
  `/rl highest`), delete the task right after it runs, and if endpoint policy blocks
  `schtasks`, ask the user instead of retrying.
- The app needs its control channel enabled at launch, with its own authentication (below).

If an earlier background launch did mark the adapter, reset the choice before blaming the
GPU: close the app, change Preferences › Performance › Graphics Processor (or set
`WGPU_ADAPTER_NAME` / `WGPU_BACKEND` for one start), or — only when you know the GPU is
healthy — delete `%APPDATA%\<App>\logs\graphics-start.json` so the next start tries it
again. Not every app writes that file.

Then connect a TCP socket to `127.0.0.1:<port>` and send one JSON request per line.
Authentication differs per app — check the app's SKILL.md before connecting:

- **PhotoCraft**: pass `--control-token <64-hex>` (or `--control-token-file <path>`) at launch.
- **WordCraft**: read the key from `%APPDATA%\<App>\control-key.local-<port>` (mode 0600, deleted on exit).
- **PdfCraft**: launch with `--control FILE` — the file holds the loopback port and per-launch token.
- **CADCraft**: every request needs `"token": "<session token>"`, read from `cadcraft-control-<port>.token` (`%LOCALAPPDATA%` on Windows; `$XDG_RUNTIME_DIR`, else `~/.cache` elsewhere) — the app prints the path at startup.
- **FilmCraft**: the listener only opens when `FILMCRAFT_CONTROL_TOKEN` holds 64 hex characters at launch; every request carries the same `"token"`.
- **GridCraft**: the first line of a connection must authenticate with the app's token — pass `--control-token <token>` or `GRIDCRAFT_CONTROL_TOKEN` at launch, or read the auto-generated token file whose path the app prints to stderr (`gridcraft-cli` reads it automatically); a connection that does not authenticate, or later sends a bad line, is closed.
- **TextureCraft**: every connection's first request must authenticate — `{"id":0,"method":"auth","params":{"token":"…"}}` with `TEXTURECRAFT_CONTROL_TOKEN` (16 characters or more) or the fresh random token the app writes to `texturecraft-control-<port>.token` in the temp directory and prints to stderr; anything else as the first request is refused.
- **All other apps**: loopback-only, unauthenticated — enable only while in use.

Send UTF-8 **without a BOM**: the control servers treat a BOM-prefixed first line as
malformed JSON and close the connection. Windows PowerShell 5.1 pipes add a BOM — use raw
sockets, `pwsh` (`utf8NoBOM`), or set `[Console]::OutputEncoding` explicitly. On macOS and
Linux the apps launch normally; this note is Windows-specific.