feat: harden Flow cold-start/force-quit and polish macOS dictation UX

Fix cold-start overlay recursion that overflowed the main-thread stack when
recording began while the ready overlay was still up; also remove temporary
on-screen Flow DEBUG panels after the orange-mic investigation, and land the
macOS overlay/catalog/layout polish plus related Flow recovery hardening.
This commit is contained in:
Rocky
2026-07-10 12:39:41 +08:00
parent dcb66a9849
commit cdf833935a
104 changed files with 5794 additions and 853 deletions
@@ -44,6 +44,9 @@ final class SettingsCloudSyncTests: XCTestCase {
providerId: SyncedField(value: "openai", updatedAt: stampA, deviceID: deviceA),
baseURL: SyncedField(value: "https://local.example", updatedAt: stampA, deviceID: deviceA),
model: SyncedField(value: "gpt-local", updatedAt: stampA, deviceID: deviceA),
asrProviderId: SyncedField(value: "zhipu", updatedAt: stampA, deviceID: deviceA),
asrBaseURL: SyncedField(value: "https://asr-local.example", updatedAt: stampA, deviceID: deviceA),
asrModel: SyncedField(value: "glm-asr-local", updatedAt: stampA, deviceID: deviceA),
modeId: SyncedField(value: "polish", updatedAt: stampA, deviceID: deviceA),
localeId: SyncedField(value: "auto", updatedAt: stampA, deviceID: deviceA),
engineMode: SyncedField(value: "cloud", updatedAt: stampA, deviceID: deviceA),
@@ -64,6 +67,9 @@ final class SettingsCloudSyncTests: XCTestCase {
providerId: SyncedField(value: "openai", updatedAt: stampA, deviceID: deviceB),
baseURL: SyncedField(value: "https://remote.example", updatedAt: stampB, deviceID: deviceB),
model: SyncedField(value: "gpt-remote", updatedAt: stampB, deviceID: deviceB),
asrProviderId: SyncedField(value: "qwen", updatedAt: stampB, deviceID: deviceB),
asrBaseURL: SyncedField(value: "https://asr-remote.example", updatedAt: stampB, deviceID: deviceB),
asrModel: SyncedField(value: "fun-asr-remote", updatedAt: stampB, deviceID: deviceB),
modeId: SyncedField(value: "polish", updatedAt: stampA, deviceID: deviceB),
localeId: SyncedField(value: "ja", updatedAt: stampB, deviceID: deviceB),
engineMode: SyncedField(value: "local", updatedAt: stampB, deviceID: deviceB),
@@ -80,6 +86,7 @@ final class SettingsCloudSyncTests: XCTestCase {
let merged = SyncedAppSettingsV2.merge(local: local, remote: remote)
XCTAssertEqual(merged.baseURL.value, "https://remote.example")
XCTAssertEqual(merged.asrProviderId.value, "qwen")
XCTAssertEqual(merged.localeId.value, "ja")
XCTAssertEqual(merged.engineMode.value, "local")
}