所有页面
本页内容

文件与文件夹

OAR 把它拥有的一切都放在一个文件夹里,即状态文件夹:配置文件、保存你的对话的数据库、日志以及上传的文件。本页说明这个文件夹在哪里、里面有什么、哪些部分可以删除、哪些保存着机密信息,以及中继会自动删除什么。有些数据根本不在状态文件夹中:每个提供商都把自己的会话数据和登录信息保存在自己的文件夹中。

状态文件夹 #

安装方式 状态文件夹
安装程序或 npm install -g,macOS、Linux 和 WSL ~/.oar
安装程序或 npm install -g,Windows %APPDATA%\oar
设置了 OAR_STATE_ROOT 的全局安装 它指定的文件夹
git 检出 在检出目录内:server/config.json、server/data/、server/uploads/、server/logs/

npm install -g 和 oar update 会替换软件包,但从不触碰状态文件夹。OAR_STATE_ROOT 必须在你运行 oar 的每个 shell 中都设置,否则该命令会去默认文件夹中查找;参见环境变量。oar doctor 会打印正在使用的路径:状态文件夹、配置文件、数据库及其大小。安装页面也按安装方式列出了同样的路径。

有三个环境变量可以单独移动某一部分:COPILOT_WEB_RELAY_CONFIG 移动配置文件,COPILOT_WEB_RELAY_DATA_DIR 移动数据文件夹(数据库、锁和上传文件),COPILOT_WEB_RELAY_LOG_DIR 移动日志文件夹。在 config.json 中,键 dataDir 也能移动数据文件夹;环境变量优先。相对路径的 dataDir 从 config.json 所在的文件夹算起。

0.9.14 新增 上传文件也跟随数据文件夹:<dataDir>/uploads。早期版本留在 server/uploads 中的上传文件,或某次迁移复制到状态文件夹 uploads/ 中的上传文件,仍会在原处被读取。

0.9.14 新增 全局安装的中继无论以何种方式启动,都使用状态文件夹中的数据文件夹:oar start、Linux 服务、Windows 的两种自启动模式,以及带有 OAR 扩展的普通 gh copilot。如果 config.json 中有早期自启动的中继用过的 dataDir,会从那里复制一次数据,然后保持原样。

0.9.14 之前:Windows 自启动与 gh copilot

在 0.9.13 及更早版本中,两个 Windows 自启动条目以及普通 gh copilot 启动的中继只设置了配置文件(gh copilot 连这个都没设置)。由它们启动的中继把数据库、锁文件、上传文件和日志保存在已安装软件包文件夹内的 server\data、server\uploads 和 server\logs 中,而 npm install -g 和 oar update 会替换这个文件夹。升级到 0.9.14 时,会在 npm 删除这些数据之前把它们复制出来;参见升级说明。

在 macOS 和 Linux 上,中继会把数据文件夹设为只有你可读(模式 700),把配置文件和数据库文件设为仅所有者可访问(模式 600)。

迁移旧安装 #

在项目改名之前,状态保存在 git 检出的 server/ 文件夹中,而检出所用启动器的配置文件和日志保存在 ~/.config/copilot-remote 中(设置了该变量时为 $XDG_CONFIG_HOME/copilot-remote;Windows 上为 %LOCALAPPDATA%\copilot-remote)。全局安装会在第一次运行 oar setup 或 oar copilot 时,把该文件夹中的配置文件和日志复制到状态文件夹中,只复制一次。oar start 不会迁移。要导入某个检出的状态(其中包括它的数据库):

oar setup --migrate-from /home/dev/projects/old-oar

