Fix payment refresh cache handling - #38
Open
ShawnyinsGit wants to merge 82 commits into
Open
Conversation
- 新增 AhaType 云端整理、账号登录、配额与支付入口 - 适配 macOS 12/15 的 SwiftUI API 差异 - 优化 BLE/Agent 连接状态展示与返回键盘控制流程
Merge pull request !1 from 尹朔/codex-ahatype-macos-compat
- 画布灯条 1:1 还原固件 update_claude_ws2812() 决策; agent 在 BLE 通知回调里写共享文件,主 App 在非编辑态也能读到 实时 lightMode/switchState/workMode/IDE state - 画布 OLED 加 0x83 元信息查询 + 已上传/未上传徽章; .id(gifPath) 修掉切 Mode 时 Claude/Cursor GIF 串图的 @State 复用 bug; build.sh 把 Resources/DefaultOLED 拷入 app bundle - 虚拟拨杆:固件加 0x91 set_sw_state 命令调 sw_state_change(), 老固件回落到 agent userSwitchOverride 软覆盖(持久化到 UserDefaults, hook auto-approve 走覆盖值),点击瞬间用 optimisticSwitchOverride 乐观更新画布 - 新手引导授权与语音输入路径若干小优化
- DefaultOLED:Mode1 默认改 cursor.gif,Mode2 默认改 codex.gif, 替换原 cursor_0.gif;首次连接 + 三 mode 0x83 查询完成后, picLength==0 的 slot 自动上传对应 bundle GIF - 画布 OLED:屏幕区固定 2:1(160×80 真实比例),AnimatedGIFView .fill→.fit 修掉 cursor 方图被裁成横条的问题;slot 余下区域 作"键盘外壳黑",看上去像屏嵌在外壳里;keyboardPictureStates 改 Equatable struct 触发 SwiftUI onChange - Mode tab guidance:Cursor 后半句"组合键映射"挪到问号 hover popover,前半句保留 - 顶部 ⋯ 菜单:去掉「清空 LCD 预览」(保留在 LCD 编辑面板) 和「重新连接设备」与「设备信息」之间的分割线 - 帮助中心:从浏览器跳转改为内嵌 .sheet 弹窗(880×620), 九个分类侧栏,结合当前代码现状写说明:BLE 占用规则、 虚拟拨杆三件事、auto 档彩虹覆盖原因、OLED 角标含义等 - Codex 描述去掉 OpenAI / CLI 字样
- 螺丝从 (8,8)/(101,8)/(8,46)/(101,46) 挪到真·边角 (5.5,5.5) 系列、直径 4.8→3.6,让出灯条左缘、按键灰底和 Key1 边线的擦边空间 - 灯条 rect 收 (12.3,5.0,55.6,9.8)→(13.0,4.5,53.5,8.6); 按键灰底 (43.8,37.3,70×24)→(43.8,38.5,67×21) 并淡 12.5%; HotspotChrome 未选中描边 opacity 0.05→0.015、选中阴影 radius 10→6,灯条选中态发光不再溢出到邻近元件 - Inspector 修改按钮按 macOS HIG:去掉 maxWidth=.infinity 撑满、 controlSize .large→.regular,包 HStack+Spacer 右下角对齐, Label 加 pencil icon,加 ⌘E 快捷键 - Mode 1 (Cursor) guidance 后半句"组合键映射"挪到问号 hover popover,前半句留在 tab 下;模型层新增 guidanceHoverDetail - 顶部 ⋯ 菜单删「清空 LCD 预览」、删「重新连接设备」和 「设备信息」之间分割线 - 帮助中心从浏览器跳转改为内嵌 .sheet 弹窗(880×620), 九个分类侧栏,结合代码现状重写说明 - Codex 描述去掉 OpenAI / CLI 字样 - 画布 OLED 屏幕区固定 2:1 真实比例、GIF .fill→.fit 修掉 cursor 方图横条裁切;keyboardPictureStates 改 Equatable struct - 默认 OLED 资源:Mode1 默认改 cursor.gif、Mode2 默认改 codex.gif; 连上键盘后 picLength==0 的 slot 自动上传 bundle GIF
之前打出来的 DMG 打开后是默认深色 Finder 视图、无背景图、 Applications 图标显示为空虚线框,原因是 .DS_Store 没写进盘里。 两处根因 + 修复: 1) -format UDRW 默认在 macOS 13+ 上落地为 APFS,APFS 的 DMG 持久化 Finder 元数据不稳定 → 强制 -fs HFS+ 2) hdiutil attach 用了 -noautoopen,Finder 不把这卷加进它的 visible volumes,AppleScript 用 `tell disk "..."` 直接报 -1728 object not found → 去掉 -noautoopen + activate + 3 秒延时让 Finder 索引完毕 附带: - AppleScript 每条属性 setter 包 try/end try 隔离失败 - background 用 colon-path `.background:InstallerBackground.png` - open → 设置 → update → close → 再 open 一次循环 force-write .DS_Store(Sonoma 后这套 dance 必需) - 完成后校验 .DS_Store 大小,没写进去给明确错误(含 Automation 权限提示) - 窗口 bounds 调到 860×480,icon size 100→128 跟 Big Sur 后 系统 DMG 视觉风格对齐;图标位置移到 (200,240)/(660,240)
AgentManager: - init() 改为读取用户上次蓝牙归属偏好,不再每次启动强制重置为 agentDaemon - install() 先 unload 旧 LaunchAgent 再写 plist,避免旧 binary 路径常驻 launchd - start() 加路径校验(launchAgentNeedsRewrite),重装 App 后自动修复 plist - 提取 launchAgentPlist/writeLaunchAgentPlist/installedAgentBinaryPath 辅助方法 - 修复 querySocketBLEConnected actor isolation warning(改为 nonisolated static) AhaKeyStudioView: - waitForConnectionThenSync 超时后调 returnToKeyboardControl,避免 UI 永远卡在编辑模式 - 四处 BLE 写命令检查从 isConnected 改为 isConnected && commandCharReady package_dmg.sh: - 两阶段挂载:文件拷贝挂 /tmp(绕过 macOS 26 /Volumes EPERM),Finder 布局再挂 /Volumes - 修复空白 HFS+ DMG 创建时误带 -format UDRW 导致级联失败的问题 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
保留远端更完整的忽略规则(Python/Node/构建产物等), 补充本项目特有条目 scripts/build.local.env。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Info.plist 新增 NSAccessibilityUsageDescription 与 NSInputMonitoringUsageDescription, 修复 macOS 26 首次启动时 VoiceRelayService 权限请求无法弹出系统对话框的问题 - LightEffectStyle 新增 isAnimated / preferredFPS,灯条 TimelineView 改为按效果速度 自适应帧率(12fps 慢效果 / 30fps 快效果 / 60s 静态),消除 app 持续 ~30% CPU 占用 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
之前只对 DMG 做公证+staple,App Bundle 本身没有 ticket。 用户拖到 /Applications 后,Gatekeeper 只查 app 自身的 staple ticket, 在离线或网络受限(macOS 26 更严格)时报"无法打开"。 现在在打 DMG 之前先把 App Bundle zip 提交 notarytool 公证, 再 stapler staple 到 app bundle,之后的 DMG 里的 app 就带完整 ticket。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maven target/*.class and firmware obj_final/*.o were committed because .gitignore only had `obj/` (not `obj_final/`) and lacked `target/`/`*.class`. Add the missing rules and drop the tracked artifacts from the index (working-tree files are kept). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 固件:新增 0x84 写任务槽、0x85 读槽、0x86 套图切换、0x90 LCD/灯效状态同步 - 固件:电源键双击切换当前 Mode 套图并持久化 - 固件:添加 Makefile + TASK_GIF_BUILD.md 支持命令行构建 - 客户端:状态槽选择、GIF 上传、74 帧空间分配、旧草稿迁移、统一写入设备链路 - CI:添加 GitHub Actions 工作流,push main-anpx 自动构建 HEX artifact - 文档:更新 BLE 协议文档与任务状态 GIF 方案设计 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Makefile: rv32imac_zicsr_zifencei (GCC 14 requires explicit extensions) - Makefile: nano.specs + correct library order (LDLIBS after objects) - Makefile: fix StdPeriphDriver path (no src/ subdir), correct exclude list - hidkbd_main.c: add missing #include main.h / ble_init.h - ips096_st7735.h: declare IPS_ShowString_len (Codex-added, was missing) - Build: FLASH 89.99% (412KB/448KB), RAM 100% Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- xpack toolchain includes nano.specs; ubuntu pkg doesn't - LIB_DIR points to EVT/EXAM/BLE/LIB (not SRC/LIB) - PREFIX: riscv-none-elf- (xpack naming) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ldmac Clean firmware and old mac client from main-anpx
- 新增 KimiPermissionModeController + KimiTUIAdapter,支持拨杆切换当前 Kimi 会话 yolo/manual - 新增睡眠防护(合盖运行)功能及设置页面,含 VirtualDisplayBridge 和诊断日志 - 新增中英文本地化(en.lproj / zh-Hans.lproj)及生成脚本 - OLED 上传支持任务状态 GIF 和 PNG - 优化云端账号管理:支付成功后强制刷新额度 - 新增 Shared 工具模块(Keychain、Paths、ProcessDetector、PowerProtectionManager) - 新增 PowerProtectionManager / ProcessDetector 单元测试 - 更新构建脚本、Package.swift 和 .gitignore
…reference Introduce ahakeyconfig-win-rust/ Tauri 2 + Svelte Windows client. This is the initial import of the existing untracked Rust workspace. Protocol layer rewrite - protocol/packet.rs: AhaKeyCommand enum expanded from 10 to 25 commands, aligned with macOS `AhaKeyCommand.swift`. Removed CRC8/MAX_PAYLOAD_LEN (not used by reference protocol). - protocol/codec.rs: frame format changed from [AA 55 cmd len:2 seq:1 payload crc:1] (incorrect) to [AA BB cmd payload CC DD] (matches macOS / Java reference). - protocol/builder.rs: 16 high-level command builders mirroring macOS `AhaKeyCommand` Swift static methods and Java `AhaKeyProtocol` static methods, byte-for-byte. Each has a `*_byte_identical_to_macos` unit test. - ble/transport.rs: adapted to new API; removed seq counter (not in ref). Verification - 19/19 byte-level tests pass (Rust output == macOS Swift output): queryDeviceStatus, saveConfig, queryCapabilities, changeName, setKeyMapping, setKeyDescription, setKeyMacro, setWorkMode, setBrightness, readPicState, setLightMapping, prepareWrite, updatePicture, updateState, previewLightEffect, changeAppearance, plus boundary clamps and decode roundtrip + 4 error paths. - cargo check passes; Tauri runtime smoke-test blocked by Win32 DLL load issue in current test env, not by code. gitignore - Exclude `.cargo/` (personal target-dir override should not be shared). Follow-up - Hook up Tauri commands/UI to the new builder API. - Phase 2: BLE connection + key mapping UI; Phase 3: replace Java stable.
Removed the following unused / redundant items from the repository: Root-level macOS baseline (replaced by ahakeyconfig-mac/): Sources/ (Swift sources for the old macOS client) Resources/ (icons, OLED assets, help HTML) Packaging/ (Info.plist) scripts/ (build.sh, generate_icons.swift, etc.) Root-level temporary shell scripts (developer scratch, hard-coded macOS paths under /Users/cjn/Desktop/keyboard1/ahakeyconfig/): create-alias.sh fix-cursor-agent.sh fix-cursor-config.sh fix-cursor-permissions.sh fix-hooks-format.sh fix-hooks.sh test-cursor-hook.sh test-hook.sh Logo (replaced by ahakeyconfig-mac/Resources/AppIcon/AhaKeyStudioIcon.png): ahakeyicon.png External clones / reference projects (not part of the desktop client): ahakeyconfig-win/Capswriter-master/ ahakeyconfig-win/vibe_code_config_tool-master/ ahakeyconfig-win/wxcloudrun-flask-main/ ahakeyconfig-win/BLE_tcp_bridge_for_vibe_code-master (1)/ Build artifacts and debug residue (covered by .gitignore going forward): ahakeyconfig-ubuntu-java/target/ (Maven build output) ahakeyconfig-win-java/features_debug.txt (96KB debug dump) ahakeyconfig-win-java/sources.txt (924B dep list) All physical deletes went through mavis-trash (recoverable from system recycle bin). No code or tracked source files were lost. Note: ble_bridge.py and 10 other .java files under ahakeyconfig-win-java are D-state from upstream PR #43 (firmware removal). They are NOT included in this commit -- the user will handle those separately.
Checkpoint before refactoring the BLE backend to talk to the BLE_tcp_bridge_v2 TCP server. The btleplug/WinRT path turned out to be the wrong architecture - AhaKey 5A93 requires the dedicated bridge. The commands wired here will be re-pointed at the new TCP client. - ble/manager.rs: STATUS_QUERY_INTERVAL 2 -> 1s; poller retries 3 consecutive failures before reporting disconnected; send_frame() is the unified write entry point - commands.rs: wire set_active_mode, apply_keys_to_device, change_name, save_config, set_brightness, preview_light_effect - lib.rs: register 4 new commands in invoke_handler - App.svelte: add connecting state, 5s -> 15s client timeout, button text switches to "连接中..." - scripts/restart-clean.ps1: kill procs + trash WebView2/Vite cache + relaunch .exe with RUST_LOG -> ahakey-test.log
…ge_v2 AhaKey 5A93 requires communication through the BLE_tcp_bridge_v2 driver (C# .NET 8 WinForms, 127.0.0.1:9000), not direct btleplug/WinRT. The direct path returns 0x8000000E from BLE APIs and the device refuses to acknowledge. The bridge exposes a [Type:1][Length:2 LE][Data:N] TCP protocol that mirrors the AhaKey 0x7340 GATT service one-to-one. ## ble/manager.rs - completely rewritten - connect() now: TcpStream::connect(127.0.0.1:9000) -> into_split() -> spawn read_loop (parse 0x81/0x82/0x83) -> spawn status query poller - send_frame() wraps data in [0x02, len_le, data] WriteCommand packet - read_loop forwards 0x81 payload to state.on_ble_notify unchanged (already 14-byte AA BB 00 ... CC DD parser) - parse_ble_status() parses 0x82 BleStatusInfo (connected / name / mac / isTarget) and triggers set_connected/set_disconnected + emit - poll_task sends [0x02, 0x05, 0x00, 0xAA, 0xBB, 0x00, 0xCC, 0xDD] every 1s to keep the bridge forwarding device status frames ## ble/transport.rs / winrt.rs / usb_hid.rs / force_disconnect.rs - DELETED - No longer needed. The btleplug and windows WinRT BLE features are gone. ## ble/mod.rs - simplified - Only re-exports BleManager ## Cargo.toml - REMOVED: btleplug workspace dep, and windows BLE WinRT features (Devices_Bluetooth, Devices_Enumeration, etc.) - KEPT: windows Win32 keyboard hook features (hook/injector.rs needs them for keyboard simulation, unrelated to BLE) ## state.rs - AppState::new now propagates BleManager::new() Result with `?` ## commands.rs - scan_devices no longer calls state.ble.scan(); instead reads crate::service::config_store::load_last_device() and returns it as a single-element Vec<ScanResult>. With the v2 bridge model there's no "scan nearby" concept -- the bridge already manages connection state and the host only needs the persisted last_device. Note: Cargo.lock changed shape; the protocol layer (src-tauri/src/protocol/*) is unchanged because it produces the same byte frames that flow through the new transport.
v2 bridge 链路下设备永远只有 1 个(从 config_store 读 last_device),
弹窗已无存在价值。点"连接设备"直接调 connectToBridge 走 v2 bridge。
- 删 showDevicePicker / scanning / scanResults / selectedDevice / connectError /
sortedResults / reconnecting state(7 个变量,无引用)
- 删 startScan / selectDevice / confirmConnect / cancelConnect /
reconnectLastDevice 函数(5 个,无调用)
- 删弹窗块 {#if showDevicePicker}(L274-363, 90 行)
- 删 .picker-* / .spinner / .badge-* CSS(L314-591, 278 行)
- 删 ScanResult interface(无引用)
- 新增 connectToBridge():15s timeout 兜底,直接 invoke connect_device
- TopBar 加 connecting prop,按钮显示"连接中..." 防止重复点击
App.svelte: 757 → 302 行(-455)
TopBar.svelte: +4 / -2
#5 键盘模式切换回跳到第一个 - 根因:onModeChange 没调后端 set_active_mode,只改 UI 变量 selectedMode;下次 device-status-changed 事件来时(state.active_mode 还是 0)就被覆盖回 0 - 修法:onModeChange 改为 async,调 invoke("set_active_mode", { mode }) 让后端通过 BLE set_work_mode 协议帧切到设备,设备回 notify 上报新 workMode → 下次事件 selectedMode 自然同步成新值 - L60/L69 device-status-changed 强制覆盖逻辑保留(本来就对:后端说啥是啥) #4 CanvasPane 摇杆状态不更新 - 根因:knob-label 写死 "手动批准",没接 switchTitle prop - 修法:CanvasPane 加 switchTitle prop(默认空字符串兜底),knob-label 显示 switchTitle;App.svelte CanvasPane 标签传 state.switch_title App.svelte: +12 / -3 CanvasPane.svelte: +2 / -1
…e groups
对齐 win-java StudioPart 架构,后端 commands 不动,只做 UI 路由骨架,
等用户视觉确认 7 个 hotspot 切换体验对路再决定 2B 怎么填内容。
App.svelte:
- 加 type StudioPart = 'lightBar' | 'oledDisplay' | 'key1' | 'key2' | 'key3' | 'key4' | 'toggleSwitch'
- 加 selectedPart state(默认 'key1')
- 加 onSelectPart():选 K1-K4 时同步 selectedKeyId
- lightSegments 8 段 → 4 段(对齐 win-java)
- CanvasPane / InspectorPane 标签改用 selectedPart / modeIndex 传参
CanvasPane.svelte(重写,基本重排成 win-java 布局):
- 左栏:灯条 hotspot + 4 键 hotspots
- 右栏:OLED hotspot + 旋钮 hotspot(带 thumb translateY 动画) + mode badge
- 7 个 hotspot 都是可点 button,class:selected 加蓝边
- 旋钮 thumb 位置根据 switchTitle 自动/手动判断(上=自动,下=手动)
- mode badge 圆球显示 mode+1(对齐 win-java)
- .hotspot.dirty class 预留(2B 改时启用)
- 灯条 4 段渐变蓝紫色装饰(will be 2B 动画)
InspectorPane.svelte(重写):
- 接收 selectedPart / mode / modeName props
- {#if selectedPart === 'lightBar'} ... {:else if 'oledDisplay'} ...
5 种 group 骨架
- lightBar / oled / toggle:占位 "待 2B 实现"
- key1-4:保留键位配置(快捷键/宏 + 描述),K1 专属"模拟按"按钮
- keyNumber 派生:key1-4 → 1-4
App.svelte: +22 / -4
CanvasPane.svelte: 重写(7124 bytes)
InspectorPane.svelte: 重写(4254 bytes)
# Conflicts: # BLE_tcp_bridge_linux/bridge_gui.py # BLE_tcp_bridge_linux/deb_package/DEBIAN/postinst # BLE_tcp_bridge_linux/deb_package/DEBIAN/prerm
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\n- force fresh account profile requests after payment confirmation\n- add cache-busting query parameters and no-cache headers for account and payment status reads\n- show an explicit post-payment refresh status\n\n## Verification\n- Swift release build for AhaKeyConfig and ahakeyconfig-agent\n- signed, notarized DMG validated by stapler, hdiutil, and Gatekeeper