[feat] synchronize client and agent component versions

This commit is contained in:
dijunkun committed 2026-11-12 12:36:53 +08:00
1 parent 2a9faf1eb1
commit b1236534ac
28 files changed
+548 -37

No files matched your search

+4 -4
View File
@@ -1,6 +1,6 @@
# CrossDesk Android
原生 Android 控制端,使用 Java 界面、JNI 和 MiniRTC,与桌面端使用相同的信令、ICE、SRTP 和输入协议。没有 WebView。当前版本为 1.6.1,支持 Android 8.0(API 26)及以上的 arm64 手机和平板。
原生 Android 控制端,使用 Java 界面、JNI 和 MiniRTC,与桌面端使用相同的信令、ICE、SRTP 和输入协议。没有 WebView。支持 Android 8.0(API 26)及以上的 arm64 手机和平板。桌面、Android、iOS 和 HarmonyOS 共用客户端发布版本,各移动平台构建号独立;可在仓库根目录执行 `python3 scripts/version.py show client` 查看,使用 `set client <版本>` 同步修改,详见[组件版本管理](../../docs/VERSIONING.md)。
## 当前功能
@@ -85,11 +85,11 @@ Release 构建使用 `./gradlew :app:assembleRelease`,默认输出未签名 AP
[`Build Android`](../../.github/workflows/build-android.yml) 可在 Actions 页面单独手动运行;修改 Android、MiniRTC、共享协议或许可证资料的 Pull Request 也会触发。仓库原有的 [`Build and Release`](../../.github/workflows/build.yml) 在分支推送、标签推送及手动运行时调用同一工作流,`v` 标签发布会等待安卓构建及签名成功,并将已签名 Release APK 加入 GitHub Release 和现有下载服务器的产物集合。推送主仓库前,先确保它引用的 MiniRTC 提交已推送到子模块远程仓库,否则 CI 无法完成检出。
单独发布使用 [`Release Mobile`](../../.github/workflows/release-mobile.yml)。先更新并提交 `gradle.properties` 中的 `crossdeskVersionName` 和递增的 `crossdeskVersionCode`,再为该提交创建 `android-v<versionName>-YYYYMMDD` 标签,例如:
单独发布使用 [`Release Mobile`](../../.github/workflows/release-mobile.yml)。先在仓库根目录运行 `python3 scripts/version.py set client <版本>` 同步全部客户端版本及各移动端构建号,检查并提交改动,再为该提交创建 `android-v<versionName>-YYYYMMDD` 标签,例如:
```sh
git tag android-v1.6.1-20261010
git push origin android-v1.6.1-20261010
git tag android-v1.7.6-20261112
git push origin android-v1.7.6-20261112
```
该标签只触发安卓构建,使用固定发布密钥签名并验证 Release APK 后,再发布到独立的 GitHub Release 和现有下载服务器。签名失败或缺少签名 Secrets 时停止发布,不回退到未签名 APK。标签版本必须与应用版本一致,日期必须有效。重试发布时,在 Actions 页面手动运行 `Release Mobile`,将已有标签填入 `source_tag`;即使从其他分支触发,也会检出该标签的源码。APK 的源码资料记录安卓标签及准确的应用、MiniRTC 提交。
+2 -2
View File
@@ -1,4 +1,4 @@
org.gradle.jvmargs=-Xmx3g -Dfile.encoding=UTF-8
android.useAndroidX=true
crossdeskVersionName=1.6.1
crossdeskVersionCode=3
crossdeskVersionName=1.7.6
crossdeskVersionCode=4
+3 -3
View File
@@ -100,11 +100,11 @@ Pi 等宿主应直接启动原生程序以可靠控制进程和专用密码描
| 推送 `cli-v0.2.0-rc.1` | 校验源码版本为 `0.2.0-rc.1`,构建并发布到 `next` |
| 在对应 `cli-v*` 标签上手动运行并取消 `dry_run` | 执行真实发布;分支上不允许关闭预演 |
准备下一版时同步修改 `apps/cli/package.json` 的 `version` 与 `apps/cli/xmake.lua` 的 `set_version`,提交并推送代码后创建同版本标签。例如源码已更新为 `0.1.1` 时:
准备下一版时,在仓库根目录运行 `python3 scripts/version.py set cli <版本>`,同步 CLI、MCP、DSH 插件及 MCP 的原生依赖版本,再执行 `python3 scripts/version.py check cli`。`set mcp <版本>` 的修改范围相同,详见[组件版本管理](../../../docs/VERSIONING.md)。先发布 CLI 的平台包和入口包,再发布同版本 MCP。提交并推送代码后创建同版本标签。例如源码已更新为 `0.2.1` 时:
```sh
git tag cli-v0.1.1
git push origin cli-v0.1.1
git tag cli-v0.2.1
git push origin cli-v0.2.1
```
已经上传过 `0.1.0` 的包不能被新构建覆盖;下一次原生程序发布应使用新版本。手动预演使用 `npm pack --dry-run` 加上内容校验,不调用 `npm publish` 或交换 OIDC 凭据;可对分支运行,也允许检查已发布的版本,但不验证 npm 发布权限。标签运行始终校验版本一致性。GitHub 的手动运行入口需要该工作流先进入默认分支。
+1 -1
View File
@@ -5,7 +5,7 @@ function setup_options_and_dependencies(enable_dependencies)
option_end()
option("CROSSDESK_VERSION")
set_default("0.0.0")
set_default("1.7.6")
set_showmenu(true)
set_description("Set CROSSDESK_VERSION for build")
option_end()
+2 -2
View File
@@ -2,8 +2,8 @@
"app": {
"bundleName": "com.chunkdash.crossdesk",
"vendor": "CrossDesk",
"versionCode": 10000,
"versionName": "0.1.0",
"versionCode": 10001,
"versionName": "1.7.6",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
+7 -4
View File
@@ -204,13 +204,16 @@ The main workflow collects this same ZIP for GitHub Releases and the download
server. Standalone `Build iOS` runs only upload the build artifact.
For an independent release, use the
[`Release Mobile`](../../.github/workflows/release-mobile.yml) workflow. Commit
the intended `MARKETING_VERSION` in the iOS target, then tag that commit with
[`Release Mobile`](../../.github/workflows/release-mobile.yml) workflow. Desktop,
Android, iOS and HarmonyOS share the same client release version while mobile
build numbers remain independent. From the repository root, run
`python3 scripts/version.py set client <version>` to update all clients,
then commit the changes and tag that commit with
`ios-v<marketing-version>-YYYYMMDD`, for example:
```sh
git tag ios-v0.0.1-20261002
git push origin ios-v0.0.1-20261002
git tag ios-v1.7.6-20261112
git push origin ios-v1.7.6-20261112
```
The tag starts only the iOS build and publishes its unsigned ZIP to a dedicated
+2 -2
View File
@@ -6,7 +6,7 @@
## 版本与依赖
MCP 包 `@chunkdash/crossdesk-mcp` 0.1.0 绑定原生 CLI 0.2.0,内置 DSH 插件随 MCP 同包分发。源码版本和本地打包不代表版本已经发布到 npm;内含原生程序的平台安装包可独立分发。
CLI、MCP 包 `@chunkdash/crossdesk-mcp` 和内置 DSH 插件共用版本,当前均为 0.2.0,MCP 原生依赖也固定为 0.2.0。使用[版本脚本](../../docs/VERSIONING.md)修改任一工具版本会同步整个分组。源码版本和本地打包不代表版本已经发布到 npm;内含原生程序的平台安装包可独立分发。
当前提供 31 个模型工具和 11 个 MCP Apps 面板专用接口。本机 MCP 接入使用 stdio,不提供 MCP Streamable HTTP 或通用远程 shell 工具。控制端原生 CLI、被控端和信令服务器需要支持对应自动化协议。
@@ -497,7 +497,7 @@ npm run pack:npm -- --native-package-dir "$native_package_dir/package" --out-dir
rm -rf "$native_package_dir"
```
平台包保留原生包的程序、源码、许可和构建信息,设置对应 OS / CPU / libc 限制,不再下载原生平台依赖;其他 JavaScript 依赖仍由包管理器安装。CLI 构建工作流为每个平台生成 `crossdesk-mcp-<平台>` 产物;平台安装包要求实际传入的原生包与 MCP 的依赖版本一致。通用包和平台包名称、版本相同,应放在不同输出目录,不要将平台包当成通用版本发布到 npm。
平台包保留原生包的程序、源码、许可和构建信息,设置对应 OS / CPU / libc 限制,不再下载原生平台依赖;其他 JavaScript 依赖仍由包管理器安装。CLI 构建工作流为每个平台生成 `crossdesk-mcp-<平台>` 产物,CLI、MCP、DSH 和原生依赖版本不一致时直接停止构建或打包。通用包和平台包名称、版本相同,应放在不同输出目录,不要将平台包当成通用版本发布到 npm。
原生 `doctor` 必须同时声明自动化协议和 `automation_video_protocols: ["h264-annexb/1", "nv12/1"]`、`automation_video_decoders: ["auto", "software"]`,以及 `automation_video_transport: "loopback-websocket/1"`、`automation_terminal_protocol: "ansi/1"`。通用 npm 分发需要先发布对应 0.2.0 平台包,再发布 MCP;内含原生程序的平台包不受此顺序限制。构建通过不等于各宿主和设备上的联调完成。
+6 -6
View File
@@ -31,7 +31,7 @@ DSH 和 Codex 都使用下表中的**平台安装包**,其中已包含所需
1. 登录 GitHub,打开 [CrossDesk 构建页面](https://github.com/kunkundi/crossdesk/actions/workflows/build-cli.yml)。
2. 选择一次成功的运行,在页面的 **Artifacts** 区域下载与你的本机对应的文件。
3. 解压下载的 `.zip`,取出里面的 `.tgz` 安装包,例如 `chunkdash-crossdesk-mcp-0.1.0.tgz`。保留 `.tgz`,安装时直接使用它。
3. 解压下载的 `.zip`,取出里面的 `.tgz` 安装包,例如 `chunkdash-crossdesk-mcp-0.2.0.tgz`。保留 `.tgz`,安装时直接使用它。
GitHub 要求登录后才能下载构建产物,操作说明见 [下载构建产物](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/download-workflow-artifacts)。
@@ -47,7 +47,7 @@ Mac 可在“关于本机”中查看芯片;Windows 可在“设置 → 系统
不同平台解压后的 `.tgz` 文件名相同,请以下载时的产物名称区分。如果某次运行没有表中对应的产物,选择另一次提供该产物的运行;也可以按 [源码构建说明](DEVELOPMENT.md#从源码运行) 自行构建。
下文以 `0.1.0` 为例。**所有 `/absolute/path/...` 都需要换成自己电脑上的完整路径**,版本号也应与实际下载的文件一致。路径中有空格时保留引号。
下文以 `0.2.0` 为例。**所有 `/absolute/path/...` 都需要换成自己电脑上的完整路径**,版本号也应与实际下载的文件一致。路径中有空格时保留引号。
<a id="install-dsh"></a>
@@ -58,7 +58,7 @@ Mac 可在“关于本机”中查看芯片;Windows 可在“设置 → 系统
在 Harness 的插件页面选择本地 `.tgz` 安装包,或在终端执行:
```sh
dsh plugin --profile desktop add "/absolute/path/chunkdash-crossdesk-mcp-0.1.0.tgz"
dsh plugin --profile desktop add "/absolute/path/chunkdash-crossdesk-mcp-0.2.0.tgz"
```
这个插件包会自动提供 MCP 工具和侧栏画面,无需另外安装 Node.js、原生 CLI 或填写 MCP 启动配置。
@@ -66,7 +66,7 @@ dsh plugin --profile desktop add "/absolute/path/chunkdash-crossdesk-mcp-0.1.0.t
如果 macOS 终端提示找不到 `dsh`,可使用应用自带的命令:
```sh
"/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh" plugin --profile desktop add "/absolute/path/chunkdash-crossdesk-mcp-0.1.0.tgz"
"/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh" plugin --profile desktop add "/absolute/path/chunkdash-crossdesk-mcp-0.2.0.tgz"
```
上述命令对应默认安装位置和 `desktop` 配置。使用自定义安装位置或 profile 时替换为自己的值。
@@ -93,7 +93,7 @@ macOS / Linux:
mkdir -p "$HOME/crossdesk-mcp"
cd "$HOME/crossdesk-mcp"
npm init -y
npm install "/absolute/path/chunkdash-crossdesk-mcp-0.1.0.tgz"
npm install "/absolute/path/chunkdash-crossdesk-mcp-0.2.0.tgz"
```
Windows PowerShell:
@@ -102,7 +102,7 @@ Windows PowerShell:
New-Item -ItemType Directory -Force "$env:USERPROFILE/crossdesk-mcp"
Set-Location "$env:USERPROFILE/crossdesk-mcp"
npm init -y
npm install "C:/Downloads/chunkdash-crossdesk-mcp-0.1.0.tgz"
npm install "C:/Downloads/chunkdash-crossdesk-mcp-0.2.0.tgz"
```
安装完成后,在同一目录运行:
@@ -8,7 +8,7 @@
2. 在 Harness 桌面版的插件页面安装该文件,或执行以下命令。将示例中的路径和版本号替换为实际文件:
```sh
dsh plugin --profile desktop add "/absolute/path/chunkdash-crossdesk-mcp-0.1.0.tgz"
dsh plugin --profile desktop add "/absolute/path/chunkdash-crossdesk-mcp-0.2.0.tgz"
```
3. 重启 Harness,确认 CrossDesk 插件已启用。
@@ -1,6 +1,6 @@
{
"name": "@chunkdash/dsh-crossdesk-sidebar",
"version": "0.1.0",
"version": "0.2.0",
"description": "Open CrossDesk remote desktop panels in DeepSeek Harness Desktop's sidebar",
"type": "module",
"main": "dist/host.js",
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@chunkdash/crossdesk-mcp",
"version": "0.1.0",
"version": "0.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@chunkdash/crossdesk-mcp",
"version": "0.1.0",
"version": "0.2.0",
"license": "GPL-3.0-only",
"dependencies": {
"@modelcontextprotocol/client": "2.4.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@chunkdash/crossdesk-mcp",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"type": "module",
"description": "Local CrossDesk MCP tools and remote desktop panels",
+8 -3
View File
@@ -23,12 +23,17 @@ const { values } = parseArgs({ options: {
const output = resolve(values["out-dir"] ?? join(repository, "build/npm-mcp"));
const project = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
const cli = JSON.parse(await readFile(join(root, "../cli/package.json"), "utf8"));
const harness = JSON.parse(await readFile(join(root, "integrations/deepseek-harness/package.json"), "utf8"));
const platforms = JSON.parse(
await readFile(join(root, "../cli/npm/platforms.json"), "utf8"),
);
const native = await import(new URL("../dist/native.js", import.meta.url));
if (native.NATIVE_VERSION !== cli.version)
throw new Error("MCP and CLI native versions must match.");
const nativeVersion = (await readFile(join(root, "src/native.ts"), "utf8"))
.match(/export const NATIVE_VERSION = "([^"]+)";/)?.[1];
if (project.version !== cli.version || project.version !== harness.version || project.version !== nativeVersion)
throw new Error("CLI, MCP, DSH and NATIVE_VERSION must match. Run python3 scripts/version.py set mcp VERSION from the repository root.");
if (!nativeVersion || native.NATIVE_VERSION !== nativeVersion)
throw new Error("Built MCP native version differs from source. Run npm run build first.");
for (const file of ["main.js", "viewer-browser.html", "viewer-apps.html", "harness.js", "harness-client.js"])
await access(join(root, "dist", file));
const staging = await mkdtemp(join(tmpdir(), "crossdesk-mcp-pack-"));
@@ -72,7 +77,7 @@ try {
"LICENSE",
],
optionalDependencies: Object.fromEntries(
Object.values(platforms).map((p) => [p.packageName, cli.version]),
Object.values(platforms).map((p) => [p.packageName, nativeVersion]),
),
publishConfig: { access: "public" },
};
+2 -1
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env node
import { parseArgs } from "node:util";
import { VERSION } from "./version.js";
import { createInterface } from "node:readline/promises";
import { Writable } from "node:stream";
import {
@@ -149,7 +150,7 @@ async function main() {
},
});
if (values.version) {
process.stdout.write("0.1.0\n");
process.stdout.write(`${VERSION}\n`);
return;
}
if (values.help || !positionals.length) {
+2 -1
View File
@@ -1,4 +1,5 @@
import { readFile } from "node:fs/promises";
import { VERSION } from "./version.js";
import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/server";
import type {
@@ -80,7 +81,7 @@ export function createServer(
terminal: TerminalPanel,
): McpServer {
const server = new McpServer(
{ name: "crossdesk-mcp", version: "0.1.0" },
{ name: "crossdesk-mcp", version: VERSION },
{
capabilities: { tools: {}, resources: {} },
instructions:
+5
View File
@@ -0,0 +1,5 @@
import { readFileSync } from "node:fs";
export const VERSION: string = JSON.parse(
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
).version;