这里的文件夹是检出目录本身,而不是它的 server/ 文件夹。具体过程如下:

  • 它会复制数据库(连同其 -wal 和 -shm 文件)、配置文件、原来位于 data/ 中的 Cursor 智能体存储(仅当存在数据库时)、uploads 文件夹,以及大小不超过 50 MB 时的 logs 文件夹。
  • 它从不修改源文件夹。等你满意之后,请自己删除旧文件夹。
  • 只要还有中继从源文件夹运行,它就会拒绝执行,并说明原因。
  • 它在确认复制有效之前会先检查副本:数据库必须通过 SQLite 的完整性检查,并且包含相同数量的对话和消息。否则,它会删除自己复制的内容(0.9.14 新增 不再删除整个状态文件夹),并留下一条消息。
  • 0.9.14 新增 它从不覆盖。状态文件夹中已有的 config.json 会被保留。安装程序的中继创建的空数据库会被移到 backups/ 中(请先用 oar stop 停止中继);如果数据库中已有对话,它会拒绝执行,并说明应该怎么做。复制数据库期间,它会持有中继的锁,因此在此期间不会有中继在该数据库上启动。
  • 它会在状态文件夹中写入一份回执 backups/MIGRATION.md 和一个标记文件 .migrated。

安装程序运行之后 0.9.14 新增

只有在真正复制之后才会写入标记,而你用 --migrate-from 指定的文件夹总会被迁移,并有一行说明复制了什么,或者为什么什么都没有复制。因此,即使安装程序已经运行过 oar setup,这个选项也同样有效。第二次指定同一个文件夹时,只会提示它已经迁移过。在 0.9.14 之前,即使没有可导入的内容,第一次 oar setup 或 oar copilot 也会写入标记,之后的 --migrate-from 会一声不吭地什么都不做。

0.9.14 新增 迁移过来的上传文件会放到 data/uploads/ 中,中继从那里读取它们;Cursor 智能体存储放到 data/cursor-agents/ 中,中继默认从那里读取。早期某次迁移留在状态文件夹 uploads/ 中的上传文件,会在下次中继启动时合并到 data/uploads/ 中;不会覆盖或删除任何内容。检出中的符号链接文件夹会作为真实文件夹复制。

里面有什么 #

路径相对于状态文件夹。“可以安全删除”指的是删除后中继仍能工作;它并不说明你会失去什么。

