 JianMiauandClaude Fable 5
|
48b10c43de
|
滑鼠移到寵物身上時跳躍三次,hover 判定改用矩形
摘要:
把 hover 跳躍加回來,並把觸發判定從逐像素 alpha 改成人物方框。
根本原因:
1. hover 跳躍在「逐項對照 Codex」那次被換成 proximity 版面(理由是 Codex 的
respondToHover 全 app 沒有開啟),上一次移除浮出選單鈕時把整套版面拿掉,
跳躍也跟著沒了,變成 hover 完全沒有反應。
2. 先前的 hover 判定用 ctx.getImageData 逐像素測 alpha。sprite 每一格的輪廓不同,
游標停著不動時,人物身上同一點會隨著動畫在不透明與透明之間變化,
造成 setHovered 在 true/false 間高速抖動(實測 2 ms 內來回多次),
連帶 pet:ignore-mouse 也被瘋狂切換。
影響:
滑鼠移到寵物身上沒有任何反應;即使觸發也會因抖動而重複進出 hover 狀態。
修法:
- 還原 setHovered:進入時 play("jumping", STATE_REPEATS),對應 Codex 的
`respondToHover && hovered ? "jumping" : state` 走 f() 播 3 次後沉澱;
一次性動作或拖曳進行中不打斷,離開視窗時清除。
- 新增 overPetArea:hover 用 canvas 的矩形判定,與 Codex 的 pet-area-hover-changed
同樣是用 rect 算的。點穿判定維持逐像素 alpha,透明處仍然點得到底下的視窗。
- README 的日常使用、行為對照表、與 Codex 的對照三處同步更新,
對照表補上 jumping 與 hover 判定兩列。
驗證:
- 在 renderer 暫時加診斷 log 實測,確認進入人物區時
`setHovered true overlay=null` 之後 overlay 變成 jumping,觸發路徑正確;
同一份 log 也是抖動問題的證據來源。改成矩形判定後移除診斷。
- 以 ELECTRON_RUN_AS_NODE 讀打包後 app.asar:版本 2.0.0、hover 跳躍與矩形判定都在、
點穿仍用 alpha、診斷已移除、無選單鈕殘留、右鍵選單仍在,九項全過。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 16:24:24 +08:00 |
|
 JianMiauandClaude Fable 5
|
6da4775867
|
移除 hover 浮出的選單鈕,版本升到 2.0.0
摘要:
拿掉游標靠近時人物縮小讓位、上方浮出圓形選單鈕的整套 hover 版面,選單只留右鍵與系統匣。
根本原因:
上一版照 Codex 的 petControlsAppearance 做了 proximity 版面,但那顆控制鈕的作用就是開選單,
而本程式的右鍵與系統匣已經有同樣的選單,多一顆按鈕沒有增加任何功能,
反而讓游標經過時人物會縮小位移。
影響:
滑鼠靠近時人物無謂地縮小、下移,並蓋出一顆重複功能的按鈕。
修法:
- renderer:移除 HOVER_SCALE / HOVER_OFFSET_Y / PROXIMITY_ENTER / PROXIMITY_EXIT 常數,
以及 updateProximity / setNear / overControls / distanceToRect 與 near 狀態、
applyScale 裡的控制鈕定位、menu-btn 的事件繫結;mousemove 的點穿判定回到人物與氣泡兩者。
- index.html 移除 #controls;style.css 移除 body.near 的縮放位移與 #controls 樣式。
- package.json 版本 0.1.0 → 2.0.0。
- README 的日常使用、行為對照表、與 Codex 的對照三處同步更新,
對照表標明此項未採用及原因。
保留不變:
右鍵與系統匣選單、idle 放慢 6 倍、狀態優先序與到期、look 列縮放補正、
first-awake 問候、拖曳 4 px 方向閾值、reduced motion。
驗證:
- 三個 js 檔語法檢查通過,全專案 grep 確認 controls / menu-btn / HOVER_ / PROXIMITY_ /
body.near / setNear 等皆無殘留。
- 實機啟動:/health 正常,events.log 顯示 look rows rescaled 8 cells 仍正常觸發;
把游標移到人物上截圖,人物維持原尺寸原位置、無按鈕浮出(測後游標已復位)。
- 以 ELECTRON_RUN_AS_NODE 讀打包後 app.asar:版本 2.0.0、html 無 menu-btn、
css 無 body.near、js 無 proximity 邏輯,且右鍵選單、idle 放慢、look 補正、
狀態優先序都還在;exe 版本資訊為 2.0.0。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 15:18:30 +08:00 |
|
 JianMiauandClaude Fable 5
