- VoxFlow / 码上写: The menu-bar application and shipped
VoxFlow.appbundle.VoiceInputremains only in compatibility paths and internal module identifiers. - Right Command session: One press-hold-release interaction that owns a single transcription.
- Partial result: A non-final text update emitted by Apple Speech while recording.
- Final result: Apple's final transcription after
endAudio(). - Bounded timeout: The 15 second fallback after right Command release that accepts the latest partial result if no final result arrives.
- Refinement: Optional conservative correction through an OpenAI-compatible API.
- Text processing pipeline: The post-ASR path that applies conservative refinement and future glossary/style rules while preserving fallback to raw text.
- Refinement guard: A post-processing safety check for ordinary dictation refinement that rejects LLM outputs which answer, execute, expand, or drop protected spoken tokens instead of conservatively correcting the ASR text.
- PromptBuilder: The pure builder that combines conservative correction rules, selected style guidance, and enabled glossary terms into an LLM system prompt.
- App style rule: A Settings-backed mapping from target app bundle/name to a style profile used during post-ASR refinement.
- ASR Provider: A descriptor and runtime entry for a speech recognition backend, including capabilities, privacy summary, availability, and fallback behavior.
- Provider target: A SwiftPM target that owns one ASR backend implementation. Provider targets live under the
Sources/VoxFlowProviders/directory, but they remain separate targets rather than one large provider module. - Capability tag: A user-facing and filterable ASR Provider label such as local, streaming, cloud, multilingual, or punctuation.
- Injection: Temporarily placing text on the pasteboard and posting ⌘V to the focused application.
- Voice HUD / 语音 HUD: The bottom-centered non-activating capsule shown during voice recording, recognition, refinement, and output status.
- Agent Confirmation HUD / 任务助手确认 HUD: The non-activating confirmation surface that lets a user choose an Agent session or fall back to direct input for an Agent Dispatch request.
- Selection Action Card / 划词动作卡: The compact surface opened for selected text that offers first-level actions such as translate, summarize, or send to Agent Dispatch.
- Text Result Panel / 文本结果面板: The reusable panel for showing obtained text and derived results such as translation or summary, regardless of whether the source text came from screenshot OCR, selected text, or another text source.
- Workbench window: The regular macOS application window shown in Dock,
⌘Tab, and Force Quit while the menu-bar dictation controls remain available. - Main Menu / 主菜单: The macOS top menu owned by VoxFlow. It provides standard app, edit, window, support, product action, and user-facing troubleshooting entries. It complements the status-bar menu rather than duplicating provider and language quick-switch controls.
- Support Menu / 帮助与支持菜单: A user-facing Main Menu section for help and troubleshooting actions that are safe to expose in all builds. It excludes developer-only cache surgery, destructive data cleanup, secrets, clipboard contents, screenshots, and raw user transcription content.
- Notes recording flow: The notes page flow that starts recording, streams transcription into the editor, finishes, and saves a note.
- VoiceTask: A persistent record tracking a voice operation across its entire lifecycle: recording, transcription, context collection, processing, and output. Created at recording start, persisted at each stage, so partial work survives crashes.
- VoiceTask mode: One of
dictation(right-Command transcription with optional style correction),agentCompose("任务助手" - context-aware LLM generation from user dictation plus window context), oragentDispatch(voice-routed instruction delivery to an Agent session). - VoiceTask stage: A step in the task lifecycle:
recording,transcribing,collectingContext,processing,outputting. Stages advance monotonically; backwards transitions are rejected. - Agent Compose ("任务助手"): A voice mode that reads the current window's context (Accessibility text, window title, optionally a screenshot fallback) and uses an LLM to generate text guided by the user's dictation intent. Output is copy-only: no keyboard injection or auto-send.
- Agent Dispatch / 任务助手调度: A voice mode that routes a dictated instruction to a registered local coding-agent session and submits it through that session's controlled input channel.
- Agent session / 任务助手会话: A registered local coding-agent CLI session that can receive an Agent Dispatch instruction.
- Agent alias / 任务助手别名: A user-confirmed phrase that resolves to an Agent session for future Agent Dispatch targeting.
- Provider session reference: A coding-agent CLI's own session identifier or transcript reference linked to an Agent session for resume, diagnostics, and log lookup.
- ContextSnapshot: A structured object holding collected context for a single agent-compose request: trimmed text, source markers, window metadata. Screenshots are transient and never persisted.
- Installed application: A discovered macOS application with name, Bundle ID, icon reference, path, and system category, produced by scanning
/Applications,~/Applications, and system directories. - Known application registry: A built-in, versioned, static mapping from Bundle IDs to suggested style IDs. Registry hits skip LLM classification and are labeled "system preset."
- Application style recommendation: A temporary suggestion (from registry or LLM classification) with source and confidence. Remains preview-only until the user explicitly confirms, at which point it becomes an app style rule.
- VoiceAction: An enum (
dictation,agentCompose,agentDispatch) representing a bindable hotkey action. Each action has an independent trigger; conflicts between actions are blocked. - OutputResult: A structured result from the output stage:
injected(dictation success),copied(agent compose success), or various failure modes with recovery paths. - OutputService: The service that selects between injection (dictation mode) and clipboard copy (agent compose mode), returning a structured OutputResult. Replaces ad-hoc injection logic.
- HistoryRecoveryAction: An enum (
copy,reinject,regenerate,retranscribe,delete) representing a recovery operation available on a history/task detail. Available actions are computed from task mode, status, and data availability. Retries never silently overwrite the original transcription or result. - Asset / 历史资产: A reusable input-context record produced by VoxFlow or captured from user copy actions, including dictation text, screenshot images, and clipboard records.
- Dictation History / 语音历史: Completed dictation text saved after a voice input flow. It is one source of Asset records, not the umbrella term for all reusable history.
- Screenshot Record / 截图记录: A saved screenshot image record. OCR text may be available as derived copyable text, but it is not a separate Asset.
- Clipboard Asset / 剪切板资产: User-copied pasteboard content captured for reuse. VoxFlow's internal pasteboard writes are not Clipboard Assets.
- Palette Root Search / 启动台根搜索: The home-level launcher surface that searches and opens Root Items such as VoxFlow commands and installed macOS applications. It is separate from the recent-assets second level.
- Palette Root Item / 启动台根项目: A stable, searchable item on the Palette home surface. Current kinds are command and application; future extension entries should join through the same ID, activation, icon, and alias contract.
- Palette File Search / 启动台文件搜索: A second-level Palette mode entered from the
Search FilesRoot Item for filename-based local file lookup, separate from Palette Root Search and Asset history. - Palette Favorites / 启动台最喜欢: User-pinned Root Items shown at the top of Palette Root Search. Stored as lightweight UI preference metadata and not the same thing as Asset favorites or screenshot
is_favorited. - Palette Suggestions / 启动台建议: Root Items ranked by recent use, usage count, and query selection history. Suggestions exclude items already shown in Favorites.
- Palette Root Action Panel / 启动台根动作面板: The
⌘Kaction panel for selected Root Items. V1 actions are open, add favorite, and remove favorite; asset rows continue to useAssetAction. - Palette Quicklink / 启动台快捷链接: A built-in searchable site-search entry on the Palette home surface (Google, Bing, Perplexity, GitHub, StackOverflow, YouTube, Bilibili, X, 小红书, 淘宝, 京东). Quicklinks are bundled in code, support alias matching and frequency sorting, and reuse the existing favorite/usage mechanism. They do not support user-defined entries.
- Palette URL Detector / 启动台 URL 检测: Detects whether Palette input is an openable URL (scheme URL, bare domain, www, localhost, IP+port) and produces an
打开网址root result ranked first. Bare domains are normalized tohttps://. - Ask AI / 问 AI: A Palette root result and selection action that sends user text (typed or selected) as a user prompt to a dedicated OpenAI-compatible chat service. Ask AI does not inject the correction system prompt used by voice refinement.
- AI Chat HUD / 问 AI 聊天 HUD: The right-side
TextResultPanelControllersurface hosting the SwiftUIAIChatHUDViewcontent: multi-turn messages, Markdown rendering (viaMarkdownUI), streaming stop button, and bottom input. It reuses the same panel shell as translation/summary results while keeping the Ask AI conversation component separate. The conversation is held in memory only for the app process lifetime. - AIChatSessionViewModel: In-memory chat session state holding
AIChatMessagehistory, streaming status, and error state. DrivesAIChatHUDViewand delegates streaming toAIChatServicing. - OpenAICompatibleChatService: Dedicated chat service that reuses
LLMProviderRepository,CredentialStore,OpenAICompatibleClient, andSSEParserbut builds multi-turnmessagespayloads without the correction system prompt. Streams accumulated text snapshots to the view model. - Selection Ask AI / 划词问 AI: The
⌘⇧Pworkflow shortcut that reads selected text from the frontmost app and sends it directly to the AI Chat HUD, bypassing the selection action card. The问 AItile in the⌘⇧Fselection action card routes through the sameaskAIContextdispatcher path. Like other selection workflow shortcuts, it is gated on dictation idle. - Vocabulary Center / 词汇表: The redesigned entry that replaces the legacy "易错词" (easy-word correction) page. Organized as two tabs:
热词(hotwords) and文本替换(text replacement). Internal type names (CorrectionTargetTerm,CorrectionRule,voice_correction_targets,voice_correction_rules) remain compatible during the migration period. - Hotword / 热词: A correct spelling maintained by the user for ASR hotword boosting and LLM correction context. Hotwords only store the correct form — users do not manage "misheard spellings." The vocabulary UI sorts hotwords by text for readability, while provider delivery can still prioritize by hit count, recency, and source weight.
- Text Replacement / 文本替换: The post-LLM deterministic strong-replacement rules, reusing the existing
VoxFlowVoiceCorrectionKitengine (LinearRuleMatcher,ContextGate,ConflictResolver,ReplacementApplier). Runs after LLM correction and before text output. The legacy "易错词规则" UI is migrated to this tab. - Internal Correction Evidence / 内部纠错证据:
correctionsfrom LLM structured output, stored as context evidence for future LLMknown_correctionsinjection. Not displayed in the hotword main UI and not automatically promoted to strong replacement rules. - OCR Temporary Context / OCR 临时上下文: Up to 5 terms extracted from the current window's OCR context, used only for the current session's LLM prompt and supported ASR context. Never written to the hotword table or auto-learning queue. Displayed with "仅本次使用,不进入学习" in the transcription detail.
- Processing Chain / 处理链路: The transcription detail section showing ASR hotword delivery, LLM structured correction, OCR temporary context, text replacement hits, and auto-learning results.
- Hotword Hit Count / 热词命中次数: Non-overlapping occurrence count of a hotword in the final output text. Used internally for provider hotword prioritization alongside recency and source weight; not shown in the vocabulary chip UI.
- Auto-learning Drawer / 自动学习建议抽屉: A dedicated drawer for LLM
key_termscandidates that have appeared 2+ times. Users can加入(add as hotword) or忽略(ignore). Candidates appearing 3 times auto-promote to hotwords unless blocklisted. - Hotword Blocklist / 热词屏蔽表: When a user deletes a hotword, its normalized form is blocklisted to prevent auto-learning from re-adding it. Manually re-adding the hotword (via UI or
hotwords.txt) removes it from the blocklist. - ASR Hotword Capability Matrix / ASR 热词能力矩阵: An explicit per-provider capability type (
ASRHotwordCapability) defining support mode (nativeHotword,promptContext,configuredVocabulary,unsupported), count limits, format limits, and pruning strategy. Only providers with real hotword APIs show the热词tag in the UI. - LLM Structured Correction / LLM 结构化纠错: LLM correction prompts that require a structured JSON output (
polished,corrections,key_terms). Supports 7 styles: 元气, 原文, 日常, 正式, 编程, 聊天, 邮件. The默认,元气,邮件,编程,正式templates are product-finalized; others follow the same structure. - StructuredCorrectionParser: A Swift port of Light-Whisper's
parse_structured_response, supporting bare JSON, array wrapper, CDATA, XML<output>wrapper, and JSON extraction from explanatory text. Parse failures fall back to raw text without blocking output. - Style Output Format / 风格输出格式: A style-level fixed enum configuration for punctuation, capitalization, tone, and emoji. It is stored with the style profile, summarized in the Style page, injected into runtime prompts, and enforced by deterministic post-processing.
- Global deterministic fallback / 全局确定性回退: The app-wide deterministic punctuation/capitalization settings used only when no effective style output format field overrides them. Default style resolution counts as an effective style.
| Module | Owns | Must not own |
|---|---|---|
AppDelegate |
Menu construction, permissions prompts, hotkey entry, HUD callback wiring | Audio math, URL parsing, pasteboard serialization, dictation state machine |
AppPresentationPolicy |
App activation policy and main-window restore rules | Window layout or menu construction |
WindowPlacementPolicy |
Pure visible-screen centering and recovery rules for the workbench window | SwiftUI content or app lifecycle |
KeyMonitor |
CGEvent tap and right Command transitions | Recording lifecycle |
AudioRecorder |
AVAudioEngine and RMS extraction | Speech requests |
SpeechRecognizer |
Speech request/task and callbacks | Audio engine |
TranscriptionSession |
Final/partial/release/timeout completion semantics | AppKit or asynchronous timers |
DictationStateMachine |
Legal dictation state transitions | ASR, audio, UI, persistence |
DictationOrchestrator |
Recording lifecycle, ASR engine callbacks, timeout fallback, text pipeline, injection, history save | Menu construction, permission prompts, view layout |
TextProcessingPipeline |
Optional LLM refinement, post-LLM deterministic voice correction, prompt context collection, and fallback warnings | ASR, audio capture, text injection |
PromptBuilder |
Pure prompt assembly from conservative rules, default style, and enabled glossary terms | Repository access, network requests, history persistence |
AppStyleRuleStore / SettingsBackedStyleSelector |
Persisted app-to-style mappings and runtime style resolution for a dictation target | Prompt construction, LLM network requests, SwiftUI layout |
ASRProviderRegistry |
ASR provider descriptors, capability filtering, default provider selection, fallback chain, engine creation | Download UI, AppKit window ownership |
ASRProviderViewModel |
Dictation model page state, provider records, tag filtering, local model path/download/delete operations | ASR engine implementation details |
CloudASRProviderClient |
Basic cloud ASR connection/file transcription protocol shape | Concrete third-party API behavior |
SettingsViewModel |
SwiftUI settings state, persisted app settings, shortcut preferences, device/permission snapshots, data actions | Hotkey event capture, real permission requests |
FileTranscriptionViewModel |
File import validation, transcription job queue state, progress/cancel/retry, export, save-as-note | Concrete ASR provider internals, note editing UI |
FileTranscriptionWorking |
File-to-text worker contract for mock and real ASR implementations | Job persistence or SwiftUI state |
NotesViewModel |
Note CRUD, notes recording flow state, Markdown draft state, search, history/file-transcription import, tag normalization, Markdown export | File transcription queue execution, audio capture implementation |
NotesRecordingService |
AudioRecorder-to-ASR transcription bridge for notes recording | Note persistence or SwiftUI layout |
OverlayWindowController |
NSPanel visibility, sizing, animation | Recognition state |
WaveformModel |
Envelope and bar heights | Drawing |
TextInjector |
Input source switching, paste, clipboard restoration | Recognition or LLM calls |
LLMRefiner |
Configuration, endpoint normalization, API request/response | UI |
LanguageManager |
Supported locales and persisted selection | Speech task lifetime |
CredentialStore / KeychainCredentialStore |
API key persistence and migration target | Non-sensitive preferences, logging |
AppLogger |
OSLog output and sensitive-token redaction | Secrets, user content transformation |
ApplicationSupportPaths |
Legacy VoiceInput Application Support paths retained for database, exports, and model compatibility |
File transfer, network downloads |
AppClock |
Testable wall-clock and sleep abstraction | Business state transitions by itself |
HistoryRepository |
Persisted dictation history records and search/delete queries | ASR lifecycle, text injection |
VoiceTaskCoordinator |
Unified entry point for dictation and agent-compose modes; wraps DictationOrchestrator; creates and advances VoiceTask records at each stage | Menu construction, view layout, audio engine |
OutputService |
Mode-aware output selection (inject vs. copy), structured OutputResult, clipboard fallback on injection failure | ASR lifecycle, prompt construction |
AgentPromptBuilder |
Pure prompt assembly for agent-compose mode: app metadata, style guidance, context snapshot, user dictation into a fixed agent prompt | Repository access, network requests, history persistence |
InstalledApplicationProvider |
Local macOS app directory scanning, Bundle ID extraction, icon reference, deduplication | LLM classification, style rule persistence |
KnownApplicationRegistry |
Static versioned Bundle ID to style ID mapping, registry lookup and hit/miss reporting | LLM requests, user rule management |
ApplicationStyleRecommendationService |
Merges registry hits and LLM classifications into preview-only recommendations; writes rules only on user confirmation | Direct rule persistence, prompt construction |
ContextPipeline |
Parallel context collection (Accessibility text, window metadata, optional visual fallback), deduplication, trimming, timeout enforcement | ASR lifecycle, text injection |
PaletteRootItem / PaletteRootSearchIndex |
Palette home command/application item modeling, fuzzy matching, Favorites/Suggestions sectioning, and ranking | Asset CRUD, AppKit window control, launching applications |
PaletteRootComposer |
Composes URL/Ask AI/Quicklink root items with existing command/application items into a single ranked list | ASR, audio, pasteboard, network requests |
PaletteQuicklink / PaletteQuicklinkCatalog |
Built-in Quicklink model and catalog with aliases, search URL templates, and default ordering | UI layout, network downloads, persistence beyond usage/favorites |
PaletteURLDetector |
Pure URL/裸域名/localhost/IP+port detection and normalization for Palette input | Palette ranking, AppKit, network |
Palette/FileSearch |
Palette File Search models, Spotlight-backed filename lookup, recent-file results, file metadata loading, and file actions | Asset persistence, content indexing, semantic search, ASR, network requests |
AIChatSessionViewModel / AIChatServicing / OpenAICompatibleChatService |
In-memory multi-turn chat session state, OpenAI-compatible streaming chat requests without correction system prompt, SSE parsing reuse | HUD window lifecycle, voice refinement prompt, agent dispatch |
AIChatHUDView |
SwiftUI message list, Markdown rendering via MarkdownUI, streaming stop button, bottom input |
Network requests, pasteboard, persistence |
SelectionActionDispatcher (askAI route) |
Routes .askAI selection action to .askAIContext(text:) route, separate from .agentContext |
LLM calls, HUD presentation |
PaletteFavoritesStore / PaletteUsageStore |
Lightweight Palette Root Search UI preferences and ranking statistics in UserDefaults | SQLite schema, asset favorite state, screenshot favorite state |
PaletteApplicationLauncher |
Opening installed application paths through NSWorkspace behind a testable protocol |
Search ranking, favorites persistence |
Sources/VoxFlowProviders/VoxFlowProvider* |
Individual ASR provider runtime, descriptor, manifest/client, and provider-specific tests | AppKit UI, settings view layout, unrelated provider implementations |
Text is injected with the clipboard and ⌘V because it works across more native, Electron, browser, and custom text controls than direct Accessibility value mutation.
CJK input methods can intercept or transform synthetic keyboard events. VoxFlow temporarily selects ABC/US for paste, then restores the exact prior input source.
Apple Speech and local ASR final-result latency is not fixed. VoxFlow completes immediately on a final result and otherwise waits up to 15 seconds before accepting the latest partial result. If ASR errors after partial text has arrived, the latest partial is used instead of dropping the dictation.
Refinement is off unless configured and enabled. API failure falls back to raw text. The prompt forbids rewriting and asks for byte-for-byte preservation when no obvious error exists.
Release and development app bundles are isolated at .build/release/VoxFlow.app and .build/dev/VoxFlow.app. Local development prefers an available Apple Development identity and falls back to ad-hoc signing. DMG packaging never falls back to ad-hoc signing: make dmg requires the stable RELEASE_CODE_SIGN_IDENTITY to exist in the active keychain.
AppDelegate keeps menu-bar, permission, and hotkey entry responsibilities, but DictationOrchestrator owns the recording lifecycle after start. This keeps right Command behavior stable while allowing timeout, LLM fallback, history persistence, and future glossary/style processing to be tested without AppKit windows or real devices.
ASR provider availability and labels are computed in ASRProviderRegistry from the current ASRManager state, then mirrored into SQLite for workbench summaries. This avoids duplicating Apple/Qwen selection logic while still giving the SwiftUI model page a repository-backed view of providers, health, tags, and default/fallback behavior.
VoiceTask uses its own voice_tasks table rather than extending dictation_history. The two entities have different lifecycles (tasks are runtime state with stages; history is a completion record), and mixing them would cause nullable field pollution and complicate incomplete-task queries.
Application style routing separates facts (InstalledApplication from scan), recommendations (temporary suggestions from registry or LLM), and rules (user-confirmed AppStyleRule). This prevents rescanning from silently overwriting user choices and keeps trust levels explicit.
The existing PromptBuilder produces conservative correction prompts for dictation mode. A new AgentPromptBuilder produces fixed agent prompts for agent-compose mode. Combining both into one builder would create conflicting constraints ("only correct" vs. "generate from intent").
Agent compose output is copy-only (clipboard write). No ⌘V injection, no Enter simulation, no app-specific send actions. This is a firm v1 boundary: automatic sending introduces reliability and safety risks that require per-app adapters and extensive testing.
Agent Dispatch sends instructions only to registered Agent sessions through a wrapper-owned input channel. This avoids GUI focus/paste risks and keeps MCP as an optional self-reporting interface rather than the mechanism that controls terminal input.
Style output format controls are runtime rules, not user-editable prompt text. When a style is resolved by manual app rule, AI auto-match, or default style, its output-format fields override global deterministic punctuation and capitalization field-by-field. If no effective style exists, the global deterministic settings preserve existing behavior.
- iOS V1: 普通 iOS App,不包含 Keyboard Extension 或任意 App 注入;通过 LiveContainer 在真机预览。
- LiveContainer: 让未签名 IPA 在真机运行的宿主 App,V1 的真机预览路径,不是长期系统能力基石。
- Shared ASR Runtime:
Sources/VoxFlowASRRuntime/中的跨平台云实时 ASR 适配层,macOS 与 iOS 共用。 - MobileCore:
Sources/VoxFlowMobileCore/中的移动端听写状态机和会话桥接,不含 UI。 - LocalCredentialStore: iOS App sandbox 内的明文 JSON 凭证存储,仅用于个人测试 key。
- AppleSpeechASREngineAdapter: 把
ASRSession(AsyncStream)适配为ASREngine(闭包回调)的桥接器,使 Apple Speech Provider 接入移动端听写会话。
| Module | Owns | Must not own |
|---|---|---|
Sources/VoxFlowASRRuntime/ |
云实时 ASR engine、PCM16 编码、转写拼接、错误映射;macOS 与 iOS 共用 | AppKit、UIKit、SwiftUI、剪贴板、Keychain、UserDefaults、LiveContainer |
Sources/VoxFlowMobileCore/ |
移动端听写状态机、ASRSession/ASREngine 与录音器的会话桥接 | UI、权限呈现、凭证存储、LiveContainer |
Apps/VoxFlowiOS/ |
iOS App 壳层:SwiftUI 页面、权限引导、本地凭证文件、UIPasteboard 复制、LiveContainer 诊断 | macOS App、AppKit、菜单栏、全局快捷键 |
iOSAudioRecorder |
AVAudioSession + AVAudioEngine 录音、中断/路由变化处理、PCM buffer → AudioFrame |
ASR、UI、凭证 |
AppleSpeechASREngineAdapter |
ASRSession → ASREngine 闭包适配;事件流 → onTranscription/onError |
UI、录音、凭证 |
iOSASREngineFactory |
根据本地凭证构建腾讯/阿里/火山云 ASREngine |
UI、权限、状态机 |
LocalCredentialStore |
App sandbox 明文 JSON 凭证读写 | Keychain、加密、网络 |
Sources/VoxFlowASRRuntime/ 和 Sources/VoxFlowMobileCore/ 不允许 import AppKit、import UIKit、import SwiftUI、import Cocoa,不允许直接调用 UIPasteboard、NSPasteboard、Keychain、UserDefaults、LiveContainer 专用符号。平台能力通过 protocol 注入(MobileAudioRecording、ASREngine、ASRSession)。
V1 不支付 Apple Developer Program 年费,通过 LiveContainer 在真机预览普通 App。Keyboard Extension、任意 App 注入、App Store/TestFlight 发布、Keychain 凭证加密、历史持久化、本地模型 Provider 均为后续轨道。
LiveContainer 环境下 Speech 权限可能不可用,Apple Speech 不能作为 V1 唯一成功路径。腾讯/阿里/火山云实时 ASR 通过共享 runtime 复用 macOS 实现作为主验收路径。Apple Speech 通过 AppleSpeechASREngineAdapter 保留为可选 baseline。
凭证以明文 JSON 保存在 Application Support/VoxFlow/credentials.json,仅用于个人测试 key。设置页持续显示警告。Keychain、加密、导入导出、服务端 token broker 为后续轨道。
iOS Simulator 提供两条电脑端预览路径:
- Simulator + Mac 麦克风:快速验证录音权限、UI 状态、云 ASR partial/final
- Simulator + 固定音频注入:通过 BlackHole 2ch 等虚拟音频设备做可重复验收
详细步骤、限制和真机 LiveContainer 验收路径见 docs/ios-preview.md。
iOS Keyboard Extension 在免费 Apple ID / AltStore / SideStore 签名路径下,App Group entitlement 经常不可用或返回 nil。键盘启动链路必须容忍这种失败:
Shared/AppGroup.swift区分defaults(强制,用于 AppGroupBridge 正式路径)与defaultsIfAvailable(可失败,用于键盘启动 / ClipboardBridge)。KeyboardState.defaults使用AppGroup.defaultsIfAvailable ?? UserDefaults.standard,确保键盘在 App Group 不可用时仍能渲染和打字。SharedStatusStore和BridgeModeStore的读写都通过defaultsIfAvailable,写入失败时退化为 standard defaults。- AppGroupBridge 路径只在
BridgeMode=AppGroup或BridgeMode=Auto + AppGroup available时进入。 - ClipboardBridge 路径完全不依赖 AppGroup — 使用 UIPasteboard + URL deep link + 本地 UserDefaults pending state。
- 详见 OpenSpec change
add-ios-keyboard-clipboard-fallback。
- iOS 系统级键盘 / Keyboard Extension / 任意 App 注入
- App Store / TestFlight 发布、付费 Apple Developer Program
- Keychain 凭证加密、导入导出、服务端 token broker
- 历史记录、SQLite 持久化、多设备同步
- Qwen3 / Whisper / FunASR / SenseVoice 本地模型 Provider
- Agent Compose、Agent Dispatch、截图/OCR、文件转写、笔记工作台