路径 内容 可以安全删除吗?
config.json 端口、访问方式、访问令牌、计时器,以及可选的隧道和预览。参见 config.json 先停止中继。oar setup 会写入一个带新令牌的新文件,这会让每台设备都退出登录。其中的隧道设置会丢失
data/copilot.db 数据库:你的对话和设置。参见数据库 不可以:这是你的历史记录。请先备份
data/copilot.db-wal、data/copilot.db-shm 数据库的预写日志及其索引,中继运行期间存在 绝不能单独删除。只能与 copilot.db 一起删除
data/uploads/<sha256> 每个上传或粘贴的附件对应一个文件,以其 SHA-256 哈希命名,因此同一个文件只存储一次。写入上传文件期间会存在一个 <sha256>.<pid>.<number>.tmp 文件 不要手动删除:数据库引用了这些文件,用过某个文件的对话会显示附件缺失。中继会删除不再使用的文件,参见保留与清理
data/relay-server.lock 每个文件夹只允许一个中继的锁,参见每个数据文件夹一个中继 仅当没有中继在运行时
data/cursor-agents/ 0.9.14 新增 每个 Cursor 对话一个文件夹:保存其智能体的状态。参见状态文件夹之外 使用 Cursor 期间不可以:失去存储的对话会得到一个新的智能体
data/deepseek-claude/ 0.9.17 新增 DeepSeek 对话的 Claude Code 状态:projects/ 下的对话记录和会话文件夹、每个 Claude Code 进程留下的内容(sessions/、session-env/、shell-snapshots/)、Claude Code 自己的设置,以及 oar-cli-starts.json,即中继对每次 Claude Code 启动的记录,删除时用它来找到正确的 shell 快照。不含 Claude 登录信息。只有你可读(macOS 和 Linux 上为模式 700)。删除一个 DeepSeek 对话会删除属于它的部分,参见保留与清理 使用 DeepSeek 对话期间不可以:它们的 Claude Code 会话就在这里。worker 启动时会重新创建该文件夹
data/diagnostics/ 0.9.19 新增 中继的堆接近上限时写出的堆快照(*.heapsnapshot),见中继内存耗尽。只有你可读(macOS 和 Linux 上为模式 700)。快照中包含访问令牌和 API 密钥 可以。中继从不删除快照:每个快照读完后请删除
data/rescued-package-data/<time>/ 0.9.14 新增 早期版本保存在软件包内的数据,由更新在 npm 删除它们之前复制到这里。中继在下次启动时接管这些数据 在中继把它接管之后(relay-console.log 中出现 [data] Brought over the database …)
backups/<time>/ 0.9.14 新增 被中继用它接管来的较新数据库替换掉的数据库;还有迁移时移到一旁的空数据库 确定不再需要时
data/relay-previous.json 正在运行的中继启动时使用的端口和令牌,在更改了它们的 oar setup 与应用更改的重启之间保留。会自动删除 可以
logs/server.log、logs/server-err.log oar start 或 oar copilot 自己启动中继时打印的内容,分别是标准输出和错误输出。只有 oar 自己启动中继时才会写入;服务和在终端中运行的中继不写入它们 可以。它们从不轮转,会一直增长
logs/relay-console.log 中继控制台的副本,每行带有时间戳,每个中继都会写入 可以
logs/worker-<session>.log 某个会话 worker 的输出,参见日志 可以
logs/worker-<session>.mcp.json 某个会话的工具配置。其中不含机密信息 可以。该会话的 worker 启动时,中继会写入一个新文件
logs/ext-debug.log、logs/relay-banner-state.json 由 Copilot 扩展引擎的扩展写入 可以
npm/ OAR 软件包,当 npm 的全局文件夹需要 root 权限、安装程序因而把它放在这里时 使用此安装期间不可以。它就是程序本身
runtime/node/ OAR 自带的 Node.js,当机器上没有足够新的版本时 oar 在其上运行期间不可以
logs/oar-uninstall.log 0.9.15 新增 oar uninstall 之后 npm 的执行结果,以及 npm 留下的任何隐藏 .oar-* 文件夹。使用 --purge 时,它改为写入系统的临时文件夹 可以
oar-web-relay-launcher.cmd、oar-relay-task.xml(Windows) 开机任务运行的启动器,以及 OAR 注册的任务定义。参见自启动 中继设为开机启动期间不可以。oar autostart off 会同时删除两者
*.bak、*.bak-2、<task>.task.xml.bak(Windows) 0.9.15 新增 被 oar autostart --replace 替换掉的手动创建的自启动条目的副本,以及切换失败后恢复的任务的副本:启动器、Startup 文件夹中的条目、任务导出的 XML(schtasks /create /xml 可以用它恢复)。OAR 生成的条目的副本会在切换成功后删除 可以,只要你不想再恢复该条目
backups/MIGRATION.md、.migrated 迁移的回执和标记 回执:可以。标记:请保留,否则从早期配置文件夹自动迁移的过程可能会再次运行

在状态文件夹之外,安装程序的 oar 启动器位于 ~/.local/bin/oar(仅在它安装到 ~/.oar/npm 的情况下),Linux 服务是 ~/.config/systemd/user/oar.service。如何删除它们,参见卸载 OAR。0.9.15 新增 oar uninstall 会删除服务和软件包,保留状态文件夹不动;oar uninstall --purge 会在你输入 delete 之后删除状态文件夹。

git 检出把同样的文件保存在 server/ 中。生成的图片不在状态文件夹中,参见状态文件夹之外。

数据库 #

