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
78 changes: 69 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ permissions:

jobs:
package-windows:
name: Package Windows x64
name: Package ${{ matrix.edition }} x64
runs-on: windows-latest
strategy:
matrix:
edition: [windows, windows_byte]
environment:
name: windows-packaging
url: ${{ github.server_url }}/${{ github.repository }}/releases
Expand Down Expand Up @@ -64,14 +67,31 @@ jobs:
shell: pwsh
env:
APP_VERSION: ${{ steps.version.outputs.version }}
APP_EDITION: ${{ matrix.edition }}
run: |
$env:APP_VERSION | Set-Content -Encoding ascii VERSION
$env:APP_EDITION | Set-Content -Encoding ascii EDITION
$versionTuple = (($env:APP_VERSION -split '\.') + '0') -join ', '
$versionInfo = Get-Content "packaging/windows/version_info.txt" -Raw
$versionInfo = $versionInfo -replace '\(\d+,\s*\d+,\s*\d+,\s*0\)', "($versionTuple)"
$versionInfo = $versionInfo -replace "u'\d+\.\d+\.\d+'", "u'$env:APP_VERSION'"
New-Item -ItemType Directory -Force -Path build | Out-Null
$versionInfo | Set-Content -Encoding utf8 "build/windows-version-info.txt"

python -m PyInstaller --noconfirm --clean --onefile --console `
--name SeeleUpdater --distpath build/updater-helper `
--workpath build/updater-helper-work --specpath build `
app_update_entry.py
if ($LASTEXITCODE -ne 0) { throw "Updater helper build failed." }

if ($env:APP_EDITION -eq "windows_byte") {
python -m PyInstaller --noconfirm --clean --onefile --console `
--name SeeleWindowsBootstrap --distpath build/windows-helper `
--workpath build/windows-helper-work --specpath build `
windows_byte_bootstrap.py
if ($LASTEXITCODE -ne 0) { throw "Windows bootstrap helper build failed." }
}

