@pebbly/aseprite-ai-artist 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +109 -141
- package/dist/bridge/client.js +4 -4
- package/dist/bridge/client.js.map +1 -1
- package/dist/tools/craft.js +1 -1
- package/dist/tools/craft.js.map +1 -1
- package/extension/ai-artist.lua +136 -24
- package/extension/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,76 @@ All notable changes to this project are documented here. Format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning is
|
|
5
5
|
[semver](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.1.5] — 2026-09-09
|
|
8
|
+
|
|
9
|
+
Three commands reported success while doing nothing. That is worse than an
|
|
10
|
+
error: the agent believes the edit landed and builds the next step on top of it.
|
|
11
|
+
All three surfaced while drawing a 35-layer scene through the bridge, none of
|
|
12
|
+
them from a crash.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **`layer` op `group` could never have worked.** It called
|
|
17
|
+
`Sprite:newGroupLayer()`, which is not in the Aseprite API. Indexing a missing
|
|
18
|
+
field throws rather than returning nil, so the whole batch — every other op in
|
|
19
|
+
it included — rolled back with `Field newGroupLayer does not exist`. The
|
|
20
|
+
method is `newGroup()`.
|
|
21
|
+
- **`cel` op `link` linked nothing and counted everything.** `LinkCels` acts on
|
|
22
|
+
the timeline range, not on the active layer and frame; the old code set those
|
|
23
|
+
and called the command once per target frame, which is a no-op, then reported
|
|
24
|
+
one success per frame. A caller was told a static layer had been shared across
|
|
25
|
+
a cycle while the target frames were still empty. The range now holds the
|
|
26
|
+
source cel and every target together in one call, the reply counts only frames
|
|
27
|
+
that actually ended up sharing the source image, and linking from a frame with
|
|
28
|
+
no cel is now an error naming `copy` as the way to seed one.
|
|
29
|
+
- **`validate` timed out on a large sprite.** Its stray and outline scans asked
|
|
30
|
+
`pixel_to_hex` — a `string.format` — whether a pixel was opaque, for every
|
|
31
|
+
pixel and each of its four neighbours: tens of millions of strings allocated
|
|
32
|
+
to compute a boolean. Presence is now answered without allocating. Measured on
|
|
33
|
+
the 35-layer, 36-frame sprite this was found on, the stray scan went from
|
|
34
|
+
10.5s to 2.2s and found the identical 1373 strays.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- **The per-pixel checks skip hidden layers**, as `outline` and `banding`
|
|
39
|
+
already did. A finding about pixels that never reach the export is noise, and
|
|
40
|
+
a document that keeps its earlier drafts as hidden layers is mostly hidden —
|
|
41
|
+
on the sprite above, 769 of 1042 cels. `validate` now says how many layers it
|
|
42
|
+
passed over, so a clean result cannot quietly mean "clean, because I did not
|
|
43
|
+
look".
|
|
44
|
+
- `validate.run` gets its own 120s budget rather than the shared 20s default. A
|
|
45
|
+
thorough pass over a rigged sprite is legitimately slow, and a timeout reads
|
|
46
|
+
to an agent as "Aseprite is not answering" — the one message that sends it
|
|
47
|
+
looking for a workaround.
|
|
48
|
+
|
|
49
|
+
## [0.1.4] — 2026-09-08
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **GIF export waited for a click nobody was there to give.** Aseprite warns
|
|
54
|
+
once per session that GIF cannot hold everything a sprite can, and no save API
|
|
55
|
+
declines it. From outside it did not look like a prompt at all: a modal pumps
|
|
56
|
+
events while it waits, so every other command kept answering and only the
|
|
57
|
+
export appeared to hang. It is now suppressed for the duration of the export
|
|
58
|
+
and handed straight back, so File ▸ Save As keeps whatever the user chose.
|
|
59
|
+
- 0.1.3 tried to fix this with `SaveFileCopyAs{ui = false}`. That flag does not
|
|
60
|
+
govern this dialog. GIF export now converts a throwaway copy to indexed
|
|
61
|
+
instead of leaving the conversion to a prompt — and on a copy, because doing
|
|
62
|
+
it in place would silently change the colour mode of the document being
|
|
63
|
+
worked in.
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- `export` op `gif` honours `scale`. A browser scaling a 128px GIF up smooths
|
|
68
|
+
it, and smoothed pixel art is ruined pixel art; exporting big keeps the pixels
|
|
69
|
+
square wherever the file is shown.
|
|
70
|
+
|
|
71
|
+
### Known
|
|
72
|
+
|
|
73
|
+
- The first GIF export in an Aseprite session costs 20-30 seconds — measured
|
|
74
|
+
20.6s, then 435ms for the identical export straight after. Something warms up
|
|
75
|
+
once. The 120s export budget from 0.1.3 covers it.
|
|
76
|
+
|
|
7
77
|
## [0.1.3] — 2026-09-08
|
|
8
78
|
|
|
9
79
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,49 +1,54 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
+
<img src="docs/media/hero2.gif" alt="A pixel robot at an easel paints a landscape stroke by stroke under a pendant lamp" width="768">
|
|
4
|
+
|
|
3
5
|
# Aseprite AI Artist
|
|
4
6
|
|
|
5
|
-
**
|
|
6
|
-
copy, not on disk
|
|
7
|
+
**Your coding agent draws pixel art in the Aseprite window you already have
|
|
8
|
+
open.** Not a copy, not a file on disk — the document you are looking at.
|
|
7
9
|
|
|
8
10
|
[](https://www.npmjs.com/package/@pebbly/aseprite-ai-artist)
|
|
9
11
|
[](https://github.com/with-pebbly/aseprite-ai-artist/actions/workflows/ci.yml)
|
|
10
12
|
[](LICENSE)
|
|
11
13
|
|
|
14
|
+
<sub>192×96, 36 frames, one palette. Drawn through this server into a live
|
|
15
|
+
Aseprite window — the paint appears under the brush, every frame.</sub>
|
|
16
|
+
|
|
12
17
|
</div>
|
|
13
18
|
|
|
14
19
|
---
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
## What it does
|
|
22
|
+
|
|
23
|
+
You ask for something. It gets drawn, in front of you.
|
|
19
24
|
|
|
20
25
|
> *"Draw me a 32×32 knight in the PICO-8 palette, then a 4-frame idle."*
|
|
21
26
|
|
|
22
|
-
The agent
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
compromised on. In your window, undoable, one Ctrl+Z per edit.
|
|
27
|
+
The agent picks a palette, blocks in a silhouette, **looks at what it drew**,
|
|
28
|
+
shades it, splits it onto layers, animates, tags the cycle, and tells you what it
|
|
29
|
+
had to compromise on. Every edit is one Ctrl+Z.
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
Works with **Claude Code, Codex CLI, Gemini CLI, Cursor, VS Code and Windsurf**
|
|
32
|
+
from the same one-line config.
|
|
28
33
|
|
|
29
34
|
## Install
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
You need [Aseprite](https://www.aseprite.org/) 1.3+ and Node 22.6+. Open Aseprite
|
|
37
|
+
once before you start, so its config folder exists.
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
**1 — Install the extension**
|
|
35
40
|
|
|
36
41
|
```bash
|
|
37
42
|
npx @pebbly/aseprite-ai-artist install-extension
|
|
38
43
|
```
|
|
39
44
|
|
|
40
|
-
Then
|
|
41
|
-
|
|
45
|
+
Then quit and reopen Aseprite. It only dials out at startup, so an editor left
|
|
46
|
+
running from before the install will never connect.
|
|
42
47
|
|
|
43
|
-
|
|
48
|
+
**2 — Connect your agent**
|
|
44
49
|
|
|
45
50
|
<details open>
|
|
46
|
-
<summary><b>Claude Code</b> —
|
|
51
|
+
<summary><b>Claude Code</b> — the plugin, not the bare server</summary>
|
|
47
52
|
|
|
48
53
|
<br>
|
|
49
54
|
|
|
@@ -52,14 +57,14 @@ an editor left running from before the install will never connect.
|
|
|
52
57
|
/plugin install aseprite-ai-artist
|
|
53
58
|
```
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
It brings its own server plus the `/pixel-*` commands, the subagents and the
|
|
61
|
+
preview hooks. Don't also add the server by hand — you'd load all eighteen tools
|
|
62
|
+
twice, on every request.
|
|
58
63
|
|
|
59
64
|
</details>
|
|
60
65
|
|
|
61
66
|
<details>
|
|
62
|
-
<summary><b>Codex
|
|
67
|
+
<summary><b>Codex, Gemini, Cursor, VS Code, Windsurf</b></summary>
|
|
63
68
|
|
|
64
69
|
<br>
|
|
65
70
|
|
|
@@ -67,132 +72,94 @@ would load the same eighteen tools twice, on every request.
|
|
|
67
72
|
npx @pebbly/aseprite-ai-artist install codex # ~/.codex/config.toml
|
|
68
73
|
npx @pebbly/aseprite-ai-artist install gemini # ~/.gemini/settings.json
|
|
69
74
|
npx @pebbly/aseprite-ai-artist install cursor # ~/.cursor/mcp.json
|
|
70
|
-
npx @pebbly/aseprite-ai-artist install --all #
|
|
75
|
+
npx @pebbly/aseprite-ai-artist install --all # all of the above
|
|
71
76
|
```
|
|
72
77
|
|
|
73
|
-
|
|
74
|
-
it
|
|
75
|
-
`--agents` also appends a section to your `AGENTS.md`.
|
|
78
|
+
Your existing config is backed up first. `--dry-run` shows the change without
|
|
79
|
+
making it, `--project` writes into the repo instead of your home directory.
|
|
76
80
|
|
|
77
81
|
</details>
|
|
78
82
|
|
|
79
|
-
|
|
83
|
+
Restart the agent afterwards so it picks up the new server.
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
**3 — Check it**
|
|
82
86
|
|
|
83
87
|
```bash
|
|
84
88
|
npx @pebbly/aseprite-ai-artist doctor
|
|
85
89
|
```
|
|
86
90
|
|
|
87
|
-
Ticks all the way down and you
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
Per-client detail and troubleshooting: **[docs/INSTALL.md](docs/INSTALL.md)**.
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Which agent should do the drawing?
|
|
91
|
+
Ticks all the way down and you're ready. If something's missing it says which
|
|
92
|
+
half, instead of making you guess. More detail in
|
|
93
|
+
[docs/INSTALL.md](docs/INSTALL.md).
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
## Which model should do the drawing?
|
|
97
96
|
|
|
98
|
-
|
|
97
|
+
Not a benchmark — a log of what actually drew the art on this page. Models we
|
|
98
|
+
haven't run are listed as untested rather than guessed at.
|
|
99
99
|
|
|
100
|
-
|
|
|
101
|
-
|
|
102
|
-
| Claude
|
|
103
|
-
| Codex CLI
|
|
104
|
-
|
|
|
100
|
+
| Model | What it drew | How it went |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| **Claude Fable 5.1** | the animation up top | Best so far. One session, no review passes needed. |
|
|
103
|
+
| **Codex CLI** `gpt-5.6-terra`, high reasoning | the harbour below, and the mascot | Strong, but it took five rounds of critique. |
|
|
104
|
+
| **Claude Opus 5** | the server, the rulebook, every review pass | The planner and the critic. Its own drawing attempt got scrapped. |
|
|
105
|
+
| Gemini 3 Pro, Sonnet 5, Cursor, others | — | Untested. Run one and send us the sprite. |
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
32×32 grid is a spatial problem: the model has to hold a coordinate frame in
|
|
111
|
-
its head, keep a silhouette readable at that size, and notice when a shape has
|
|
112
|
-
gone wrong. Turn reasoning up before you blame the tool.
|
|
113
|
-
- **Codex CLI on a high-reasoning setting is the best drawer we have used**,
|
|
114
|
-
working from a brief and the rulebook alone.
|
|
115
|
-
- **Claude Code is the better planner and critic.** Palette construction, rig
|
|
116
|
-
layout, animation timing and the review pass come out noticeably stronger;
|
|
117
|
-
raw pixel placement at small canvas sizes is weaker.
|
|
118
|
-
- If you have both, split the work: brief and review in Claude Code with
|
|
119
|
-
`pixel-brief` and `pixel-review`, execute the drawing passes in Codex. They
|
|
120
|
-
talk to the same live document through the same bridge, so they can take turns
|
|
121
|
-
on one sprite.
|
|
107
|
+
<div align="center">
|
|
108
|
+
<img src="docs/media/mascot.png" alt="The mascot" width="96"><br>
|
|
109
|
+
<sub><i>the mascot — Codex, from the brief and the rulebook alone</i></sub>
|
|
110
|
+
</div>
|
|
122
111
|
|
|
123
|
-
|
|
124
|
-
still cannot casually widen your palette, because `draw` and `recolor` snap by
|
|
125
|
-
perceptual distance and report every colour they moved. It does not close it.
|
|
112
|
+
**Method mattered more than the model.** Both good results came the same way:
|
|
126
113
|
|
|
127
|
-
|
|
114
|
+
- **Generate, don't hand-place.** Write a small program that emits every frame,
|
|
115
|
+
then push it. Placing pixels one call at a time by eye is where the weak
|
|
116
|
+
attempts died.
|
|
117
|
+
- **Look at frames full-size, one at a time.** A filmstrip is a trap — at that
|
|
118
|
+
size you see what you already know is meant to be there.
|
|
119
|
+
- **Turn reasoning up** before you blame the model. A 32×32 grid is a spatial
|
|
120
|
+
problem.
|
|
128
121
|
|
|
129
|
-
##
|
|
122
|
+
## Why this one
|
|
130
123
|
|
|
131
124
|
**It works everywhere, not just in Claude Code.** Most Aseprite MCP projects put
|
|
132
|
-
their craft knowledge in a Claude Code plugin
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
`rules://` and `skill://` resources *and* as MCP prompts, so every client gets
|
|
136
|
-
them from one source of truth.
|
|
125
|
+
their craft knowledge in a Claude Code plugin, so Codex and Cursor get raw tools
|
|
126
|
+
and none of the discipline. Here the rules and workflows are served over MCP, so
|
|
127
|
+
every client reads the same source of truth.
|
|
137
128
|
|
|
138
129
|
**Eighteen tools, not ninety.** Every tool schema sits in the model's context on
|
|
139
|
-
every turn,
|
|
140
|
-
|
|
141
|
-
|
|
130
|
+
every turn, drawing or not. Grouping by noun with an `op` enum covers the same
|
|
131
|
+
ground at a sixth of the cost — and makes batching the default, so one `draw`
|
|
132
|
+
call is one undo step for you.
|
|
142
133
|
|
|
143
|
-
**
|
|
144
|
-
|
|
134
|
+
**It has to look at its own work.** `look` gives the agent an upscaled preview, a
|
|
135
|
+
one-glyph-per-pixel text grid, a filmstrip and a frame-to-frame diff. `validate`
|
|
136
|
+
then checks the sprite mechanically before anything is called finished.
|
|
145
137
|
|
|
146
|
-
**It
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
138
|
+
**It can't quietly wreck your file.** With Aseprite detached, every tool refuses
|
|
139
|
+
immediately instead of timing out — because an agent that "recovers" by editing
|
|
140
|
+
the `.aseprite` on disk makes changes you never see, and your next save
|
|
141
|
+
overwrites them.
|
|
150
142
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
an agent that "recovers" by editing the `.aseprite` file makes changes you never
|
|
154
|
-
see, and your next save overwrites them.
|
|
155
|
-
|
|
156
|
-
There is [a whole page](docs/RESEARCH.md) on the other projects in this space,
|
|
157
|
-
what was taken from them, and where they are still better.
|
|
158
|
-
|
|
159
|
-
---
|
|
143
|
+
There's [a whole page](docs/RESEARCH.md) on the other projects in this space and
|
|
144
|
+
where they're still better.
|
|
160
145
|
|
|
161
|
-
##
|
|
146
|
+
## What's inside
|
|
162
147
|
|
|
163
|
-
Eighteen
|
|
148
|
+
**Eighteen tools**, grouped by noun — `preflight` · `sprite_info` ·
|
|
149
|
+
`sprite_manage` · `look` · `read_pixels` · `draw` · `select` · `transform` ·
|
|
150
|
+
`recolor` · `layer` · `frame` · `tag` · `cel` · `palette` · `validate` ·
|
|
151
|
+
`reference` · `export` · `tileset`, plus `run_lua` as an escape hatch, off by
|
|
152
|
+
default. Full reference: [docs/TOOLS.md](docs/TOOLS.md).
|
|
164
153
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
| **Structure** | `layer` · `frame` · `tag` · `cel` |
|
|
171
|
-
| **Colour & quality** | `palette` · `validate` |
|
|
172
|
-
| **Assets** | `reference` · `export` · `tileset` |
|
|
154
|
+
**Eleven workflows** the agent follows, served to every client — `pixel-brief` ·
|
|
155
|
+
`pixel-new` · `pixel-palette` · `pixel-draw` · `pixel-shade` · `pixel-rig` ·
|
|
156
|
+
`pixel-animate` · `pixel-tileset` · `pixel-review` · `pixel-fix` ·
|
|
157
|
+
`pixel-export`. In Claude Code you also get four specialists: **pixel-critic**,
|
|
158
|
+
**palette-smith**, **rig-builder**, **animation-director**.
|
|
173
159
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
Workflows the agent follows, served to every client:
|
|
179
|
-
|
|
180
|
-
`pixel-brief` · `pixel-new` · `pixel-palette` · `pixel-draw` · `pixel-shade` ·
|
|
181
|
-
`pixel-rig` · `pixel-animate` · `pixel-tileset` · `pixel-review` · `pixel-fix` ·
|
|
182
|
-
`pixel-export`
|
|
183
|
-
|
|
184
|
-
And in Claude Code, four specialist subagents: **pixel-critic** (visual QA),
|
|
185
|
-
**palette-smith** (colour), **rig-builder** (layer rigs), **animation-director**
|
|
186
|
-
(cycle planning).
|
|
187
|
-
|
|
188
|
-
## The rules
|
|
189
|
-
|
|
190
|
-
The craft is encoded in [`rules/`](rules/) and served as `rules://` resources —
|
|
191
|
-
palette discipline, hue-shifted shading, silhouette and proportion, outlines and
|
|
192
|
-
edges, animation timing, layer rigging, and a review checklist. Skills reference
|
|
193
|
-
rules rather than restating them, so a rule has exactly one place to be wrong.
|
|
194
|
-
|
|
195
|
-
---
|
|
160
|
+
**A rulebook** in [`rules/`](rules/) — palette discipline, hue-shifted shading,
|
|
161
|
+
silhouette, outlines, animation timing, layer rigging, review checklist. Skills
|
|
162
|
+
reference rules rather than restating them, so a rule has one place to be wrong.
|
|
196
163
|
|
|
197
164
|
## How it works
|
|
198
165
|
|
|
@@ -201,38 +168,39 @@ your agent ──stdio/MCP──▶ server ──ws:9932──▶ bridge
|
|
|
201
168
|
```
|
|
202
169
|
|
|
203
170
|
Aseprite's Lua WebSocket is a client only, so the bridge holds the listening
|
|
204
|
-
socket. It runs as its own
|
|
205
|
-
|
|
206
|
-
|
|
171
|
+
socket. It runs as its own process, so restarting the MCP server — which agent
|
|
172
|
+
hosts do freely — doesn't drop your Aseprite connection, and a second agent
|
|
173
|
+
window can attach without stealing the first one's replies. Details in
|
|
174
|
+
[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
207
175
|
|
|
208
|
-
|
|
209
|
-
|
|
176
|
+
Both ports bind `127.0.0.1` only. `run_lua` is arbitrary code execution inside
|
|
177
|
+
the app holding your unsaved work, and stays off unless you turn it on — full
|
|
178
|
+
threat model in [SECURITY.md](SECURITY.md).
|
|
210
179
|
|
|
211
180
|
## Development
|
|
212
181
|
|
|
213
182
|
```bash
|
|
214
|
-
npm install
|
|
215
|
-
npm
|
|
216
|
-
npm test
|
|
217
|
-
npm run test:
|
|
218
|
-
npm run test:extension # Lua handlers, headless, against a real sprite
|
|
183
|
+
npm install && npm run build
|
|
184
|
+
npm test # TypeScript
|
|
185
|
+
npm run test:pure # Lua that needs no editor — what CI runs
|
|
186
|
+
npm run test:extension # the real handlers, headless, against a real sprite
|
|
219
187
|
```
|
|
220
188
|
|
|
221
|
-
`test:extension`
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
runs anywhere.
|
|
189
|
+
`test:extension` needs Aseprite installed, so CI can't run it.
|
|
190
|
+
|
|
191
|
+
## One more, drawn the same way
|
|
225
192
|
|
|
226
|
-
|
|
193
|
+
<div align="center">
|
|
227
194
|
|
|
228
|
-
|
|
229
|
-
no authentication, because there is nothing remote to authenticate. `run_lua` is
|
|
230
|
-
arbitrary code execution inside the app holding your unsaved work, and is off
|
|
231
|
-
unless you turn it on. Full threat model in [SECURITY.md](SECURITY.md).
|
|
195
|
+
<img src="docs/media/harbour.gif" alt="A pixel-art harbour at night: a lighthouse beam sweeps over the water, windows flicker, smoke drifts from a chimney" width="768">
|
|
232
196
|
|
|
233
|
-
|
|
197
|
+
<sub>256×144, 28 frames, ten layers. Only six of them move — beam, windows,
|
|
198
|
+
water, smoke, boat, stars — each on its own cycle length, which is what keeps an
|
|
199
|
+
ambient loop from feeling mechanical.</sub>
|
|
234
200
|
|
|
235
|
-
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
## Licence
|
|
236
204
|
|
|
237
|
-
Aseprite is a trademark of Igara Studio S.A
|
|
238
|
-
|
|
205
|
+
MIT — see [LICENSE](LICENSE). Aseprite is a trademark of Igara Studio S.A.; this
|
|
206
|
+
project isn't affiliated with them.
|
package/dist/bridge/client.js
CHANGED
|
@@ -105,10 +105,10 @@ export class LiveClient {
|
|
|
105
105
|
*/
|
|
106
106
|
// TODO(boundary): only the call sites whose fields feed a summary or a
|
|
107
107
|
// decision declare `expect` — draw.batch, recolor.apply, export.run,
|
|
108
|
-
// session.site, sprite.info. The rest (select, transform,
|
|
109
|
-
// look, palette) still rest on `call<T>` alone. Extend as
|
|
110
|
-
// against a real reply; guessing a field name here turns a
|
|
111
|
-
// a hard error.
|
|
108
|
+
// session.site, sprite.info, validate.run. The rest (select, transform,
|
|
109
|
+
// reference, tileset, look, palette) still rest on `call<T>` alone. Extend as
|
|
110
|
+
// each is checked against a real reply; guessing a field name here turns a
|
|
111
|
+
// working path into a hard error.
|
|
112
112
|
async call(cmd, args = {}, opts = {}) {
|
|
113
113
|
const expect = opts.expect ?? [];
|
|
114
114
|
const timeoutMs = opts.timeoutMs ?? this.timeoutMs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/bridge/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/bridge/client.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/craft.js
CHANGED
|
@@ -119,7 +119,7 @@ export function registerCraftTools(server, live) {
|
|
|
119
119
|
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
120
120
|
}, async (args) => {
|
|
121
121
|
try {
|
|
122
|
-
const data = await live.call("validate.run", args);
|
|
122
|
+
const data = await live.call("validate.run", args, { expect: ["findings"], timeoutMs: 120_000 });
|
|
123
123
|
const errors = data.findings.filter((f) => f.severity === "error");
|
|
124
124
|
const warnings = data.findings.filter((f) => f.severity === "warning");
|
|
125
125
|
const passed = errors.length === 0 && (!args.strict || warnings.length === 0);
|
package/dist/tools/craft.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"craft.js","sourceRoot":"","sources":["../../src/tools/craft.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"craft.js","sourceRoot":"","sources":["../../src/tools/craft.ts"],"names":[],"mappings":"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"}
|
package/extension/ai-artist.lua
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
--------------------------------------------------------------------------------
|
|
16
16
|
|
|
17
17
|
local PROTOCOL_VERSION = 1
|
|
18
|
-
local EXTENSION_VERSION = "0.1.
|
|
18
|
+
local EXTENSION_VERSION = "0.1.5"
|
|
19
19
|
|
|
20
20
|
-- Optional capabilities. The wire version stays 1 across builds; new command
|
|
21
21
|
-- families are gated on these flags plus the loud unsupported_command reply,
|
|
@@ -105,6 +105,21 @@ local function pixel_to_hex(sprite, value)
|
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
+
-- "Is there paint here?" without asking which colour. The scans in validate
|
|
109
|
+
-- test presence far more often than they read a colour — every opaque pixel
|
|
110
|
+
-- plus its four neighbours — and pixel_to_hex answers with a string.format,
|
|
111
|
+
-- so it allocated tens of millions of strings to compute a boolean.
|
|
112
|
+
local function pixel_is_opaque(sprite, value)
|
|
113
|
+
local pc = app.pixelColor
|
|
114
|
+
if sprite.colorMode == ColorMode.INDEXED then
|
|
115
|
+
if value == sprite.transparentColor then return false end
|
|
116
|
+
return value < #sprite.palettes[1]
|
|
117
|
+
elseif sprite.colorMode == ColorMode.GRAY then
|
|
118
|
+
return pc.grayaA(value) ~= 0
|
|
119
|
+
end
|
|
120
|
+
return pc.rgbaA(value) ~= 0
|
|
121
|
+
end
|
|
122
|
+
|
|
108
123
|
-- Convert a Color into the raw pixel value this sprite's colour mode stores.
|
|
109
124
|
local function color_to_pixel(sprite, color)
|
|
110
125
|
local pc = app.pixelColor
|
|
@@ -1322,7 +1337,10 @@ local function apply_layer_op(s, op)
|
|
|
1322
1337
|
return
|
|
1323
1338
|
end
|
|
1324
1339
|
if kind == "group" then
|
|
1325
|
-
|
|
1340
|
+
-- Sprite:newGroup(), not newGroupLayer(): the latter does not exist, and
|
|
1341
|
+
-- indexing a missing field throws rather than returning nil, so the whole
|
|
1342
|
+
-- batch transaction rolled back with "Field newGroupLayer does not exist".
|
|
1343
|
+
local group = s:newGroup()
|
|
1326
1344
|
group.name = op.name or "group"
|
|
1327
1345
|
for _, name in ipairs(op.names or {}) do find_layer(s, name).parent = group end
|
|
1328
1346
|
return
|
|
@@ -1573,15 +1591,42 @@ H["cel.apply"] = function(args)
|
|
|
1573
1591
|
s:newCel(dstLayer, dstFrame, src.image:clone(), src.position)
|
|
1574
1592
|
applied = 1
|
|
1575
1593
|
elseif op == "link" then
|
|
1576
|
-
|
|
1594
|
+
-- LinkCels acts on the timeline range, not on app.layer/app.frame. The
|
|
1595
|
+
-- previous version set those and called the command once per frame, which
|
|
1596
|
+
-- linked nothing at all — and still counted one success per frame, so a
|
|
1597
|
+
-- caller was told a static layer had been shared across a cycle when the
|
|
1598
|
+
-- target frames were still empty. The range has to hold the source cel
|
|
1599
|
+
-- and every target together, in one call.
|
|
1600
|
+
local targets = args.frames or {}
|
|
1601
|
+
if #targets == 0 then
|
|
1602
|
+
fault("invalid_args", "cel op 'link' needs 'frames' — the frames to share this cel with.")
|
|
1603
|
+
end
|
|
1604
|
+
local source = get_cel(s, layer, frame, false)
|
|
1605
|
+
if not source then
|
|
1606
|
+
fault("invalid_args", "No cel on '" .. layer.name .. "' frame " .. frame.frameNumber ..
|
|
1607
|
+
" to link from. Draw it there first, or use op 'copy'.")
|
|
1608
|
+
end
|
|
1609
|
+
|
|
1610
|
+
local numbers = { frame.frameNumber }
|
|
1611
|
+
for _, n in ipairs(targets) do numbers[#numbers + 1] = find_frame(s, n).frameNumber end
|
|
1612
|
+
|
|
1577
1613
|
preserving_site(function()
|
|
1578
|
-
app.
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
end
|
|
1614
|
+
app.sprite = s
|
|
1615
|
+
app.range.layers = { layer }
|
|
1616
|
+
app.range.frames = numbers
|
|
1617
|
+
app.command.LinkCels()
|
|
1618
|
+
pcall(function() app.range:clear() end)
|
|
1584
1619
|
end)
|
|
1620
|
+
|
|
1621
|
+
-- Count what happened rather than what was asked for: linking replaces
|
|
1622
|
+
-- the shared image, so a target counts only if it now holds the same
|
|
1623
|
+
-- image object as the source does afterwards.
|
|
1624
|
+
local shared = layer:cel(frame)
|
|
1625
|
+
local id = shared and shared.image.id
|
|
1626
|
+
for _, n in ipairs(targets) do
|
|
1627
|
+
local c = layer:cel(find_frame(s, n))
|
|
1628
|
+
if c and id and c.image.id == id then applied = applied + 1 end
|
|
1629
|
+
end
|
|
1585
1630
|
elseif op == "unlink" then
|
|
1586
1631
|
preserving_site(function()
|
|
1587
1632
|
app.layer = layer; app.frame = frame; app.command.UnlinkCel(); applied = 1
|
|
@@ -2210,17 +2255,66 @@ H["export.run"] = function(args)
|
|
|
2210
2255
|
out:close()
|
|
2211
2256
|
files[#files + 1] = path
|
|
2212
2257
|
|
|
2213
|
-
elseif op == "
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
--
|
|
2219
|
-
--
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2258
|
+
elseif op == "aseprite" then
|
|
2259
|
+
s:saveCopyAs(path)
|
|
2260
|
+
files[#files + 1] = path
|
|
2261
|
+
|
|
2262
|
+
elseif op == "gif" then
|
|
2263
|
+
-- GIF holds 256 indexed colours, so writing an RGB sprite to one needs a
|
|
2264
|
+
-- quantisation — and Aseprite asks a human how to do it. Neither
|
|
2265
|
+
-- Sprite:saveCopyAs nor SaveFileCopyAs{ui = false} declines that dialog;
|
|
2266
|
+
-- the export simply waits, forever if nobody is watching the screen. It
|
|
2267
|
+
-- does not even look like a prompt from the outside: a modal dialog pumps
|
|
2268
|
+
-- events while it waits, so every other command keeps answering normally
|
|
2269
|
+
-- and only the export appears stuck.
|
|
2270
|
+
--
|
|
2271
|
+
-- So do the conversion here, on a throwaway copy, and hand Aseprite a
|
|
2272
|
+
-- sprite it has nothing left to ask about. The copy keeps the sprite's
|
|
2273
|
+
-- own palette, which is the point of a palette-first tool: the colours
|
|
2274
|
+
-- that come back are the colours the artist chose.
|
|
2275
|
+
--
|
|
2276
|
+
-- Headless tests cannot catch a regression here — `aseprite -b` has no
|
|
2277
|
+
-- dialogs at all, so the broken version passed them.
|
|
2278
|
+
-- `scale` matters more here than for a still: a browser scaling a 128px
|
|
2279
|
+
-- GIF up smooths it, and smoothed pixel art is ruined pixel art. Exporting
|
|
2280
|
+
-- big means the pixels stay square wherever the file is shown.
|
|
2281
|
+
local scale = args.scale or 1
|
|
2282
|
+
|
|
2283
|
+
-- Aseprite warns, once per session, that GIF cannot hold everything a
|
|
2284
|
+
-- sprite can — and waits for a click. Nothing in the save API declines
|
|
2285
|
+
-- it, and from the outside it does not even look like a prompt: a modal
|
|
2286
|
+
-- pumps events while it waits, so every other command keeps answering and
|
|
2287
|
+
-- only the export appears to hang, forever, on a machine nobody is
|
|
2288
|
+
-- watching. Silence it for the duration and hand it back, so the user's
|
|
2289
|
+
-- own File > Save As keeps whatever they chose.
|
|
2290
|
+
local restore_alert = nil
|
|
2291
|
+
pcall(function()
|
|
2292
|
+
restore_alert = app.preferences.gif.show_alert
|
|
2293
|
+
app.preferences.gif.show_alert = false
|
|
2294
|
+
end)
|
|
2295
|
+
|
|
2296
|
+
local ok, err = pcall(function()
|
|
2297
|
+
if s.colorMode == ColorMode.INDEXED and scale == 1 then
|
|
2298
|
+
s:saveCopyAs(path)
|
|
2299
|
+
else
|
|
2300
|
+
preserving_site(function()
|
|
2301
|
+
local copy = Sprite(s)
|
|
2302
|
+
app.sprite = copy
|
|
2303
|
+
if scale > 1 then copy:resize(s.width * scale, s.height * scale) end
|
|
2304
|
+
if copy.colorMode ~= ColorMode.INDEXED then
|
|
2305
|
+
app.command.ChangePixelFormat{ ui = false, format = "indexed" }
|
|
2306
|
+
end
|
|
2307
|
+
copy:saveCopyAs(path)
|
|
2308
|
+
copy:close()
|
|
2309
|
+
end)
|
|
2310
|
+
end
|
|
2223
2311
|
end)
|
|
2312
|
+
|
|
2313
|
+
if restore_alert ~= nil then
|
|
2314
|
+
pcall(function() app.preferences.gif.show_alert = restore_alert end)
|
|
2315
|
+
end
|
|
2316
|
+
if not ok then error(err, 0) end
|
|
2317
|
+
|
|
2224
2318
|
files[#files + 1] = path
|
|
2225
2319
|
|
|
2226
2320
|
elseif op == "frames" then
|
|
@@ -2862,6 +2956,13 @@ H["validate.run"] = function(args)
|
|
|
2862
2956
|
end
|
|
2863
2957
|
end
|
|
2864
2958
|
|
|
2959
|
+
-- Hidden layers are skipped by the per-pixel scans, the way outline and
|
|
2960
|
+
-- banding already skipped them: a finding about pixels that do not reach the
|
|
2961
|
+
-- export is noise, and a document that keeps its earlier drafts around as
|
|
2962
|
+
-- hidden layers is mostly hidden — on the sprite this was measured against,
|
|
2963
|
+
-- 769 of 1042 cels, which is where the 20s budget went.
|
|
2964
|
+
local hidden_skipped = 0
|
|
2965
|
+
|
|
2865
2966
|
for _, layer in ipairs(s.layers) do
|
|
2866
2967
|
if not layer.isGroup then
|
|
2867
2968
|
if wanted.layers and #layer.cels == 0 then
|
|
@@ -2869,22 +2970,24 @@ H["validate.run"] = function(args)
|
|
|
2869
2970
|
"Layer '" .. layer.name .. "' has no cels on any frame.", { layer = layer.name })
|
|
2870
2971
|
end
|
|
2871
2972
|
|
|
2973
|
+
if not layer.isVisible then hidden_skipped = hidden_skipped + 1 end
|
|
2974
|
+
|
|
2872
2975
|
for _, cel in ipairs(layer.cels) do
|
|
2873
2976
|
local img = cel.image
|
|
2874
2977
|
|
|
2875
|
-
if wanted.strays then
|
|
2978
|
+
if wanted.strays and layer.isVisible then
|
|
2876
2979
|
-- A lone opaque pixel with no opaque neighbour is nearly always a
|
|
2877
2980
|
-- misplaced click or an off-by-one in generated coordinates.
|
|
2878
2981
|
local strays = 0
|
|
2879
2982
|
local first = nil
|
|
2880
2983
|
for y = 0, img.height - 1 do
|
|
2881
2984
|
for x = 0, img.width - 1 do
|
|
2882
|
-
if
|
|
2985
|
+
if pixel_is_opaque(s, img:getPixel(x, y)) then
|
|
2883
2986
|
local neighbours = 0
|
|
2884
2987
|
for _, d in ipairs({ { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }) do
|
|
2885
2988
|
local nx, ny = x + d[1], y + d[2]
|
|
2886
2989
|
if nx >= 0 and ny >= 0 and nx < img.width and ny < img.height
|
|
2887
|
-
and
|
|
2990
|
+
and pixel_is_opaque(s, img:getPixel(nx, ny)) then neighbours = neighbours + 1 end
|
|
2888
2991
|
end
|
|
2889
2992
|
if neighbours == 0 then
|
|
2890
2993
|
strays = strays + 1
|
|
@@ -2901,7 +3004,7 @@ H["validate.run"] = function(args)
|
|
|
2901
3004
|
end
|
|
2902
3005
|
end
|
|
2903
3006
|
|
|
2904
|
-
if wanted.antialiasing and s.colorMode ~= ColorMode.INDEXED then
|
|
3007
|
+
if wanted.antialiasing and layer.isVisible and s.colorMode ~= ColorMode.INDEXED then
|
|
2905
3008
|
local semi = 0
|
|
2906
3009
|
for y = 0, img.height - 1 do
|
|
2907
3010
|
for x = 0, img.width - 1 do
|
|
@@ -2940,7 +3043,7 @@ H["validate.run"] = function(args)
|
|
|
2940
3043
|
for _, d in ipairs({ { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }) do
|
|
2941
3044
|
local nx, ny = x + d[1], y + d[2]
|
|
2942
3045
|
if nx < 0 or ny < 0 or nx >= img.width or ny >= img.height
|
|
2943
|
-
or
|
|
3046
|
+
or not pixel_is_opaque(s, img:getPixel(nx, ny)) then exposed = true end
|
|
2944
3047
|
end
|
|
2945
3048
|
if exposed then
|
|
2946
3049
|
total = total + 1
|
|
@@ -3036,6 +3139,15 @@ H["validate.run"] = function(args)
|
|
|
3036
3139
|
end
|
|
3037
3140
|
end
|
|
3038
3141
|
|
|
3142
|
+
-- Say what was not looked at, rather than letting a clean result imply the
|
|
3143
|
+
-- whole document was checked.
|
|
3144
|
+
if hidden_skipped > 0 then
|
|
3145
|
+
add_finding(findings, "layers", "note",
|
|
3146
|
+
hidden_skipped .. " hidden layer(s) were not scanned for strays, outline, banding or " ..
|
|
3147
|
+
"antialiasing — those checks describe what the sprite shows. Make a layer visible to include it.",
|
|
3148
|
+
{ count = hidden_skipped })
|
|
3149
|
+
end
|
|
3150
|
+
|
|
3039
3151
|
return { sprite = sprite_display_name(s), findings = findings }
|
|
3040
3152
|
end
|
|
3041
3153
|
|
package/extension/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "aseprite-ai-artist",
|
|
3
3
|
"displayName": "Aseprite AI Artist",
|
|
4
4
|
"description": "Lets a coding agent draw in this Aseprite session over a local WebSocket link. Connects to 127.0.0.1 only; nothing leaves the machine.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.5",
|
|
6
6
|
"author": "with-pebbly",
|
|
7
7
|
"publisher": "with-pebbly",
|
|
8
8
|
"license": "MIT",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pebbly/aseprite-ai-artist",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Agent-native control layer for Aseprite. MCP server (2025-11-25 spec, designed forward to 2026-07-28) + cross-agent skills for Claude Code, Codex, Gemini CLI and Cursor.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|