Deck
A modern, native, privacy-first clipboard OS for macOS
Release Notes v1.2.0
新增 / Added
-
自动更新国内加速与兜底下载
自动更新部署了 CF 反代,国内无法访问 GitHub 时也可稳定更新,并保留 GitHub 下载作为兜底。
Auto-update now uses a CF proxy for reliable access in mainland China, with GitHub downloads kept as a fallback. -
诊断上传与内存采样
新增诊断上传与内存采样器:每日 15:00 本地时间上传 24 小时诊断报告,失败会去掉日志再试;每分钟采样内存,最多 1440 点,数据写入memory_samples.json。
Added diagnostics upload and memory sampling: uploads a 24-hour report daily at 15:00 local time with a log-less fallback, and records minute-level memory samples up to 1440 points inmemory_samples.json.
DiagnosticsUploadService.swift, DiagnosticsMemorySampler.swift -
隐私设置中的分析数据入口
隐私设置新增“分析数据”卡片与开关,开启后提供“手动上传”按钮。
Privacy settings add an “Analytics Data” card with a toggle and a manual upload action when enabled.
PrivacySettingsView.swift -
新增繁体中文支持
增加对繁体中文(zh-Hant)的本地化翻译支持。
Added Traditional Chinese (zh-Hant) localization support.
Localizable.xcstrings
Deck × Orbit
-
每次安装唯一 Token 与安全兜底
Orbit bridge token 改为每次安装随机生成并存储,#if DEBUG仍兼容 legacy token;Release 不再接受硬编码 token。
Orbit bridge tokens are now per-install random values with a DEBUG legacy fallback; Release no longer accepts a hardcoded token.
OrbitBridgeAuth.swift -
启动即准备 Token 与 401 重试
启动时强制创建 token,并在 401 时从磁盘重载并重试一次。
Tokens are eagerly created at launch, and 401 responses trigger a disk reload and one retry.
AppDelegate.swift, OrbitBridgeAuth.swift, OrbitBridgeClient.swift
优化 / Improvements
-
预览渲染与缩略图网格增强
预览始终显示电话行 + 全文并保留智能摘要;file URL 多图新增缩略图网格,历史卡片缩略图修复,预览对鼠标点击也会刷新。
Preview now always shows the phone line + full text while keeping smart details; added multi-image thumbnail grids for file URLs, fixed history card thumbnails, and made previews refresh on mouse clicks.
PreviewWindowController.swift, PreviewOverlayView.swift, HistoryListView.swift -
多图卡片的布局与省略指示优化
多图卡片仅显示首图,右侧独立省略指示条(固定高度与最小宽度),不再遮盖图片、也不会顶起标题。
Multi-image cards now show only the first image with a separate right-side ellipsis indicator of fixed height/min width, without overlaying the image or pushing titles.
ClipItemCardView.swift -
安装/更新界面图标渲染稳定
安装/更新 UI 强制使用原色应用图标,避免暗色模式出现模板色偏。
Install/update UI now forces original-color app icons to avoid dark-mode template tinting.
SettingsView.swift -
统计视图轻量化与内存回收
统计改为仅用元数据查询,退出视图时触发 SQLite shrink;Top Apps 使用appPath作为稳定 id。
Statistics now use metadata-only queries with a shrink-memory hook on exit, and Top Apps useappPathas a stable id.
StatisticsView.swift, DeckSQLManager.swift -
数据库启动与向量索引性能优化
PRAGMAquick_check(1)以 24h 窗口限频,仅在备份恢复时强制;向量回填仅在 embeddings 存在且 vec 表为空时触发,并按最近数据分批带短暂休眠;updateVecIndex避免重序列化并使用INSERT OR REPLACE。
PRAGMAquick_check(1)is throttled to a 24h window and forced only on restore; vec backfill runs only when embeddings exist and vec tables are empty, favoring recent rows with short sleeps;updateVecIndexavoids heavy serialization and usesINSERT OR REPLACE.
DeckSQLManager.swift -
隐写解码与导出任务离线化
隐写解码改为后台任务执行并支持取消;导出认证在主线程,抓取/编码/写入在后台完成。
Stego decoding now runs off-main with cancellation support; export auth stays on main while fetch/encode/write run in a detached worker.
ClipboardService.swift, SteganographyService.swift, DataExportService.swift -
自动删除调度器替换逐条 sleep
用AutoDeleteScheduleractor 统一调度自动删除,减少队列阻塞。
Auto-delete is now coordinated by anAutoDeleteScheduleractor instead of per-item sleeps.
SmartRuleService.swift -
语义检索矩阵化与缓存
引入矩阵化评分与向量范数缓存,保持阈值/排序语义不变,并用vDSP_mmul替代弃用的cblas_sgemv。
Added matrixized scoring with norm caching while preserving threshold/sort semantics, and replaced deprecatedcblas_sgemvwithvDSP_mmul.
SemanticSearchService.swift
变更 / Changes
-
更新缓存清理与更新完成提示
启动时清理~/Library/Caches/Deck/Updates/下所有版本前缀目录(含unknown-),并记录pendingUpdateVersion;满足条件时 8 秒后打开设置并提示“更新完成”,设置窗口新增showWindow()防止 toggle 误关。
On launch, clears all version-prefixed update caches (includingunknown-) and recordspendingUpdateVersion; when applicable, opens Settings after 8 seconds to show “Update complete,” with a newshowWindow()to avoid toggle mis-close.
UpdateService.swift, AppDelegate.swift, SettingsWindowController.swift -
更新服务的签名强制与安全约束
Release 更新路径强制代码签名校验。
Release updates now enforce code signature validation.
UpdateService.swift -
脚本执行队列策略调整
脚本执行队列做过串行化以降低资源争用,现改为并发以避免单个脚本阻塞其他任务。
Script execution was serialized to reduce contention, and is now concurrent to avoid head-of-line blocking.
ScriptPluginService.swift -
规则/模板持久化稳定码
TransformType持久化改用稳定 code,并兼容旧中文 rawValue。
TransformTypepersistence now uses a stable code with backward compatibility for legacy Chinese raw values.
TextTransformer.swift -
加密迁移与行级状态跟踪
数据库新增is_encrypted列并实现按字段幂等加解密与行级决策,检测阶段使用静默解密避免日志刷屏。
DB now tracksis_encryptedwith idempotent per-field encrypt/decrypt and row-level decisions; detection uses silent decrypt to avoid log spam.
DeckSQLManager.swift, SecurityService.swift -
导出路径与临时文件策略
导出改为直接写入用户选择路径,并在启动时清理遗留临时导出文件。
Exports now write directly to the user-chosen path and clean leftover temp exports on launch.
DataExportService.swift -
DirectConnect 明文接收限制
没有确认回调时拒绝明文接收。
Plaintext receives are rejected when no confirmation callback is wired.
DirectConnectService.swift
修复 / Fixes
-
事件回调内存泄漏与 RunLoop 解绑问题
所有 CGEventTap 回调返回passUnretained(event),并统一使用CFRunLoopGetMain()绑定/解绑,避免泄漏与 runloop 不一致导致的资源悬挂。
All CGEventTap callbacks now returnpassUnretained(event)and useCFRunLoopGetMain()for consistent attach/detach, preventing leaks and runloop mismatches.
PasteQueueService.swift, CursorAssistantService.swift -
热键卸载遍历崩溃
unregisterAllHotKeys()改为遍历Array(hotKeys.keys),避免遍历中修改集合崩溃。
unregisterAllHotKeys()now iteratesArray(hotKeys.keys)to avoid mutation-during-enumeration crashes.
HotKeyManager.swift -
热键修饰键事件泄漏
修饰键 event tap 回调改为返回passUnretained(event)。
Modifier event tap callbacks now returnpassUnretained(event)to prevent leaks.
HotKeyManager.swift -
剪贴板轮询定时器竞态
轮询定时器的 schedule/cancel 全部在其所属队列执行,避免竞态和异常。
Poll timer scheduling/canceling now runs on its own queue to avoid races and odd behavior.
ClipboardService.swift -
云同步回环与漏同步
远端变更落库时支持shouldSyncToCloud=false,避免上传回环;moreComing拉取改为循环直到完成,并正确推进 token。
Remote changes now apply withshouldSyncToCloud=falseto prevent echo uploads;moreComingfetches loop until complete with proper token advancement.
CloudSyncService.swift, DeckDataStore.swift -
云端加密记录解密逻辑
只要 record 标记为加密就强制解密,不再受本地开关影响。
Encrypted records are always decrypted regardless of local encryption toggle.
CloudSyncService.swift -
云同步远端更新落地方式
远端更新改为直接更新数据库,不再 delete+insert,避免重复与写放大。
Remote updates now write directly to the DB instead of delete+insert, preventing duplication and write amplification.
CloudSyncService.swift, DeckSQLManager.swift -
CloudSync 竞争态修复
pendingUploadCount统一在主线程更新,避免后台修改可观察状态导致竞态。
pendingUploadCountnow updates on the main thread to avoid races from background mutations.
CloudSyncService.swift -
云同步编译错误清理
移除ManagedCriticalState并补齐显式 tuple 类型,修复编译错误。
RemovedManagedCriticalStateand added explicit tuple types to fix compile errors.
CloudSyncService.swift -
唯一索引与重复去重
unique_id建立 UNIQUE 索引并在需要时去重重试,失败则降级为普通索引并报警。
unique_idnow uses a UNIQUE index with dedupe-and-retry and a safe fallback to a normal index.
DeckSQLManager.swift -
重复记录的稳定读取
fetchRow(uniqueId:)增加排序,确保重复时命中最新记录。
fetchRow(uniqueId:)now orders results to pick the most recent row deterministically.
DeckSQLManager.swift -
Blob 更新一致性与磁盘清理
更新时写入blob_path,必要时转存大数据到 blob;旧 blob 路径在更新成功后清理。
Updates now persistblob_path, offload large data to blob storage when needed, and remove old blob files after successful updates.
DeckSQLManager.swift, BlobStorage.swift -
Blob 路径与 symlink 安全
BlobStorage路径不再触碰@MainActor;symlink 解析加强以避免路径穿越。
BlobStorageno longer depends on@MainActor, and symlink resolution is hardened to prevent path traversal.
BlobStorage.swift -
文件 URL 缩略图解码错误
避免将文件路径字符串当作图像数据解码,直接从 file URL 生成缩略图。
Avoids decoding file path strings as image data by generating thumbnails directly from file URLs.
ClipItemCardView.swift -
JS 执行超时与兼容性
JSCore 执行加入超时限制;不可用符号改用dlsym动态查找,仅在支持时生效。
JSCore execution now has a time limit; unavailable symbols are resolved viadlsymand applied only when present.
ScriptPluginService.swift -
导出 OOM 修复
大文件导出改为流式解析items,避免一次性 decode 造成内存爆。
Large exports now stream-parseitemsto avoid OOM from full JSON decoding.
DataExportService.swift -
Swift 6 并发与隔离修复
日志方法标记nonisolated(unsafe)以支持后台调用;移除不必要的全局 loggernonisolated;隐写解码使用非隔离静态管线与预取 key;SteganographyKeyStore访问改为 nonisolated。
Logging now usesnonisolated(unsafe)for background calls while removing unnecessary global logger isolation; stego decoding routes through nonisolated static helpers with pre-fetched keys;SteganographyKeyStoreaccess is nonisolated.
AppLogger.swift, SteganographyService.swift, SteganographyKeyStore.swift, ClipboardService.swift -
Swift 6 语义与线程安全修复
主线程捕获隐写服务后再 detach,自动删除日志改到主线程,修复 Swift 6 隔离错误。
Stego services are captured on main before detaching and auto-delete logging is moved to main to satisfy Swift 6 isolation.
ClipboardService.swift, SmartRuleService.swift -
统计 SQL 迭代与 shrinkMemory 异步化
原生 SQL 遍历改为 Statement 行索引,shrinkMemory()改为 async 并补齐调用点。
Raw SQL loops now use Statement row indexing, andshrinkMemory()is async with updated call sites.
DeckSQLManager.swift, StatisticsView.swift, DeckDataStore.swift -
本地化警告清理
16 个未引用 key 的extractionState改为manual,保留翻译同时消除警告。
Set 16 unused localization keys tomanualto keep translations and remove warnings.
Localizable.xcstrings
说明 / Notes
- 诊断上传内容范围
上传日志不包含剪贴板数据,仅包含 App 版本、系统信息、用户 ID、24h 内存曲线与崩溃日志。
Diagnostic uploads exclude clipboard content and include only app version, system info, user ID, 24-hour memory curve, and crash logs.