pi-sprite 1.0.0

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE.md +7 -0
  4. package/README.md +353 -0
  5. package/examples/README.md +15 -0
  6. package/examples/custom-pets/wumpus-template/README.md +21 -0
  7. package/examples/custom-pets/wumpus-template/pet.json +14 -0
  8. package/examples/petdex-downloads/.gitkeep +0 -0
  9. package/extensions/index.ts +104 -0
  10. package/package.json +77 -0
  11. package/skills/pi-sprite-authoring/SKILL.md +330 -0
  12. package/skills/pi-sprite-authoring/assets/wumpus-template/pet.json +14 -0
  13. package/skills/pi-sprite-authoring/references/character-cohesion-review.md +65 -0
  14. package/skills/pi-sprite-authoring/references/gpt-image-sprite-workflow.md +181 -0
  15. package/skills/pi-sprite-authoring/references/petdex-reference-to-custom-pet.md +155 -0
  16. package/skills/pi-sprite-authoring/references/wumpus-sprite-prompts.md +54 -0
  17. package/skills/pi-sprite-authoring/scripts/assemble_sprite_strip.py +98 -0
  18. package/skills/pi-sprite-authoring/scripts/create-pet-template.mjs +51 -0
  19. package/skills/pi-sprite-authoring/scripts/create_motion_strip.py +110 -0
  20. package/skills/pi-sprite-authoring/scripts/download-petdex-examples.mjs +79 -0
  21. package/skills/pi-sprite-authoring/scripts/openai_sprite_image.py +223 -0
  22. package/skills/pi-sprite-authoring/scripts/remove_sprite_background.py +207 -0
  23. package/src/agent/session-entries.ts +28 -0
  24. package/src/agent/side-completion.ts +94 -0
  25. package/src/agent/side-session-text.ts +20 -0
  26. package/src/agent/side-session-types.ts +12 -0
  27. package/src/agent/side-session.ts +107 -0
  28. package/src/btw/completion.ts +15 -0
  29. package/src/btw/format.ts +30 -0
  30. package/src/btw/index.ts +306 -0
  31. package/src/btw/prompt.ts +35 -0
  32. package/src/btw/recap.ts +56 -0
  33. package/src/btw/session.ts +37 -0
  34. package/src/btw/thread-store.ts +37 -0
  35. package/src/context/index.ts +343 -0
  36. package/src/recap/conversation.ts +22 -0
  37. package/src/recap/direct.ts +15 -0
  38. package/src/recap/format.ts +25 -0
  39. package/src/recap/generation.ts +58 -0
  40. package/src/recap/index.ts +86 -0
  41. package/src/sprite/commands.ts +205 -0
  42. package/src/sprite/download.ts +75 -0
  43. package/src/sprite/kitty-placeholder.ts +441 -0
  44. package/src/sprite/live-status-format.ts +67 -0
  45. package/src/sprite/live-status.ts +48 -0
  46. package/src/sprite/loader.ts +134 -0
  47. package/src/sprite/manifest.ts +87 -0
  48. package/src/sprite/paths.ts +8 -0
  49. package/src/sprite/petdex.ts +133 -0
  50. package/src/sprite/renderer.ts +491 -0
  51. package/src/sprite/runtime.ts +524 -0
  52. package/src/sprite/turn-status-format.ts +112 -0
  53. package/src/sprite/turn-status.ts +88 -0
  54. package/src/ui/overlay.ts +308 -0
