fix: keyboard stability, host-only analytics, and auto-reply dedupe
- record analytics/usage only in the host app; the extension no longer opens the SQLite queues, so hiding the keyboard cannot hold WAL locks (0xdead10cc) - sync clipboard history writes across processes so deletes made on one side are not reverted by the other - guard memory-relief reentrancy on controller and telemetry sides to break the recursive crash loop - resolve credentials off the main thread and migrate legacy keys once per install, so Keychain reads cannot be caught in the suspend window - gate Volcengine ASR ping completion to once (SIGTRAP on double resume) - treat same-text captures as the same logical copy and dedupe auto actions by content fingerprint within 30s, stopping Universal Clipboard storms - realign version line to 2.1.0 (build 110)
This commit is contained in:
@@ -7,7 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- **Host-only analytics recording**: the keyboard extension no longer opens the analytics or keyboard-usage SQLite queues. The host app is the only process that records and uploads events, so hiding the keyboard cannot hold WAL locks and get killed as `0xdead10cc`. Keyboard-activated and per-keystroke usage events are no longer collected. / **仅主 App 记埋点**:键盘扩展不再打开统计与键盘用量 SQLite 队列;开库、记账与上传只在主 App 进行,收起键盘时不会因 WAL 锁被系统以 `0xdead10cc` 终止。不再采集「键盘激活」和逐次按键用量。
|
||||
|
||||
### Fixed
|
||||
- **Clipboard history reverting deletes**: history is one shared blob, and the main App kept an in-memory copy that only refreshed when a screen appeared — so a delete made there could write back entries the keyboard had just captured or removed, and a clear done in the keyboard could be undone entirely. Both processes now announce their writes to each other, and the main App re-reads history whenever it returns to the foreground. / **剪贴板历史撤销删除**:历史记录是整块共享数据,而主 App 仅在页面出现时刷新内存副本——因此在主 App 中删除一条,可能把键盘刚采集或刚删除的条目重新写回,在键盘里执行的清空也可能被整体撤销。现在两端写入时会互相通知,主 App 每次回到前台也会重新读取历史。
|
||||
- **Keyboard crash loop on memory relief**: recording a memory milestone could request relief while relief was already running, and the two sides called each other until the keyboard extension exhausted its stack (SIGSEGV grouped under `KeyboardViewController.viewDidLoad`). Reentrancy guards on both the controller and the telemetry side break the cycle. / **键盘内存降级递归崩溃**:记录内存里程碑时可能再次请求降级,两侧互相回调直至扩展栈溢出(崩溃聚合在 `KeyboardViewController.viewDidLoad`)。控制器与遥测两侧均加重入保护,打断循环。
|
||||
- **Keyboard killed while reading credentials**: the extension resolved API keys synchronously on the main thread at every config read — including boot and Flow session setup — and a Keychain read in flight while the system suspends the keyboard is killed as `0xdead10cc`. Legacy credential migration is now attempted once per install instead of on every load, credential availability refreshes asynchronously after appear, and the onboarding gate reads the Keychain off the main thread. / **键盘读取凭据时被系统终止**:扩展此前每次读取配置都会在主线程同步解析 API 密钥(含启动与 Flow 会话建立),而挂起窗口内进行中的钥匙串读取会被系统以 `0xdead10cc` 查杀。旧凭据迁移改为每次安装仅尝试一次,凭据可用性改为键盘出现后异步刷新,入门引导门控的钥匙串读取移出主线程。
|
||||
- **Managed ASR connect crash**: `URLSessionWebSocketTask.sendPing` can invoke its completion twice when the task is cancelled mid-ping, so opening a managed Volcengine session could trap on the second continuation resume (SIGTRAP). The handler now passes through a once-only gate. / **托管语音识别建连崩溃**:`URLSessionWebSocketTask.sendPing` 在 ping 在途时被取消会回调两次,打开托管火山引擎会话时第二次恢复 continuation 会触发 SIGTRAP 断言。回调现经一次性闸门过滤。
|
||||
- **Auto-reply storms from Universal Clipboard**: copying on a nearby Mac re-announces one copy under several pasteboard changeCounts, and each re-announcement re-armed auto reply/translate and the auto-reply guide — including on every later keyboard open, because re-ingesting the same text kept refreshing its 30-second hint window. A capture whose text is identical to the newest history entry is now treated as the same logical copy (bookkeeping only, no re-analysis), and auto actions additionally dedupe on a content fingerprint within a 30-second window. The same text fires once; copying something else and then re-copying the text still triggers. / **跨端剪贴板引发自动回复风暴**:在附近 Mac 上复制一次会被系统以多个 changeCount 重复宣告,且每次宣告都会重新武装自动回复/翻译与自动回复引导——由于同文本被重复入库并不断刷新 30 秒提示窗口,之后每次打开键盘也会再触发。现在,与最新历史条目文本相同的采集会被视为同一次复制(仅更新记账,不重新分析),自动动作再叠加内容指纹 + 30 秒窗口去重。同一文本只触发一次;复制其他内容后再重新复制该文本仍可触发。
|
||||
- **Style card captions**: resolve each built-in style’s short description through the in-app language override, so switching App Language updates the caption instead of showing a localization key or the system language. / **风格卡片说明**:内置风格的说明小字改为走应用内语言设置;切换 App 语言后说明会跟着变,而不再显示本地化 key 或跟随系统语言。
|
||||
|
||||
## [2.2.0] - 2026-09-18
|
||||
|
||||
Reference in New Issue
Block a user