Feat/vibebar#40
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.
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.
1. Summary / 修改概述
Summary / 概述:
This pull request introduces several key improvements to device connection diagnostics, BLE management, and package structure. The main focus is on providing more granular feedback about device connection states, improving reliability when the device is connected via system Bluetooth/HID, and enhancing package modularity and dependency management.
Device connection diagnostics and BLE management:
LinkDiagnosticenum to track and expose detailed device connection states, enabling the UI to provide actionable feedback to users about where the device is "stuck" in the connection process.linkDiagnosticaccordingly [1] [2] [3] [4] [5] [6].Package and dependency management:
AhaKeyPluginKit,PluginShowcase), and integrated the localvibebarpackage as a dependency [1] [2] [3].DynamicNotchKit, ensuring reproducible builds.App integration and reliability:
VibeBarinto the main app, attaching it to the BLE manager and starting the controller on app launch.These changes significantly improve the user experience by providing clearer connection status, better handling of edge cases, and a more modular codebase.
2. Type of change / 修改类型
请选择本次 PR 的类型。
Please select the type of this PR.
3. Area / 涉及范围
请选择本次修改涉及的部分。
Please select the area affected by this PR.