@@ -0,0 +1,330 @@
1
+ ---
2
+ name: pi-sprite-authoring
3
+ description: Create custom pi-sprite pets from AI-generated, reference-driven, or hand-drawn sprites. Use when making Wumpus or Petdex-inspired sprites, preparing pet.json manifests, generating GPT Image prompts or images, converting outputs into /pet import folders, or dogfooding custom pi-sprite pets.
4
+ ---
5
+
6
+ # Pi Sprite Authoring
7
+
8
+ Create importable `pi-sprite` pet folders from generated, reference-driven, or hand-drawn sprites.
9
+
10
+ ## Default workflow
11
+
12
+ 1. Prefer the expanded five-image format for first-time authoring:
13
+ `idle.png`, `thinking.png`, `working.png`, `success.png`, `error.png`, and `pet.json`.
14
+ 2. Gather the character brief and any local reference images before generating. Ask for user choice when the character direction is still open.
15
+ 3. If the user mentions Boba, Petdex, Sprite Mart, or another existing pet as inspiration, read `references/petdex-reference-to-custom-pet.md`.
16
+ 4. If the user wants GPT/OpenAI image generation or copy-paste image prompts, read `references/gpt-image-sprite-workflow.md`.
17
+ 5. If the user wants Wumpus-specific mascot prompts, read `references/wumpus-sprite-prompts.md`.
18
+ 6. Bind each reference image to an explicit role and instruction. Use references for style, scale, outline, palette, or mood; do not copy unclear-license third-party character identity.
19
+ 7. Present 3-5 direction cards before locking the character, unless the user already supplied a precise design.
20
+ 8. After the user chooses a direction, write a stable character lock and generate or select a canonical `idle` anchor before making the remaining states.
21
+ 9. Use the canonical anchor as the primary `character_reference` for `thinking`, `working`, `success`, and `error`; use Petdex or other third-party references only as secondary style/scale references.
22
+ 10. Run a character-cohesion review against the canonical anchor before packaging. Regenerate states with major drift. Read `references/character-cohesion-review.md` when a reusable review prompt would help.
23
+ 11. If generated outputs lack alpha, run local background cleanup before packaging; keep the original generated files and metadata.
24
+ 12. Ask whether the user wants an animated version. If yes, create subtle per-state frame strips and add `frame.width`/`frame.height` to `pet.json`.
25
+ 13. Ask whether the user wants optional pet personality metadata. If yes, add one short bounded `personality` sentence to `pet.json`; if no, omit it.
26
+ 14. Create a pet folder containing `pet.json` plus accepted image files or strips.
27
+ 15. Import with a single slash command, `/pet import <folder>`, then run follow-up commands separately: `/pet clear-native`, `/pet show`, `/pet size small`, and `/pet label off`.
28
+
29
+ ## Direction-card format
30
+
31
+ Use this format before image generation when the user is still choosing a character direction:
32
+
33
+ ```markdown
34
+ ## Direction options
35
+
36
+ 1. **Short name**
37
+ - Character: concrete subject and silhouette
38
+ - Mood: emotional target
39
+ - Visual lock: palette, outline, scale, one or two immutable traits
40
+ - Why it fits: why this works as a terminal pet
41
+ - Risk: what may become generic or hard to read
42
+ ```
43
+
44
+ Ask the user to pick one direction, combine directions, or revise the brief. Do not silently pick a final design unless the user asks for speed/autonomy.
45
+
46
+ ## Create a starter pet folder
47
+
48
+ Run from the pi-sprite repo or installed package root:
49
+
50
+ ```bash
51
+ node skills/pi-sprite-authoring/scripts/create-pet-template.mjs \
52
+ --id wumpus \
53
+ --name Wumpus \
54
+ --out /tmp/wumpus-sprite
55
+ ```
56
+
57
+ Add generated images to the output folder as:
58
+
59
+ ```text
60
+ idle.png
61
+ thinking.png
62
+ working.png
63
+ success.png
64
+ error.png
65
+ ```
66
+
67
+ Then import. Run each slash command separately; do not paste the import plus follow-up commands as one multi-line command.
68
+
69
+ ```text
70
+ /pet import /tmp/wumpus-sprite
71
+ /pet choose wumpus
72
+ /pet show
73
+ ```
74
+
75
+ ## Optional personality pass
76
+
77
+ Personality metadata is optional. Ask after the user accepts the visual sprite set and before finalizing `pet.json`:
78
+
79
+ ```text
80
+ Do you want this pet to have a short personality for explicit /btw side conversations, or should it stay visual-only?
81
+ ```
82
+
83
+ If the user says yes, write one short bounded style sentence. Keep it under about 120 characters when possible and never longer than `pet.json`'s 2000-character limit. It should guide tone and concise response style only, not add operational instructions, autonomy, status behavior, main-thread commentary, or roleplay obligations.
84
+
85
+ Good examples:
86
+
87
+ ```text
88
+ Warm, concise, lightly mischievous, and practical. Keep BTW answers short.
89
+ Sweet, loyal, curious, and a little goofy. Keep BTW answers short and grounded.
90
+ ```
91
+
92
+ For Wendy, a good first pass would be:
93
+
94
+ ```json
95
+ "personality": "Sweet, loyal, curious, and a little goofy. Keep BTW answers short and grounded."
96
+ ```
97
+
98
+ Do not invent personality when the user only wants a visual pet. Do not make the personality longer than the manifest description. The personality is not injected into normal main-agent turns; it only guides explicit BTW side replies such as `/btw`, `/btw:ask`, and `/btw:new <message>`.
99
+
100
+ To create a starter folder with personality already in the manifest, pass `--personality`:
101
+
102
+ ```bash
103
+ node skills/pi-sprite-authoring/scripts/create-pet-template.mjs \
104
+ --id wendybot3000 \
105
+ --name WendyBot3000 \
106
+ --personality "Sweet, loyal, curious, and a little goofy. Keep BTW answers short and grounded." \
107
+ --out /tmp/wendybot3000-sprite
108
+ ```
109
+
110
+ ## Canonical anchor gate
111
+
112
+ For generated pets, avoid generating all five states independently. First generate or choose a canonical `idle` image. Treat it as the ground-truth identity for the pet.
113
+
114
+ Use this acceptance gate before final packaging:
115
+
116
+ ```markdown
117
+ ## Character cohesion review
118
+
119
+ Canonical anchor: path/to/idle.png
120
+
121
+ | State | Identity | Silhouette | Face | Ears/props | Palette/outline | State readability | Verdict |
122
+ | --- | --- | --- | --- | --- | --- | --- | --- |
123
+ | thinking | same/minor drift/major drift | ... | ... | ... | ... | clear/unclear | accept/regenerate |
124
+ ```
125
+
126
+ Regenerate any state with major drift in identity, silhouette, face, signature props, palette, or outline thickness. Pose and expression should change; the character design should not. For a reusable human/vision-model review prompt, use `references/character-cohesion-review.md`.
127
+
128
+ ## Optional animation pass
129
+
130
+ After the static five-state pet works, ask whether the user wants an animated version. Offer two levels:
131
+
132
+ 1. **Simple motion** — no image API needed. Reuse one accepted image per state and create subtle bob/shift strips. This is safest for character consistency.
133
+ 2. **Expressive keyframes** — generate or draw per-frame differences, such as eye shifts, head tilts, prop twinkles, or sprite-specific details. This is higher quality but must pass the cohesion review because identity drift is easier.
134
+
135
+ Keep animation subtle; terminal pets read best when the character identity stays fixed and only a few pixels, the whole body, or one sprite-specific feature changes. Do not blindly use feature examples like leaf bob or tail wag unless that character actually has the feature.
136
+
137
+ Recommended frame counts:
138
+
139
+ ```text
140
+ idle: 4 frames — blink, breathing, or leaf/ear bob
141
+ thinking: 4 frames — slight head tilt or eye shift
142
+ working: 6 frames — paw/key tap loop
143
+ success: 5 frames — bounce or sparkle twinkle
144
+ error: 4 frames — worried blink or small droop
145
+ ```
146
+
147
+ `pi-sprite` supports per-state horizontal strips when `pet.json` includes a frame size:
148
+
149
+ ```json
150
+ {
151
+ "sprites": {
152
+ "idle": "idle-strip.png",
153
+ "thinking": "thinking-strip.png",
154
+ "working": "working-strip.png",
155
+ "success": "success-strip.png",
156
+ "error": "error-strip.png"
157
+ },
158
+ "frame": { "width": 128, "height": 128 }
159
+ }
160
+ ```
161
+
162
+ For simple motion, create a strip from one accepted state image:
163
+
164
+ ```bash
165
+ uv run --with pillow python skills/pi-sprite-authoring/scripts/create_motion_strip.py \
166
+ --input /tmp/wumpus/clean/thinking.png \
167
+ --output /tmp/wumpus/pet/thinking-strip.png \
168
+ --metadata /tmp/wumpus/pet/thinking-strip.metadata.json \
169
+ --preset thinking-bob \
170
+ --frame-width 128 \
171
+ --frame-height 128
172
+ ```
173
+
174
+ Useful simple presets:
175
+
176
+ ```text
177
+ bob
178
+ thinking-bob
179
+ working-tap
180
+ success-bounce
181
+ error-droop
182
+ ```
183
+
184
+ For expressive keyframes, generate or draw cleaned frames first, then assemble them into a strip:
185
+
186
+ ```bash
187
+ uv run --with pillow python skills/pi-sprite-authoring/scripts/assemble_sprite_strip.py \
188
+ --frame /tmp/wumpus/frames/idle-0.png \
189
+ --frame /tmp/wumpus/frames/idle-1.png \
190
+ --frame /tmp/wumpus/frames/idle-2.png \
191
+ --frame /tmp/wumpus/frames/idle-3.png \
192
+ --output /tmp/wumpus/pet/idle-strip.png \
193
+ --metadata /tmp/wumpus/pet/idle-strip.metadata.json \
194
+ --frame-width 128 \
195
+ --frame-height 128
196
+ ```
197
+
198
+ ## Background cleanup
199
+
200
+ If the image model returns a non-alpha PNG, use the local cleanup helper before packaging. It removes only edge-connected background pixels, which is safer than deleting every near-white pixel inside the sprite.
201
+
202
+ ```bash
203
+ uv run --with pillow python skills/pi-sprite-authoring/scripts/remove_sprite_background.py \
204
+ --input /tmp/boba-sprite/generated/thinking.png \
205
+ --output /tmp/boba-sprite/clean/thinking.png \
206
+ --metadata /tmp/boba-sprite/clean/thinking.metadata.json \
207
+ --target-size 128 \
208
+ --padding 10
209
+ ```
210
+
211
+ Use the cleaned images in the importable pet folder, but keep original generation outputs, prompts, and metadata for provenance.
212
+
213
+ ## Optional OpenAI image generation
214
+
215
+ Use prompt-only mode when no image API is available. When `OPENAI_API_KEY` is available and the user approves API calls, use the bundled helper:
216
+
217
+ ```bash
218
+ uv run --with openai python skills/pi-sprite-authoring/scripts/openai_sprite_image.py \
219
+ --prompt-file /tmp/boba-sprite/prompts/idle.txt \
220
+ --reference-image /tmp/boba-ref.png \
221
+ --reference-instruction "Use for pixel-art scale, outline thickness, and terminal readability only. Do not copy character identity." \
222
+ --output-dir /tmp/boba-sprite/generated \
223
+ --prefix idle
224
+ ```
225
+
226
+ Use `--dry-run` first to validate prompt/reference wiring without making API calls:
227
+
228
+ ```bash
229
+ uv run --with openai python skills/pi-sprite-authoring/scripts/openai_sprite_image.py \
230
+ --dry-run \
231
+ --prompt "Create a tiny transparent pixel-art idle sprite." \
232
+ --reference-image /tmp/boba-ref.png \
233
+ --reference-instruction "Use for silhouette scale only; do not copy identity." \
234
+ --output-dir /tmp/boba-sprite/generated \
235
+ --prefix idle
236
+ ```
237
+
238
+ ## Use reference sprites safely
239
+
240
+ Do not commit copyrighted or unclear-license third-party sprite assets to the repo. For temporary visual references, run:
241
+
242
+ ```bash
243
+ node skills/pi-sprite-authoring/scripts/download-petdex-examples.mjs --limit 12 --out examples/petdex-downloads
244
+ ```
245
+
246
+ Use downloaded examples only as local reference unless the asset license is verified. The script writes provenance notes next to the downloads.
247
+
248
+ ## Output requirements
249
+
250
+ For generated Wumpus or custom sprites, produce:
251
+
252
+ ```text
253
+ custom-sprite/
254
+ ├── pet.json
255
+ ├── idle.png
256
+ ├── thinking.png
257
+ ├── working.png
258
+ ├── success.png
259
+ └── error.png
260
+ ```
261
+
262
+ Keep contact sheets, raw generations, prompts, and metadata next to the working directory, not inside the final import folder unless you intentionally want those files copied into the installed pet.
263
+
264
+ ```text
265
+ working-dir/
266
+ ├── anchor/
267
+ ├── generated/
268
+ ├── prompts/
269
+ ├── clean/
270
+ ├── contact-sheet.png
271
+ └── custom-sprite/
272
+ ├── pet.json
273
+ ├── idle.png
274
+ ├── thinking.png
275
+ ├── working.png
276
+ ├── success.png
277
+ └── error.png
278
+ ```
279
+
280
+ For animated pets, use strips and record the frame size:
281
+
282
+ ```text
283
+ custom-sprite/
284
+ ├── pet.json
285
+ ├── idle-strip.png
286
+ ├── thinking-strip.png
287
+ ├── working-strip.png
288
+ ├── success-strip.png
289
+ └── error-strip.png
290
+ ```
291
+
292
+ Use this manifest shape:
293
+
294
+ ```json
295
+ {
296
+ "id": "wumpus",
297
+ "name": "Wumpus",
298
+ "author": "Alex",
299
+ "description": "A tiny Wumpus companion for pi-sprite.",
300
+ "personality": "Warm, concise, lightly mischievous, and practical. Keep BTW answers short.",
301
+ "sprites": {
302
+ "idle": "idle.png",
303
+ "thinking": "thinking.png",
304
+ "working": "working.png",
305
+ "success": "success.png",
306
+ "error": "error.png"
307
+ }
308
+ }
309
+ ```
310
+
311
+ ## Quality checklist
312
+
313
+ - Keep the character readable at `small` size.
314
+ - Use transparent backgrounds, or run local background cleanup when the model returns non-alpha images.
315
+ - Keep each state visually consistent: same pose scale, outline, palette, and canvas size.
316
+ - Avoid text, shadows, busy props, and tiny facial details.
317
+ - Add optional `personality` only when the pet should speak with a bounded voice in explicit `/btw` side conversations.
318
+ - Record prompt files and reference instructions next to generated assets.
319
+ - For animated strips, keep frame size consistent and verify `pet.json` has `frame.width` and `frame.height`.
320
+ - Test in native and ANSI fallback modes when possible:
321
+
322
+ ```text
323
+ /pet size small
324
+ /pet label off
325
+ /pet show
326
+ ```
327
+
328
+ ```bash
329
+ PI_SPRITE_NATIVE_IMAGES=0 pi -e . -p "/pet show" --no-session
330
+ ```
@@ -0,0 +1,14 @@
1
+ {
2
+ "id": "wumpus",
3
+ "name": "Wumpus",
4
+ "author": "Alex",
5
+ "description": "A tiny Wumpus companion for pi-sprite.",
6
+ "personality": "Warm, concise, lightly mischievous, and practical. Keep BTW answers short.",
7
+ "sprites": {
8
+ "idle": "idle.png",
9
+ "thinking": "thinking.png",
10
+ "working": "working.png",
11
+ "success": "success.png",
12
+ "error": "error.png"
13
+ }
14
+ }
@@ -0,0 +1,65 @@
1
+ # Character cohesion review
2
+
3
+ Use this after generating a canonical anchor and the remaining sprite states. The goal is to catch when image generation creates five related variants instead of one character in five states.
4
+
5
+ ## Inputs
6
+
7
+ - `anchor/canonical-idle.png` — the ground-truth character identity.
8
+ - Candidate state images: `thinking.png`, `working.png`, `success.png`, `error.png`.
9
+ - Optional style reference images, used only to understand intended palette, outline, and scale.
10
+
11
+ ## Review prompt
12
+
13
+ Use this prompt with a human reviewer or a vision-capable model. Do not ask the reviewer to judge whether the art is generally cute until identity preservation is checked.
14
+
15
+ ```text
16
+ You are reviewing a custom pi-sprite pet for character consistency.
17
+
18
+ The first image is the canonical character anchor. Treat it as ground truth.
19
+ The remaining images are state candidates for thinking, working, success, and error.
20
+
21
+ Judge whether each state preserves the same character identity. Pose and expression may change. The character design should not change.
22
+
23
+ Check these invariants:
24
+ - overall silhouette and body proportions
25
+ - head/body shape
26
+ - face shape and eye style
27
+ - signature ears, props, straw, horns, tail, clothes, or other defining features
28
+ - palette and relative color placement
29
+ - outline thickness and pixel-art style
30
+ - canvas scale, baseline, and padding
31
+
32
+ Return a markdown table with these columns:
33
+ State | Identity | Silhouette | Face | Signature traits | Palette/outline | Scale/baseline | State readability | Verdict | Regeneration notes
34
+
35
+ Use only these verdicts:
36
+ - accept
37
+ - regenerate-minor
38
+ - regenerate-major
39
+
40
+ If verdict is regenerate-minor or regenerate-major, give concrete regeneration notes that say what must be preserved from the anchor and what pose/expression should change.
41
+ ```
42
+
43
+ ## Manual rubric
44
+
45
+ | Rating | Meaning | Action |
46
+ | --- | --- | --- |
47
+ | same | Clearly the same character in a new pose. | Accept if state reads clearly. |
48
+ | minor drift | Mostly same character, but one trait moved or softened. | Accept for rough dogfood, or regenerate for final asset. |
49
+ | major drift | Reads as a sibling/variant/new character. | Regenerate. |
50
+
51
+ Reject on any major drift in identity, silhouette, face, signature traits, palette, or outline. A state can be readable and still fail if it reads as a different character.
52
+
53
+ ## Regeneration prompt pattern
54
+
55
+ ```text
56
+ Regenerate the STATE image using the canonical anchor as the first reference.
57
+ Preserve exact character identity from the anchor: [specific silhouette, face, props, palette, outline, scale].
58
+ The previous attempt drifted because [specific issue].
59
+ Change only [pose/expression/state cue].
60
+ Do not redesign the character, change proportions, move signature props, or introduce a new variant.
61
+ ```
62
+
63
+ ## Packaging gate
64
+
65
+ Only package/import states that pass the cohesion review or are explicitly accepted by the user for rough dogfood. Record the review notes next to the generated assets so future iterations know which traits are locked.
@@ -0,0 +1,181 @@
1
+ # GPT Image Sprite Workflow
2
+
3
+ Use this workflow when generating `pi-sprite` pet images with ChatGPT, GPT Image, or the bundled OpenAI helper.
4
+
5
+ ## Contents
6
+
7
+ - First choice: five separate images
8
+ - Prompt structure
9
+ - Canonical anchor workflow
10
+ - Five-state prompt set
11
+ - OpenAI helper
12
+ - Iteration prompts
13
+ - Final packaging
14
+
15
+ ## First choice: five separate images
16
+
17
+ For first-time authoring, generate five separate transparent PNGs instead of a spritesheet:
18
+
19
+ ```text
20
+ idle.png
21
+ thinking.png
22
+ working.png
23
+ success.png
24
+ error.png
25
+ ```
26
+
27
+ Spritesheets are useful later, but five files are easier to inspect, rename, regenerate, and import.
28
+
29
+ ## Prompt structure
30
+
31
+ Use a character lock plus a state-specific delta.
32
+
33
+ ```text
34
+ Create one transparent PNG pixel-art sprite for a terminal companion.
35
+
36
+ CANONICAL CHARACTER:
37
+ [stable character lock]
38
+
39
+ STATE:
40
+ [idle/thinking/working/success/error plus pose]
41
+
42
+ STYLE AND CANVAS:
43
+ - 128x128 square transparent canvas
44
+ - centered with consistent feet/baseline and 6-10px padding
45
+ - crisp pixel-art look, bold dark outline, limited palette
46
+ - readable at small terminal size
47
+ - no text, letters, logo, watermark, background, drop shadow, or busy props
48
+
49
+ REFERENCE IMAGES:
50
+ [explicit role/instruction for each reference]
51
+ ```
52
+
53
+ ## Canonical anchor workflow
54
+
55
+ For better character consistency, use a ground-truth anchor image:
56
+
57
+ 1. Generate 3-6 `idle` candidates from the character lock and style references.
58
+ 2. Ask the user to pick the canonical anchor.
59
+ 3. Save it as `anchor/canonical-idle.png`.
60
+ 4. Generate `thinking`, `working`, `success`, and `error` with `anchor/canonical-idle.png` as the first reference and role `character_reference`.
61
+ 5. Keep Petdex or other third-party images as secondary `style_reference` or `scale_reference` only.
62
+ 6. Run the character-cohesion review before packaging. Use `character-cohesion-review.md` when you need a reusable review prompt.
63
+ 7. If accepted images lack alpha, run local background cleanup before importing.
64
+
65
+ State prompts should say:
66
+
67
+ ```text
68
+ Use the first attached image as the canonical character identity. Preserve the exact body shape, ear/pearl shapes, straw angle, face style, palette, outline thickness, proportions, canvas scale, and baseline. Change only the pose and expression needed for this state. Do not redesign the character or create a new variant.
69
+ ```
70
+
71
+ ## Five-state prompt set
72
+
73
+ After the user chooses a direction and canonical anchor, create one prompt file per state:
74
+
75
+ ```text
76
+ prompts/idle.txt
77
+ prompts/thinking.txt
78
+ prompts/working.txt
79
+ prompts/success.txt
80
+ prompts/error.txt
81
+ ```
82
+
83
+ Use these state deltas:
84
+
85
+ - `idle`: relaxed neutral pose, calm expression.
86
+ - `thinking`: curious head tilt, small pondering gesture, no question-mark text.
87
+ - `working`: focused and active, maybe typing on one large simple prop.
88
+ - `success`: celebratory pose, sparkle-like body language but no text.
89
+ - `error`: confused or worried expression, still friendly and readable.
90
+
91
+ Keep all other character details identical.
92
+
93
+ ## OpenAI helper
94
+
95
+ Dry-run first:
96
+
97
+ ```bash
98
+ uv run --with openai python skills/pi-sprite-authoring/scripts/openai_sprite_image.py \
99
+ --dry-run \
100
+ --prompt-file /tmp/boba-sprite/prompts/idle.txt \
101
+ --reference-image /tmp/boba-ref.png \
102
+ --reference-instruction "Use for compact pixel-art scale and outline only; do not copy character identity." \
103
+ --output-dir /tmp/boba-sprite/generated \
104
+ --prefix idle
105
+ ```
106
+
107
+ Generate when the user approves API calls and `OPENAI_API_KEY` is set:
108
+
109
+ ```bash
110
+ uv run --with openai python skills/pi-sprite-authoring/scripts/openai_sprite_image.py \
111
+ --prompt-file /tmp/boba-sprite/prompts/idle.txt \
112
+ --reference-image /tmp/boba-ref.png \
113
+ --reference-instruction "Use for compact pixel-art scale and outline only; do not copy character identity." \
114
+ --output-dir /tmp/boba-sprite/generated \
115
+ --prefix idle
116
+ ```
117
+
118
+ The helper uses image generation when no references are supplied and image edit when references are supplied. It appends reference roles/instructions to the effective prompt sent to OpenAI, so the model can distinguish the canonical `character_reference` from style/scale references. It defaults to `--background auto` because some current GPT Image models reject transparent-background requests; pass `--background transparent` only with a model that supports it. The helper writes output images, prompt copies, and metadata, and records the background setting.
119
+
120
+ For anchor-based generation with multiple references, pass each reference with its own role and instruction in order:
121
+
122
+ ```bash
123
+ uv run --with openai python skills/pi-sprite-authoring/scripts/openai_sprite_image.py \
124
+ --prompt-file /tmp/boba-sprite/prompts/thinking.txt \
125
+ --reference-image /tmp/boba-sprite/anchor/canonical-idle.png \
126
+ --reference-role character_reference \
127
+ --reference-instruction "Preserve exact character identity; only change pose and expression." \
128
+ --reference-image /tmp/boba-sprite/refs/boba-spritesheet.png \
129
+ --reference-role style_reference \
130
+ --reference-instruction "Use only for pixel-art scale and outline thickness; do not copy identity." \
131
+ --output-dir /tmp/boba-sprite/generated \
132
+ --prefix thinking
133
+ ```
134
+
135
+ ## Background cleanup
136
+
137
+ If the accepted image lacks alpha, clean it locally before packaging:
138
+
139
+ ```bash
140
+ uv run --with pillow python skills/pi-sprite-authoring/scripts/remove_sprite_background.py \
141
+ --input /tmp/boba-sprite/generated/thinking.png \
142
+ --output /tmp/boba-sprite/clean/thinking.png \
143
+ --metadata /tmp/boba-sprite/clean/thinking.metadata.json \
144
+ --target-size 128 \
145
+ --padding 10
146
+ ```
147
+
148
+ The cleanup helper removes edge-connected background colors sampled from image edges, then places the sprite onto a square transparent canvas. Check the result in Preview or via `/pet import`; adjust `--threshold`, `--background-color`, or `--padding` if it removes too much or too little.
149
+
150
+ ## Iteration prompts
151
+
152
+ After inspecting output, iterate with delta prompts instead of restarting.
153
+
154
+ ```text
155
+ Keep: [specific successful silhouette/palette/expression].
156
+ Change: [specific pose or readability issue].
157
+ Remove: [text, background, extra props, over-detail, copied identity].
158
+ Preserve: same character lock, 128x128 transparent canvas, bold pixel outline, same palette.
159
+ ```
160
+
161
+ Common fixes:
162
+
163
+ - Too detailed: "Simplify to one large readable silhouette; remove tiny decorative details."
164
+ - Background not transparent: "Transparent background only; no floor, shadow, frame, or scene." If the current model rejects `--background transparent`, regenerate with a compatible model or remove the background in a separate image-editing step before final packaging.
165
+ - Character drift: "Preserve the canonical character lock exactly; only change the pose/expression."
166
+ - Looks copied from reference: "Make this an original character; keep only pixel-art density and readability from the reference."
167
+ - Too large/small: "Center on 128x128 with 8px transparent padding and consistent feet baseline."
168
+
169
+ ## Final packaging
170
+
171
+ Select the best output for each state and copy/rename into the pet folder:
172
+
173
+ ```text
174
+ pet/idle.png
175
+ pet/thinking.png
176
+ pet/working.png
177
+ pet/success.png
178
+ pet/error.png
179
+ ```
180
+
181
+ Keep generated prompt and metadata files in a separate dogfood workspace for provenance. Do not commit generated third-party-reference-derived assets unless licenses and provenance are acceptable.