|
f886df554e
|
逐項對照 Codex 校正所有行為邏輯
摘要:
從 Codex app 的 app.asar 讀出寵物的完整行為邏輯(狀態決策、優先序、到期、hover 版面、
初次問候、拖曳、reduced motion),逐項對照後校正本程式。
根本原因:
先前只對齊了動畫時序,狀態機本身仍是自訂的,與 Codex 有多處不一致:
1. 跨 session 優先序是 waiting>running>review>idle,但 Codex 的 Ai() 是
waiting>failed>review>running,review 其實高於 running。
2. Stop 用 jumping 一次 + 6 秒 review,Codex 是 review 持續狀態直到該 thread 被讀取。
3. StopFailure 用 failed 播兩次就回 idle,Codex 的 failed 是持續狀態。
4. 工具失敗(PostToolUseFailure)會播 failed,Codex 中單一工具失敗不改變 turn 狀態。
5. 每個 hook 事件都重播動畫,Codex 只在狀態改變時重播(effect 相依只有 state)。
6. hover 是「跳躍」,Codex 實際的 respondToHover 全 app 沒人開啟;真正的 hover 行為是
proximity 版面:40px 內人物縮 0.9、下移、露出控制鈕,56px 外退出。
7. 追視綁滑鼠且預設開,但 Codex 的追視來源是 quick chat 文字游標/computer-use 游標,
不是滑鼠。
8. 沒有 first-awake 問候;狀態到期時間、拖曳方向閾值、reduced motion、預設位置也都沒對齊。
影響:
多 session 時顯示的狀態可能不對(running 蓋掉 review);完成與失敗的表現和 Codex 差很多;
待機期間仍可能因連續事件一直重播;hover 行為與 Codex 完全不同。
修法(數值皆取自 codex-pet-assets / avatar-overlay-native-frame / 主程序):
- 優先序改為 waiting(4)>failed(3)>review(2)>running(1)>idle(0)(對應 Ai())。
- 到期改為 failed 1h、waiting 24h、review 7d、running/idle 不到期(對應 Ei()),
另保留一個 Codex 沒有的安全網:running 30 分鐘無事件視為終端機關閉。
- Stop→review 持續狀態;StopFailure→failed 持續狀態;PostToolUseFailure 只給氣泡不改狀態;
idle_prompt 不再算 waiting。
- 動畫只在狀態改變時重播(移除 pulse)。
- hover 改為 proximity 版面:enter 40px / exit 56px,人物縮 0.9、下移 14px、
200ms 過渡,上方露出 24px 選單鈕(對應 hoverControlSize/hoverOffsetY/hoverControlGap)。
- 追視改為選配、預設關;first-awake 問候每隻寵物一次(記在設定檔 greetedPetIds);
拖曳方向改為單次位移 >= 4px 才決定(對應 Codex 的取樣邏輯);
reduced motion 只顯示第一格;預設位置改為工作區右下各 24px;尺寸檔位對齊 80–224px 範圍。
- README 新增「與 Codex 的對照」整節,逐項列出相同與刻意不同之處。
驗證:
- baseState 單元測試:優先序(review>running、waiting>failed、failed>review)與各狀態
到期(failed 1h、waiting 24h、review 7d、running 安全網、idle 清理)全數通過。
- 啟動實機以 HTTP /event 灌事件、/state 讀回:Stop→review、review 蓋過 running、
授權→waiting、waiting>failed、failed>running、工具失敗不改狀態,皆正確。
- 桌面截圖:寵物正常顯示;滑鼠移到人物 40px 內時人物縮小下移、上方浮出圓形選單鈕,
與 Codex 的 hover 版面一致。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 15:11:56 +08:00 |
|
 JianMiauandClaude Fable 5
