Skip to content

Commit 8a541b0

Browse files
authored
fix(installer): resolve latest stable plugin release (#85)
Resolve the newest stable namespaced Release across all GitHub API pages while retaining explicit version rollback.
1 parent 25fa2c9 commit 8a541b0

10 files changed

Lines changed: 150 additions & 24 deletions

File tree

‎.github/workflows/deepseek-harness-plugin-release.yml‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ jobs:
4646
const installer = readFileSync('skills/opengui-coremate-install/scripts/install-macos.sh', 'utf8')
4747
const skill = readFileSync('skills/opengui-coremate-install/SKILL.md', 'utf8')
4848
const agent = readFileSync('skills/opengui-coremate-install/agents/openai.yaml', 'utf8')
49-
if (!installer.includes(`release_version="${pkg.version}"`)) throw new Error('installer version is out of sync')
50-
if (!skill.includes(`OpenGUI v${pkg.version} release`)) throw new Error('Skill version is out of sync')
51-
if (!agent.includes(`OpenGUI v${pkg.version}`)) throw new Error('Skill agent version is out of sync')
49+
if (!installer.includes('/releases?per_page=100') || !installer.includes('--version VERSION')) {
50+
throw new Error('installer must resolve the latest stable release and retain an explicit version override')
51+
}
52+
if (!skill.includes('latest stable OpenGUI release')) throw new Error('Skill latest-release guidance is out of sync')
53+
if (!agent.includes('latest stable OpenGUI release')) throw new Error('Skill agent latest-release guidance is out of sync')
5254
NODE
5355
5456
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
@@ -156,7 +158,7 @@ jobs:
156158
157159
The macOS installer now runs DSH through a per-user LaunchAgent and includes a matching uninstall script. Verified phone-view caches are shared across DSH profiles, including existing \`~/.dsh\` caches.
158160
159-
Download both the \`.tgz\` package and its \`.sha256\` file. The recommended macOS path is the [Codex installer Skill](https://github.com/Core-Mate/OpenGUI/tree/${GITHUB_REF_NAME}/deepseek-harness-plugin/skills/opengui-coremate-install).
161+
Download both the \`.tgz\` package and its \`.sha256\` file. The recommended macOS path is the stable [Codex installer Skill](https://github.com/Core-Mate/OpenGUI/tree/main/deepseek-harness-plugin/skills/opengui-coremate-install), which resolves the latest stable plugin release each time it runs.
160162
161163
The package supports DeepSeek Harness through \`/opengui\` and \`@OpenGUI\`, and Codex through the \`opengui:control\` Skill plus seven local stdio MCP tools. Both hosts share the same bounded Android execution runtime, multi-device locking, cancellation, and read-only device-wall support.
162164

‎README.ja-JP.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ OpenGUI は実際の Android アプリ UI を読み取り、次のステップ
3838

3939
## DeepSeek HarnessでOpenGUIを使う
4040

41-
macOSでは、固定バージョンのインストーラーSkillをCodexに実行させる方法が最短です。Node.js 22.19以降または24以降が必要で、互換性のあるDSHバージョンは自動的にインストールされます。次の内容を1つのプロンプトとして送信します:
41+
macOSでは、`main` ブランチの安定したインストーラーSkillをCodexに実行させる方法が最短です。実行するたびに最新の安定版OpenGUIプラグインを解決してインストールし、ロールバック用に明示的なバージョン指定も利用できます。Node.js 22.19以降または24以降が必要で、互換性のあるDSHバージョンは自動的にインストールされます。次の内容を1つのプロンプトとして送信します:
4242

4343
```text
44-
Install and run the OpenGUI installer Skill from https://github.com/Core-Mate/OpenGUI/tree/dsh-coremate-mobile-v0.1.7/deepseek-harness-plugin/skills/opengui-coremate-install for my DSH web profile. Proceed autonomously, and only pause when I need to authorize or select a phone, add or select a DSH workspace, or provide fallback visual-model credentials.
44+
Install and run the OpenGUI installer Skill from https://github.com/Core-Mate/OpenGUI/tree/main/deepseek-harness-plugin/skills/opengui-coremate-install for my DSH web profile. Install the latest stable release. Proceed autonomously, and only pause when I need to authorize or select a phone, add or select a DSH workspace, or provide fallback visual-model credentials.
4545
```
4646

4747
Skillは公開ReleaseのパッケージとチェックサムをダウンロードしてSHA-256を検証し、OpenGUIプラグインだけをインストールします。必要な場合はDSHを起動して開き、既存のプラグインと設定は保持します。DSHがすでに起動していた場合は、一度再起動するとプラグインが読み込まれます。LinuxまたはWindowsでは、[手動パッケージガイド](./deepseek-harness-plugin/README.md#1-download-the-release-package)を使用してください。

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ OpenGUI reads a real Android app UI, plans the next step, takes mobile actions,
3939

4040
## Use OpenGUI in DeepSeek Harness
4141

42-
The shortest path on macOS is to let Codex run the pinned installer Skill. It requires Node.js 22.19+ or 24+ and installs the compatible DSH version automatically. Paste this as one prompt:
42+
The shortest path on macOS is to let Codex run the stable installer Skill from `main`. Each run resolves the latest stable OpenGUI plugin release, while an explicit version remains available for rollback. It requires Node.js 22.19+ or 24+ and installs the compatible DSH version automatically. Paste this as one prompt:
4343

4444
```text
45-
Install and run the OpenGUI installer Skill from https://github.com/Core-Mate/OpenGUI/tree/dsh-coremate-mobile-v0.1.7/deepseek-harness-plugin/skills/opengui-coremate-install for my DSH web profile. Proceed autonomously, and only pause when I need to authorize or select a phone, add or select a DSH workspace, or provide fallback visual-model credentials.
45+
Install and run the OpenGUI installer Skill from https://github.com/Core-Mate/OpenGUI/tree/main/deepseek-harness-plugin/skills/opengui-coremate-install for my DSH web profile. Install the latest stable release. Proceed autonomously, and only pause when I need to authorize or select a phone, add or select a DSH workspace, or provide fallback visual-model credentials.
4646
```
4747

4848
The Skill downloads the public release package and checksum, verifies SHA-256, installs only the OpenGUI plugin, starts DSH when needed, and opens DSH. It preserves unrelated DSH plugins and settings. If DSH was already running, restart it once to load the plugin. For Linux or Windows, use the [manual package guide](./deepseek-harness-plugin/README.md#1-download-the-release-package).

‎README.zh-CN.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ OpenGUI 会读取真实 Android App 界面,规划下一步操作,执行移
3838

3939
## 在 DeepSeek Harness 中使用 OpenGUI
4040

41-
macOS 上最短的路径,是让 Codex 运行固定版本的安装 Skill。环境需要 Node.js 22.19+ 或 24+,兼容的 DSH 版本会自动安装。把下面整段作为一条消息发给 Codex:
41+
macOS 上最短的路径,是让 Codex 运行 `main` 分支上的稳定安装 Skill。每次执行时,安装器都会解析并安装最新正式版 OpenGUI 插件,同时保留指定版本参数用于回滚。环境需要 Node.js 22.19+ 或 24+,兼容的 DSH 版本会自动安装。把下面整段作为一条消息发给 Codex:
4242

4343
```text
44-
请安装并运行这个 OpenGUI 安装 Skill:https://github.com/Core-Mate/OpenGUI/tree/dsh-coremate-mobile-v0.1.7/deepseek-harness-plugin/skills/opengui-coremate-install,把插件安装到我的 DSH web profile。请自主完成安装,仅在需要我授权或选择手机、添加或选择 DSH workspace,或者提供备用视觉模型凭据时暂停并询问我。
44+
请安装并运行这个 OpenGUI 安装 Skill:https://github.com/Core-Mate/OpenGUI/tree/main/deepseek-harness-plugin/skills/opengui-coremate-install,把最新正式版插件安装到我的 DSH web profile。请自主完成安装,仅在需要我授权或选择手机、添加或选择 DSH workspace,或者提供备用视觉模型凭据时暂停并询问我。
4545
```
4646

4747
Skill 会下载公开 Release 的插件包和校验文件,验证 SHA-256,只安装 OpenGUI 插件,在需要时启动并打开 DSH,同时保留其他 DSH 插件和设置。如果 DSH 原本正在运行,重启一次即可加载插件。Linux 或 Windows 用户可按[手动安装说明](./deepseek-harness-plugin/README.zh.md#1-下载发布包)操作。

‎deepseek-harness-plugin/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ The examples use the `web` profile and the default `$DSH_HOME=~/.dsh`. Substitut
5050

5151
### macOS: install with the Codex Skill
5252

53-
Ask Codex to install the repository skill from [`deepseek-harness-plugin/skills/opengui-coremate-install`](./skills/opengui-coremate-install), then invoke `$opengui-coremate-install`. The Skill downloads and verifies the pinned `v0.1.7` package from the public OpenGUI Release, preserves the rest of the `web` profile, and installs a per-user LaunchAgent so DSH returns after a crash or login. GitHub login is not required.
53+
Ask Codex to install the repository skill from [`deepseek-harness-plugin/skills/opengui-coremate-install`](./skills/opengui-coremate-install), then invoke `$opengui-coremate-install`. The Skill resolves the latest stable namespaced plugin Release, downloads its package and checksum, preserves the rest of the `web` profile, and installs a per-user LaunchAgent so DSH returns after a crash or login. Drafts, prereleases, and unrelated OpenGUI releases are ignored. GitHub login is not required. Use `--version VERSION` only for rollback or a reproducible install.
5454

5555
If port 3080 belongs to an OpenGUI-managed DSH, the installer safely reloads that LaunchAgent. It never terminates an unowned DSH process; in that case the new LaunchAgent takes over after the next login. The manual package flow below remains available on every supported host.
5656

‎deepseek-harness-plugin/README.zh.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ codex plugin add opengui@opengui-local
5252

5353
### macOS:通过 Codex Skill 安装
5454

55-
让 Codex 从仓库的 [`deepseek-harness-plugin/skills/opengui-coremate-install`](./skills/opengui-coremate-install) 安装 Skill,然后调用 `$opengui-coremate-install`。Skill 会从 OpenGUI 的公开 Release 下载并校验固定的 `v0.1.7` 安装包,保留 `web` profile 中的其他配置,并安装用户级 LaunchAgent,让 DSH 在异常退出或重新登录后自动恢复;不要求登录 GitHub。
55+
让 Codex 从仓库的 [`deepseek-harness-plugin/skills/opengui-coremate-install`](./skills/opengui-coremate-install) 安装 Skill,然后调用 `$opengui-coremate-install`。Skill 会解析最新的插件正式版 Release,下载并校验对应的安装包,忽略草稿、预发布版和 OpenGUI 的其他 Release;同时保留 `web` profile 中的其他配置,并安装用户级 LaunchAgent,让 DSH 在异常退出或重新登录后自动恢复。整个过程不要求登录 GitHub。只有回滚或需要可复现安装时才使用 `--version VERSION`。
5656

5757
如果 3080 端口属于 OpenGUI 管理的 DSH,安装器会安全更新并重启对应 LaunchAgent;如果属于其他 DSH 进程,安装器绝不会强制终止它,新 LaunchAgent 会在下次登录后接管。下面的手动安装方式仍适用于所有受支持的系统。
5858

‎deepseek-harness-plugin/skills/opengui-coremate-install/SKILL.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
---
22
name: opengui-coremate-install
3-
description: Install the pinned OpenGUI v0.1.7 release into a DeepSeek Harness web profile on macOS. Use when the user asks to download, install, update, open, or verify OpenGUI for DSH.
3+
description: Install the latest stable OpenGUI release into a DeepSeek Harness web profile on macOS. Use when the user asks to download, install, update, open, or verify OpenGUI for DSH.
44
---
55

66
# Install OpenGUI
77

8-
Install and verify the signed-off `v0.1.7` release without replacing unrelated DSH plugins or settings.
8+
Install and verify the latest stable OpenGUI release without replacing unrelated DSH plugins or settings.
99

1010
## Run the installer
1111

1212
1. Confirm the host is macOS. Do not improvise a Linux or Windows install.
1313
2. Run `scripts/install-macos.sh` from this skill directory.
1414
3. Report the installed package version, profile path, runtime URL, and whether an existing DSH process still needs a manual restart.
1515

16-
The script checks the host Node version, pins DSH to `0.1.0-rc.7`, downloads both the release tarball and checksum from the public GitHub Release, verifies SHA-256, installs only `dsh-coremate-mobile` into the `web` profile, and validates the package, bundle, Client entry, and `/opengui` command. GitHub authentication is not required.
16+
By default, the script resolves the highest stable `dsh-coremate-mobile-v*` release from the public GitHub Releases API. It ignores drafts, prereleases, and unrelated OpenGUI releases. Use `--version VERSION` only when the user explicitly requests a rollback or reproducible install.
17+
18+
The script checks the host Node version, pins DSH to `0.1.0-rc.7`, downloads both the resolved release tarball and checksum, verifies SHA-256, installs only `dsh-coremate-mobile` into the `web` profile, and validates the package, bundle, Client entry, and `/opengui` command. GitHub authentication is not required.
1719

1820
The script installs a user LaunchAgent with `KeepAlive` so DSH returns after a crash or login. It may safely reload an instance already owned by that exact LaunchAgent. If port 3080 belongs to any other DSH process, preserve it: the installer writes the LaunchAgent but defers takeover until the next login. When DSH is not running, the script starts and verifies `http://127.0.0.1:3080`.
1921

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
interface:
22
display_name: "OpenGUI Installer"
3-
short_description: "Install verified OpenGUI v0.1.7 into DSH on macOS"
3+
short_description: "Install the latest stable OpenGUI release into DSH on macOS"
44
icon_small: "./assets/opengui-mark.svg"
55
icon_large: "./assets/opengui-wordmark.svg"
66
brand_color: "#F1BF1F"
7-
default_prompt: "Use $opengui-coremate-install to download, verify, install, and open OpenGUI v0.1.7 for my DSH web profile."
7+
default_prompt: "Use $opengui-coremate-install to download, verify, install, and open the latest stable OpenGUI release for my DSH web profile."

‎deepseek-harness-plugin/skills/opengui-coremate-install/scripts/install-macos.sh‎

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
release_version="0.1.7"
54
dsh_version="0.1.0-rc.7"
65
profile="web"
76
port="${COREMATE_INSTALL_PORT_OVERRIDE:-3080}"
87
package_name="dsh-coremate-mobile"
98
github_repository="Core-Mate/OpenGUI"
9+
release_version="${COREMATE_INSTALL_VERSION_OVERRIDE:-}"
1010
github_release_base="https://github.com/${github_repository}/releases/download"
11+
github_releases_api="${COREMATE_INSTALL_RELEASES_API_OVERRIDE:-https://api.github.com/repos/${github_repository}/releases?per_page=100}"
1112
release_base="${COREMATE_INSTALL_RELEASE_BASE:-${github_release_base}}"
1213
dsh_home="${DSH_HOME:-${HOME}/.dsh}"
1314
launch_agents_dir="${COREMATE_INSTALL_LAUNCH_AGENTS_DIR_OVERRIDE:-${HOME}/Library/LaunchAgents}"
1415
start_runtime=true
1516
open_browser=true
1617

1718
usage() {
18-
printf '%s\n' 'Usage: install-macos.sh [--dsh-home PATH] [--release-base URL] [--no-start] [--no-open]'
19+
printf '%s\n' 'Usage: install-macos.sh [--version VERSION] [--dsh-home PATH] [--release-base URL] [--no-start] [--no-open]'
1920
}
2021

2122
while (($# > 0)); do
2223
case "$1" in
24+
--version)
25+
[[ $# -ge 2 ]] || { usage >&2; exit 2; }
26+
release_version="$2"
27+
shift 2
28+
;;
2329
--dsh-home)
2430
[[ $# -ge 2 ]] || { usage >&2; exit 2; }
2531
dsh_home="$2"
@@ -52,7 +58,7 @@ done
5258

5359
platform="${COREMATE_INSTALL_PLATFORM_OVERRIDE:-$(uname -s)}"
5460
if [[ "$platform" != "Darwin" ]]; then
55-
printf 'OpenGUI v%s installer supports macOS only; detected %s.\n' "$release_version" "$platform" >&2
61+
printf 'The OpenGUI installer supports macOS only; detected %s.\n' "$platform" >&2
5662
exit 1
5763
fi
5864

@@ -90,6 +96,79 @@ if [[ "$installed_dsh" != "$dsh_version" ]]; then
9096
exit 1
9197
fi
9298

99+
temporary="$(mktemp -d "${TMPDIR:-/tmp}/opengui-coremate-install.XXXXXX")"
100+
trap 'rm -rf "$temporary"' EXIT
101+
102+
if [[ -z "$release_version" ]]; then
103+
printf 'Resolving the latest stable OpenGUI plugin release...\n'
104+
api_args=(-fsSL --retry 3 --connect-timeout 15 --max-time 60
105+
-H 'Accept: application/vnd.github+json'
106+
-H 'X-GitHub-Api-Version: 2022-11-28')
107+
if [[ "$github_releases_api" == https://* ]]; then api_args+=(--proto '=https' --tlsv1.2); fi
108+
releases_directory="${temporary}/releases"
109+
mkdir -p "$releases_directory"
110+
releases_url="$github_releases_api"
111+
releases_page=1
112+
while [[ -n "$releases_url" ]]; do
113+
page_body="${releases_directory}/${releases_page}.json"
114+
page_headers="${releases_directory}/${releases_page}.headers"
115+
if ! curl "${api_args[@]}" --dump-header "$page_headers" --output "$page_body" "$releases_url"; then
116+
printf 'Could not read OpenGUI plugin releases from GitHub. Check GitHub access or retry with --version VERSION.\n' >&2
117+
exit 1
118+
fi
119+
if ! node -e '
120+
const releases = JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8"))
121+
if (!Array.isArray(releases)) throw new Error("GitHub Releases response is not an array")
122+
' "$page_body"; then
123+
printf 'GitHub returned an invalid Releases response. Retry with --version VERSION.\n' >&2
124+
exit 1
125+
fi
126+
releases_url="$(node -e '
127+
const headers = require("node:fs").readFileSync(process.argv[1], "utf8")
128+
const link = headers.split(/\r?\n/u).find(line => /^link:/iu.test(line)) ?? ""
129+
const next = link.replace(/^link:\s*/iu, "").split(",").map(value => value.trim())
130+
.map(value => value.match(/^<([^>]+)>;\s*rel="([^"]+)"$/u))
131+
.find(match => match?.[2]?.split(/\s+/u).includes("next"))
132+
if (next) process.stdout.write(next[1])
133+
' "$page_headers")"
134+
releases_page=$((releases_page + 1))
135+
done
136+
137+
if ! release_version="$(
138+
node --input-type=module -e '
139+
import { readFileSync, readdirSync } from "node:fs"
140+
const packageName = process.argv[1]
141+
const directory = process.argv[2]
142+
const releases = readdirSync(directory)
143+
.filter(name => name.endsWith(".json"))
144+
.flatMap(name => JSON.parse(readFileSync(`${directory}/${name}`, "utf8")))
145+
const pattern = new RegExp(`^${packageName}-v(\\d+)\\.(\\d+)\\.(\\d+)$`)
146+
const versions = releases.flatMap(release => {
147+
if (release?.draft || release?.prerelease || typeof release?.tag_name !== "string") return []
148+
const match = release.tag_name.match(pattern)
149+
return match ? [{ version: match.slice(1).join("."), parts: match.slice(1).map(Number) }] : []
150+
})
151+
versions.sort((left, right) => {
152+
for (let index = 0; index < 3; index += 1) {
153+
if (left.parts[index] !== right.parts[index]) return right.parts[index] - left.parts[index]
154+
}
155+
return 0
156+
})
157+
if (versions.length === 0) throw new Error(`No stable ${packageName} release was found`)
158+
process.stdout.write(versions[0].version)
159+
' "$package_name" "$releases_directory"
160+
)"; then
161+
printf 'Could not resolve the latest stable OpenGUI plugin release. Check GitHub access or retry with --version VERSION.\n' >&2
162+
exit 1
163+
fi
164+
fi
165+
166+
if [[ ! "$release_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
167+
printf 'Invalid OpenGUI plugin version: %s. Expected a stable version such as 0.1.7.\n' "$release_version" >&2
168+
exit 1
169+
fi
170+
printf 'Using OpenGUI plugin v%s.\n' "$release_version"
171+
93172
runtime_running=false
94173
if lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; then
95174
page="$(curl -fsS --max-time 3 "http://127.0.0.1:${port}" || true)"
@@ -104,8 +183,6 @@ archive_name="${package_name}-${release_version}.tgz"
104183
checksum_name="${archive_name}.sha256"
105184
release_tag="${package_name}-v${release_version}"
106185
release_url="${release_base%/}/${release_tag}"
107-
temporary="$(mktemp -d "${TMPDIR:-/tmp}/opengui-coremate-install.XXXXXX")"
108-
trap 'rm -rf "$temporary"' EXIT
109186

110187
download() {
111188
local url="$1"

0 commit comments

Comments
 (0)