Add vibebar and solve light state - #52
Merged
Merged
Conversation
…er (Issue AhakeyAI#34) macOS Studio showed a flat "等待设备" whenever the 0x7340 config link wasn't up, so users couldn't tell a half-connected device (HID/voice up, config link down) from a device that's simply absent — see AhakeyAI#34. Root cause: once the keyboard is connected via the system BLE / voice (HID) link it stops advertising, so the advertising-based scanForPeripherals(withServices:[0x7340]) never finds it, and the retrieveConnectedPeripherals(withServices:[0x7340]) fallback is empty when no one has discovered 0x7340 yet — both fallbacks miss and we scan forever. - Root-cause fix (B): connectAutomatically() now retrieves system-connected peripherals using a wider standard-service set (0x7340/180A/180F/1812), matches by "AhaKey" name prefix, and actively connects; didConnect's discoverServices then brings up 0x7340 even when the device isn't advertising. - Diagnostics (A): new LinkDiagnostic enum distinguishes scanning / connecting / connected / bluetoothOff / bluetoothUnauthorized / ownedByAgent / systemConnectedNoConfigLink / noDeviceFound, each with short + actionable text. Scan timeout re-probes via the wide set to pick the right state. - UI: top-bar pill shows the diagnostic instead of "等待设备", with the detailed explanation as a tooltip. Builds clean (swift build). Runtime behavior against real hardware not yet verified — needs a device exhibiting the issue. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The CH582m vibe-coding firmware advertises as "vibe code XXXX", but both the app and the standalone agent only matched a hard-coded "AhaKey" name prefix, so such devices were filtered out of scan results and connected-peripheral lookups — the app scanned forever / showed "未发现设备". Replace the single deviceNamePrefix with a prefix allow-list ["AhaKey", "vibe code"] plus a matchesDeviceName() helper, applied in both AhaKeyBLEManager (scan callback + wide-service system-connected fallback) and AhaKeyAgent. Verified end to end: app auto-connects to a real "vibe code B1D2" device. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nt can't run If a LaunchAgent plist exists but the agent can't actually run (e.g. it points at a stale build path, or the binary crashes), `launchctl start` does not error and the socket never appears — so the keyboard stays "given to the agent" with nobody actually connecting it, and the app is stuck on "Agent 占用中" until the user manually re-connects. (Hit in practice via a 6/2 plist pointing at a deleted Xcode DerivedData path.) In the agentDaemon branch, after load+start, wait up to ~2.5s for the agent to come up; if it doesn't, release BLE suppression and let the app connect directly (plus a non-launch user alert). Liveness is checked with a real connect() probe (agentSocketAlive) rather than checkRunning()'s file-exists test, so a leftover dead socket no longer masks a non-running agent. Verified: with a broken plist + no agent, app falls back and scans/connects; with a clean state it auto-connects to "vibe code B1D2" on launch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… command The UI stopped reflecting live keyboard changes (knob/mode/light) until a manual reconnect. Root cause: status polling is gated by `guard protocolResponseWaiters.isEmpty`, and that set could leak forever. In sendCommandAwaitingResponse the timeout child task only `throw`s; it never resumes the pending CheckedContinuation. Since CheckedContinuation ignores task cancellation, withThrowingTaskGroup keeps awaiting the never-finishing waiter task on timeout, so the function never returns, its `defer` cleanup never runs, and the waiter entry stays in protocolResponseWaiters — permanently blocking the 1.5s status poll. Reproduced on connect: reading picture-state for a mode the firmware doesn't answer (mode=3) left waiter[0x83] stuck. Fix: on timeout, atomically remove the waiter and resume its continuation (throwing) on the main actor before throwing, so the group can finish, defer runs, and the waiter set drains. removeValue is atomic vs the response handler, so no double-resume. Verified: in App-direct mode the app now polls every ~1.5s and picks up live mode changes (3->0) without a reconnect. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pulls vibebar (notch-style dynamic island, based on DynamicNotchKit) into the repo as a SwiftPM sub-package and wires it through the main macOS app as an in-process module rather than a sibling executable. The island now reflects live app state — keyboard connection + battery, lever auto/ask flag, and voice-agent activity — and offers a tile that calls back into the app to reopen the main window. - vibebar/ — new sub-package: VibeBar library + VibeBarSmoke executable for standalone UI smoke tests; depends on DynamicNotchKit 1.0.0, pinned at 3c40593 - ahakeyconfig-mac/Package.swift — split AhaKeyPluginKit/AhaKeyPlugin/ PluginShowcase into their own targets so the root package actually compiles; bump min macOS to 13 (DynamicNotchKit floor); depend on ../vibebar and link VibeBar into AhaKeyConfig - ahakeyconfig-mac/scripts/build.sh — bump default MACOS_DEPLOYMENT_TARGET to 13 to match the package floor - AhaKeyConfigApp.swift — own a VibeBarBridge, attach on .onAppear, start VibeBarController.shared with the bridged state - VibeBarBridge.swift — Combine mirror of BLE manager + voice services onto VibeBarState; lever maps switchState==0 to auto, preferring the agent's cached value when the app's own BLE link is dormant; fail-safe to leverKnown=false when neither source has answered Root Package.swift also updated for parity (path: "vibebar") so swift build from the repo root keeps working.
Closing the main window with the red close button doesn't terminate the app (macOS convention), so reopening the window rebuilds ContentView and resets all @State. That meant dismissedIncompleteOnboardingThisSession went back to false every time, and as long as any permission was still missing the unified onboarding sheet popped up again — even though the user had already been through it. Per product intent: once unifiedOnboardingCompleted is true, never show the onboarding again. Permission gaps surface through the main UI's own indicators instead. Drops the session-scoped dismissal flag entirely.
ZephyrKeXiner
requested review from
TheNorthStarYang
and
a lite review from Copilot
August 22, 2026 17:41
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a new “VibeBar” DynamicNotch-based UI module to the AhaKeyConfig macOS app while also improving BLE connection robustness and diagnostics, adding safer lighting-protocol writes with confirmation, and restructuring the SwiftPM project to include new targets and tests.
Changes:
- Introduces the
vibebarSwiftPM package (UI, controller, hover geometry, smoke app, and tests) and integrates it into the main app via a bridge that mirrors BLE/voice state. - Enhances BLE discovery/connection with device-name whitelist matching, richer
LinkDiagnosticstates surfaced in the UI, and HID-based fallback for “system-connected but not advertising config service” cases. - Adds “configurable lighting” firmware verification and sequential command writes that confirm device ACKs; adds BLE manager unit tests; bumps minimum macOS to 13 and expands package targets.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| vibebar/Tests/VibeBarTests/VibeBarHoverGeometryTests.swift | Adds unit tests validating multi-screen hover zone calculations. |
| vibebar/Sources/VibeBarSmoke/VibeBarSmokeApp.swift | Adds a standalone smoke app to visually validate VibeBar UI state updates. |
| vibebar/Sources/VibeBar/VibeBarViews.swift | Adds compact and expanded SwiftUI views for notch/menu presentation. |
| vibebar/Sources/VibeBar/VibeBarState.swift | Defines observable state model consumed by VibeBar UI. |
| vibebar/Sources/VibeBar/VibeBarHoverGeometry.swift | Implements hot-zone and expanded interaction zone geometry helpers. |
| vibebar/Sources/VibeBar/VibeBarController.swift | Implements notch presentation state machine and pointer tracking. |
| vibebar/Package.swift | Declares the VibeBar package, products, targets, and DynamicNotchKit dependency. |
| vibebar/Package.resolved | Pins DynamicNotchKit resolution for the VibeBar package. |
| vibebar/.gitignore | Adds SwiftPM/Xcode/macOS ignore rules for the vibebar subpackage. |
| Package.swift | Bumps macOS min to 13, adds vibebar dependency, and introduces plugin-related targets and tests. |
| Package.resolved | Pins SwiftPM dependency resolution at the repository root. |
| ahakeyconfig-mac/Tests/AhaKeyConfigTests/AhaKeyBLEManagerTests.swift | Adds unit tests for Bluetooth auth gating and lighting protocol command framing/advertising. |
| ahakeyconfig-mac/Sources/Views/ContentView.swift | Adjusts unified onboarding display logic. |
| ahakeyconfig-mac/Sources/Views/AhaKeyStudioView.swift | Surfaces LinkDiagnostic in the UI and adds lighting firmware support messaging + confirmed writes. |
| ahakeyconfig-mac/Sources/Utilities/VibeBarBridge.swift | Adds bridge wiring BLE/voice state into VibeBarState for notch UI. |
| ahakeyconfig-mac/Sources/Utilities/AgentManager.swift | Adds agent socket liveness probing and fallback to direct app BLE connection. |
| ahakeyconfig-mac/Sources/BLE/AhaKeyBLEManager.swift | Adds device-name whitelist matching, richer diagnostics, HID fallback retrieval, lighting support verification, and confirmed sequential command writes. |
| ahakeyconfig-mac/Sources/AhaKeyConfigApp.swift | Starts VibeBar on app launch and attaches the state bridge. |
| ahakeyconfig-mac/Sources/Agent/AhaKeyAgent.swift | Aligns agent-side device name matching with app whitelist logic. |
| ahakeyconfig-mac/scripts/build.sh | Bumps deployment target to macOS 13.0. |
| ahakeyconfig-mac/Package.swift | Bumps macOS min to 13 and adds vibebar dependency + test target. |
| ahakeyconfig-mac/Package.resolved | Updates SwiftPM resolution for the ahakeyconfig-mac package. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
TheNorthStarYang
approved these changes
Aug 23, 2026
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / 概述:
AhaKeyConfigmacOS app, focusing on enhanced BLE device detection, diagnostics, and project structure. The main changes include a more robust device name matching system, detailed connection diagnostics, improved handling of Bluetooth permissions, and expanded package configuration to support new modules and dependencies.BLE Device Detection and Diagnostics:
["AhaKey", "vibe code"]) for broader device compatibility, and refactored all device name checks to use a newmatchesDeviceNamemethod. [1] [2]LinkDiagnosticenum to provide detailed connection state diagnostics, allowing the UI to offer actionable feedback to the user about where the BLE connection process is stalling. This includes new states for agent ownership, system-connected devices without config link, and more. [1] [2] [3] [4] [5] [6]Bluetooth Permission Handling:
Lighting Protocol and Command Handling:
Project Structure and Dependencies:
AhaKeyPluginKit,Plugin,PluginShowcase), and included theVibeBarpackage as a dependency. Test targets were also added for better test coverage. [1] [2] [3] [4] [5]VibeBarinto the main app, initializing and attaching it to the BLE manager on app launch.DynamicNotchKit, preparing for future integration.These changes collectively make the app more robust, user-friendly, and maintainable, especially in complex BLE environments and with a growing codebase.