mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 03:43:11 +08:00
feat(desktop): let a nine-row action sheet become a pet instead of demanding an exact atlas
Importing an animated pet required a file that was exactly 1536x2288, laid out as 88 seamless cells, with the last two rows holding sixteen distinct gaze angles. No image model emits that. Whatever a user got back from Jimeng or ChatGPT was some fixed size like 1024x1536, so the path ended at "the animation atlas must be exactly 1536x2288 pixels" every time. The third card was worse: "AI-generate full animation" was hardcoded `disabled`, so the one entry point named after what people actually wanted to do was dead. The fix was already in the tree. `scripts/assemble-generated-pet-atlas.py` landed in the same commit as the four built-in pets, which is to say the built-ins were produced this way — it takes an action sheet at any size, slices it on an 8x9 grid, fits each cell to 192x208, mirrors the run row to make run-left, and reuses rows to reach eleven. That capability was never wired to anything a user could reach. `petAtlasNormalize.ts` reimplements it on a canvas in the renderer, so an author draws nine rows and the app derives the rest. Verified against the reference assembler by reversing dada-code's atlas into a nine-row sheet and re-normalizing it: every difference lands on semi-transparent antialiased edges (2314 pixels, max channel delta 14/255) and opaque regions are identical. That residue is canvas premultiplied-alpha round-tripping, not a slicing bug. Three contract details worth stating. Row frame counts are now derived from `PET_ANIMATION_DEFINITIONS` rather than typed out a fourth time; they come out equal to the assembler's `(6,8,8,4,5,8,6,6,6,8,8)`. A sheet already at 1536x2288 passes through byte-for-byte instead of being resliced, because resampling finished artwork buys nothing. And since the validator never inspects the alpha channel, a flattened white background used to import happily and render as a rectangle on the desktop — the renderer now rejects sheets whose atlas is under 5% transparent (the built-ins sit near 78%) with a message that names the actual problem. The copy stops describing the implementation. "Animate one image" and "Import professional animation atlas / exact 1536x2288 v2 PNG" become "use a picture you already have" and "I already have an action sheet"; the dead AI card becomes a three-step walkthrough carrying a copyable prompt, a labelled 8x9 reference grid that can be saved locally, and the checks that catch the common failures. Reference images are generated by a script rather than hand- placed, in both languages. All five locales move together. Caught while reviewing the real dialog in Electron: after finishing the walkthrough the form heading fell through to the atlas branch and announced "I already have an action sheet" to someone who had just been walked through drawing one. Covered by a test now. Not done: docs/images/desktop_ui/15_pet_create_methods.png still shows the old dialog and needs a fresh capture from a running app to match the styling of the shots around it.
This commit is contained in:
@@ -123,7 +123,7 @@ Open **Settings → Pets** and enable **Show desktop pet**.
|
||||
3. Enable the active-task panel if you want it to open automatically while a task is running. The panel remains hidden when no task is active.
|
||||
4. Hover for a small reaction, click the pet to focus the main window, or drag it to another position. Right-click the pet to close it; return to **Settings → Pets** to show it again.
|
||||
|
||||
Select **Add pet** to make a lightweight local animation from a transparent PNG or WebP, or import a supported `1536×2288` v2 animation atlas. The AI full-animation option is currently unavailable. Pets run only in the Electron desktop app and are not supported in H5.
|
||||
Select **Add pet** to make one of your own: use a transparent PNG or WebP you already have, or follow the in-dialog prompt to have any drawing AI produce an action sheet and pick that (sizes are aligned for you). Everything happens locally, without calling the current chat model or using chat quota. Pets run only in the Electron desktop app and are not supported in H5.
|
||||
|
||||
Follow the complete [Desktop Pet Guide](./pets.md) for custom-image requirements, task states, and interaction details.
|
||||
|
||||
|
||||
@@ -110,11 +110,13 @@ The window also supports direct interaction:
|
||||
|
||||
Select **Add pet** to choose a local creation path.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Animate one image** turns a static transparent PNG or WebP into a lightweight locally animated pet.
|
||||
- **Import professional animation atlas** accepts the supported `1536×2288` v2 sprite-sheet format.
|
||||
- **Generate full animation with AI** is visible for context but is currently unavailable.
|
||||
- **Use a picture you already have** turns a static transparent PNG or WebP into a lightweight locally animated pet. It will not run or track the cursor.
|
||||
- **Draw one with AI that runs and jumps** supplies a copyable prompt, a reference template and a checklist, so any drawing AI can produce an 8-column × 9-row action sheet you then pick.
|
||||
- **I already have an action sheet** skips the walkthrough and imports a sheet or finished atlas directly.
|
||||
|
||||
The last two paths slice, rescale and mirror the sheet locally on import, so exact source dimensions are not required; a finished `1536×2288` atlas is kept as-is.
|
||||
|
||||
Imports stay local and do not call the selected chat model. After a successful import, the custom companion appears under **Your pets** and becomes the selected pet.
|
||||
|
||||
|
||||
@@ -92,7 +92,8 @@ A custom pet made from one image receives lightweight breathing, floating, and t
|
||||
Check each requirement:
|
||||
|
||||
- A single image must be PNG or WebP, 32–4096 pixels on each side, no larger than 8 MB, and no more than 16,777,216 total pixels.
|
||||
- A v2 animation atlas must be exactly 1536×2288 pixels and use the documented 8-column × 11-row frame layout.
|
||||
- An action sheet must use an 8-column × 9-row layout. Exact pixel dimensions are not required — it is sliced and rescaled on import. A finished 1536×2288 atlas is kept as-is.
|
||||
- An action sheet must have a transparent background. White or coloured backdrops are rejected because the pet would render as a square on the desktop.
|
||||
- The pet ID may be at most 73 characters, contain only lowercase letters, numbers, and single hyphens, and must not duplicate an existing ID.
|
||||
- Display name and description are required.
|
||||
|
||||
@@ -110,11 +111,9 @@ There is no in-app delete button in the current version. Select a built-in pet f
|
||||
|
||||
Delete only the confirmed pet directory under `${CLAUDE_CONFIG_DIR:-~/.claude}/cc-haha/pets`. Do not delete the entire `~/.claude` directory. Built-in pets ship with the app and are not removed here.
|
||||
|
||||
### Why is “Generate full animation with AI” unavailable?
|
||||
### Does “Draw one with AI that runs and jumps” use my chat quota?
|
||||
|
||||
That path requires a separately configured image-generation service. The current chat model is not used to generate pet artwork or action frames, so the option is explicitly unavailable when no suitable service is configured.
|
||||
|
||||
You can use the recommended single-image animation path now, or import a prepared v2 animation atlas.
|
||||
No. That path never calls the chat model selected for the session, and the app does not request any image-generation service on your behalf. It gives you a prompt and a reference template; you generate the picture in whichever drawing tool you like and then pick the file. Assembly and import both happen on your own machine.
|
||||
|
||||
### Can the pet approve permissions or send replies?
|
||||
|
||||
|
||||
+101
-22
@@ -40,9 +40,9 @@ The animation switch affects the pet only. Turning it off does not stop sessions
|
||||
|
||||
## Create a custom pet
|
||||
|
||||
Select **Add pet** under **Your pets**. The creation dialog offers two working local import paths and shows a third, currently unavailable AI path.
|
||||
Select **Add pet** under **Your pets**. The dialog offers three ways to make one. Images are processed entirely on your own computer: nothing is uploaded, and no chat quota is used.
|
||||
|
||||

|
||||

|
||||
|
||||
Before choosing a file, enter:
|
||||
|
||||
@@ -52,41 +52,120 @@ Before choosing a file, enter:
|
||||
|
||||
The ID must be unique among your custom pets.
|
||||
|
||||
### Option 1: animate one image
|
||||
### Option 1: use a picture you already have
|
||||
|
||||
This is the recommended path for most users.
|
||||
The quickest route, about a minute. Pick a static image with a transparent background and the app adds breathing, floating and status motion locally.
|
||||
|
||||
Use a static image with:
|
||||
The image must have:
|
||||
|
||||
- PNG or WebP format;
|
||||
- a transparent background for the cleanest floating-window result;
|
||||
- PNG or WebP format (APNG and animated WebP are rejected);
|
||||
- width and height between `32px` and `4096px`;
|
||||
- no more than `16,777,216` total pixels;
|
||||
- a file size no larger than `8MB`.
|
||||
|
||||
Claude Code Haha copies and validates the image locally, then adds lightweight breathing, floating, and status motion. It does not invent new action frames, and it does not call the model selected for chat.
|
||||
This kind of pet only sways gently. It **will not run, and it will not track your cursor**. For full motion, use option 2.
|
||||
|
||||
### Option 2: import a v2 animation atlas
|
||||
### Option 2: draw one with AI that runs and jumps
|
||||
|
||||
Use this path only when you already have a correctly prepared frame atlas.
|
||||
About ten minutes, and you need an AI that can draw. The dialog walks you through the prompt, the reference template and the checks.
|
||||
|
||||
The atlas must be a static PNG or WebP with:
|
||||
#### Step 1: have an AI draw an action sheet
|
||||
|
||||
| Property | Required value |
|
||||
|---|---|
|
||||
| Full size | Exactly `1536×2288` |
|
||||
| Grid | `8` columns × `11` rows |
|
||||
| Cell size | `192×208` |
|
||||
| Spacing | No padding or gaps between cells |
|
||||
| Background | Transparent |
|
||||
Open any AI that can draw (Nano Banana, ChatGPT image generation, Midjourney, Stable Diffusion and Jimeng all work — these are examples, not endorsements) and send it the whole block below, replacing the two "Character" lines with what you want:
|
||||
|
||||
Rows are assigned to idle, run right, run left, wave, jump, failed, waiting, working, review, and two rows containing 16 gaze directions. The review row is part of the asset format; its presence does not guarantee that the current runtime will surface a separate review state.
|
||||
```text
|
||||
Draw me a game character action sheet (sprite sheet).
|
||||
|
||||
Every row may use fewer than eight visible action frames, but the grid dimensions and row positions must remain unchanged.
|
||||
[Character]
|
||||
A round-headed orange kitten wearing a small blue scarf, chibi
|
||||
three-heads-tall proportions, 3D cartoon render, soft glossy
|
||||
surface, bright cheerful colours.
|
||||
(Replace these lines with your own character - the more specific the better)
|
||||
|
||||
### AI animation is not available
|
||||
[Whole image]
|
||||
- Fully transparent background: no backdrop colour, no grid lines, no text, no drop shadow
|
||||
- Divide the image evenly into 8 columns x 9 rows, 72 equally sized cells
|
||||
- One action frame per cell, character centred with a little margin around it
|
||||
- Every cell must show the same character with identical proportions, colours and art style
|
||||
- Leave unused cells fully transparent
|
||||
|
||||
**AI-generate full animation** is displayed as an unavailable future path. It requires a separate image-generation service and does not fall back to the current chat model. A disabled card in this dialog is therefore expected behavior, not a provider configuration error.
|
||||
[What to draw in each row]
|
||||
Row 1, first 6 cells: standing still with a gentle breathing bob
|
||||
Row 2, all 8 cells: a full run cycle facing right, always facing right
|
||||
Row 3, first 4 cells: raising a hand and waving hello
|
||||
Row 4, first 5 cells: crouch, leap, land
|
||||
Row 5, all 8 cells: dejected and downcast, head lowered, sighing
|
||||
Row 6, first 6 cells: waiting in place, glancing around
|
||||
Row 7, first 6 cells: head down, busy working
|
||||
Row 8, all 8 cells: head and gaze starting straight up, turning slowly to the right through upper-right, right and lower-right, ending near straight down
|
||||
Row 9, all 8 cells: continuing from straight down, turning left through lower-left, left and upper-left, back to near straight up
|
||||
```
|
||||
|
||||
Getting it wrong on the first try is normal. Ask for a redraw, or say "keep the character, redraw row 2 only".
|
||||
|
||||
#### Step 2: check it against the template
|
||||
|
||||