数据库是一个 SQLite 文件 copilot.db。中继在首次启动时创建它。它保存的就是你所说的“你的数据”:

  • 对话及其消息,包括对话记录、附件索引和置顶消息
  • 消息队列、排队中和等待中的消息,以及智能体提出的问题
  • 你在网页界面中更改的中继设置(应用级开关、提供商设置、保留期限选择、更新偏好、模型列表)
  • OpenAI、Cursor 和 0.9.17 新增 DeepSeek 的 API 密钥(如果你输入过)
  • 已配对的中继及其令牌,以及在此中继和已配对的中继上监视会话的订阅
  • 你的设备的 Web Push 订阅,以及中继的推送密钥
  • 分享对话的链接
  • 每个对话的子智能体和工作流记录、活动和思考
  • 上传文件的索引,以及哪些消息使用了它们
  • Check Usage(查看用量)中套餐用量条的用量快照,以及 0.9.17 新增 DeepSeek 卡片统计的内容:DeepSeek 各轮按模型和按天的 token 数与搜索次数、每个 DeepSeek 会话最近报告的合计,以及其余额条所依据的余额读数
  • 图片对话:其操作以及生成图片之间的关联
  • 预览卡片

每次中继启动时,迁移都会自动运行。它们会创建缺少的内容并添加列,再次运行也不会改变任何东西。你不需要运行它们,也无法跳过它们。

备份 #

OAR 没有备份命令。数据库以 SQLite 的预写日志模式运行,因此最近的更改可能还在它旁边的 -wal 文件中。要备份它:

  1. 用 oar stop 停止中继。
  2. 把 copilot.db 以及 copilot.db-wal 和 copilot.db-shm(如果存在)一起复制。
  3. 再次启动中继。

要恢复,请停止中继,然后把复制的文件按原样放回去。不要在中继运行时单独复制 copilot.db,也不要把一个数据库文件与另一份副本的 -wal 文件混用。备份中包含你的 API 密钥和令牌,参见机密信息存放在哪里;请像对待状态文件夹一样妥善保管它。

日志 #

文件 写入者 轮转
relay-console.log 中继,始终写入 达到 5 MB 时,该文件变为 relay-console.log.1,较旧的文件依次移为 .2 和 .3,最旧的一个被丢弃。各行中的访问令牌显示为 [token]。OAR_NO_CONSOLE_LOG=1 会关闭该文件
server.log、server-err.log oar start 或 oar copilot 的 shell,当它在后台启动中继时 无
worker-<session>.log 每个 Node 会话 worker(Claude、Claude Cloud、Cursor、Grok、0.9.17 新增 DeepSeek 和 Copilot SDK 引擎),worker 重启后继续追加 每次启动时,超过 10 MB 的文件变为 worker-<session>.log.1,替换之前的那个。已删除对话的文件会保留
ext-debug.log Copilot 扩展引擎的扩展 无

Copilot 扩展引擎没有 worker 日志:它就是 Copilot CLI 自己的终端。作为 systemd 服务运行的中继还会写入日志(journal),参见自动启动中继。

用 npm start 启动的 git 检出把日志保存在 server/logs 中。用 oar start 或 oar copilot 启动的检出把日志保存在 ~/.config/copilot-remote/logs 中(Windows:%LOCALAPPDATA%\copilot-remote\logs),除非 COPILOT_WEB_RELAY_LOG_DIR 指定了其他文件夹。

机密信息存放在哪里 #

