Skip to content

Improve Buddy Bluetooth recovery and signing#187

Open
Lakphy wants to merge 9 commits into
wxtsky:mainfrom
Lakphy:feat/buddy-stability
Open

Improve Buddy Bluetooth recovery and signing#187
Lakphy wants to merge 9 commits into
wxtsky:mainfrom
Lakphy:feat/buddy-stability

Conversation

@Lakphy
Copy link
Copy Markdown
Contributor

@Lakphy Lakphy commented May 21, 2026

中文说明

摘要

这个 PR 增强了 Buddy 桌宠的 macOS 端 BLE 桥接、ESP32 固件协议和硬件文档,目标是让 Buddy 在配对、重连、状态同步和桌宠屏幕信息展示上更稳定、更可诊断。

核心变更包括:

  • 新增 Buddy 应用层配对协议:Mac 端生成稳定 hostId,固件端保存已配对主机,首次连接需要在 Buddy 上按 BOOT 物理确认。
  • 扩展 ESP32 下行/上行协议:支持配对响应、工作区、消息预览、模型名、会话统计、子代理数量、事件动画、时间提示和工具历史帧。
  • 改进 BLE 写入可靠性:新增有优先级的写队列,避免长消息预览或工具历史在回压时挤掉主状态帧、事件帧或关键控制帧。
  • 修复配对恢复边界:新固件使用 .withResponse 写入配对请求,写失败或新固件无响应不会再误判成 legacy connected;只有只支持 WRITE_NR 的旧固件才进入 legacy fallback。
  • 修复 Buddy 事件动画误触发:complete/error/approval 事件按当前显示 session identity 作用域判断,切换会话或重连不会沿用上一 session 的状态。
  • 修复固件断开连接:固件记录当前 BLE connId,替换硬编码 disconnect(0),避免在连接 id 不是 0 时无法断开被拒绝/重置的客户端。
  • 新增硬件 README,补充 Buddy 桌宠硬件、烧录、配对、操作和排障说明。

macOS 端变更说明

Buddy 相关 macOS 端变更:

  • ESP32BridgeManager:负责 Buddy 扫描、选择、配对、重连、写队列、button/control uplink 分发。
  • ESP32StatePublisher:将当前岛上展示的 session 状态同步到 Buddy,并推送扩展信息帧。
  • SettingsView / L10n:展示 pairing / waiting confirm / rejected / legacy firmware 等 Buddy 状态和提示。
  • ESP32Protocol:集中定义 Buddy BLE 协议和 payload 编解码,降低 Mac 端与固件端协议漂移风险。

涉及 macOS 端但不是 Buddy UI/桥接本体的改动及必要性:

  • SessionSnapshot.totalToolCallCount:这是共享会话模型字段,不是 Buddy 专用 UI。它是必要的,因为 Buddy 只保留最近工具历史用于屏幕展示,而统计面板需要累计工具调用总数;如果直接使用截断后的 toolHistory.count,Buddy 显示的工具统计会越来越不准确。
  • scripts/build-dmg.sh:增加 Xcode.app toolchain 选择和 ad-hoc 签名 fallback。Buddy Bluetooth 在 macOS 上依赖 signed .app bundle 和 Bluetooth entitlement;当本机没有 Developer ID 证书或使用 SKIP_SIGN=1 做本地验证时,仍需要对 app/nested Sparkle helpers 做 ad-hoc signing,避免 CoreBluetooth 权限和本地调试行为与真实 app 不一致。
  • scripts/dev-hot-restart.sh 与 README 提示:明确 bare executable 不能代表 Buddy Bluetooth 的真实运行环境。这样可以避免开发者用 swift build && ./.build/debug/CodeIsland 测 Buddy 时遇到权限问题却误以为是 BLE 或固件问题。
  • ClineView#Preview#if DEBUG:这是生产构建清理,不改变运行时功能;它避免 release/signing 构建路径包含 SwiftUI preview-only 代码,减少 app bundle 构建和签名流程中的非业务噪音。

固件/硬件变更说明

  • 固件增加配对状态机:未配对时显示确认页,按 BOOT 接受,长按 BOOT 拒绝;已配对主机可自动接受;不同主机需要先重置配对。
  • 固件解析更多帧类型:workspace、message preview、model、stats、subagent、event、time hint、tool history。
  • 所有 mascot header 增加 question alert 支持,让 waiting question 状态能与 waiting approval 区分显示。
  • 增加连接 id 追踪,拒绝配对或长按重置配对后断开当前真实连接。

验证

  • DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test 通过,320 tests。
  • DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test --filter 'ESP32BridgeManagerQueueTests|AppStatePrimarySourceTests|ESP32ProtocolTests' 通过,53 tests。
  • git diff --check 通过。
  • 固件未在本地编译:当前环境没有 arduino-cli,本 PR 已做源码级检查,并确认 disconnect(0) 已清除。

English Description

Summary

This PR improves the Buddy desktop pet integration across the macOS BLE bridge, ESP32 firmware protocol, and hardware documentation. The goal is to make Buddy pairing, reconnect recovery, status synchronization, and on-device status panels more reliable and easier to diagnose.

