feat(keyboard): improve typing, voice flow, and polish reliability

Reduce extension memory pressure and delivery races while adding richer candidates, tactile feedback, and safer two-level creative polishing.
This commit is contained in:
Rocky
2026-08-05 21:39:31 +08:00
parent 38e5ad570d
commit 31f5937a7f
177 changed files with 8343 additions and 3904 deletions
@@ -30,7 +30,8 @@ final class AppGroupConfigurationTests: XCTestCase {
XCTAssertFalse(config.translationEnabled)
XCTAssertEqual(config.handednessPreference, .left)
XCTAssertTrue(config.cursorDragNavigationEnabled)
XCTAssertEqual(config.polishIntensity, .default)
XCTAssertEqual(config.keyboardHapticIntensity, .light)
XCTAssertEqual(config.polishIntensity, .light)
XCTAssertTrue(config.personalDictionary.entries.isEmpty)
XCTAssertTrue(config.flowSkipAppSwitch)
XCTAssertEqual(config.flowKeepAliveMode, .pictureInPicture)
@@ -69,7 +70,8 @@ final class AppGroupConfigurationTests: XCTestCase {
config.translationTargetLocaleId = "en"
config.handednessPreference = .right
config.cursorDragNavigationEnabled = false
config.polishIntensity = .light
config.keyboardHapticIntensity = .strong
config.polishIntensity = .heavy
config.flowSkipAppSwitch = false
config.flowKeepAliveMode = .pictureInPicture
// Use a non-default value so the round-trip actually proves persistence.
@@ -93,12 +95,22 @@ final class AppGroupConfigurationTests: XCTestCase {
XCTAssertTrue(loaded.translationEnabled)
XCTAssertEqual(loaded.handednessPreference, .right)
XCTAssertFalse(loaded.cursorDragNavigationEnabled)
XCTAssertEqual(loaded.polishIntensity, .light)
XCTAssertEqual(loaded.keyboardHapticIntensity, .strong)
XCTAssertEqual(loaded.polishIntensity, .heavy)
XCTAssertFalse(loaded.flowSkipAppSwitch)
XCTAssertEqual(loaded.flowKeepAliveMode, .pictureInPicture)
XCTAssertEqual(loaded.flowInactivityDuration, .threeHours)
}
func testRetiredMediumPolishIntensityMigratesToLight() {
let defaults = makeDefaults()
defaults.set("medium", forKey: AppGroupConfiguration.Keys.polishIntensity)
let config = AppGroupConfiguration.load(fromAvailable: defaults)
XCTAssertEqual(config.polishIntensity, .light)
}
/// Existing installs retain their legacy engine, but an unset inactivity
/// duration adopts the current privacy-safe default.
func testDefaultMigrationUsesPrivacySafeInactivityDuration() {
@@ -168,15 +180,6 @@ final class AppGroupConfigurationTests: XCTestCase {
XCTAssertEqual(defaults.string(forKey: AppGroupConfiguration.Keys.providerId), "deepseek")
}
func testPolishIntensityLegacyOffMigratesToMedium() {
let defaults = makeDefaults()
defaults.set(PolishIntensity.legacyOffRawValue, forKey: AppGroupConfiguration.Keys.polishIntensity)
let config = AppGroupConfiguration.load(fromAvailable: defaults)
XCTAssertEqual(config.polishIntensity, .medium)
XCTAssertEqual(defaults.string(forKey: AppGroupConfiguration.Keys.polishIntensity), PolishIntensity.medium.rawValue)
}
func testLoadFromNilUsesAppGroupWhenAvailable() {
if AppGroup.defaultsIfAvailable != nil {
XCTAssertNotNil(AppGroupConfiguration.load(from: nil))