|
7d4c5d849c
|
滑鼠移到寵物身上時跳躍,對齊 Codex 的 hover 行為
摘要:
游標壓在人物像素上時播 jumping 3 次再沉澱回慢速 idle,離開後回到原本狀態。
根本原因:
Codex 的寵物元件(codex-pet-assets)在 hover 時會把顯示狀態換成 jumping
(respondToHover && hovered ? "jumping" : state),桌面寵物那層透過
pet-area-hover-changed 事件驅動它。本程式只有點擊會揮手,滑鼠停上去沒有反應。
影響:
滑鼠移到她身上沒有任何回饋,與 Codex 的手感不同。
修法:
- 把 overOpaque 拆成 overBubble 與 overSprite:點穿判定兩者都算,hover 反應只看人物像素,
游標停在氣泡上不會觸發跳躍。
- 新增 setHovered:進入人物像素時 play("jumping", STATE_REPEATS),與 Codex 的 f("jumping")
相同是播 3 次;一次性動作或拖曳進行中不打斷。mouseout 離開視窗時清除 hover 狀態。
- 移除已無人使用的 overOpaque。
驗證:
以 ELECTRON_RUN_AS_NODE 讀打包後 app.asar 內的 renderer.js,確認 setHovered、
play("jumping", STATE_REPEATS)、mousemove/mouseout 的呼叫都在出貨檔案裡,overOpaque 已不存在。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 14:49:34 +08:00 |
|
 JianMiauandClaude Fable 5
|
c96dcccb80
|
動畫時序照 Codex 校正,並修掉 look 列被畫小造成的縮水
摘要:
待機動畫放慢成 Codex 的速度、非 idle 狀態播 3 次後沉澱,並自動補正 spritesheet 裡整列 look 格子被畫小的缺陷。
根本原因:
1. idle 直接用合約上的幀時長無限循環,一輪只有 1.1 秒,看起來一直在動。Codex 的 codex-pet-assets 裡有一個放慢倍率 6,idle 實際是一輪 6.6 秒,其他狀態則是播 3 次後接上慢速 idle 並從那裡循環。
2. 內附的小念 spritesheet 第 10 列(看向 180 度到 337.5 度)整列被畫成 idle 的 78%,寬高同時縮小。游標移到人物身上或左邊時會切到那一列,人物就突然矮一截。第 9 列尾端只有高度變矮、寬度不變,那是低頭姿勢,不能一起改。
3. 追視參考點取在頭部高度(0.3),與 Codex 的方框中心不同,使得更多游標位置被判成「在下方」,更容易踩到第 10 列。
影響:
待機時一直晃;游標一靠近或移到左側,人物就明顯縮水又彈回來。
修法:
- 動畫改成序列模型(frames = [{row, col, ms}] + loopStart),對應 Codex 的 f(state):
IDLE_SLOWDOWN = 6、STATE_REPEATS = 3、播完 3 次後循環慢速 idle。
- 每個 hook 事件都重播一次動畫(pulse),對應 Codex 每次狀態更新都會重跑動畫效果;
否則狀態播完 3 次後就再也看不出 Claude Code 在忙。
- 載入寵物時量測 16 個 look 格子,以整列中位數判斷是否整列被縮小(門檻 0.9),
是的話以腳底為支點放大回 idle 身高;單格差異不動,避免把低頭姿勢拉直。
- 追視參考點改為人物方框中心、死區改為 1 px,與 Codex 相同。
- 拖曳用的 running-left / running-right 維持持續循環,不套用沉澱規則。
刻意不同於 Codex 的地方:
Codex 的追視會覆蓋所有狀態,本程式只在 idle 時追視。否則工作中的動畫會被靜態擺姿蓋掉,
寵物就失去反映 Claude Code 狀態的作用。
驗證:
- 抽出序列邏輯單獨執行:idle 一輪 6600 ms(幀長 1680/660/660/840/840/1920);
running / waiting / review 皆為 24 幀、第 18 幀起循環列 0;拖曳維持循環;一次性動作播完即止。
- 以 PIL 重現量測與繪製:小念第 9 列中位數比 0.995 不補正,第 10 列 0.783 補正倍率 1.2774,
補正後畫面身高 128.7-132.1 px(idle 為 130.4),且無任何一格超出畫布;
xiao-nian-realistic 兩列都是 0.99,判定不需補正而未受影響。
- 以 ELECTRON_RUN_AS_NODE 讀打包後 app.asar 內的 renderer.js 與 main.js,確認六項改動都在出貨的檔案裡。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 14:41:42 +08:00 |
|
 JianMiauandClaude Fable 5
|
e591475d4c
|
加上免安裝版,寵物來源改成執行目錄的 pets
摘要:
新增 portable 單檔與 zip 資料夾兩種免安裝產物;寵物一律從執行目錄的 pets/ 掃,設定檔不再累積程式自己算出來的路徑。
根本原因:
1. 只有 NSIS 安裝檔,沒有點兩下就能跑的版本。
2. 內附寵物被 asarUnpack 埋在 resources/app.asar.unpacked/pets,使用者要新增寵物得先鑽進 resources 資料夾。
3. loadConfig 會把算出來的來源路徑寫回 config.json,程式一搬家或在安裝版與 portable 之間切換,petSources 就越積越多失效的絕對路徑(實際已累積出 dist/win-unpacked/resources/app.asar.unpacked/pets 這種殘留)。
4. CODEX_PETS_DIR 用到 HOME,但 const HOME 宣告在它下面,會在啟動時就 TDZ ReferenceError。
影響:
沒有免安裝選項;新增寵物的路徑不直覺;設定檔會長出一堆死路徑;且上一版打包後的程式其實一啟動就會崩潰。
修法:
- win target 加上 portable 與 zip;portable 設 unpackDirName=ClaudePet、requestExecutionLevel=user。
- pets/ 改用 extraFiles 放到 exe 旁邊(不再進 asar),APP_ROOT 打包後取 process.execPath 的目錄。
- portable 的 NSIS 外殼每次啟動都重解壓、結束就刪整個目錄,因此:hook 腳本另外複製到 ~/.claude-pet/hook/ 並註冊該穩定路徑(否則寵物沒開時 Claude Code 每次觸發 hook 都找不到檔案);使用者寵物放那顆 exe 旁邊;開機自動啟動改用 PORTABLE_EXECUTABLE_FILE。
- petSources 語意改為「只存使用者自己加的額外路徑」;執行目錄的 pets 與 ~/.codex/pets 為隱含來源,由 petSearchDirs() 組出實際掃描清單,載入時剔除隱含項與不存在的路徑。同 id 以使用者自己放的優先。
- 把 HOME/CONFIG_DIR 移到常數區最前面,修掉 TDZ。
- 內附第二隻寵物 xiao-nian-realistic。
驗證:
以 ELECTRON_RUN_AS_NODE 執行打包後的 exe(不開視窗):
- 一般模式與模擬 portable 模式下的 pets 路徑、hook 路徑、autostart 指令皆正確。
- 用假的 USERPROFILE 實跑 install/uninstall:hook 腳本確實複製、指令含空白路徑會加引號、其他人的 Stop/PreToolUse hook 與 model 設定在安裝與移除後都完整保留、備份有產生。
- 帶殘留路徑的設定檔會被正確清理,掃描順序為「使用者 pets → 內附 pets → ~/.codex/pets → 額外路徑」。
- 從 app.asar 讀回 main.js 確認出貨的程式碼順序正確。
- 以純 node 載入 main.js,確認常數區與 loadConfig 不再有 TDZ。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 14:11:20 +08:00 |
|
 JianMiauandClaude Fable 5