Main changes:

  • Adds an application-level Buddy pairing flow: macOS generates a stable hostId, firmware stores the paired host, and first-time pairing requires physical BOOT-button confirmation on Buddy.
  • Extends the ESP32 protocol with pairing responses, workspace metadata, message previews, model name, session stats, subagent count, transient event animations, time hints, and tool history frames.
  • Improves BLE write reliability with a prioritized write queue so large preview/history bursts cannot evict primary status frames, event frames, or key control/config frames under write backpressure.
  • Tightens pairing recovery: newer firmware uses .withResponse for pair requests, and failed/no-response acknowledged writes no longer fall through into legacy connected mode. Legacy fallback is limited to firmware that only supports WRITE_NR.
  • Scopes Buddy event animations by displayed session identity, preventing reconnects or session switches from reusing the previous session status and falsely triggering complete/error events.
  • Fixes firmware disconnect behavior by tracking the active BLE connId instead of hard-coding disconnect(0).
  • Adds Buddy hardware documentation covering parts, flashing, pairing, controls, and troubleshooting.

macOS Changes

Buddy-specific macOS changes:

  • ESP32BridgeManager: scanning, selection, pairing, reconnects, prioritized write queue, and Buddy uplink dispatch.
  • ESP32StatePublisher: pushes the currently displayed island session state and richer metadata frames to Buddy.
  • SettingsView / L10n: shows pairing, confirmation, rejection, reconnecting, and legacy firmware states in Settings.
  • ESP32Protocol: centralizes Buddy BLE payload definitions and encoding/decoding to keep macOS and firmware behavior aligned.

macOS-side changes that are not Buddy UI/bridge code, and why they are necessary:

  • SessionSnapshot.totalToolCallCount: this is a shared session model change rather than Buddy UI code. It is needed because Buddy keeps a bounded recent tool history for display, while the stats panel needs an accumulated tool-call count. Reusing the truncated history length would make Buddy stats drift lower over long sessions.
  • scripts/build-dmg.sh: selects the Xcode.app toolchain and adds ad-hoc signing fallback. Buddy Bluetooth on macOS needs a signed .app bundle with Bluetooth entitlements. When a Developer ID certificate is unavailable, local builds still need ad-hoc signing for the app and nested Sparkle helpers so CoreBluetooth permission behavior matches the real app environment.
  • scripts/dev-hot-restart.sh and README notes: document that launching a bare executable is not a valid Buddy Bluetooth test environment. This prevents Bluetooth entitlement failures from being mistaken for BLE or firmware regressions.
  • ClineView #Preview DEBUG guard: this is production build hygiene and does not change runtime behavior. It keeps SwiftUI preview-only declarations out of release/signing paths, reducing unrelated noise in app bundle builds.

Firmware / Hardware Changes

  • Adds firmware pairing state: unpaired Buddy shows a confirmation screen, BOOT accepts, long BOOT rejects, known hosts are accepted automatically, and different hosts require pairing reset.
  • Parses richer host-to-Buddy frames for workspace, preview, model, stats, subagent, event, time hint, and tool history data.
  • Adds question alert support across mascot headers so waiting-for-question and waiting-for-approval states can render differently.
  • Tracks the active BLE connection id and disconnects that real connection after pairing rejection or pairing reset.

Validation

  • DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test passed, 320 tests.
  • DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test --filter 'ESP32BridgeManagerQueueTests|AppStatePrimarySourceTests|ESP32ProtocolTests' passed, 53 tests.
  • git diff --check passed.
  • Firmware was not compiled locally because arduino-cli is not available in this environment. Source-level checks were performed, and all hard-coded disconnect(0) calls have been removed.

Lakphy and others added 9 commits April 26, 2026 00:59
Co-authored-by: Copilot <copilot@github.com>
- Introduced `*_Question` functions in multiple mascot header files to enable a question alert mode.
- Updated `drawBang` function to render a question mark when `_questionMode` is active.
- Modified `clawdSleep` to include a bored yawn animation based on global bored state.
- Added global variables for bored state and eye offset to enhance mascot behavior.
- Implemented tool icon classification and drawing functions for better visual representation of tools.
- Updated ESP32BridgeManager to handle legacy pairing fallback and timeout scenarios.
- Improved error messages and status handling for pairing states.
- Added new payload for clearing tool history.
- Enhanced localization strings for better user guidance.
- Updated README with clearer pairing instructions and hints for legacy firmware mode.
- Added tests for new functionality in AppState and ESP32Protocol.
@Lakphy Lakphy marked this pull request as ready for review May 21, 2026 18:39
nguyenvanduocit pushed a commit to nguyenvanduocit/CodeIsland that referenced this pull request May 22, 2026
…ilure modes

No new upstream commits since May 10. Two new user reports (wxtsky#185, wxtsky#186) document
a second failure mode in T-056: the display picker in Settings only shows the
built-in Retina Display and never surfaces external monitors in active dual-display
mode. Updated T-056 criteria to cover both the jump and the missing-picker-entry
scenarios. Also documents new upstream items (PR wxtsky#187 ESP32, issue wxtsky#188 companion
concept) as out of scope.

https://claude.ai/code/session_01GkndnzUrzdzTD2NvXFHmob
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant