Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
check:
name: ${{ matrix.os }} / Node ${{ matrix.node }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -65,6 +65,10 @@ jobs:
if: matrix.node == '22'
run: npm install --prefix tmp/opencode-unreviewed --no-package-lock --no-save @opencode/cli@2.0.18

- name: Install legacy OpenCode v2
if: matrix.node == '22'
run: npm install --prefix tmp/opencode-v2-legacy --no-package-lock --no-save @opencode/cli@2.0.0

- name: Run public roundtrip command with baseline v2
if: matrix.node == '22'
run: npm run verify:opencode -- --binary tmp/opencode/node_modules/@opencode/cli/bin/opencode.exe --output tmp/roundtrip-v2-baseline
Expand All @@ -73,24 +77,37 @@ jobs:
if: matrix.node == '22'
run: npm run verify:opencode -- --binary tmp/opencode-unreviewed/node_modules/@opencode/cli/bin/opencode.exe --output tmp/roundtrip-v2-unreviewed

- name: Run public roundtrip command with legacy v2
if: matrix.node == '22'
run: npm run verify:opencode -- --binary tmp/opencode-v2-legacy/node_modules/@opencode/cli/bin/opencode.exe --output tmp/roundtrip-v2-legacy

- name: Verify legacy v2 managed-server fallback
if: matrix.node == '22'
run: npm run verify:legacy-startup
env:
T2O_TEST_V2_LEGACY_BINARY: tmp/opencode-v2-legacy/node_modules/@opencode/cli/bin/opencode.exe

- name: Verify current and adjacent version contracts
if: matrix.node == '22'
run: npm run verify:versions
env:
T2O_TEST_OPENCODE_BINARY: tmp/opencode/node_modules/@opencode/cli/bin/opencode.exe
T2O_TEST_V2_LEGACY_BINARY: tmp/opencode-v2-legacy/node_modules/@opencode/cli/bin/opencode.exe

- name: Install baseline and unreviewed OpenCode v1
- name: Install baseline, unreviewed and legacy OpenCode v1
if: matrix.node == '22'
run: |
npm install --prefix tmp/opencode-v1-current --no-package-lock --no-save opencode-ai@1.18.32
npm install --prefix tmp/opencode-v1-unreviewed --no-package-lock --no-save opencode-ai@1.18.31
npm install --prefix tmp/opencode-v1-legacy --no-package-lock --no-save opencode-ai@1.16.0

- name: Verify v1 protocol compatibility and recovery
if: matrix.node == '22'
run: npm run verify:integration:v1
env:
T2O_TEST_OPENCODE_BINARY: tmp/opencode-v1-current/node_modules/opencode-ai/bin/opencode.exe
T2O_TEST_V1_ADJACENT_BINARY: tmp/opencode-v1-unreviewed/node_modules/opencode-ai/bin/opencode.exe
T2O_TEST_V1_LEGACY_BINARY: tmp/opencode-v1-legacy/node_modules/opencode-ai/bin/opencode.exe

- name: Run public roundtrip command with baseline v1
if: matrix.node == '22'
Expand All @@ -100,6 +117,10 @@ jobs:
if: matrix.node == '22'
run: npm run verify:opencode -- --binary tmp/opencode-v1-unreviewed/node_modules/opencode-ai/bin/opencode.exe --output tmp/roundtrip-v1-unreviewed

- name: Run public roundtrip command with legacy v1
if: matrix.node == '22'
run: npm run verify:opencode -- --binary tmp/opencode-v1-legacy/node_modules/opencode-ai/bin/opencode.exe --output tmp/roundtrip-v1-legacy

- name: Verify bounded heap and process interruption recovery
if: matrix.node == '22'
run: npm run verify:resilience
Expand All @@ -114,6 +135,7 @@ jobs:
path: |
tmp/m7-1-platform-report.json
tmp/m7-2-version-report.json
tmp/m7-2-legacy-startup-report.json
tmp/m7-3-resilience-report.json
tmp/roundtrip-v*/report.json
tmp/roundtrip-v*/*.schema.json
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,23 @@ OpenCode **v1 或 v2 协议**。
| 组件 | 要求 |
| --- | --- |
| TRAE 来源 | TRAE CN **3.3.104**,已登录,并以本机 CDP 端口 `9222` 启动 |
| OpenCode v2 目标 | 已验证基线:`@opencode/cli` **2.0.12**、**2.0.16**;其他稳定 2.x 自动检测兼容性 |
| OpenCode v1 目标 | 已验证基线:`opencode-ai` **1.17.9**、**1.18.32**;其他稳定 1.x 自动检测兼容性 |
| OpenCode v2 目标 | 已验证基线:**2.0.0**(legacy)、**2.0.12**、**2.0.16**;其他稳定 2.x 自动检测兼容性 |
| OpenCode v1 目标 | 已验证基线:**1.16.0 / 1.17.0**(legacy)、**1.17.9 / 1.18.32**;其他稳定 1.x 自动检测兼容性 |
| 系统 | macOS、Windows 可直接读取本机 TRAE;Linux 只支持导入已导出的 bundle |
| Node.js | `>=18.18`,推荐 Node.js 22 |

附件、Skill 与 MCP 资源不在当前迁移范围内。未知的 TRAE 来源版本仍会被拒绝。
OpenCode 根据实际协议和隔离往返结果决定能否迁移。目标方言由可执行文件版本决定:v2 走 HTTP
`SessionTransfer`,v1 走 `opencode import` / `opencode export` 子命令。
OpenCode 根据实际协议 profile 和隔离往返结果决定能否迁移。v2 自动区分旧版与当前
HTTP `SessionTransfer` 路径;v1 自动区分 legacy 与当前会话 schema,均通过
`opencode import` / `opencode export` 子命令。

> **未收录的 OpenCode 稳定版本不再仅因版本号被拒绝。**
> CLI 与目标服务必须为同一版本,必要路由和 schema 必须完全匹配或仅有安全增量,然后在独立临时库中
> 验证导入、导出、回读、冲突与删除保护。通过后才允许迁移;预发布版本、未知主版本、
> 破坏性 schema 变化或行为验证失败仍会停止。无需增加跳过校验参数。
>
> **旧版本也不是无条件放行。** `opencode-ai@1.15.x` 无法保留安全所有权 metadata,
> `1.14.x` 的 OpenAPI 不暴露完整会话 schema,因此仍拒绝写入;工具不会直写旧版数据库。

## 快速开始

Expand Down Expand Up @@ -71,7 +75,8 @@ npm install -g opencode-ai@1.18.32
opencode --version
```

建议使用上述基线版本;其他稳定 1.x/2.x 会在迁移前自动检测兼容性。
建议新安装使用上述当前基线;已有 2.0.0 或 1.16/早期 1.17 环境无需为了迁移强制升级,
工具会选择 legacy profile。其他稳定 1.x/2.x 会在迁移前自动检测兼容性。
也可运行 `npm run verify:opencode` 单独检查本机 OpenCode,命令复用相同协议规则和
隔离往返验证,支持 `--binary`、`--output` 与 `--json`;详见[独立验证说明](docs/opencode-compatibility.md#独立验证本机-opencode)。
`migrate:local` 会读取
Expand Down Expand Up @@ -229,7 +234,7 @@ TRAE 本身的历史被删除,源数据始终保持只读。
| `无法发现 TRAE workbench` | 完全退出后,用上面的终端命令重新启动 TRAE;确认目标项目窗口已打开。 |
| `所选 workbench 没有可迁移的本地会话` | 选择正确的项目窗口,并在 TRAE 中打开该项目后再运行。 |
| `无法自动启动 OpenCode` | 确认 `opencode --version` 可运行,再用 `npm run verify:opencode` 检查兼容性;需要重装时可选择上述已验证基线。 |
| `OpenCode 版本或协议不受支持` | 确认是稳定 1.x/2.x;必要路由和 schema 必须完全匹配或只有可验证的安全增量。 |
| `OpenCode 版本或协议不受支持` | 确认是稳定 1.x/2.x;目标必须匹配当前或 legacy profile,并保留安全所有权和回读能力。 |
| `未收录的 OpenCode 版本需要同版本 CLI` | 安装与目标服务相同版本的 CLI,或用 `T2O_OPENCODE_BINARY` 指定。 |
| `隔离导入、回读或删除验证失败` | 尚未向目标写入会话;使用已验证基线版本,保留错误码用于排查。 |
| `所选会话包含当前无法无损映射的内容` | 工具尚未写入 OpenCode。保留产物并查看[故障排查](docs/troubleshooting.md)。 |
Expand Down
2 changes: 1 addition & 1 deletion docs/implementation-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ OpenCode 2.0.12,expected/actual 计数和 hash 一致。resume 与重复跳过
| ID | 任务 | 依赖 | 验收 |
| --- | --- | --- | --- |
| M7-1 | macOS/Windows 集成矩阵 | M5 | 已通过三系统 Node 18.20.8/22;macOS/Windows 默认源目录与三端目标链路通过 |
| M7-2 | OpenCode 版本契约测试 | M4 | 已通过:基线原生写入/回读;2.0.11 与 2.0.12 混用拒写,同版本 2.0.11 通过隔离检测后准入 |
| M7-2 | OpenCode 版本契约测试 | M4 | 已通过:current 与 legacy profile 原生写入/回读;跨 profile 混用拒写,未收录版本需隔离准入 |
| M7-3 | 大会话与异常中断测试 | M5 | 已通过三端:512 MiB 堆固定负载、两组真实 kill/resume,无重复 import |
| M7-4 | 安装包、README、故障排查 | M7-1..3 | 已通过:白名单 tarball、隔离安装/SQLite/bin/dry-run;三端六任务安装 CI 成功 |
| M7-5 | 可选 SQLite fallback 评估 | M7-2 | 当前原生 import 满足 P0,不立项 |
Expand Down
12 changes: 7 additions & 5 deletions docs/m4-1-opencode-capability.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# M4-1:OpenCode 版本与原生导入契约探测

初始契约日期:2026-09-24;2026-09-26 增加清单外稳定版本的自动兼容性检测;
2026-09-27 增加 schema 兼容分析和声明式协议规则。
2026-09-27 增加 schema 兼容分析和声明式协议规则;2026-09-28 增加旧协议 profile。

## 探测契约

`probeOpenCodeCapabilities` 对用户目标只读取版本及 OpenAPI,不创建目标会话。
v2 读取 `/api/info` 和 `/openapi.json`,v1 读取 `/global/health` 和 `/doc`。
基线 v2 `2.0.12` / `2.0.16`、v1 `1.17.9` / `1.18.32` 使用已有行为证据。
v2 current 读取 `/api/info`,legacy 读取 `/api/health`,两者 OpenAPI 均位于
`/openapi.json`;v1 读取 `/global/health` 和 `/doc`。
基线 v2 `2.0.0` / `2.0.12` / `2.0.16`、v1 `1.16.0` / `1.17.0` /
`1.17.9` / `1.18.32` 使用已有行为证据。
其他稳定 1.x/2.x 要求同版本 CLI,在独立临时库完成导入、导出、回读和删除保护验证,
并在测试结束后重新核对实际目标的版本与 schema。
OpenAPI 的 `info.version` 为 HTTP 接口版本 `0.0.1`,不能用作产品版本门禁。
Expand All @@ -29,8 +31,8 @@ schema 对象 key 顺序不影响比较,不相关 API/schema 变化不阻断
实际数据 schema 使用 `schemaHash` 标识;规则、必要操作、envelope 和数据 schema 的组合
使用 `protocolHash` 标识。任一证据在隔离验证期间变化都会让本次结果失效。

固定 schema hash:
`sha256:8379854ab529739a39826bbabcb0103847c66368280803e4b5559f09415a3d32`。
current 与 legacy profile 分别固定自己的 schema hash;完整列表见
[版本契约](m7-2-version-contract.md)。

`writable` 表示目标契约门禁通过;源 profile、完成时间、映射和逐会话对账
仍由后续写入流程校验,不能据此宣称真实迁移完成。
Expand Down
37 changes: 28 additions & 9 deletions docs/m7-2-version-contract.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# M7-2 OpenCode 版本契约

已验证基线为 v2 **2.0.12**、**2.0.16**,以及 v1 **1.17.9**、**1.18.32**。
已验证基线为 v2 **2.0.0**(legacy)、**2.0.12**、**2.0.16**,以及
v1 **1.16.0** / **1.17.0**(legacy)、**1.17.9**、**1.18.32**。
其他稳定 1.x/2.x 不再仅因版本号拒写,详见[协议兼容性检测](opencode-compatibility.md)。
`2.0.11` 保持不在基线清单内,用 npm 官方原生二进制验证自动准入路径,不伪造版本字符串。

Expand All @@ -19,19 +20,29 @@
`compatibility=isolated-roundtrip`。检查实际目标仍为空,再执行 migrate、verify、
resume 与 rollback,全流程通过。
7. 切回 2.0.12 后原生 import/export 完整往返成功。
8. 2.0.0 自动选择 `v2-session-transfer-legacy`,使用旧 `/api/health`、
`/api/session/import` 与 `/api/session/{sessionID}/export`,完成 migrate、verify、
resume、冲突保护及 rollback;2.0.2 另通过未收录版本隔离准入。

CI 在三系统的 Node 22 任务执行 2.0.12 与 2.0.11 的验收;传入
`T2O_TEST_COMPATIBLE_BINARY` 时额外验证 2.0.16。报告为 `m7-2-version-report.json`。
CI 在三系统的 Node 22 任务执行 2.0.0、2.0.12 与 2.0.11 的验收,并通过
`verify:legacy-startup` 验证 2.0.0 无 service descriptor 时的一键启动回退;传入
`T2O_TEST_COMPATIBLE_BINARY` 时额外验证 2.0.16。报告为
`m7-2-version-report.json` 与 `m7-2-legacy-startup-report.json`。

安装相邻二进制:

```bash
npm install --prefix tmp/opencode-adjacent --no-package-lock --no-save @opencode/cli@2.0.11
npm install --prefix tmp/opencode-v2-legacy --no-package-lock --no-save @opencode/cli@2.0.0
T2O_TEST_V2_LEGACY_BINARY="$PWD/tmp/opencode-v2-legacy/node_modules/@opencode/cli/bin/opencode.exe" \
npm run verify:versions
T2O_TEST_V2_LEGACY_BINARY="$PWD/tmp/opencode-v2-legacy/node_modules/@opencode/cli/bin/opencode.exe" \
npm run verify:legacy-startup
```

可通过 `T2O_TEST_OPENCODE_BINARY` 指定当前二进制,
`T2O_TEST_ADJACENT_BINARY` 指定未收录的 2.0.11 二进制,
`T2O_TEST_V2_LEGACY_BINARY` 指定 legacy 2.0.0 二进制,
`T2O_TEST_COMPATIBLE_BINARY` 指定 2.0.16 二进制。路径作为独立参数传给进程。

不因版本号更高而推定兼容。已验证基线仍检查实际协议;其他候选必须满足同版本 CLI、
Expand All @@ -50,21 +61,27 @@ CLI 的 `export` / `import` 是顶层子命令且不接受 `--server` / `--direc
`serve` 没有 `--service`,会话 JSON 为 `{info, messages:[{info, parts:[]}]}`。
因此 v1 不能复用 v2 的 adapter,而是独立的 contract / mapping / reconciliation / adapter。

v1 基线为 **1.18.32** 与 **1.17.9**,两个都使用 npm 官方发布的原生二进制实测。
v1 当前基线为 **1.18.32** 与 **1.17.9**;legacy 基线为 **1.16.0** 与 **1.17.0**,
都使用 npm 官方发布的原生二进制实测。
清单外稳定 1.x 需要额外通过隔离 CLI 验证。契约摘要:

1. 版本:`opencode --version` 与 `GET /global/health` 的 `version` 必须同属 v1。
清单外版本要求两者完全一致;基线使用已有行为证据,其他版本执行隔离 import/export
和删除保护测试,不能仅由 `/doc` schema 推断 CLI 兼容。
2. 路由:`GET /doc` 的 OpenAPI 必须包含 `DELETE /session/{sessionID}` 与
`GET /session/{sessionID}/children`,否则拒绝写入。
3. schema:`fixtures/opencode/1.18.32/evidence/session.schema.json` 是从 v1 `/doc` 的
`Session` / `Message` / `Part` 三个根定义按 `$ref` 递归抽取出的 envelope,其规范化
hash 为 `sha256:e110d00a7c579aac2ff85453d7661bbbdd7b5720efa12caa3da9ceb2c722a132`;
新版本必须让 `extractV1SessionSchema` 的 hash 与之一致。
4. 真实往返:两个版本都在隔离数据目录中完成 probe、plan、`opencode import`(以目标
3. schema:current 与 legacy fixture 都从 v1 `/doc` 的 `Session` / `Message` /
`Part` 三个根定义按 `$ref` 递归抽取;目标必须匹配其中一个 profile,或只存在
经过兼容分析并通过隔离验证的增量。
4. 真实往返:各基线都在隔离数据目录中完成 probe、plan、`opencode import`(以目标
目录为 cwd)、`opencode export` 回读、逐项对账、`verify`、重复迁移冲突检测与
`rollback`。合成 fixture 的 2 条消息、2 个 text、2 个 reasoning、1 个 tool 全部无损。
5. legacy:1.16.0 / 1.17.0 的 schema hash 为
`sha256:45fa528fc128f0884b3abd8d02b77ab8a06b92bca6f05f873176f006e9f20f53`,
自动选择 `v1-cli-library-legacy`。当前 v1 映射的合成数据属于该旧 schema 的安全子集,
原生迁移、续跑、冲突和回滚全部通过。
6. 旧版下界:1.15.x 没有 Session metadata,1.14.x 不暴露完整会话 schema;
两者无法满足所有权和契约验证,继续拒绝写入。

实测确认的 v1 语义(写 adapter 时必须遵守):

Expand All @@ -85,8 +102,10 @@ v1 基线为 **1.18.32** 与 **1.17.9**,两个都使用 npm 官方发布的原

```bash
npm install --prefix tmp/opencode-v1-adjacent --no-package-lock --no-save opencode-ai@1.17.9
npm install --prefix tmp/opencode-v1-legacy --no-package-lock --no-save opencode-ai@1.16.0
T2O_TEST_OPENCODE_BINARY="$(command -v opencode)" \
T2O_TEST_V1_ADJACENT_BINARY="$PWD/tmp/opencode-v1-adjacent/node_modules/opencode-ai/bin/opencode.exe" \
T2O_TEST_V1_LEGACY_BINARY="$PWD/tmp/opencode-v1-legacy/node_modules/opencode-ai/bin/opencode.exe" \
npm run verify:integration:v1
```

Expand Down
Loading
Loading