python -m PyInstaller `
--noconfirm `
--clean `
Expand All @@ -96,13 +116,27 @@ jobs:
--add-data "DEVELOPMENT_LOG.md;." `
--add-data "MAC_BYTE_AUTO_INSTALL_COMMANDS.md;." `
--add-data "MAC_BYTE_ZERO_TOUCH_RESEARCH.md;." `
--add-data "WINDOWS_BYTE_INSTALL.md;." `
--add-data "windows_byte_linux.py;." `
--add-data "botmux_setup_coach.py;." `
--add-data "platform_utils.py;." `
--add-data "EDITION;." `
--add-data "VERSION;." `
--add-data "LICENSE;." `
run_exe.py
if (-not (Test-Path "dist/Seele/Seele.exe")) {
throw "PyInstaller did not produce dist/Seele/Seele.exe"
}
New-Item -ItemType Directory -Force -Path dist/Seele/bin | Out-Null
Copy-Item build/updater-helper/SeeleUpdater.exe dist/Seele/bin/
& "dist/Seele/Seele.exe" --updater-smoke-test
if ($LASTEXITCODE -ne 0) { throw "Packaged updater smoke test failed." }
if ($env:APP_EDITION -eq "windows_byte") {
New-Item -ItemType Directory -Force -Path dist/Seele/bin | Out-Null
Copy-Item build/windows-helper/SeeleWindowsBootstrap.exe dist/Seele/bin/
& "dist/Seele/Seele.exe" --windows-bootstrap-smoke-test
if ($LASTEXITCODE -ne 0) { throw "Packaged WSL resource/helper smoke test failed." }
}
$env:QT_QPA_PLATFORM = "offscreen"
& "dist/Seele/Seele.exe" --smoke-test
if ($LASTEXITCODE -ne 0) {
Expand All @@ -113,42 +147,44 @@ jobs:
shell: pwsh
env:
APP_VERSION: ${{ steps.version.outputs.version }}
APP_EDITION: ${{ matrix.edition }}
run: |
New-Item -ItemType Directory -Force -Path release | Out-Null
Compress-Archive `
-Path "dist/Seele" `
-DestinationPath "release/Seele-$env:APP_VERSION-windows-x64-portable.zip" `
-DestinationPath "release/Seele-$env:APP_VERSION-$env:APP_EDITION-x64-portable.zip" `
-CompressionLevel Optimal

$iscc = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe"
if (-not (Test-Path $iscc)) {
throw "Inno Setup compiler was not found."
}
& $iscc "/DMyAppVersion=$env:APP_VERSION" "packaging\windows\Seele.iss"
& $iscc "/DMyAppVersion=$env:APP_VERSION" "/DMyEdition=$env:APP_EDITION" "packaging\windows\Seele.iss"
if ($LASTEXITCODE -ne 0) {
throw "Inno Setup failed with exit code $LASTEXITCODE"
}

$manifest = @{
product = "Seele"
version = $env:APP_VERSION
edition = $env:APP_EDITION
commit = $env:GITHUB_SHA
platform = "windows-x64"
built_at = (Get-Date).ToUniversalTime().ToString("o")
} | ConvertTo-Json
$manifest | Set-Content -Encoding utf8 "release/release-manifest-windows.json"
$manifest | Set-Content -Encoding utf8 "release/release-manifest-$env:APP_EDITION.json"

Get-ChildItem release -File |
Where-Object { $_.Name -ne "SHA256SUMS-windows.txt" } |
Where-Object { $_.Name -ne "SHA256SUMS-$env:APP_EDITION.txt" } |
Sort-Object Name |
ForEach-Object {
$hash = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()
"$hash $($_.Name)"
} | Set-Content -Encoding ascii "release/SHA256SUMS-windows.txt"
} | Set-Content -Encoding ascii "release/SHA256SUMS-$env:APP_EDITION.txt"

- uses: actions/upload-artifact@v4
with:
name: Seele-${{ steps.version.outputs.version }}-windows
name: Seele-${{ steps.version.outputs.version }}-${{ matrix.edition }}
path: release/*
if-no-files-found: error

Expand Down Expand Up @@ -223,6 +259,8 @@ jobs:
APP_VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
printf '%s\n' "$APP_VERSION" > VERSION
printf '%s\n' mac_byte > EDITION
mkdir -p build/coach-spec
python -m PyInstaller \
--noconfirm \
Expand All @@ -235,6 +273,12 @@ jobs:
--specpath build/coach-spec \
botmux_setup_coach_entry.py

python -m PyInstaller \
--noconfirm --clean --onefile --console \
--name SeeleUpdater --distpath build/updater-dist \
--workpath build/updater-work --specpath build/coach-spec \
app_update_entry.py

python -m PyInstaller \
--noconfirm \
--clean \
Expand Down Expand Up @@ -268,6 +312,8 @@ jobs:
cp "build/coach-dist/SeeleBotmuxCoach" \
"dist/Seele.app/Contents/Resources/bin/SeeleBotmuxCoach"
chmod 755 "dist/Seele.app/Contents/Resources/bin/SeeleBotmuxCoach"
cp "build/updater-dist/SeeleUpdater" "dist/Seele.app/Contents/Resources/bin/SeeleUpdater"
chmod 755 "dist/Seele.app/Contents/Resources/bin/SeeleUpdater"
script -q /dev/null \
env "SEELE_RESOURCES_DIR=$PWD/dist/Seele.app/Contents/Resources" \
"dist/Seele.app/Contents/Resources/bin/SeeleBotmuxCoach" \
Expand All @@ -282,6 +328,7 @@ jobs:
codesign --verify --deep --strict --verbose=2 "dist/Seele.app"
QT_QPA_PLATFORM=offscreen "dist/Seele.app/Contents/MacOS/Seele" --smoke-test
"dist/Seele.app/Contents/MacOS/Seele" --botmux-coach-smoke-test
"dist/Seele.app/Contents/MacOS/Seele" --updater-smoke-test

- name: Build mac_byte DMG, ZIP, and checksums
shell: bash
Expand All @@ -293,9 +340,12 @@ jobs:
zip_path="release/Seele-${APP_VERSION}-mac_byte-macos-arm64.zip"
dmg_path="release/Seele-${APP_VERSION}-mac_byte-macos-arm64.dmg"
ditto -c -k --sequesterRsrc --keepParent "dist/Seele.app" "$zip_path"
mkdir -p build/dmg-content
ditto "dist/Seele.app" "build/dmg-content/Seele.app"
ln -s /Applications "build/dmg-content/Applications"
hdiutil create \
-volname "Seele ${APP_VERSION} mac_byte" \
-srcfolder "dist/Seele.app" \
-srcfolder "build/dmg-content" \
-ov \
-format UDZO \
"$dmg_path"
Expand Down Expand Up @@ -341,7 +391,8 @@ jobs:
steps:
- uses: actions/download-artifact@v4
with:
name: Seele-${{ needs.package-windows.outputs.version }}-windows
pattern: Seele-${{ needs.package-windows.outputs.version }}-windows*
merge-multiple: true
path: release
- uses: actions/download-artifact@v4
with:
Expand All @@ -360,6 +411,13 @@ jobs:

### 本版新增

- 启动后及每小时自动检查 GitHub 正式新版;右键最后的「检查更新」出现红点,点击自动下载、校验、替换并重启。
- 角色、语音和 Botmux 设置迁移到当前用户的 Seele 数据目录,更新后保留;新版启动失败自动回滚。
- macOS ZIP 首次打开可安装到应用程序目录,DMG 提供 Applications 拖放入口。
- Windows 字节版新增 WSL2 检测、缺失安装、重启保存进度与同用户登录续装。
- 复用原 Ubuntu、Linux 普通用户和机器人配置;字节 CLI 授权网页在 Windows 打开。
- systemd/watchdog/linger 配合 Windows 登录任务、恢复触发器和前台保活,自动恢复 Botmux。
- 桌宠自动读取选定 WSL 用户的 Dashboard 动态配置,安装完成与地址变化后重连。
- 新增「任务面板」:桌宠右键菜单打开独立窗口,展示最近 24 小时内有活动的 Botmux 任务(最初发起者、会话、机器人、标题、状态、相对活动时间),点击任意任务直接跳转到对应飞书话题。
- 任务状态归纳为「进行中 / 等你回复 / 空闲」三类,仅接受 applink.feishu.cn 深链跳转。
- 桌宠自动发现本机 Botmux Dashboard(读取 ~/.botmux 的端口与读取令牌),无需随包附带配置即可连通。
Expand Down Expand Up @@ -388,6 +446,8 @@ jobs:

- \`Seele-${VERSION}-windows-x64-setup.exe\`:Windows 安装版
- \`Seele-${VERSION}-windows-x64-portable.zip\`:Windows 便携版
- \`Seele-${VERSION}-windows_byte-x64-setup.exe\`:Windows 字节版安装包
- \`Seele-${VERSION}-windows_byte-x64-portable.zip\`:Windows 字节版便携包
- \`Seele-${VERSION}-mac_byte-macos-arm64.dmg\`:字节内部 Apple Silicon 安装版
- \`Seele-${VERSION}-mac_byte-macos-arm64.zip\`:字节内部 Apple Silicon 压缩包
- \`Seele-mac_byte-macos-arm64.dmg\` / \`.zip\`:供文档长期引用、始终指向当前 Release 的稳定文件名
Expand Down
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# 更新记录

## 2.5.0

- 启动后和每小时后台检查 GitHub 新版;右键最后一项“检查更新”显示新版红点,
点击下载、SHA256/清单校验、自检、替换并重启。
- 独立更新程序在旧应用退出后替换,新版未成功启动则恢复旧版;
保留 Windows 安装版卸载信息。
- 角色、语音、自定义工作流和 Botmux 配置迁移到当前用户的 Seele 目录,
更新后保留;普通版与字节版隔离。
- macOS ZIP 首次打开提示安装到应用程序,DMG 增加 Applications 拖放入口。
- 包含上一个未发布的 2.4.0 Windows 字节版改动,仍需 Windows 真机验收。

## 2.4.0(并入 2.5.0 发布)

- 新增 Windows 字节版:检测可运行 WSL2,复用已有 Ubuntu 和普通 Linux 用户;
缺组件先安装,需重启时保存进度,同一 Windows 用户登录后自动续装。
- WSL 内安装官方自包含 Botmux 和字节 CLI,保留已有配置;复用 PTY 交互引导,
在 Windows 浏览器打开授权地址并播放语音。
- 合并 systemd 设置,启用用户服务、watchdog 和 linger,注册 Windows 登录后
自启与恢复任务;增加前台保活,防止 WSL 因没有前台进程而退出。
- 桌宠后台读取选定 WSL 用户的动态 Dashboard 配置,安装完成与地址变化时重连。
- Windows 普通版与字节版分别打包,增加冻结安装终端与资源自检。
本次未执行真实 Windows 重启与 EXE 构建,须真机验收。

## 2.3.1

- 任务面板新增“发起者”信息,使用 Botmux 创建会话时固定保存的 `ownerOpenId`
Expand Down
91 changes: 91 additions & 0 deletions DEVELOPMENT_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,97 @@
- 不在本文记录 Token、Cookie、账号、内网凭据或其他秘密。
- 不删除远端 Release、Tag 或回退远端分支,除非用户明确批准。

## 2026-10-21 安装、自动更新与设置保留(2.5.0 发布准备)

用户授权实现启动联网检查、右键最后“检查更新”红点、点击下载安装重启、
设置移出应用包。本批次包含上一个未发布的 Windows 字节版改动;
用户已明确回复“OK啦,推吧”,授权本批次提交、合并和发布。
采用功能分支 -> PR -> CI 通过后合并 -> Tag/Release,保留分支和 PR 记录。

- `platform_utils.py`:区分只读资源与可写用户目录,按 edition 隔离设置;
首次迁移 state/uid/file_name/config/botmux_config,原子写入与私有文件权限。
macOS 新 ZIP 可优先迁移已安装同类型旧应用的设置。
- macOS 设置目录 `~/Library/Application Support/Seele/<edition>/`,
Windows `%LOCALAPPDATA%/Seele/<edition>/`,Linux XDG data home。
`SEELE_DATA_DIR` 用于测试隔离;配置窗口、语音、RPA、Botmux、日志均已接入。
- `UpdateUi.py`:启动 5 秒后检查、每小时检查、菜单末项红点,
点击下载进度提示;离线后台静默、手动反馈,不与 Botmux 安装同时替换。
- `app_update.py`:官方 GitHub latest API,匿名限流时使用官方 latest/download
manifest;严格版本/发行类型/平台选择,SHA256、发布清单、ZIP 路径与链接、
包内版本/资源/签名和冻结主程序自检,拒绝降级。随包携带 certifi CA,
不依赖构建机 Homebrew 证书;兼容 ditto 未标 UTF-8 的中文 ZIP 文件名。
- `app_update_entry.py`:独立 onefile helper,退出前准备与授权握手,
等待旧进程退出后同目录原子替换,实际新版 PID/版本/nonce 健康回执;
失败回滚,保留 Inno 卸载资源,安装目标文件锁,下一次启动清理已完成过程目录。
- macOS ZIP 首次启动可安装到 /Applications(不可写时 ~/Applications),
已存在版本不降级、不跨发行类型覆盖;DMG 增加 Applications 拖放入口。
- 发布 workflow 与本地构建均打包独立更新 helper、增加冻结主程序 helper 自检;
Windows VIP 从自身独立复制的 embeddable Python 执行更新程序,
切换正式 EXE 后保留“启动希儿.vbs”入口;普通版启动刷新 RPA 的资源和设置路径。
- 验证:98 项 Python 测试通过(含设置保留、SHA、ZIP/symlink、
平台选择、真实子进程健康回执、成功替换/失败回滚/父进程不退出、
菜单最后项和红点、离线与点击下载、匿名限流回退);插件测试通过,
release YAML 解析与 diff 格式通过。
- 在线只读验证成功:官方 latest 显示 2.3.1,mac_byte/arm64 三个版本资产
正确解析,真实 ZIP/清单下载 SHA256 与安全解压资源核验通过;临时副本已清理。
- 冻结 macOS 完整事务实跑:重新解压 ZIP 严格签名与 GUI/helper smoke,
独立冻结 helper 准备、等待旧 PID 退出、原子替换、真实新版 GUI PID 健康回执、
角色保留、替换后严格签名均通过。使用临时目标和隔离数据,未替换工作区或本机应用。
冻结主程序在系统 CA 路径设为不存在时 HTTPS 检查通过,确认 certifi 随包可用。
当前 2.5.0 不会降级;普通用户菜单安装与未来更高版本点击更新仍待真机验收。
- VIP 输出固定在 `vip-packages/Seele-2.5.0-vip-test-*.zip`,附 SHA256。
Windows EXE/WSL 安装、重启和授权仍需 Windows 真机验收。
- 最终 mac_byte ZIP SHA256:
`be801c99522ef1858849d25802d742eb091b0ed7e4f5c988b4d959c16a78508f`。
- 最终 windows_byte VIP ZIP SHA256:
`4b166d22df7aaa877b3ede3762ffec5f7e354cf3a2cca5249cf37bee6af4f2cc`。
两包 ZIP/摘要核验通过;Windows 包包含 certifi CA、独立 helper 源码与内置 Python。
- 菜单视觉证据:`vip-packages/Seele-2.5.0-update-menu.png`,
模拟高版本红点,验证“检查更新”始终在底部;线上当前没有高于 2.5.0 的 Release。
- 发布 CI 修正:首次 Windows CI 在 CP1252 输出中文安装提示时抛
`UnicodeEncodeError`,导致成功、重启和锁竞争分支异常退出。
`run_install()` 开始时将可配置 stdout/stderr 设为 UTF-8,
新增英文系统重定向输出与重启返回码回归,本地 99 项测试通过。
该失败触发矩阵 fail-fast;PR/分支 CI 修正后重新运行。

## 2026-10-21 Windows 字节版 WSL 安装修复(2.4.0 本地待验收)

用户授权按其成功部署指南直接修复 Windows 字节版。本批次仅本地修改;
未提交、未推送、未发布。用户新增指南和 `.vscode/` 保留。

- `windows_byte_bootstrap.py`:当前用户 WSL2 探测、普通用户复用/初始化、
窄范围 UAC 组件安装、原子进度、内核锁、重启续装任务及 HKCU Run 备用。
- `windows_byte_linux.py`:合并 WSL 配置、官方 Botmux 二进制安装、
字节 CLI 安装与授权、插件、systemd/watchdog/linger、前台保活。
- `botmux_setup_coach.py`:WSL 内调用 Windows PowerShell 播放原语音,
优先 Chrome 打开授权地址;文字参数用 UTF-16 编码脚本和单引号字面量传递。
- `Seele.py`/`botmux_client.py`:Windows 字节版避开旧影刀首次安装,
菜单继续安装、后台 UNC Dashboard 发现、Qt 主线程更新连接。
- Windows 打包矩阵分普通版/字节版,冻结独立 console helper,
主程序执行 helper 路径与 Linux 源资源自检;Inno 字节版独立目录与卸载任务。
- 本地版本升为 2.4.0;线上仍为 2.3.1。安装说明见 `WINDOWS_BYTE_INSTALL.md`。

验证:82 项 Python 测试通过,新增 16 项覆盖重启边界、续装、
Windows 身份、并发锁、systemd 合并、保活恢复、浏览器与 UNC 路由。
插件 build/validate/MCP smoke、Python 编译、diff 格式、离屏桌宠通过。
PowerShell 7.4.6 解析安装脚本和 workflow 的 PowerShell 部分通过;
release YAML 解析通过。仅语法校验,不代表 Windows 系统接口已实跑。

本地 VIP:

- `vip-packages/Seele-2.4.0-vip-test-windows_byte-x64-portable.zip`:
官方 Windows Python 3.11.9 embeddable + Windows Qt/wheels,
完整解压后双击 `启动希儿.vbs`;没有另装 Python 的前置要求。
ZIP CRC、资源清单、Python/Qt Windows DLL 校验通过。
- `vip-packages/Seele-2.4.0-vip-test-mac_byte-macos-arm64.zip`:
本地 PyInstaller arm64,ad-hoc 严格签名、冻结主程序 smoke、
coach 路径 smoke 与 ZIP 校验通过。
- 两包均带 `.zip.sha256`。构建脚本 `packaging/windows/build_vip.py` 和
`packaging/build_mac_vip.py` 只做本地产物,不发布。

真实 Windows WSL 安装、重启/登录、账号授权、计划任务注册与
Windows PyInstaller EXE 构建未在当前 macOS 主机执行。

## 远端基线

- 仓库:`https://github.com/xinna2001/Seele`
Expand Down
Loading
Loading