Skip to content

Add vibebar and solve light state - #52

Merged
TheNorthStarYang merged 11 commits into
AhakeyAI:mainfrom
ZephyrKeXiner:feat/vibebar
Aug 23, 2026
Merged

Add vibebar and solve light state#52
TheNorthStarYang merged 11 commits into
AhakeyAI:mainfrom
ZephyrKeXiner:feat/vibebar

Conversation

@ZephyrKeXiner

Copy link
Copy Markdown
Member

Summary / 概述:

  • This pull request introduces several significant improvements to the AhaKeyConfig macOS 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:

  • Replaced the single device name prefix with a whitelist (["AhaKey", "vibe code"]) for broader device compatibility, and refactored all device name checks to use a new matchesDeviceName method. [1] [2]
  • Added a new LinkDiagnostic enum 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:

  • Improved Bluetooth authorization checks by introducing a new method that more accurately reflects current permission state, and updated connection logic to set diagnostics accordingly when permissions are missing or Bluetooth is off. [1] [2]

Lighting Protocol and Command Handling:

  • Added support for verifying and reporting firmware support for configurable lighting, including new async methods to confirm device protocol support and to write commands with confirmation.

Project Structure and Dependencies:

  • Updated the minimum macOS version to 13, added new targets (AhaKeyPluginKit, Plugin, PluginShowcase), and included the VibeBar package as a dependency. Test targets were also added for better test coverage. [1] [2] [3] [4] [5]
  • Integrated VibeBar into the main app, initializing and attaching it to the BLE manager on app launch.
  • Added a resolved package file for 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.

ZephyrKeXiner and others added 10 commits June 21, 2026 16:32
…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
ZephyrKeXiner requested review from TheNorthStarYang and a lite review from Copilot August 22, 2026 17:41
@ZephyrKeXiner ZephyrKeXiner self-assigned this Aug 22, 2026
@ZephyrKeXiner ZephyrKeXiner added bug Something isn't working feature labels Aug 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 vibebar SwiftPM 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 LinkDiagnostic states 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.

Comment thread ahakeyconfig-mac/Sources/Views/ContentView.swift
Comment thread ahakeyconfig-mac/Sources/Utilities/VibeBarBridge.swift
Comment thread ahakeyconfig-mac/Sources/Utilities/AgentManager.swift
Comment thread ahakeyconfig-mac/Sources/BLE/AhaKeyBLEManager.swift
Comment thread vibebar/Package.swift Outdated

@TheNorthStarYang TheNorthStarYang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@TheNorthStarYang
TheNorthStarYang merged commit b1e65c3 into AhakeyAI:main Aug 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants