# 云同步 ## Cloud Sync V3 预览 设置中的 **Cloud Sync V3** 提供独立的 V4 同步空间,首批支持 WebDAV、S3 和本地目录后端。选择 V3 后先保存设置,再生成同步预览。确认时会重新检查本地数据和已可见的远端发布;预览过期时须重新生成。 连接、分组、代理、隧道、快捷命令、笔记、自定义图标和主题按稳定 ID 合并。不同字段可自动合并,同字段冲突保留候选和本机当前值;可以在预览中选择候选,也可以先同步无冲突部分。删除和并发编辑会保留存在性冲突。外观偏好可单独开启,仅同步主题、终端字体、光标和对比度白名单。快捷键是独立的可选范围,按操作合并;关闭后保留已有配置。 首次确认会在配置目录创建并回读验证加密的 `cloud-sync-v3-safety-.nya` 备份。旧云端数据保留,检测到旧客户端后续写入时暂停自动同步;可手动生成导入预览,确认后保留双方资源和冲突候选。V4 的合并结果先原子应用到本机,再发布;上传失败显示“等待发布”,重试会复用已保留的精确密文。已完成回读验证的状态会单独显示。 AI 非敏感配置是独立的可选范围,包含供应商配置、手动添加的模型、自定义操作及默认模式。API 密钥和请求头由独立的敏感数据范围控制;代理、执行权限、外部工具路径和自动发现的模型保留在本机。未开启敏感数据同步时,涉及本机密钥的地址变更和删除会暂缓,需先在本机编辑确认。无效引用、循环和不完整配置也会暂缓相关原子组;预览列出暂缓字段,其他有效修改继续应用,完整候选保留在副本中。 密码、私钥、凭据、OTP、连接/代理密码及 AI 密钥可在独立的敏感数据范围中开启,默认关闭。因果副本只保存版本引用,值使用独立加密对象;接收后用本机密钥重新加密。SSH/VNC 信任范围也默认关闭,每项收到的身份新增、变更和删除都须在本机预览中单独确认;自动同步不会授予信任。关闭范围保留已有数据,重新开启会重新合并。其他 Provider 的 V4 写入尚未开放。引用缺失凭据的认证组会暂缓,待接收设备补齐本机凭据后重新应用。原有 Provider 的旧协议入口保留;选择 V3 后不会因失败而自动写回旧协议。自动双向同步要求首次迁移已确认、自动推送和拉取均开启,并且没有活动会话或未保存设置。 完成 V3 迁移后,在安全设置修改主密码会先发布并回读验证新的 `rotation-` 子空间,再原子切换密码、远程命名空间和本地副本。失败或上传期间有新的本地编辑时,原密码和原空间继续有效;重试复用已保存的密文。旧空间保留,其他设备须使用新的命名空间和密码接入。云账户/范围变更须与改密分开保存。已有 V4 副本时不能直接关闭主密码。 下面介绍的是保留用于兼容的旧快照协议与 Provider 设置。`.nya` 始终是独立备份,不携带 V4 Writer 身份、发布历史或同步副本。 NyaTerm 的 **云同步** 能力,解决的不是“远程文件传输”,而是把应用里的可移植配置数据同步到一份加密的远端核心快照。 远端使用不可变快照和每台设备独立的提交记录: - `sync/snapshots/.redb.enc` 保存加密快照,是当前协议的正常数据路径 - `sync/heads/` 保存每台设备的提交记录及上传中的临时标记,用于识别并保留并发修改 - `sync/latest.redb` 保存供兼容读取使用的最新 revision、设备、时间和 hash 元数据 - `sync/current.redb.enc` 是尽力更新的兼容/恢复副本,不是唯一权威数据源 两台设备同时推送时,各自的提交都会保留;下一次检查发现并发分支后,会要求明确选择本地或云端。远端存储若存在可见性延迟,冲突可能在后续检查才出现。判断先后关系使用因果记录,不依赖设备时钟。 `.nya` 本地导出 / 导入仍然是配置备份和迁移入口。云端旧快照会按保留策略清理;设备正在引用、尚未解决的并发分支及上传中的快照受到保护。云同步不会自动删除用户云端已有的旧 `backups/` 数据,保留的快照也不替代独立备份。 当前支持这些远程存储提供方: - **WebDAV** - **S3 兼容**存储 - **Gitee 代码片段(Gitee Snippet)** - **GitHub Gist** - **Google Drive** - **OneDrive** - **AliyunDrive** ## 先决条件:先设置主密码 在使用 **设置 → 云同步** 前,你必须先到 **设置 → 安全** 设置 **主密码**。 这是硬性前置条件。没有主密码时: - 不能启用云同步 - 不能执行测试连接、推送、拉取等手动操作 上传到云端的是**加密后的可移植快照**。新快照使用随机盐的 Argon2id 派生密钥,再通过 AES-256-GCM 加密和认证;版本头、参数、盐和 nonce 也参与认证。 旧 NyaTerm 和 Dragonfly 快照仍可读取。下次实际上传或显式覆盖会写成新格式;仅检查到内容相同不会重写旧密文。新格式需要所有参与同步的设备升级到支持它的版本,旧客户端无法解密新快照,也不具备新的并发保护。升级前建议保留本地 `.nya` 备份。 升级后第一次检查,如果旧同步基线无法证明完整数据未变,可能需要手动确认冲突;这是为了保护此前未计入变更 hash 的 VNC 信任记录和扩展数据。 ## 从哪里进入 这项功能主要有两个入口: ### 1. 设置 → 云同步 这里是主要配置页,负责: - 选择 provider - 配置远程命名空间与 provider 根路径 - 设置自动同步策略 - 运行测试连接、立即推送、立即拉取 - 在冲突发生时执行处理 ### 2. 工作区中的 Cloud Sync / 云同步面板 主工作区侧栏里的 **云同步** 面板用于查看: - 当前状态 - 最近的同步活动 - 最近一次检查、同步时间 - 冲突状态与快速处理入口 改配置去设置页,看运行状态看工作区面板。 ## Provider 配置 ### 通用项 无论使用哪种 provider,都需要先确认这几项: - **启用云同步** - **存储提供方配置** - **设备名称** - **远程命名空间** 其中: - **设备名称** 会写入快照元数据,方便你识别是哪台设备上传的内容 - **远程命名空间** 是 NyaTerm 在远端保存云同步快照时使用的顶层路径前缀 ### WebDAV 如果 provider 选的是 **WebDAV**,通常需要填写: - **WebDAV Endpoint** - **Provider Root**(可选) - **用户名** - **密码** WebDAV 认证同时支持 **Basic** 和 **Digest** 两种方式。当服务端要求 Digest 时,NyaTerm 会自动改用 Digest,以提升对 NAS / 网关的兼容性。 ### S3 兼容存储 如果 provider 选的是 **S3 兼容**,通常需要填写: - **S3 Endpoint** - **Bucket** - **Region** - **Provider Root**(可选) - **Access Key ID** - **Secret Access Key** - **Session Token**(可选) - **Virtual Host Style**(按 provider 要求决定是否开启) ### Gitee 代码片段(Snippet) 如果 provider 选的是 **Gitee 代码片段**,NyaTerm 会把加密后的云同步对象保存到一个 Gitee 代码片段中。 Gitee 的文件数量限制也适用于快照、设备提交及临时标记。设备较多或保留了多个冲突分支时,可能需要使用新的代码片段或更换存储提供方;不会为了腾出位置删除未解决的分支。 通常需要填写: - **Gitee 个人访问令牌(Personal Access Token)** - **代码片段 ID** ### GitHub Gist 如果 provider 选的是 **GitHub Gist**,NyaTerm 会通过 GitHub device flow 授权,并把加密后的云同步对象保存到一个私有 Gist 中。 通常需要: - 点击 **连接 GitHub** - 在浏览器打开的 GitHub 授权页面输入设备码 - 授权 `gist` scope 在 GitHub device-flow 授权流程中,如果没有填写 Gist ID,NyaTerm 会在授权成功后自动创建并回填一个私有 Gist;已有 Gist ID 时,会先验证并复用该 Gist。 ### Google Drive / OneDrive / AliyunDrive 如果 provider 选的是 **Google Drive**、**OneDrive** 或 **AliyunDrive**,NyaTerm 会通过桌面端原生 HTTP adapter 访问对应网盘服务。 当前需要手动填写 OAuth 信息: - **Refresh Token** - **Client ID** - **Client Secret** - **Access Token**(可选,长期同步建议依赖 Refresh Token) - **Provider Root**(可选) AliyunDrive 还需要填写 **Drive Type**,通常为 `resource`。 ### 配置校验 当前实现会先做最基本的 provider 校验: - WebDAV 至少需要填写 endpoint - S3 至少需要填写 endpoint 与 bucket - `Access Key ID` 和 `Secret Access Key` 需要成对出现 - GitHub Gist 需要完成 GitHub 授权;Gist ID 可以在授权流程中自动创建并回填,也可以使用已有 ID - Google Drive / OneDrive / AliyunDrive 需要填写 Refresh Token、Client ID、Client Secret 建议在真正启用自动策略前,先执行一次 **测试连接**。 ## 自动同步策略 ### 启动时检查 开启后,NyaTerm 会在启动时检查远端是否已经有新的同步快照。 常见结果包括: - 本地与云端一致 - 远端有更新,可以拉取 - 本地有尚未同步的变化 - 本地和云端都变了,进入冲突状态 所有 Provider(包括 GitHub Gist)还会每 15 分钟检查一次;窗口重新聚焦时也会检查,聚焦检查至少间隔 120 秒。关闭“启动时检查”只跳过启动检查。失败时会退避重试,限流时遵守服务端有效的 `Retry-After`;认证失效会暂停,修改设置后恢复。 ### 自动拉取远端变更 开启 **自动拉取远端变更** 后,如果启动检查或同步检查发现“只有远端发生变化”,NyaTerm 会自动拉取并应用当前云端快照。 它只处理本地没有未同步变更的情况;存在活动会话或未保存设置草稿时,会等到安全后再拉取。本地和云端都变了时仍然进入冲突状态,不会自动选一边覆盖另一边。 ### 本地变更后的自动推送 开启后,当受支持的本地配置数据发生变化并保存完成时,NyaTerm 会在一个防抖窗口后自动推送快照。 你可以设置: - **同步防抖秒数** 它是「保存后延迟推送」,不是实时双向同步。 ## 手动操作 ### 测试连接 先验证 provider 配置与远端布局是否可用。 ### 立即推送 把当前设备的可移植配置快照上传到云端。用于刚完成一组设置调整后,或需要明确控制何时写入云端时。 ### 立即拉取 把云端当前最新同步快照拉回本地并应用。用于另一台设备已经推送过更新,需要让当前设备显式对齐时。 ## 冲突是怎么出现的? 如果**本地状态**和**云端状态**自上次同步后都发生了变化,就会进入冲突状态。 典型场景: - A 设备改了设置但还没拉取 B 的更新 - B 设备已经把新的同步快照推到了云端 - A 再尝试推送或启动检查时发现双方都变了 这时你会看到冲突预览,例如: - 本地快照哈希 - 远程 revision - 远程设备信息 - 当前云端快照时间与 hash - 冲突提示信息 ## 冲突怎么处理? 当前实现提供两种处理方式: ### 下载远程版本 分支列表显示每个并发 revision、设备名称(旧快照显示缩短的 UUID)、时间、可读状态及差异数量。仅有一个可读分支时自动选中;有多个可读分支时必须先选择。差异摘要仅展示已知集合新增、删除、修改数量、设置分类以及未知实体是否变化,不显示凭据、OTP、笔记或命令正文。 把选定的远端快照拉回当前设备并应用。**当前设备上未同步的本地变更会丢失**,选它之前先确认云端版本是要保留的那份。 ### 上传本地版本 用当前设备的本地快照解决当前预览中已观察到的分支。确认时会重新校验本地内容、所选快照和分支集合;发生变化会刷新预览,要求再次确认。**远端那份变更会被覆盖**,其他设备后续会以这份状态为准。 这里要特别注意: - 当前不是字段级 merge - 也不是多人协作式冲突解决 - 本质上是“本地快照”和“远程快照”二选一 NyaTerm 保留独立的设备提交和因果记录。明确选择本地或云端会生成覆盖已观察到分支的新提交;选择云端时会固定使用预览中明确选定的 revision。若其他设备随后提交新的并发修改,仍会再次提示冲突。`sync/snapshots/` 是现行协议的数据路径,不要手动清空。 ## 会同步哪些内容? 当前实现基于 **portable snapshot**,覆盖的是 NyaTerm 的可移植配置数据,例如: - 已保存连接 / 分组 - 密钥、密码、OTP 配置 - 代理与隧道 - 快捷命令 - 大部分应用设置 - known_hosts 与主密钥 token 命令历史不会进入云同步核心快照;如需离线留档或迁移,使用本地 `.nya` 导出 / 导入。 当前实现会保留一部分设备本地 UI 状态,例如: - 当前打开的标签页 - 面板开合与尺寸等运行态布局 所以它同步的是可移植配置,让多台设备共享当前核心配置状态,不是完整的桌面会话镜像。 ## 建议的首次配置顺序 首次启用按这个顺序: 1. 在 **设置 → 安全** 中设置主密码 2. 打开 **设置 → 云同步** 3. 先选 provider,再填写 endpoint / bucket / root / 凭据 4. 设置设备名称与远程命名空间 5. 先执行 **测试连接** 6. 再决定是否启用: - 启动时检查 - 自动拉取远端变更 - 自动推送 7. 最后手动执行一次 **立即推送**,确认整条链路可用 ## 凭据、设备名称与活动历史 三个网盘刷新令牌后,会先加密保存新的 Access Token 和服务端返回的 Refresh Token,再继续认证请求;未返回 Refresh Token 时保留原值。保存失败会停止操作,后续同步失败或取消不会撤销已完成的令牌保存。未编辑的设置令牌字段会跟随轮换更新,显式编辑的凭据仍需通过保存冲突检查。 设备名称保存在加密快照中;UUID 仍是设备身份。名称修改在下一次实际发布时生效,不会仅为改名重新上传。 自动上传、下载、冲突、失败和恢复成功会由进程统一写入活动历史,多窗口共享一条记录。无变化、忙碌、防抖或禁用检查不会刷屏;相同错误分类、触发原因和 revision 在 15 分钟内去重。错误只包含受控分类、Provider、操作和 HTTP 状态,不包含请求 URL、签名地址或响应正文;历史写入故障不会改变已经成功的同步结果。 ## 后台检查与流量 自动检查先检查指针和全部设备提交,已验证且未变化的快照最多每 24 小时完整下载校验一次。轻量检查不会延长这个期限。S3 支持 ETag 条件请求时,未变化的指针返回 304,设备提交可以复用本次列表确认的缓存;服务不支持时退回普通 GET。 其他 Provider 仍需传输各自的指针和目录 API 响应;Gist/Snippet 的容器响应还可能包含文件内容。因此每日校验限制针对显式快照读取和验证,不能保证每个 Provider 的网络正文都只包含元数据。 缓存由同一进程的窗口共享,关闭应用后丢弃。首次启动、切换远端配置或账号、轮换凭据、修改主密码、缓存淘汰及分支变化都可能增加完整读取。实际推送、拉取、恢复和冲突确认仍验证快照;每日历史清理、上传回读及兼容副本也会产生流量。 本地变更通知没有改变实际同步内容时,可以跳过联网。持续编辑不会推迟定时远端检查,但上传仍等待防抖结束。最近成功的手动或自动检查会推迟下一次定时检查,并在 120 秒内抑制聚焦重复检查;测试连接不算完整检查。关闭“启动时检查”不会关闭 15 分钟定时检查。 日志提供受控的操作汇总:请求数、上传和下载正文的字节、304、缓存命中及完整校验次数。所有 Provider 均在 HTTP 边界统计,包含认证重试和已读取的错误正文;上传字节为每次尝试提交的正文大小,下载字节为应用实际读取量,不包含 HTTP 头和 TLS 开销,不能直接视为云厂商账单。日志不包含地址、对象路径、ETag、凭据或同步正文。实际流量取决于在线时长、设备数、快照大小、变更、重试和存储服务能力。 ## 排障建议 按钮不可用或操作被拦住时,依次检查: - 是否已经设置主密码 - 当前设置是否已经保存(未应用的草稿会阻止某些手动操作) - provider 必填项是否已经补齐 - 远端命名空间、provider root、endpoint 是否填写正确 查看最近发生了什么看工作区的 **云同步** 面板,改配置回设置页。 :::tip 使用建议 - 首次接入新 provider 时,先“测试连接”,再启用自动策略。 - 做较大范围的连接、OTP、快捷命令调整前,如果需要可回退点,请先使用本地 `.nya` 导出。 - 在多台设备之间切换时,统一远程命名空间规则,并给每台设备设置可区分的设备名称。 :::