机密信息 存放位置
访问令牌 config.json,明文。请像对待密码一样对待该文件、它的副本以及登录地址(?token=)。浏览器会把它作为登录 Cookie 保存 30 天。中继的锁文件只保存它的哈希值
之前的访问令牌,在 oar setup 与重启之间 data/relay-previous.json,明文,只有你可读;会自动删除
Cloudflare 隧道令牌(托管隧道) config.json 中的键 cloudflaredTunnel.token,或环境变量 COPILOT_CLOUDFLARED_TOKEN
OpenAI API 密钥 数据库。面板不会再次显示它,也不会把它发送给浏览器
Cursor API 密钥 数据库,方式相同
DeepSeek API 密钥 0.9.17 新增 数据库,方式相同(设置项 deepseek_api_key)。中继只把它发送到 DeepSeek 的基础 URL,并且只交给 DeepSeek 对话的 worker。参见 DeepSeek
已配对中继的令牌 数据库。从不发送给浏览器或智能体。使用此中继自身令牌的配对不保存任何令牌
分享对话链接的令牌 数据库
Web Push 密钥和设备订阅 数据库
堆快照 0.9.19 新增 data/diagnostics/:中继内存中的所有内容,包括访问令牌和 API 密钥。切勿原样分享。见中继内存耗尽
Claude 登录 中继所在机器上 Claude CLI 自己的文件夹:~/.claude,或 CLAUDE_CONFIG_DIR 中的文件夹。中继不保存任何登录信息。Claude Cloud 读取同一个登录,并把它保存在内存中。DeepSeek 对话不使用它
Grok 登录 Grok CLI 自己的文件夹:~/.grok/auth.json
GitHub Copilot 登录 中继所在机器上 Copilot CLI 自己的登录

当 worker 在 tmux 下启动时,中继会把它的提供商密钥(OpenAI、Cursor 或 0.9.17 新增 DeepSeek 的密钥,或者中继环境中供 Claude Cloud worker 或 0.9.17 新增 Claude worker 使用的 CLAUDE_CODE_OAUTH_TOKEN)写入系统临时文件夹中的一个临时文件,只有你可读。worker 的 shell 读取它一次后就将其删除。每个 worker 只会拿到它自己提供商的密钥。

保留与清理 #

中继会自动删除下列内容。除非你删除对话,否则不会删除其他任何内容。

内容 规则
不再使用的上传文件 没有任何消息或草稿引用的文件,一旦超过 24 小时就会被删除。检查在中继启动时运行,之后每 6 小时运行一次。没有相关设置。删除对话也会删除只有该对话使用的文件
子智能体记录 已结束子智能体的工具输入和结果会在 Keep sub-agent tool output(保留子智能体的工具输出)天数之后删除,该设置位于 Settings → General(设置 → 常规):7、14、30 或 90 天,或 Always(永久)。默认为 90。思考、回复、留言以及每次调用的单行摘要会保留。检查在启动 30 秒后运行,之后每天运行一次,你更改设置 5 秒后也会运行。数据库文件不会缩小;SQLite 会重用释放出来的空间
用于监视会话的中继事件 已交给监视对话的事件会在 2 小时后删除。已结束的订阅会在 7 天后删除。详见监视会话。清理每 10 分钟运行一次
已配对中继尚未获取的事件 每个订阅保留最新的 500 个,且都不超过 7 天;7 天内无人获取的订阅会结束。提问和错误最后才被丢弃。参见远程中继
relay-console.log 达到 5 MB 时轮转,并保留三个较旧的文件,参见日志
worker-<session>.log 启动时如果超过 10 MB,就移为 .1。不会有任何东西删除已删除对话的日志
生成的图片 从不按时间删除。删除对话会删除其图片
锁文件 中继停止时删除。崩溃之后,下次启动会替换它,参见每个数据文件夹一个中继

删除对话会从数据库中删除它的消息、队列条目、提问和子智能体记录,并删除属于它的 Claude 对话记录和生成的图片。0.9.17 新增 对于 DeepSeek 对话,它还会在 data/deepseek-claude/ 中删除对话记录、该会话的文件夹、它已停止的 Claude Code 留下的内容(其注册信息、hook 环境和 shell 快照),以及在没有其他会话使用时删除项目文件夹,并从数据库中删除其会话最近报告的合计。它计入 DeepSeek 卡片合计和每日数据的部分会保留。每个提供商自己保存的内容见下一节。

状态文件夹之外 #

