同步与备份#
换电脑或重装之后,ThinkWatch Lite 的配置可以从一个文件整体导入,不必逐项重新填写。多台电脑与服务器上的 core 也可以经自选的同步位置共用一份配置:在一台设备上新增上游或更换密钥,其他设备随之更新。每次配置变更都会留下一个可以恢复的版本。
本页的功能需要 ThinkWatch Lite 2026.10.25 或更高版本。连接远程 core 时,服务器上的 core 须为 0.78.0 或更高版本。
本页说明配置包、备份、导出与导入、开启同步及各种同步位置的配置方法、加密、冲突、恢复,以及不随导出与同步带走的内容。单个上游的分享见导入链接。
这些功能集中在「设置 › 同步与备份」,分为「同步」与「备份」两部分。连接远程 core 时,这一节归在服务器的配置之下,管理的是服务器上的那份配置,见连接远程 core 时。
配置包#
配置包是扩展名为 .twconfig 的单个文件,包含配置、插件脚本与 Lite 的通用偏好。导出、分享、本机的备份版本与同步位置上的版本都使用这种文件。
- 未加密的配置包是 ZIP 文件。以口令加密的配置包为 age 格式,口令经 scrypt 派生密钥,解密后是同样的 ZIP 文件。两者扩展名相同,由文件头区分。
- 配置包不超过 16 MiB,只能包含约定的几类文件;出现其他路径、绝对路径或
..时,整个配置包被拒绝。插件文件的 SHA-256 与配置中的记录不一致时,该插件标为错误。 - 由较新版本导出的配置包要求先更新,提示「此配置包由较新版本导出,请先更新 ThinkWatch Lite」。较旧版本导出的配置包在导入时自动修复:当前版本不认识的字段被删除,不合法的取值改回缺省值,预览中列出修改了哪几处。
- 口令错误时提示「口令不正确」。
备份#
备份是配置的历史版本,存放在两处:
| 存放位置 | 生成时机 | 保留 |
|---|---|---|
| 本机 | 每次配置变更生成一个版本:界面修改、命令行、手动编辑文件、同步、导入、恢复与一键修复。内容与上一版本相同时不生成,ChatGPT 令牌续期也不生成。 | 最近 10 个版本 |
| 同步位置 | 开启同步后,各设备上传的版本 | 最新与上一个版本 |
本机版本是完整的配置包,包含插件、ChatGPT 与 OAuth 上游的登录令牌,以及本机设置(其中的控制通道密钥以掩码保存),存放在数据目录的 history/ 中。目录与文件只有所有者可读,不加密,与 config.yaml 本身的保护程度相同。这些版本取代了原先的版本历史,配置原文编辑器中的「备份」同样打开这个列表。升级后第一次保留备份时,旧的版本历史文件随之删除。
「备份」部分按时间倒序列出各个版本:时间、来源(如「界面修改」「导入」「手动编辑文件」「同步自 MacBook Air」)、存放位置(本机、同步位置)、内容(如「7 个上游,2 个插件」)与生成它的 Core 版本,正在使用的版本标为「当前」。同一版本同时存在于本机与同步位置时显示为一行,两处一并标出。其余版本各有「恢复…」与「另存为…」:前者见恢复,后者把该版本保存为配置包,可以选择以口令加密。
ThinkWatch Lite 不做定时备份,也不提供单独的手动备份。需要另存一份时,使用「导出配置…」或某个版本的「另存为…」,文件可以存放在任意位置。
导出配置#
导出有三个入口:
- 「备份」部分的「导出配置…」,缺省导出全部配置;
- 上游页多选上游之后,工具条上的「导出所选 N 个上游…」;
- 上游分享对话框中的「导出为配置包…」。
三者打开同一个导出对话框;从上游页进入时,范围缺省为「选择项目」,并预先勾选对应的上游。
| 项目 | 说明 |
|---|---|
| 范围 | 「全部配置」或「选择项目」。选择项目时,按类别列出上游、出站代理、网关密钥、别名、策略组、路由、价目表、安全规则、插件与全局设置。所选项目引用的其他项目自动勾选并标为「随附」,例如路由引用的上游、上游引用的出站代理。 |
| 包含密钥 | 缺省开启。包括上游密钥、请求头的值、AWS 凭据、OAuth 的 Client Secret、代理密码、网关密钥,以及 Z.ai / BigModel 账号登录所得的密钥。写成 ${变量名} 的值原样导出,不展开。 |
| 口令加密 | 缺省关闭。开启后须输入两次口令,至少 8 个字符。口令不保存,导入时须输入同一口令。 |
| 不随文件导出 | 列出这次被剔除的内容,例如「ChatGPT 账号与 OAuth 的登录凭据(1 个上游),导入后需重新登录或填写。」「监听、远程控制与同步设置。」「请求记录。」关闭「包含密钥」时还列出上游密钥、网关密钥与代理密码。 |
包含密钥且不加密时,对话框底部提示「文件包含明文密钥,请妥善保管。」
导入配置#
导入有三个入口:
- 「备份」部分的「导入配置…」;
- 把配置包拖放到主窗口;
- 新安装的应用(配置仍为初始配置)在上游页的空状态中,于「新建上游」旁提供「导入配置…」。
加密的配置包先要求输入口令。随后对话框写明配置包的概况:完整或部分配置、是否包含密钥、导出时间与导出它的 Core 版本;再按类别列出其中每一项及其状态:
| 状态 | 条件 | 处理 |
|---|---|---|
| 新增 | 当前配置中没有同名项 | 直接导入;取消勾选即跳过 |
| 相同 | 同名且内容一致 | 不处理,只计入统计 |
| 冲突 | 同名而内容不同 | 必须选择「覆盖」「改名导入」或「跳过」,没有缺省值 |
| 冲突(全局设置) | 本机的该节已经修改,且与导入的值不同 | 必须选择「覆盖」或「跳过」 |
| 缺少密钥 | 配置包不含密钥,且本机没有目的地相同的同名项(见下文);或者是使用 OAuth 刷新令牌的上游,而本机没有令牌端点相同的同名上游 | 导入为停用状态,上游行显示「缺少密钥」标签,补填密钥(OAuth 上游为 Refresh Token)后即可启用 |
| 需要登录 | ChatGPT 上游,而本机的同名上游不是 ChatGPT 账号 | 导入为停用状态,上游行提供「登录…」 |
| 插件 | 插件脚本 | 导入为停用状态;可改写工具调用的插件须在启用时批准 |
| 错误 | 引用了本机不存在的 AWS profile、出站代理或上游;字段不合法,例如上游地址含反斜杠,或在主机前带有用户名与密码;网关密钥的值与另一把现有密钥相同 | 不可导入,注明原因 |
所有冲突都选定处理方式之前,「导入」不可用。列表上方的「全部覆盖」「全部改名导入」「全部跳过」一次处理全部冲突。
导入按以下规则进行:
- 按名称逐项加入上游、出站代理、网关密钥、别名、策略组、路由、价目表、自定义安全规则与插件。当前配置中有、配置包中没有的项保持不变,导入不删除任何内容。以一份配置整体替换当前配置属于恢复,见恢复。
- 全局设置(故障转移、各项防护的状态、默认路由、默认密钥、辅助请求、价目表设置)每一节作为一项:本机该节仍为缺省值时直接采用导入的值,否则与导入的值不同即构成冲突。
- 「改名导入」的名称缺省为原名称加序号,如「公司中转 (2)」,可以在行内修改,但不能与现有名称重复。配置包中引用该项的路由、别名与策略组随之改用新名称。
- 「覆盖」以导入的内容替换同名项,本机引用该项的路由与别名不变。覆盖本机同名的 ChatGPT 上游,或令牌端点相同的 OAuth 上游时,保留本机的登录令牌。
- 配置包不含密钥时,覆盖只在目的地不变时沿用本机的密钥:协议、主机与端口,AWS 区域,OAuth 令牌端点,以及所经的出站代理都相同(覆盖出站代理时比较代理的地址)。目的地不同时,该行注明「地址与本机不同,不沿用本机密钥」,上游导入为停用状态,须填写密钥。
- 「改名导入」不沿用本机的密钥、代理密码与登录:改名导入的上游为停用状态,须填写密钥或重新登录;改名导入的插件为停用状态。
- 路由、别名或策略组引用了被跳过的上游时,一并标为错误,并注明缺少的上游;改名导入的上游不在此列。
- 配置包不含密钥时,导入的网关密钥重新生成。
- 导入作为一个版本记入备份,因此可以恢复到导入之前的配置。预览之后配置又被修改时,导入会提示重新预览。
开启同步#
同步让多台设备共用一份配置。设备指参与同步的一份 Core,可以是本机的 core,也可以是服务器上的远程 core。每台设备同一时间只连接一个同步位置。ThinkWatch 不提供官方托管的同步服务,同步位置由用户自行选择:
| 类型 | 适用的存储 | 连接参数 |
|---|---|---|
| 文件夹 | 由 iCloud Drive、Dropbox、OneDrive、Google Drive、Syncthing 等同步的文件夹,或 NAS 的共享目录 | 文件夹路径 |
| WebDAV | 坚果云、Nextcloud、群晖 NAS、InfiniCloud 等 | 地址、用户名、密码(或应用密码) |
| S3 兼容存储 | Amazon S3、Cloudflare R2、阿里云 OSS、腾讯云 COS、MinIO 等 | 端点、区域、存储桶、前缀、Access Key ID、Secret Access Key |
WebDAV 与 S3 兼容存储的请求可以直连(缺省)、经系统代理,或经某个出站代理发出,在「代理」中选择。两者的 http:// 地址都只接受本机与内网地址,规则与导入链接相同,而且只能直连,以免密码以明文经过代理;其他地址须使用 https://,证书一律校验。请求不跟随重定向,以免同步位置的密码被带到别的主机,因此须填写最终的地址。
未开启同步时,「同步」部分只有「开启同步…」与一句说明:「多台设备共用一份配置,并在同步位置保存最新与上一个版本。」开启同步分为三步:
- **同步位置。**选择类型并填写连接参数,「测试连接」检查能否读写。同步位置为空时,进入第 2 步设置加密;已有同步数据时,按其加密设置进入第 2 步输入同步口令,未加密时跳过第 2 步。
- **加密。**新建同步时选择加密(缺省)或不加密,加密时输入两次同步口令,至少 12 个字符。加入已有的同步时输入一次口令,并显示已在同步的设备及其最后同步时间。口令错误时提示「同步口令不正确」。
- **合并。**只在加入已有的同步、且本机已有配置时出现。按导入的规则逐项预览,冲突项逐项选择覆盖、改名或跳过;也可以选择「使用同步数据替换本机配置」。
合并时,各设备安装时自动生成的默认网关密钥不需要选择:采用同步数据的值,本机已接管的客户端自动改用新值。
本机配置仍为初始配置(新安装后未修改)时不出现第 3 步,直接使用同步数据。两台设备同时在一个空的同步位置上开启同步时,后完成的一台提示重新测试连接,再以加入的方式继续。新安装的应用在上游页的空状态中提供「加入同步…」,直接打开上述步骤。加入之前的本机配置保留在备份中。本设备名称缺省为计算机名称,可以修改。
开启之后,「同步」部分显示状态(如「已同步 · 2 分钟前」)、同步位置及其连接参数、代理、加密、不同步的上游与本设备名称,以及参与同步的设备列表:每台设备的名称、最后同步时间、Core 版本与状态。「立即同步」立即检查一次。同步设置写入 config.yaml,修改后选择「保存」生效。修改连接参数只用于同一个同步位置,例如更换密码;改用另一个同步位置须先停止同步,再重新开启。
同步时机#
| 时机 | 行为 |
|---|---|
| 本机配置变更 | 合并 10 秒内的变更,上传一个新版本。Core 退出前立即上传尚未上传的变更,上传失败的在下次启动时上传。 |
| 定时检查 | WebDAV 与 S3 兼容存储每 30 分钟检查一次是否有新版本,有则下载、合并并应用。文件夹监听文件变化,新版本到达后即时应用。 |
| 事件 | Core 启动、设备从睡眠中唤醒、网络恢复与打开主窗口时立即检查。 |
| 手动 | 「立即同步」。 |
ChatGPT 令牌续期、本机设置的修改与默认插件的升级不上传。使用 WebDAV 或 S3 兼容存储时,其他设备的修改最迟 30 分钟内到达本设备,打开主窗口时立即到达;使用文件夹时,第三方客户端传送完成即到达。其他设备的版本经正常的配置写入流程应用,先校验,再热更新,并作为一个版本记入备份,来源记为「同步自」加设备名称。
各同步位置的配置方法#
每台设备都要连接同一个同步位置:同一个云盘中的同一个文件夹、同一个 WebDAV 地址,或同一个存储桶与前缀。填写的文件夹、地址或前缀本身就是同步位置的根,keyring(仅加密时)、versions/ 与 devices/ 直接存放在其中,不另建子文件夹。因此应为 ThinkWatch 单独新建一个空文件夹或前缀,例如 ThinkWatch,不与其他文件混放。
iCloud Drive、Dropbox、OneDrive 等文件夹#
选择「文件夹」,在文件夹选择对话框中选取云盘中为 ThinkWatch 新建的文件夹,每台设备选择同一个文件夹。文件在设备之间的传送由云盘客户端完成,ThinkWatch 只读写这个文件夹。
| 云盘 | 文件夹通常所在的位置 |
|---|---|
| iCloud Drive | macOS:访达边栏中的「iCloud 云盘」,即 ~/Library/Mobile Documents/com~apple~CloudDocs;Windows:iCloud for Windows 的 %USERPROFILE%\iCloudDrive |
| Dropbox | macOS:~/Library/CloudStorage/Dropbox,较早的安装为 ~/Dropbox;Windows:%USERPROFILE%\Dropbox;Linux:~/Dropbox |
| OneDrive | macOS:~/Library/CloudStorage/ 下以 OneDrive 开头的文件夹;Windows:%USERPROFILE%\OneDrive |
| Google Drive | macOS:~/Library/CloudStorage/ 下以 GoogleDrive 开头的文件夹;Windows:Google 云端硬盘盘符下的「我的云端硬盘」 |
| Syncthing、NAS 共享目录 | 各设备上同步或挂载的同一个文件夹 |
云盘设为按需下载时,其他设备上传的版本在下载到本机之前按「尚未到达」处理,下载完成后再合并。把这个文件夹设为始终保留在本机(例如 OneDrive 的「始终保留在此设备上」),新版本即可随传送完成即时到达。
ThinkWatch 写入版本时先使用临时文件名,写完再改名,云盘因此不会传出写了一半的文件;无法解密或校验失败的文件同样视为尚未到达,不报错。
坚果云#
- 在坚果云中新建一个文件夹,例如
ThinkWatch。 - 在坚果云网页版的账户信息中打开「安全选项」,在第三方应用管理中添加一个应用,坚果云随即生成一个应用密码。
- 在 ThinkWatch Lite 中选择「WebDAV」:地址为
https://dav.jianguoyun.com/dav/ThinkWatch/,用户名为坚果云的登录账号,密码为第 2 步生成的应用密码,而不是登录密码。
Nextcloud#
- 在 Nextcloud 中新建一个文件夹,例如
ThinkWatch。 - 在个人设置的「安全」页中创建一个应用密码。开启了两步验证的账号必须使用应用密码。
- 地址为
https://<服务器>/remote.php/dav/files/<用户名>/ThinkWatch/,用户名为 Nextcloud 用户名,密码为第 2 步的应用密码。Nextcloud「文件」页的文件设置中也列出了 WebDAV 地址。
群晖 NAS#
- 在 DSM 的套件中心安装 WebDAV Server,启用 HTTPS,缺省端口为 5006。
- 在一个共享文件夹中新建子文件夹,例如
ThinkWatch。建议为 ThinkWatch 单独建一个只能读写该文件夹的 DSM 账号。 - 地址为
https://<NAS 地址>:5006/<共享文件夹>/ThinkWatch/,用户名与密码为该 DSM 账号的用户名与密码。
ThinkWatch 强制校验 TLS 证书,DSM 自带的自签名证书无法通过校验。可以在 DSM 的「控制面板 › 安全性 › 证书」中为 NAS 的域名申请 Let’s Encrypt 证书。只在局域网内使用时,也可以使用 http://<内网 IP>:5005/…,此时密码以及未加密时的配置以明文经过局域网。
S3 兼容存储的寻址方式#
寻址方式由端点自动决定,无需设置:端点的主机以 amazonaws.com、aliyuncs.com 或 myqcloud.com 结尾时,存储桶写在主机名中(虚拟主机方式),即 Amazon S3、阿里云 OSS 与腾讯云 COS;其他端点,例如 Cloudflare R2、MinIO 或一个 IP 地址,存储桶写在路径中(路径方式)。存储桶名称只能使用小写字母、数字、点与连字符;前缀是存储桶中的一个文件夹,不能以 / 开头,也不能含 . 或 .. 段。
Cloudflare R2#
- 在 Cloudflare 控制台的 R2 中创建一个存储桶,不开启公开访问。
- 在 R2 的 API 令牌管理中创建一个令牌,权限为对象读写,并只适用于这个存储桶。创建后得到 Access Key ID 与 Secret Access Key。
- 在 ThinkWatch Lite 中选择「S3 兼容存储」:
| 栏位 | 填写 |
|---|---|
| 端点 | https://<account-id>.r2.cloudflarestorage.com,<account-id> 为 Cloudflare 账户 ID;存储桶位于欧盟管辖区时为 https://<account-id>.eu.r2.cloudflarestorage.com |
| 区域 | auto |
| 存储桶 | 第 1 步创建的存储桶名称 |
| 前缀 | 可以留空,也可以填写 thinkwatch/ 等,与存储桶中的其他内容分开 |
| Access Key ID、Secret Access Key | 第 2 步得到的值 |
阿里云 OSS#
| 栏位 | 填写 |
|---|---|
| 端点 | OSS 的 S3 兼容地址 https://s3.oss-<地域 ID>.aliyuncs.com,例如华东 1(杭州)为 https://s3.oss-cn-hangzhou.aliyuncs.com |
| 区域 | 地域 ID,例如 cn-hangzhou |
| 存储桶 | Bucket 名称 |
| Access Key ID、Secret Access Key | RAM 用户的 AccessKey ID 与 AccessKey Secret |
建议在 RAM 访问控制中为 ThinkWatch 单独创建一个 RAM 用户,只授予这个 Bucket 的读写权限;Bucket 的读写权限保持为私有。
腾讯云 COS#
| 栏位 | 填写 |
|---|---|
| 端点 | https://cos.<地域>.myqcloud.com,例如广州为 https://cos.ap-guangzhou.myqcloud.com |
| 区域 | 地域简称,例如 ap-guangzhou |
| 存储桶 | 完整的存储桶名称,带有 APPID,形如 <名称>-<APPID> |
| Access Key ID、Secret Access Key | 访问管理中 API 密钥的 SecretId 与 SecretKey |
建议使用只拥有这个存储桶读写权限的子用户的密钥;存储桶的访问权限保持为私有读写。
MinIO#
| 栏位 | 填写 |
|---|---|
| 端点 | MinIO 的 S3 API 地址,例如 https://minio.example.com:9000;只在局域网内使用时也可以写 http://192.168.1.20:9000。缺省端口为 9000,不是控制台的端口。MinIO 使用路径方式,无需为存储桶配置域名 |
| 区域 | MinIO 设置的区域;未设置时为 us-east-1 |
| 存储桶 | 事先创建的存储桶 |
| Access Key ID、Secret Access Key | 为 ThinkWatch 创建的访问密钥,其策略只允许读写这个存储桶 |
其他 S3 兼容存储#
端点为存储服务的 S3 API 地址,Amazon S3 为 https://s3.<区域>.amazonaws.com;区域为存储桶所在的区域。存储桶应设为私有,并使用只能访问这个存储桶的密钥。
加密#
- 是否加密在开启同步时选择,缺省为加密,同一同步位置上的所有设备采用同一设置。每台设备加入时输入一次同步口令。口令与同步位置的凭据保存在本机
config.yaml的sync节中,与其他密钥的保存方式相同,不随导出与同步带出。 - 加密时,第一台设备生成一把随机密钥,以同步口令加密后作为
keyring存放在同步位置;各个版本与设备记录都以这把密钥加密(age 格式)。同步位置的服务商只能看到文件名(版本序号与设备标识的前 8 位)、文件大小与修改时间。认证加密同时保证版本未被篡改,没有口令的人无法写入有效的版本。 - 不加密时,版本是普通的配置包:同步位置的服务商可以读取配置及其中的密钥,任何对同步位置有写入权限的人都可以写入版本、改动配置。开启同步时选择「不加密」,会显示这一提示。为限制篡改的影响,不加密时经同步新增或脚本有变化的插件在本设备为停用状态,须在本设备上启用;上游地址经同步改变时,上游行以「地址经同步变更」标签提示一次。不加密的版本带有 SHA-256 校验和,只用于发现传输中的损坏。
- 之后开启加密:设置同步口令后,最新版本重新以加密形式上传,未加密的版本随之删除,其他设备在下次同步时须输入口令。关闭加密须输入当前口令,随后重新上传未加密的版本;各设备保存的同步口令保留,用于核对同步密钥。
- 加密的同步位置不接受未加密的版本,也不会自行关闭加密:同步密钥(
keyring)缺失,或被替换为较早的版本时,同步暂停,而不是改为不加密,见同步状态。 - 「更改同步口令…」只重新加密
keyring,已有版本不变;其他设备在下次同步时显示「同步口令已在其他设备上更改」,输入新口令后继续同步。 - 同步口令遗失、且已没有设备仍在同步时,同步位置上的内容无法解密,只能停止同步后重新开启。每台设备在本机保存一份同步密钥,同步位置上的同步密钥丢失时,可以用它放回。各设备本机的配置与备份不受影响。
同步的内容#
除本机设置、ChatGPT 与 OAuth 上游的登录令牌,以及请求记录等数据外,配置全部同步,包括密钥。完整的对照见不导出、不同步的内容。
- ChatGPT 上游:在新设备上出现时为停用状态,上游行显示「需要登录」,在这台设备上登录之前保持停用;这只影响这台设备,不会让其他设备上的这个上游停用。登录令牌与登录所得的账号标识只保存在各自的设备上,不参与比较;登录、续期与退出都不触发同步。各设备可以登录不同的 ChatGPT 账号。
- 使用 OAuth 刷新令牌的上游:与 ChatGPT 上游一样,每台设备分别登录。令牌端点、Client ID 与 Client Secret 照常同步;Refresh Token 与 Access Token 只保存在各自的设备上,令牌刷新不触发同步。在还没有令牌的设备上,这个上游保持停用,填入这台设备自己的 Refresh Token 后才能使用;其他设备不受影响。这是因为许多 OAuth 服务每次刷新都换发新的 Refresh Token 并作废旧的,同一个令牌在两台设备上使用会相互作废。
- 不同步的上游:在同步设置的「不同步的上游」中选择,属于本机设置。所选上游不上传,也不会被其他设备的同名上游覆盖,适用于地址在本机的 Ollama 等。引用这些上游的路由、别名与策略组随之不同步,在同步设置中列于「随之不同步」之后。开启同步时,这些上游的行显示「不同步」标签。
- 插件:随同步分发,启用状态在各设备之间保持一致;可改写工具调用的插件须在每台设备上分别批准后才运行。Core 自带的默认插件,脚本由各设备的 Core 提供并随 Core 升级,不同步,启用状态与设置照常同步。各设备的 Core 版本不同时,默认插件的版本差异不引起同步。
- 环境变量:写成
${变量名}的值原样同步。某台设备没有设置这个变量时,该上游在这台设备上的请求失败,上游行显示原因,不影响其他配置。 - Lite 的通用偏好:语言、外观、菜单栏显示、通知与检查更新随同步保持一致,其他设备上的改动即时生效。同步数据中的通用偏好超过 64 KiB 时,本设备保留自己的通用偏好,其余内容照常同步。
冲突#
合并规则#
每个版本都记录它所依据的上一版本。合并以两边共同的上一版本为基准,把本机当前的配置与同步位置上的最新版本按合并单位逐一比较:
| 对象 | 合并单位 |
|---|---|
| 上游 | 连接(服务类型、地址、协议、认证方式、密钥、请求头、出站代理、AWS 设置);模型(模型列表、只用这些模型、手动添加的模型、规格);计费(计费方式、价目、价格倍率);其他(并发上限、用量上限、转发客户端身份、余额来源、停用状态) |
| 出站代理、网关密钥、别名、策略组、路由、价目表、自定义安全规则 | 整个对象 |
| 插件 | 脚本;设置;启用状态 |
| 上游顺序、路由顺序、插件顺序 | 各一个单位 |
| 全局设置、Lite 的通用偏好 | 每个字段 |
两台设备修改同一对象的不同合并单位时自动合并,例如一台更换了上游的密钥,另一台修改了它的价目。只有同一合并单位在两边被改为不同的内容,或一边删除而另一边修改时,才构成冲突。重命名按删除原名称、新增新名称处理。合并的结果须通过配置校验,例如路由引用的上游必须存在;校验不通过的对象按冲突处理。
两台设备同时上传时,同步位置上会出现序号相同的两个版本,下一台同步的设备把它们合并为一个新版本。每台设备在本机保存上次同步的版本,作为下一次合并的基准,因此设备离线期间同步位置上的旧版本被删除,不影响恢复连接后的合并。
处理冲突#
- 冲突不阻断同步:其余内容照常合并与上传,冲突的对象在各设备上沿用各自的内容。
- 冲突记录随版本上传,参与冲突的设备显示同一组冲突。在任一台设备上处理之后,结果作为新版本上传,其他设备随之清除这些冲突,不必重复处理。
- 「同步」部分与上游页顶部显示黄色提示,例如「同步有 2 项冲突」,其中的「处理冲突…」打开「同步冲突」对话框。提示可以忽略,冲突保留到处理为止。
- 对话框逐项列出对象、双方的修改时间与设备名称以及差异的字段,点击对象名称查看差异。每一项在「采用」一列中选择本机、另一台设备,或「两者都保留」:本机的内容保留原名称,另一方的内容以「名称 (设备名称)」新增,名称可以修改。全局设置、各种顺序与 Lite 的通用偏好,以及一方已删除的对象,不提供「两者都保留」。「稍后处理」关闭对话框而不做改动;「应用」写入已选择的各项,未选择的留待下次处理。
同步状态#
| 状态 | 显示 | 处理 |
|---|---|---|
| 已同步 | 设置中显示「已同步 · 2 分钟前」,其他页面不提示 | — |
| 同步中 | 设置中显示「正在同步」 | — |
| 冲突 | 黄色提示,如「同步有 2 项冲突」;设置中显示「有 2 项冲突」 | 「处理冲突…」 |
| 同步位置不可用 | 连续 2 小时失败后,显示黄色提示「无法连接同步位置」及原因 | 恢复后自动继续,本机的修改随后上传 |
| 认证失败 | 黄色提示「同步位置拒绝访问」 | 修改连接参数 |
| 同步口令已更改 | 黄色提示「同步口令已在其他设备上更改」 | 「输入口令…」,输入新口令 |
| 版本过新 | 黄色提示「同步已暂停」:「其他设备使用较新版本,更新 ThinkWatch Lite 后继续同步。」其他设备的设备列表中,这台设备显示「已暂停:需更新」 | 「检查更新」,更新 ThinkWatch Lite |
| 同步密钥不可用 | 黄色提示「同步位置上的同步密钥不可用」:同步密钥缺失、被替换为较早的版本或无法读取,同步暂停 | 「重新上传本机配置」(同时放回本设备保存的同步密钥),或「停止同步…」 |
| 同步位置为空 | 黄色提示「同步位置为空」:其他设备可能删除了同步数据,或同步位置已不是原来的位置,同步暂停。同步位置读来为空时,先再检查几次才作此判断 | 「重新上传本机配置」,或「停止同步…」 |
| 同步设置无法使用 | 黄色提示「同步设置无法使用」,例如所选的出站代理已不存在 | 修改同步位置的连接参数或代理 |
| 安全模式 | 状态显示「已暂停:安全模式」 | 配置恢复正常后自动继续 |
以上任何一种状态都不会自动停止同步,是否停止由用户决定。正常运转时不发送系统通知;需要处理的状态按「设置 › 通用」的提醒设置发送一次系统通知,黄色提示都可以忽略。同步位置上有无法使用的文件时,状态旁注明跳过了几个。
同步位置上的最新版本由较新的 Core 生成、本机无法读取时,本机暂停同步,既不下载也不上传。暂停期间本机的修改只保存在本机,更新之后再按合并规则合并,较旧的 Core 因此不会覆盖较新 Core 写入的字段。远程 core 需要在服务器上单独更新,设备列表显示每台设备的 Core 版本。
180 天未更新的设备记录自动移除。
停止同步#
「停止同步…」提供两种方式:
- 停止同步:本机保留当前配置,删除本机的同步设置,并从同步位置移除本设备的设备记录。其他设备不受影响。
- 停止同步并删除同步数据…:须再次确认,删除同步位置上的全部版本、设备记录与
keyring,无法撤销;本机配置与本机备份不受影响。其他设备随后提示同步位置为空,各自可以重新上传本机配置,或停止同步。
恢复#
- 「备份」列表中,每个版本的「恢复…」打开恢复预览。预览按项目列出该版本与当前配置之间的差异(新增、删除、修改),缺省全部勾选,即以该版本整体替换当前配置;取消勾选的项目保持当前内容。只需找回一个已删除的上游时,只勾选这一项即可。
- 勾选的项目引用了未勾选的项目时,后者随所选项目一并恢复;要删除的项目仍被保留的项目引用时,标为「保留:仍被保留的项目引用」,不删除。预览与写入按同一方案进行。
- 本机设置保留当前的值。同名的 ChatGPT 上游,以及令牌端点相同的 OAuth 上游,保留当前的登录令牌,不写回备份中的旧令牌,因为旧令牌可能已在刷新后作废。
- 恢复本身作为一个新版本记入备份,因此可以撤销。
- 开启同步时,恢复的结果作为新版本上传,其他设备随之更新,预览对话框底部注明,例如「恢复后的配置将同步到其他 2 台设备」。不同步的上游不受影响。
配置无法读取时#
配置无法读取而进入安全模式时,出错页在「一键修复」旁提供「从备份恢复…」:列出本机的版本,同步位置可用时也列出同步位置上的版本,选择后直接进入恢复预览。配置完全无法读取时,恢复取回整个版本,只保留当前的控制通道密钥。升级本身不改写配置,因此不单独生成版本;升级后无法读取的配置就是最新的版本,一键修复之前的内容同样保留在备份中。
从 2026.10.25 起,上游地址不能含反斜杠,也不能在主机前带有用户名或密码。含有这种地址的配置升级后进入安全模式;备份中的地址与此相同,应修改配置文件,把凭据移到密钥或请求头中。
与已接管客户端的关系#
本机已接管的客户端在各自的配置文件中写有网关密钥。同步、恢复与导入(覆盖)改动网关密钥时按下表处理,客户端不会因此失效:
| 情形 | 处理 |
|---|---|
| 客户端所用的网关密钥的值被替换 | 与在密钥页更换密钥时一样,自动改写这些客户端的配置 |
| 客户端所用的网关密钥将被删除 | 同步:保留这把密钥,作为冲突列出,并注明如「本机 2 个客户端正在使用」。恢复:预览中该项标为「保留:本机客户端正在使用」,不删除 |
| 加入同步时,两边的默认网关密钥不同 | 采用同步数据的值,本机已接管的客户端自动改用新值 |
| 加入同步时选择「使用同步数据替换本机配置」 | 本机客户端正在使用的密钥并入同步数据,随后同步到其他设备;加入的步骤中会注明 |
连接远程 core 时,由连接着它的 Lite 在收到变更时做同样的处理。
连接远程 core 时#
- 「同步与备份」归在设置中服务器的配置之下,备份、导出、导入与同步都作用于服务器上的配置。
- 导出与导入经控制通道进行,配置包在运行 Lite 的这台电脑上保存与读取。
- 远程 core 同样可以加入同步。同步位置的连接由服务器发起;文件夹路径是服务器上的路径,须手动填写,文件夹选择对话框只在连接本机 core 时可用。
- Lite 的通用偏好保存在运行 Lite 的电脑上,不交给远程 core:导出时由 Lite 附加到配置包,导入时由 Lite 应用,不参与远程 core 的备份与同步。
命令行#
在没有界面的服务器上,或在配置损坏时手动恢复,可以使用 twcore 的命令:
twcore export -o all.twconfig
twcore export --providers relay --no-secrets --encrypt -o relay.twconfig
twcore import all.twconfig --dry-run
twcore import all.twconfig --on-conflict rename
twcore backup list
twcore backup restore <编号> --dry-run
twcore backup restore <编号>
twcore sync status
twcore sync now
twcore sync enable
twcore sync republish
twcore sync disable --purge
export导出全部配置;--providers只导出以逗号分隔的这些上游,连同它们引用的项目。--no-secrets不含密钥,--encrypt以口令加密,口令在终端中输入(不回显),或取自环境变量TWCORE_PASSPHRASE。两者都不加时,文件含明文密钥。import加入本机没有的项目,与本机不同的项目逐项询问;--on-conflict overwrite|rename|skip对所有这样的项目一并作答,--dry-run只显示导入会做什么,不写入。加密的配置包同样询问口令或读取TWCORE_PASSPHRASE;较旧版本导出的配置包先列出自动修复之处。backup list按时间倒序列出版本及其编号;backup restore恢复整个版本,--dry-run只列出会改变的内容。恢复保留本机设置、ChatGPT 登录与本机客户端正在使用的网关密钥。export、import与backup直接读写数据目录中的文件,core 未运行时同样可用,配置损坏、core 无法启动时也能恢复;正在运行的 core 在一秒内读入改动。sync经控制通道与正在运行的 core 通信:status显示状态、同步位置与设备,now立即同步一次,enable以交互方式填写同步位置与口令,republish在同步位置被清空或丢失同步密钥之后重新上传本机配置(并放回本设备保存的同步密钥),disable停止同步、本机保留当前配置,加--purge同时删除同步位置上的全部版本、设备记录与keyring。
用安装脚本安装的服务器上,命令以 sudo -u thinkwatch THINKWATCH_HOME=/var/lib/thinkwatch 开头,与连接远程 core 中的命令相同。各命令的完整参数见 twcore <命令> --help。
不导出、不同步的内容#
| 内容 | 导出 | 同步 | 本机备份 | 说明 |
|---|---|---|---|---|
| 上游、出站代理、别名、策略组、路由、默认路由、价目表、安全规则、故障转移、辅助请求 | 包含 | 包含 | 包含 | — |
| 插件脚本与设置 | 包含 | 包含 | 包含 | 导入后为停用状态;同步见同步的内容 |
| 上游密钥、请求头的值、AWS 凭据、OAuth 的 Client Secret、代理密码、网关密钥、Z.ai / BigModel 登录所得的密钥 | 缺省包含,可以关闭 | 包含 | 包含 | ${变量名} 原样保留,不展开。导出时关闭「包含密钥」的,导入时须补填上游密钥,网关密钥重新生成 |
| ChatGPT 登录令牌;OAuth 上游的 Refresh Token 与 Access Token | 不包含 | 不包含 | 包含 | 同一个刷新令牌在两台设备上使用会相互作废。上游本身照常导出与同步,每台设备分别登录 |
| Lite 的通用偏好:语言、外观、菜单栏显示、通知、检查更新 | 包含 | 包含 | 包含 | 连接本机 core 时由 Core 保存在数据目录中 |
| 本机设置:网关监听、控制通道密钥、远程控制、同步设置(含不同步的上游)、日志保留 | 不包含 | 不包含 | 包含 | 恢复时保留当前的值 |
| 客户端配置位置、客户端接管状态 | 不包含 | 不包含 | 不包含 | 这些是本机路径与各客户端自己的配置文件;换机后在客户端页重新接管 |
| 远程连接 | 不包含 | 不包含 | 不包含 | 连接地址与设备所在的网络有关;连接密钥可以在服务器上重新生成 |
| 请求记录、费用记录、会话正文 | 不包含 | 不包含 | 不包含 | 属于数据而不是配置,体积可达数 GB |