feat: cursor navigation, key sounds, dictionary tooling, key security

Batch of in-progress app work from the working tree.

- feat(keyboard): CursorNavigation + CursorDragPad for caret movement;
  KeyboardSoundFeedback for system key click sounds
- feat(dictionary): DictionaryAliasGenerator + PersonalDictionaryEntrySheet;
  TranscriptPostProcessor quality gate; retire DictionaryLearner
- feat(ui): TabBarVisibility handling; drop PageHeaderRow /
  PageHeaderConfirmButton; refresh views and localizable strings
- fix(security): move the hardcoded DeepSeek key out of
  PreconfiguredKeys.swift into a gitignored PreconfiguredKeys.local.swift
  (seeded from .example by generate-xcodeproj.sh)
- docs(agents): add Conventional Commits versioning + bilingual changelog rules
- chore(gitignore): ignore PreconfiguredKeys.local.swift, .cache/, pycache

Custom language model / lexicon work stays on
feature/custom-language-model-asr. Changelog bullets added under
[Unreleased]; no version bump.
This commit is contained in:
Rocky
2026-07-05 18:27:23 +08:00
parent 074e24d87f
commit 05e005e9ce
60 changed files with 3247 additions and 1388 deletions
+9 -5
View File
@@ -52,13 +52,11 @@ public struct LLMProvider: Identifiable, Codable, Hashable, Sendable {
id: "deepseek",
name: "DeepSeek",
defaultBaseURL: "https://api.deepseek.com/v1",
// v0.2.0: bumped default to `deepseek-v4-flash` for the
// local-mode cloud-polish toggle. `deepseek-chat` is
// retained as a valid user-overridable model name; only
// the default is updated.
defaultModel: "deepseek-v4-flash",
apiKeyURL: URL(string: "https://platform.deepseek.com/api_keys"),
blurb: "deepseek-v4-flash · 默认 · 快速且中文友好"
blurb: "deepseek-v4-flash · 本地引擎内置 · Local engine built-in",
// Local engine only never shown in cloud-engine pickers.
isUserSelectable: false
),
.init(
id: "qwen",
@@ -96,4 +94,10 @@ public struct LLMProvider: Identifiable, Codable, Hashable, Sendable {
public static func provider(id: String) -> LLMProvider {
presets.first(where: { $0.id == id }) ?? .presets[0]
}
/// Presets the user may pick in Settings / onboarding. DeepSeek is
/// excluded it is wired exclusively to the local engine.
public static var userSelectablePresets: [LLMProvider] {
presets.filter(\.isUserSelectable)
}
}