|
||||
|
||||
When the picture is ready, check three things before importing:
|
||||
|
||||
1. **The background is see-through, not white.** A white backdrop becomes a square on your desktop; this is the most common mistake.
|
||||
2. **8 cells across, 9 rows down**, one action per cell.
|
||||
3. **The same character throughout**, with no change of face, colours or proportions.
|
||||
|
||||
**Save the template** in the dialog writes this reference image to disk so you can lay out frames against it.
|
||||
|
||||
#### Step 3: pick the file
|
||||
|
||||
Fill in the ID, name and description, then select the picture. **You do not need to resize anything** — see "Sizes are aligned for you" below.
|
||||
|
||||
### Option 3: I already have an action sheet
|
||||
|
||||
If you have drawn a sheet already, or hold a finished atlas, this path skips the walkthrough and goes straight to the form. Validation is identical to option 2.
|
||||
|
||||
### What to draw in each row
|
||||
|
||||
You only draw **nine rows**; the app derives the rest:
|
||||
|
||||
| Row | Content | Frames needed |
|
||||
|-----|---------|---------------|
|
||||
| 1 | Idle: standing still with a gentle breathing bob | 6 |
|
||||
| 2 | Run right: full run cycle, always facing right | 8 |
|
||||
| 3 | Wave: raise a hand and greet | 4 |
|
||||
| 4 | Jump: crouch, leap, land | 5 |
|
||||
| 5 | Fail: discouraged, head down, sighing | 8 |
|
||||
| 6 | Wait: looking around, shifting in place | 6 |
|
||||
| 7 | Work: head down, busy | 6 |
|
||||
| 8 | Gaze, upper half: straight up turning clockwise to near straight down | 8 |
|
||||
| 9 | Gaze, lower half: continuing from straight down back to near straight up | 8 |
|
||||
|
||||
Notes:
|
||||
|
||||
- **You do not draw "run left".** The app mirrors row 2 horizontally to produce it.
|
||||
- **The last two rows are optional in practice.** Repeat the first idle frame and the pet simply will not track your cursor; everything else still works.
|
||||
- Leave unused cells at the right of each row fully transparent.
|
||||
|
||||
### Sizes are aligned for you
|
||||
|
||||
After you pick the file, the app assembles the runtime atlas locally: it slices the sheet on an 8 × 9 grid, rescales each cell to `192 × 208`, centres the character, mirrors the run row, and fills in the remaining runtime rows to reach `1536 × 2288`.
|
||||
|
||||
That means:
|
||||
|
||||
- **Exact dimensions are not required.** Common AI output sizes such as `1024 × 1152` work; a ratio close to 8:9 gives the best result. The reference size is `1536 × 1872`.
|
||||
- **A finished `1536 × 2288` atlas is kept byte-for-byte** and is never resampled.
|
||||
- The assembled file stays under `8MB`; WebP encoding is used automatically if a lossless PNG would exceed it.
|
||||
|
||||
### Common problems
|
||||
|
||||
| Message | Cause and fix |
|
||||
|---------|---------------|
|
||||
| This image has no transparent background… | The sheet was exported on a white or coloured backdrop. Ask for a transparent PNG, or remove the background with an editor. |
|
||||
| This image cannot be sliced into 8 columns by 9 rows | The row or column count is off. Confirm 8 across and 9 down, or use a finished `1536 × 2288` atlas. |
|
||||
| That image could not be read | An animated file (APNG / animated WebP) or a corrupt one. Use a static PNG or WebP. |
|
||||
| That image is too big | The source exceeds 8 MB. Compress it, or ask for smaller output. |
|
||||
| A pet with this ID already exists | Choose a different Pet ID, or remove the existing one (see "Storage and removal"). |
|
||||
|
||||
When the size, format, or image content does not meet these rules, the app refuses to create the pet and shows the matching error instead of adding an invalid entry.
|
||||
|
||||
After a successful import, the new pet is selected automatically and appears under **Your pets**.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user