Expand onboarding and adaptive keyboard intelligence

Add resilient usage analytics, OOBE gateway flows, clipboard semantic ranking, purchase recovery, style learning, and managed current-information search.
This commit is contained in:
Rocky
2026-08-22 16:33:18 +08:00
parent ac374631ae
commit e5a83843db
162 changed files with 23574 additions and 1013 deletions
@@ -1,22 +1,19 @@
// AIAgentSkillLayout.swift
// OSGKeyboard · Shared
//
// Enabled clipboard-skill slots (max 8, ordered) plus which export skills
// the user confirmed a companion Shortcut for. Missing storage hydrates
// to the three default transform skills; an explicit empty list is kept
// Enabled clipboard skills (ordered) plus which export skills the user
// confirmed a companion Shortcut for. Missing storage hydrates to every
// built-in default skill; an explicit empty list is kept
// so turning every skill off is distinct from a fresh install.
import Foundation
public struct AIAgentSkillLayout: Codable, Equatable, Sendable {
public static let maximumEnabled = 8
public static let defaultEnabledIDs = [
AIClipboardSkillCatalog.replyID,
AIClipboardSkillCatalog.summarizeID,
AIClipboardSkillCatalog.translateID
]
public static let defaultEnabledIDs = AIClipboardSkillCatalog.catalog
.filter(\.isDefault)
.map(\.id)
/// Keyboard chip order. Unknown / unconfirmed IDs are dropped on sanitize.
/// Keyboard chip order. Unknown and duplicate IDs are dropped on sanitize.
public var enabledIDs: [String]
/// Export skills whose companion Shortcut the user marked as added.
public var confirmedShortcutIDs: [String]
@@ -31,10 +28,6 @@ public struct AIAgentSkillLayout: Codable, Equatable, Sendable {
self.confirmedShortcutIDs = confirmedShortcutIDs
}
public var isFull: Bool {
enabledIDs.count >= Self.maximumEnabled
}
public func isEnabled(_ id: String) -> Bool {
enabledIDs.contains(id)
}
@@ -43,20 +36,16 @@ public struct AIAgentSkillLayout: Codable, Equatable, Sendable {
confirmedShortcutIDs.contains(id)
}
/// Drops unknown IDs, unconfirmed export skills, and duplicates; caps at 8.
/// Drops unknown IDs and duplicates. Shortcut setup is tracked separately
/// so bundled export skills can remain visible as installed defaults.
public func sanitized(
catalog: [AIClipboardSkill] = AIClipboardSkillCatalog.catalog
) -> AIAgentSkillLayout {
let known = Dictionary(uniqueKeysWithValues: catalog.map { ($0.id, $0) })
var seenEnabled = Set<String>()
let enabled = enabledIDs.filter { id in
guard let skill = known[id], seenEnabled.insert(id).inserted else { return false }
if skill.requiresShortcut {
return confirmedShortcutIDs.contains(id)
}
return true
known[id] != nil && seenEnabled.insert(id).inserted
}
.prefix(Self.maximumEnabled)
var seenConfirmed = Set<String>()
let confirmed = confirmedShortcutIDs.filter { id in
@@ -65,7 +54,7 @@ public struct AIAgentSkillLayout: Codable, Equatable, Sendable {
}
return AIAgentSkillLayout(
enabledIDs: Array(enabled),
enabledIDs: enabled,
confirmedShortcutIDs: confirmed
)
}
@@ -75,6 +64,5 @@ public enum AIAgentSkillEnableResult: Equatable, Sendable {
case enabled
case alreadyEnabled
case needsShortcut
case full
case unknown
}