@kkkey/dsh-pet-assets
v0.2.0
Published
Codex-style pet asset catalog: scans the pets directories (default $DSH_HOME/pets and $CODEX_HOME/pets, merged), validates manifests against the spritesheet contract, and serves catalog JSON plus spritesheet bytes over webserver routes
Readme
@kkkey/dsh-pet-assets
English | 中文
Codex 格式宠物资源提供者:激活时扫描宠物目录(所有存在的默认候选目录都会扫描并合并),按 Codex 宠物契约(与 codex-rs/tui/src/pets/model.rs 相同的规则)校验每份清单,并通过两条 dsh-host-webserver 命名路由提供解析后的目录与精灵图字节。浏览器侧的 dsh-client-pet-ui 是唯一出厂消费者。宠物目录始终是仓库之外的用户数据——不做任何拷贝入库。
配置
| 键 | 默认值 | 含义 |
|---|---|---|
| petsDir | $DSH_HOME/pets(变量未设置时为 ~/.dsh/pets),随后 $CODEX_HOME/pets(变量未设置时为 ~/.codex/pets);存在的候选目录全部扫描并合并(按此顺序) | 宠物根目录。开头的 ~ 展开为用户主目录。显式配置的目录不存在(或不是目录)会让组合失败;默认候选全部缺失则只提供空目录。冲突规则(方案 B,后扫者胜):同名宠物(id = 目录名)以后扫描目录(Codex 侧)的版本生效——目录里每个 id 恰好一条,位置按 dsh 优先,内容与精灵图取 Codex 版本。 |
| gaze | { wakeRadiusPx: 320, sleepRadiusPx: 400, idleTimeoutMs: 3000 } | v2 宠物的注视环行为参数,随目录下发。接近唤醒式:指针进入唤醒半径才抬头注视,滞回带(上限为沉睡半径)内保持注视,指针静止超过静止超时即回正。sleepRadiusPx 必须大于 wakeRadiusPx,否则组合响亮失败。 |
routePrefix 刻意不开放配置:固定前缀 /pet-assets 是本包与浏览器插件之间的线协议常量,两侧必须一致。
线协议面
GET /pet-assets/catalog.json—— 解析后的目录:每只宠物的 id、展示名、描述、路由相对精灵图 URL、精灵图契约代际(1 = 1536×1872 网格,2 = 多出两行注视环)、帧格几何、解析后的动画表、作为客户端缓存破坏键的精灵图修改时间,以及gaze注视环参数。校验失败的宠物不在pets里,而是进入errors数组({ id, displayName, message },最佳可用展示名 + 失败原因),供界面渲染降级占位。GET /pet-assets/sprites/<id>/<file>—— 精灵图字节流,带图像 content-type。只服务清单声明的那一个文件;相对路径相等性检查同时就是目录穿越防线。两条路由只回答 GET/HEAD,其余方法一律 405。
清单与动画语义
一只宠物就是一个目录:pet.json(或遗留的 avatar.json)加一张精灵图。清单可带可选的 id/displayName/description/spritesheetPath、可选的 frame 网格覆盖与可选的自定义 animations。校验对齐 Codex 契约:精灵图尺寸必须是两种契约尺寸之一;帧格必须精确铺满整图;帧数上限 256;自定义动画默认 8 fps、默认循环、默认回退 idle;精灵索引不得越界;fallback 必须指向真实轨道。清单未给动画表时解析为默认表(idle、running、running-left/right、waving、jumping、failed、waiting、review,以及 TUI 别名 move_*/wave/bounce/sad);默认表中的状态轨道把主序列连播三遍后沉入减速 idle 循环。
宠物规范
目录规则
- 布局 —— 一只宠物就是宠物根下的一个目录:
pet.json(或遗留的avatar.json)加一张精灵图。没有清单的目录被跳过;目录名是宠物的稳定 id,也是精灵图 URL 的键。 - 默认根 —— 所有存在的候选目录按顺序扫描并合并:
$DSH_HOME/pets(未设置时为~/.dsh/pets),随后$CODEX_HOME/pets(未设置时为~/.codex/pets);全部缺失则提供空目录。 - 显式
petsDir—— 配置的目录不存在(或不是目录)会响亮失败;那是配置错误而非数据问题。 - 同名冲突 —— 后扫描目录(Codex 侧)的版本生效(方案 B):目录里每个 id 恰好一条,位置按 dsh 优先,内容与精灵图取 Codex 目录。
- 坏宠物降级 —— 校验失败的宠物进入目录 JSON 的
errors数组(最佳可用展示名 + 原因);其余目录与组合照常工作。
清单字段(全部可选)
| 字段 | 含义 | 缺省 |
|---|---|---|
| id | 展示用回退 id(不是目录键;键是目录名)。 | 目录名 |
| displayName | 面向用户的展示名。 | 清单 id,否则目录名 |
| description | 一句话描述。 | 空字符串 |
| spritesheetPath | 宠物目录内的相对精灵图文件名;拒绝绝对路径与 .. 逃逸。 | spritesheet.webp |
| frame | 网格覆盖 { width, height, columns, rows };必须精确铺满整图。 | 契约默认(192×208 单元) |
| animations | 自定义轨道 { frames, fps?, loop?, fallback? }。 | 默认表(idle、running、running-left/right、waving、jumping、failed、waiting、review,以及 TUI 别名 move_*/wave/bounce/sad) |
精灵图契约
- 格式 —— PNG 或 WebP(按文件头判定;其他一律校验失败)。
- 尺寸 —— 必须恰好 1536×1872(v1,8×9 网格)或 1536×2288(v2,8×11,含注视环行)。
- 帧格 —— 必须精确铺满整图;帧数上限 256。
- 动画 —— 自定义轨道默认 8 fps、循环、回退
idle;fps 必须是 0 到 60 之间的有限数;每个精灵索引必须存在、每个 fallback 必须指向真实轨道。
Model Experience
无:本包只为面向用户的 UI 提供 HTTP 资源,不接触任何 prompt、消息、schema、流或工具结果。
KV Cache effect
无;本包从不组装或发送模型请求。
Known Limitations and Deferred Work
- 扫描是激活时快照 —— 新增、替换或修复宠物在下一次组合(重启或 HMR 重载)时生效,不会在请求间热更新。
- 坏宠物降级、不拖垮组合 —— 校验失败的宠物目录(清单 JSON 损坏、精灵图不符契约、动画非法)会进入目录 JSON 的
errors数组,带最佳可用展示名与失败原因;其余目录与界面照常工作。错误条目的占位渲染在浏览器侧(dsh-client-pet-ui):灰格占位 + 名字 + 悬停显示原因,全部宠物都坏时显示降级占位块。显式配置的petsDir目录不存在仍会让组合失败——那是配置错误而非数据问题。
