# 制作 Agent 搭档宠物

自定义宠物是一份 UTF-8 JSON，包含元信息和七个状态的内嵌位图。不需要编译应用，也不加载外部网页或脚本。

## 准备七张图片

文件名对应：`idle.png`（陪伴）、`thinking.png`（思考）、`running_tools.png`（执行工具）、`waiting_user.png`（等待确认）、`success.png`（完成）、`error.png`（异常）、`petting.png`（逗宠）。推荐透明背景、相同画布尺寸、主体位置一致，先用 128～256px 验证清晰度与文件大小。

每个状态都必须提供，允许多种状态共用同一张图。格式只允许 PNG、WebP、GIF；图片可以是该格式支持的动画。每张宽和高都不能超过 2048px。SVG、远程 URL、HTML 和 CSS 不支持。

## 用 Node.js 生成包

把以下代码保存为 `build-pet.mjs`，与七张 PNG 放在同一目录，运行 `node build-pet.mjs`：

```javascript
import { readFileSync, writeFileSync } from 'node:fs'
const states = ['idle','thinking','running_tools','waiting_user','success','error','petting']
const images = Object.fromEntries(states.map(state => [state,
  'data:image/png;base64,' + readFileSync(state + '.png').toString('base64')]))
const pet = {
  schemaVersion: 1, id: 'studio.my-cat', name: '我的小猫',
  version: '1.0.0', author: 'Your Studio', images
}
const source = JSON.stringify(pet)
if (Buffer.byteLength(source, 'utf8') > 1024 * 1024) throw new Error('宠物包超过 1 MiB，请压缩图片')
writeFileSync('studio-my-cat-1.0.0.json', source)
```

使用 WebP/GIF 时相应修改文件后缀和 `data:image/...;base64,` 的 MIME 类型，不能只改类型名称。Base64 会增大体积，检查最终 JSON 大小，而不是只计算原图片。

## 元信息规则

| 字段 | 当前规则 |
| --- | --- |
| schemaVersion | 必须为 1 |
| id | `^[a-z0-9][a-z0-9._-]{2,63}$`；不能以保留的 `eos.` 开头 |
| name | 非空，最多 64 个 JS 字符单元 |
| version | 三段数字，例如 `1.0.0`；这里不接受预发布后缀 |
| author | 可选，最多 64 个 JS 字符单元 |
| images | 上述七个状态均为有效的 `data:image/png`、`webp` 或 `gif` 的 Base64 图片 |

整个 JSON 不超过 **1 MiB**。当前自定义宠物目录还有约 3 MiB 的本地存储限制；装满时先删除不用的自定义外观。

## 在应用中验证

打开 **设置 → 外观 → 搭档宠物**，启用宠物并导入 JSON。应用会先解析字段、解码每张图片并检查尺寸，成功后选中导入的外观。

依次验证任务的空闲、思考、工具执行、等待确认、成功与异常状态，再点击宠物检查 petting 状态。可以先在 [宠物展示](https://plugins.eosaios.com/pets/?lang=zh) 的状态选择器查看图片，但最终任务状态切换与动作需在应用中检查。

自定义图片使用宿主的轻微动作，不包含内置小猫的分层骨骼和眼睛渲染。关闭动态效果或系统减少动态效果时，动作也会受到限制。

## 升级与发布

重复 ID 会拒绝导入，即使 version 增大也一样。先删除旧自定义包，再导入新包；删除当前外观会切回内置小猫。使用自己的 ID，内置宠物不能删除。

发布到自己的下载站或仓库时提供 JSON、七状态预览、名称、版本、作者、资源许可、SHA-256、文件大小与导入步骤。不要把原图许可推断为任意再分发许可。当前展示站为官方维护，尚无作者上传、审核或自行上架入口。

宠物保存在当前应用的数据空间，不自动云同步，也不因下载网页文件而自动安装。

## 常见错误

- 包超限：缩小透明画布、压缩图片，减少动画帧；仍须保留七个字段。
- 缺少有效图片：核对字段名、MIME 和标准 Base64；不要填文件路径或网页地址。
- 图片解码失败：用浏览器或图片查看器打开原图，确认不是损坏文件或伪装后缀。
- ID 已存在：删除旧自定义包后再导入，保留原文件以便恢复。
- 与预览动作不同：网页只预览状态图片，宿主动作取决于应用版本与系统动态效果设置。
