From 4e4563e861243f970b76622ed17d7b9efc7fc932 Mon Sep 17 00:00:00 2001 From: JianMiau Date: Mon, 24 Aug 2026 16:40:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=99=82=E6=B0=A3=E6=B3=A1?= =?UTF-8?q?=E6=94=B9=E9=A1=AF=E7=A4=BA=E6=9C=80=E5=BE=8C=E4=B8=80=E5=8F=A5?= =?UTF-8?q?=E5=9B=9E=E8=A6=86=EF=BC=8C=E4=B8=8D=E5=86=8D=E5=BB=B6=E5=88=B0?= =?UTF-8?q?=E4=B8=8B=E4=B8=80=E8=BC=AA=E6=89=8D=E5=87=BA=E7=8F=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根本原因: Stop 事件時 main.js 已從 transcript 附上最後一句助理訊息(narration), 但 renderer 的 Stop 分支寫死顯示「完成!」沒使用它,也沒把 narrationId 標記為已顯示;下一輪第一個工具事件呼叫 sayActivity 時,transcript 裡 最新的助理訊息仍是上一輪結尾、id 又沒被消費過,就被當成新話顯示出來。 影響: 對話收尾只看得到「完成!」,看不到 AI 的最後一句回覆;等使用者送出 下一句指令後,寵物反而冒出上一輪的舊訊息,時序錯亂。 修法: Stop 時若帶有 narration,氣泡直接顯示「✅ 最後一句」並消費 narrationId, 沒有才退回「完成!」;UserPromptSubmit 也先把當下 narrationId 標記為已 顯示,雙重保險。另修 release.js 只挑檔名含當前版本的產物,避免 dist/ 殘留的舊版檔案混進新 release。版號 2.0.9。 Co-Authored-By: Claude Fable 5 --- package-lock.json | 4 ++-- package.json | 2 +- renderer/renderer.js | 11 ++++++++++- scripts/release.js | 3 ++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6f80cd3..c444d84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-pet", - "version": "2.0.8", + "version": "2.0.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-pet", - "version": "2.0.8", + "version": "2.0.9", "devDependencies": { "electron": "^43.4.1", "electron-builder": "^26.0.12" diff --git a/package.json b/package.json index be14387..537ee6d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claude-pet", - "version": "2.0.8", + "version": "2.0.9", "description": "Codex Pets 相容的 Claude Code 桌面寵物(spriteVersionNumber 2:9 個動作列 + 16 方向追視)", "main": "main.js", "private": true, diff --git a/renderer/renderer.js b/renderer/renderer.js index b59cc73..d36667d 100644 --- a/renderer/renderer.js +++ b/renderer/renderer.js @@ -409,6 +409,9 @@ function handleEvent(p) { break; case "UserPromptSubmit": setState(s, "running"); + // 這時 transcript 裡最新的助理訊息還是上一輪的結尾, + // 先標記成已顯示,免得接下來的工具事件把它當成新話講出來 + if (p.narrationId) lastNarrationId = p.narrationId; hideBubble(); break; case "PreToolUse": @@ -456,7 +459,13 @@ function handleEvent(p) { // Codex:turn 完成且未讀 → review(播 review 3 次後沉澱),直到使用者回到該 thread 才回 idle。 // 這裡對應成:維持 review 直到該 session 有下一個動作(UserPromptSubmit)、結束或 7 天到期。 setState(s, "review"); - say("✅ 完成!", 8000, false, title); + // 收尾時把最後一句回覆講出來,而不是只說「完成」 + if (p.narration) { + lastNarrationId = p.narrationId || lastNarrationId; + say(`✅ ${firstSentence(p.narration)}`, 8000, false, title); + } else { + say("✅ 完成!", 8000, false, title); + } break; case "StopFailure": // Codex:turn 失敗 → failed 狀態(播 failed 3 次後沉澱),維持到下一個 turn 或 1 小時到期 diff --git a/scripts/release.js b/scripts/release.js index 5f61a21..cd333d7 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -144,8 +144,9 @@ async function main() { console.log(`Tag : ${TAG}`); if (!fs.existsSync(DIST_DIR)) throw new Error(`找不到 ${DIST_DIR},先執行 npm run dist`); + // dist/ 可能留著前幾版的產物,只挑檔名含當前版本的,免得舊檔混進新 release const files = fs.readdirSync(DIST_DIR) - .filter((f) => ASSET_PATTERNS.some((re) => re.test(f))) + .filter((f) => ASSET_PATTERNS.some((re) => re.test(f)) && f.includes(pkg.version)) .map((f) => path.join(DIST_DIR, f)) .filter((f) => fs.statSync(f).isFile()); if (!files.length) throw new Error(`${DIST_DIR} 裡沒有 .exe / .zip,先執行 npm run dist`);