|
56fd8448ba
|
用 electron-builder 打包成 Windows exe
摘要:
加上 electron-builder 設定,`npm run dist` 產出 NSIS 安裝檔與免安裝版,並修正打包後才會出現的路徑問題。
根本原因:
原本三處路徑都假設程式是攤在資料夾裡跑的,打包成 asar 後會壞:
1. hook 腳本路徑會落在 app.asar 內,而 Claude Code 是用 `node <路徑>` 執行它,node 讀不到 asar 裡的檔案,hook 會直接失敗。
2. pets 資料夾同樣在 asar 內,使用者無法自己丟寵物進去,選單「開啟寵物資料夾」也開不起來。
3. 開機自動啟動寫入的是 `electron.exe + 專案路徑`,打包後沒有 node_modules,登錄值會指向不存在的檔案。
影響:
沒有可散佈的執行檔;直接打包的話 hook、換寵物、開機啟動三個功能都會壞掉。
修法:
- 新增 lib/paths.js:unpacked() 把 app.asar 換成 app.asar.unpacked,isPackaged() 以 process.defaultApp 判斷是否為打包版。
- build.asarUnpack 把 hook/ 與 pets/ 解到 asar 外,hooks-installer 與 main.js 的 PETS_DIR 都改走 unpacked()。
- autostart 打包後改用 process.execPath,並跳過開發版才需要的 electron.exe 存在檢查。
- NSIS 設為 per-user、可改安裝路徑、建立桌面與開始選單捷徑,解除安裝不刪 ~/.claude-pet。
- 新增 build/icon.ico(16–256,七種尺寸),取自小念 spritesheet 第 0 列第 6 欄的頭肩方形裁切。
- dist/ 加入 .gitignore;README 補上「打包成 exe」一節與安裝檔的使用方式。
驗證:
以 ELECTRON_RUN_AS_NODE 執行打包後的 exe(不開視窗)載入打包內的 lib,確認 isPackaged 為 true、hook 路徑指到 app.asar.unpacked 且檔案存在、autostart 指到 exe 本身、pets 掃得到 xiao-nian、renderer 讀得到 asar 內的 index.html;另確認 exe 版本資訊與七種尺寸圖示皆已嵌入。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 11:03:11 +08:00 |
|
 JianMiauandClaude Fable 5
|
a014f9a279
|
把 100% 的顯示尺寸對齊 Codex 桌面寵物(126 × 137)
摘要:
原本 100% 直接用 spritesheet 的單格尺寸 192 × 208 顯示,比並排的 Codex 桌面寵物大了一半,就算縮到 75% 還是明顯偏大。
根本原因:
把「spritesheet 來源格子大小」直接當成「畫面顯示大小」在用。Codex 是另外算的:mascot 以寬度為基準,高度用 ceil(寬 × 208/192) 求得,跟單格 192 × 208 無關。
影響:
兩隻並排時大小不一致;使用者得手動調到某個非整數的縮放才勉強接近,而每一級縮放又都以 192 × 208 為基礎,永遠對不準。
修法:
- 新增 PET_W / PET_H(126 × 137),與 CELL_W / CELL_H 分家:後者只負責從 spritesheet 取格子,前者才是畫到畫面上的大小。
- 高度沿用 Codex 的 ake() 公式 ceil(寬 × 208/192),長寬比與 Codex 一致。
- 尺寸取自實測:Codex 與本程式並排截圖比對,因 xiao-nian 每一格的人物輪廓都固定是 208 中的 198 px,兩者輪廓高度比即等於顯示尺寸比(與螢幕 DPI 無關),推得 Codex 為 137.3 × 126.7。
- 視窗寬度加上 MIN_WIN_W = 240 下限:寵物縮小後視窗跟著變窄會讓氣泡被截斷,Codex 的氣泡(315 px)同樣遠寬於寵物本身。
- 追視死區 56 → 38,維持與寵物尺寸相同的比例。
- 視窗高度與游標追視的頭部位置一併改用 PET_H。
驗證:
scale 1 時人物實高 130.4 px,實測 Codex 為 130.7 px,誤差 0.2%。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 10:53:08 +08:00 |
|
 JianMiauandClaude Fable 5
|
b1d57249f8
|
初始提交:Codex Pets 相容的 Claude Code 桌面寵物
摘要:
Electron 桌面寵物,透過 Claude Code hooks 即時反映工作狀態(思考、等待授權、失敗、完成),並支援 16 方向追視游標。
根本原因:
專案尚未納入版控,需要建立初始 repo 以便後續追蹤與協作。
影響:
建立 main 分支的第一個版本,包含完整可執行的程式碼與內附寵物「小念」。
修法:
納入以下內容:
- main.js / preload.js:Electron 主程序、透明置頂視窗、系統匣選單、HTTP 事件伺服器、游標輪詢與拖曳
- renderer/:Codex V2 spritesheet 幀動畫播放器、session 狀態機、氣泡、alpha 點穿判定
- hook/claude-pet-hook.js:Claude Code hook 端,stdin → POST /event,永遠 exit 0
- lib/、scripts/:hooks 安裝/移除、Windows 開機自動啟動
- pets/xiao-nian:內附寵物包(pet.json + spritesheet.webp)
- README.md、docs/states.png:使用說明與狀態總覽圖
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-08-21 10:32:39 +08:00 |
|