内容 位置
Claude 对话记录和会话文件夹 位于 Claude 配置文件夹(~/.claude,或 CLAUDE_CONFIG_DIR)中的 projects 下。删除对话会删除其对话记录。参见 Claude。0.9.17 新增 DeepSeek 对话则把它们保存在数据文件夹中:即上文的 data/deepseek-claude/
GitHub Copilot 会话状态 ~/.copilot/session-state,或 COPILOT_SESSION_STATE_DIR 中的文件夹
OpenAI Image 对话中的图片 在 Copilot 会话状态文件夹中,位于该对话下的 <session>/generated-images/。参见 OpenAI
Cursor 智能体存储 0.9.14 新增 每个对话一个文件夹,位于中继数据文件夹的 cursor-agents 中(~/.oar/data/cursor-agents、%APPDATA%\oar\data\cursor-agents),或位于 CURSOR_AGENT_STORE_DIR 指定的文件夹中。全局安装时位于状态文件夹中;之所以列在这里,是因为早期版本把它们放在别处。参见 Cursor
Grok CLI 及其登录 ~/.grok
Copilot 扩展包装器 ~/.copilot/extensions/web-relay/,由 oar copilot 或 oar copilot --install-extension 写入。0.9.15 新增 如果它是 OAR 为此安装写入的那个,oar uninstall 会删除它
Claude Cloud 磁盘上没有任何内容。云端会话在 Anthropic 运行;其结果以推送的分支形式返回
临时文件 上文提到的短暂存在的提供商密钥文件,位于系统的临时文件夹中

在 0.9.14 之前,Cursor 存储默认位于软件包文件夹内的 server/data/cursor-agents 中,而更新会替换这个文件夹,因此对话可能会丢失已存储的智能体并得到一个新的(参见 Cursor)。存储仍在旧位置的对话会继续在那里使用它;在两个位置都有存储的对话会使用最近更改过的那个;不会移动或删除任何内容。

你的智能体的工作成果,也就是你项目文件夹中的文件,完全在 OAR 的存储之外。

每个数据文件夹一个中继 #

中继在启动时会在数据文件夹中创建 relay-server.lock,并在停止时删除它。该文件保存中继的进程号、其令牌的哈希值以及启动时间。

如果在第一个中继运行期间,第二个中继在同一个数据文件夹上启动,第二个中继会打印一行信息然后退出,0.9.14 新增 退出码为 78(之前为 1),Linux 服务不会对此重试:

Relay already running (pid=4242, startedAt=2026-01-05T09:12:40.000Z; lock /home/dev/.oar/data/relay-server.lock). It is held by relay process 4242: oar stop, or end process 4242.

如果显示的是 Relay appears to be owned by another live process 而不是 Relay already running,则表示正在运行的中继使用的是另一个令牌。当无法判断持有者是否是中继时,提示为 If no relay is running, end process 4242 or delete the lock.。oar start 会在 The relay did not come up 之后打印同样的提示。第一个中继不受影响。当正在运行的中继并不是你预期的那个时,消息会一直处于待处理状态;oar doctor 会显示正在使用的配置和数据库。

崩溃或断电之后,锁文件会被留下。0.9.14 新增 早于上次开机的锁,或其进程号现在属于一个在它之后才启动的进程的锁,都是过时的:下次启动会把它移到一旁,记录 Recovered stale singleton lock,然后接管锁。这不再依赖时钟,因此时钟跳变不会让正在运行的中继看起来已经消失,两次同时恢复同一个锁的启动也不会都运行起来。无法读取的锁(断电留下的空锁)会被再次读取,并被视为已被持有,除非其时间相差超过 10 秒。oar start 不再删除此版本写入的锁;对于早期版本写入的锁,当中继端口上没有任何响应时,它仍会将其删除。

当两个中继使用各自独立的数据文件夹和端口时,它们可以并行运行。关于 oar 如何找到中继,参见 oar 命令;关于重启会保留什么,参见重启与恢复。