At a glance
What it does
Debug Mobius Electron-shell changes remotely by replacing app.asar, restarting the Windows app, and checking screenshots.
Before you choose it
This skill provides a repeatable remote loop for Mobius desktop changes in the Electron main process, preload layer, title bar, window controls, and renderer assets packaged in app.asar. It explains when repackaging is necessary, how to transfer the new archive safely, use a detached script so the aimux bridge can reconnect after the app exits, and confirm the running app with a screenshot feedback loop.
Best for
Mobius contributors who can build the desktop client and have access to an aimux-connected Windows machine.
Common tasks
- Test a change to Electron main-process, preload, title-bar, or window-control code on a remote Windows device.
- Replace only the rebuilt app.asar instead of transferring a full Windows package.
- Diagnose visual desktop-shell changes by capturing, downloading, and reviewing screenshots.
- Recover from a failed iteration using the retained original or previous app.asar backup.
Permissions and data
Requires control of a remote Windows machine through aimux and transfers build artifacts and scripts to its temporary directory.
Permissions- Create aimux sessions and send commands to the remote Windows machine.
- Stop and start Mobius Desktop processes.
- Copy, back up, and replace app.asar in the remote application directory.
- Capture and download screenshots from the remote machine.
- Transfers the rebuilt app.asar, PowerShell scripts, process status, and captured screenshots between the local environment and the remote machine.
- Keeps remote app.asar backup files and temporary artifacts unless you remove them.
- aimux bridge to a remote Windows machine.
- Access to an aimux remote is required; specific authentication requirements are not declared.
Limitations
- Applies specifically to the Mobius Electron desktop client and an aimux-connected Windows device.
- The loop intentionally disconnects the current bridge when it stops the app; you must wait for reconnection and use a new session name if an old session becomes stale.
- Packaging, type checks, remote connectivity, and screenshot review can still fail independently.
- The skill documents a Windows titleBarOverlay issue in one unsigned, high-DPI environment; it is not a universal Electron guarantee.
What DSHub checked
- The pinned skill document describes the repackaging, remote app.asar swap, restart, reconnection, and screenshot-validation workflow.
- The source commit and complete skill document were captured as passing hard checks.
What DSHub did not check
- DSHub did not install, execute, or validate the workflow against a remote Windows device.
- No harness version range is declared in the supplied evidence.
Pinned install
Primary action
This standalone skill does not have a DSH Plugin install action. Use its source documentation for the delivery method.
Maintainer source
Skill instructions
name: mobius-electron-debug description: Iterate on the Mobius desktop (Electron) client on a remote Windows machine via aimux — hot-swap app.asar through the bridge, restart the exe, and verify with a screenshot feedback loop. Use when changing Electron-shell code (main process / preload / title bar / window controls) that requires repackaging.
Mobius 桌面端 (Electron) 远程调试循环
改桌面端 Electron 壳代码(主进程 / preload / 标题栏 / 窗口控制等)后,必须重打包 + 替换真机 app.asar 才生效。本 skill 总结如何在 aimux 反向连接的 Windows 真机上,做「改代码 → 重打包 → 热替换 asar → 重启 exe → 截图验证 → 据反馈再改」的闭环迭代,无需用户手动操作。
本文所有路径里的
<remote>= aimux bridge remote 名(Windows 主机);<version>= 桌面端版本号(见mobius/desktop/package.json的version)。真机工作目录示例C:\tmp\mobius-desktop-<version>-win-x64。
0. 先判断:这次改动要不要重打包?
| 改动位置 | 进 app.asar? | 生效方式 |
|---|---|---|
mobius/desktop/electron/**(main.ts / preload.ts / lib/*) |
✅ 进 asar | 必须重打包 + 替换真机 asar + 重启 exe |
mobius/desktop/src/**(登录页 login.ts / styles.css / index.html) |
✅ 进 asar(renderer) | 同上 |
mobius/frontend/src/**(远程工作台前端 shell.tsx / App.tsx 等) |
❌ 不进 asar(服务器托管) | python3 start.py --only-update-frontend 部署后,exe 重启或硬刷新即生效 |
python-runtime / Electron 版本 / electron-builder.yml |
— | 整包重打 + 重装 |
关键:壳改动(main/preload/登录页)在 asar 里,远程前端改动在服务器。两者都要让 exe 重新加载——壳改动靠替换 asar + 重启 exe,前端改动靠重启 exe(loadURL 会拉最新前端 hash)。
1. 核心约束:aimux bridge 依赖 exe 运行
桌面端的 aimux supervisor 是 exe 的子进程。这意味着:
- kill exe = 断 bridge = 你的 aimux session 立即失联。
- 但 exe 重启后 supervisor 会自动 reverse-connect,bridge 几秒内重连,可重新
aimux new建会话。 - 因此替换 asar 必须用 detached 脚本(独立进程),让它在 bridge 断开后仍能完成 kill → 替换 → 重启。不能在当前 session 里同步 kill exe(会把自己掐断,替换/重启就没人执行了)。
2. 完整调试循环(一次迭代 ≈ 3–4 分钟)
步骤 1:改代码 + 本地类型检查
cd mobius/desktop && npx tsc --noEmit # 壳类型检查(exit 0 才继续)
cd mobius/frontend && npm run build # 前端改动时验证 vite build 通过
步骤 2:重打包壳(只打 win-x64,跳过菜单同步省时间)
python3 build.py --build-electron --targets win-x64 --skip-menu-sync
# 产物:mobius/desktop/release/win-unpacked/resources/app.asar (约 48KB!)
# mobius/desktop/release/Mobius Desktop-<version>-win-x64.zip
关键优化:标题栏/窗口控制这类壳改动全部编译进
app.asar(仅几十 KB)。只需替换真机的app.asar,不用推 180MB 整个目录。asar 不含 python runtime(python 是 extraResources,单独在resources/python/)。
步骤 3:建 aimux 会话 + 备份原版 asar + 推新 asar 到临时目录
export PATH="$HOME/.local/bin:$PATH"
BASE='C:\tmp\mobius-desktop-<version>-win-x64'
aimux new --remote <remote> --profile powershell --name sw --reuse
# 首次:把真机自带的原始 app.asar 另存为 .orig(永久回滚点,只存一次)
aimux send-keys "<remote>/sw" -- "if (!(Test-Path '$BASE\resources\app.asar.orig')) { Copy-Item '$BASE\resources\app.asar' '$BASE\resources\app.asar.orig' -Force; 'ORIG_SAVED' } else { 'ORIG_EXISTS' }" Enter
sleep 2
# 推新 asar 到临时目录(不直接覆盖运行中的 app.asar!)
aimux send_files <remote> 'C:\tmp\new-asar' 'mobius/desktop/release/win-unpacked/resources/app.asar'
不要直接
send_files覆盖resources\app.asar:运行中的 Electron 可能锁文件,且覆盖到一半会损坏。永远先推到临时目录,再用脚本原子替换。
步骤 4:detached 脚本原子替换 + 重启 exe
把 swap-asar.ps1(见 §3)推到真机并 detached 执行:
aimux send_files <remote> 'C:\tmp\new-asar' '/tmp/swap-asar.ps1'
# detached 启动:Start-Process 起独立 powershell 进程,当前 session 命令立即返回
aimux send-keys "<remote>/sw" -- 'Start-Process powershell -WindowStyle Hidden -ArgumentList "-NoProfile","-ExecutionPolicy","Bypass","-File","C:\tmp\new-asar\swap-asar.ps1"; echo LAUNCHED' Enter
脚本时序:sleep 2(让当前 session 命令返回)→ 备份当前 asar → Stop-Process 杀 exe(bridge 断)→ 替换 asar → Start-Process 重启 exe → 写完成标记。
步骤 5:等 bridge 重连 + 建新会话
sleep 20 # 等 exe 重启 + supervisor 反连
aimux remote ls | grep <remote> # 确认 connected
aimux new --remote <remote> --profile powershell --name chk # 用新会话名(见 §5 坑)
步骤 6:验证 asar 已替换 + exe 在跑
aimux send-keys "<remote>/chk" -- \
"Write-Output ('asar=' + (Get-Item '$BASE\resources\app.asar').Length)" Enter \
'$p = @(Get-Process "Mobius Desktop" -ErrorAction SilentlyContinue); Write-Output ("proc=" + $p.Count)' Enter \
"Write-Output ('done=' + (Get-Content C:\tmp\new-asar\swap-done.txt -ErrorAction SilentlyContinue))" Enter
sleep 3
aimux capture "<remote>/chk" --lines 20 | sed 's/\x1b\[[0-9;]*[mGKHJ]//g' | tail -10
期望:asar= = 新 asar 字节数、proc=4(Electron 多进程:main + GPU + renderer + utility)、done=DONE_HHMMSS。
步骤 7:截图验证(见 §4 详述)→ 据反馈回到步骤 1
3. 关键脚本(推到真机 C:\tmp\new-asar\ 下)
swap-asar.ps1 —— 原子替换 + 重启
Start-Sleep -Seconds 2
$base = 'C:\tmp\mobius-desktop-<version>-win-x64'
# 备份当前 asar(每次覆盖 .bak;原版永久存在 .orig)
try { Copy-Item "$base\resources\app.asar" "$base\resources\app.asar.bak" -Force -ErrorAction SilentlyContinue } catch {}
# 杀 exe(会断 aimux bridge;supervisor 重启后自动重连)
Get-Process -Name 'Mobius Desktop' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 3
# 替换 asar
Copy-Item 'C:\tmp\new-asar\app.asar' "$base\resources\app.asar" -Force
Start-Sleep -Seconds 1
# 重启 exe(加载新 asar;supervisor 起 bridge 重连)
Start-Process -FilePath "$base\Mobius Desktop.exe" -WorkingDirectory $base
# 完成标记
'DONE_' + (Get-Date -Format 'HHmmss') | Out-File 'C:\tmp\new-asar\swap-done.txt'
screenshot.ps1 —— 激活窗口 + 截全屏
Add-Type -AssemblyName System.Windows.Forms,System.Drawing
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h);
[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr h, int n);
}
"@
# 把 Mobius 窗口拉到前台(截图前必须,否则截到的是别的窗口)
$procs = Get-Process 'Mobius Desktop' -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowHandle -ne [IntPtr]::Zero }
if ($procs) {
$h = $procs[0].MainWindowHandle
[Win32]::ShowWindowAsync($h, 9) | Out-Null # SW_RESTORE
Start-Sleep -Milliseconds 400
[Win32]::SetForegroundWindow($h) | Out-Null
Start-Sleep -Milliseconds 700
}
$b = [System.Windows.Forms.SystemInformation]::VirtualScreen
$bmp = New-Object System.Drawing.Bitmap $b.Width, $b.Height
$g = [System.Drawing.Graphics]::FromImage($bmp)
$g.CopyFromScreen($b.X, $b.Y, 0, 0, $b.Size)
$bmp.Save('C:\tmp\new-asar\screen.png')
$g.Dispose(); $bmp.Dispose()
Write-Output ('shot=' + (Get-Item 'C:\tmp\new-asar\screen.png').Length + ' ' + $b.Width + 'x' + $b.Height)
⚠️ 避坑:曾尝试在 screenshot.ps1 里加
$wsh.SendKeys('^+{R}')触发 exe 的 Ctrl+Shift+R 硬刷新,结果 conda 的 PowerShell 报ParserError: UnexpectedToken。reload exe 改用 swap 重启(swap 不换 asar 也行,纯重启就重新 loadURL 拉最新前端),别在 ps1 里混 SendKeys。
4. 截图 feedback 循环(本 skill 的核心价值)
「改了壳代码但看不到效果」是桌面端调试最大痛点。这套循环让你纯远程、无需用户介入就能看到渲染结果并迭代。
4.1 截图
aimux send-keys "<remote>/chk" -- 'powershell -ExecutionPolicy Bypass -File C:\tmp\new-asar\screenshot.ps1' Enter
sleep 6 # 激活+截图含几处 sleep,留够时间
aimux capture "<remote>/chk" --lines 5 # 看到 shot=xxxx 即成功
4.2 下载到本地
aimux get_files <remote> /tmp/host-screen 'C:\tmp\new-asar\screen.png'
4.3 裁剪 + 放大要看的区域
全屏图(可能双屏 3840×1080)细节看不清。用 ffmpeg 裁目标区域放大:
cd /tmp/host-screen
# 裁右上角窗口按钮区(坐标按实际截图调整:crop=宽:高:x:y,原点左上)
ffmpeg -y -loglevel error -i screen.png -filter "crop=380:130:3460:0,scale=1140:390" topright.png
# 裁整个顶栏
ffmpeg -y -loglevel error -i screen.png -filter "crop=1920:420:1920:0,scale=1600:350" topnav.png
没有 ffmpeg 就用 PIL:
python3 -c "from PIL import Image; Image.open('screen.png').crop((x,y,x+w,y+h)).save('out.png')"。
4.4 看图 + 客观验证
Read一张图 → 直接看到渲染效果(图会自动上传 CDN)。- 细节拿不准(按钮有没有渲染?图标大小协调吗?)→ 用
analyze_image客观提问(「右上角有几个按钮?图标颜色?距右边缘多远?」),不要让它推测。 - 根据截图判断是否符合预期 → 不符合就回 §2 步骤 1 改代码,进入下一轮。
4.5 实战案例:标题栏按钮的 5 轮迭代
这个循环在本任务里跑了多轮,每轮都靠截图发现问题:
| 轮次 | 改动 | 截图反馈 | 结论 |
|---|---|---|---|
| v1 | titleBarStyle:hidden + titleBarOverlay:{color:rgba(0,0,0,0)} |
右上角无按钮 | 透明 color 不渲染符号 |
| v2 | overlay color 改不透明 #0a0e16 |
右上角仍无按钮(只有背景色块,无 min/max/close 符号) | 此环境(未签名 exe + 高 DPI)titleBarOverlay 原生按钮符号根本不渲染 |
| v3 | 放弃 overlay,改前端自绘按钮 + window:* IPC |
右上角4 个按钮齐全 ✅ | 自绘方案生效 |
| v4 | 自绘按钮缩小 + 加刷新按钮 | 刷新图标比其他大很多 | svg viewBox 24 width 12 vs 其他 viewBox 11 width 10,视觉不一致 |
| v5 | 刷新 svg 改 width 10 |
4 图标大小协调 ✅ | 完成 |
没有截图循环,v1/v2 的「按钮不渲染」根本发现不了(代码逻辑全对、tsc 全过、exe 正常跑),会误以为成功。
5. aimux bridge session 的坑
坑 1:session 状态不一致(zombie session)
exe 重启(bridge 断再重连)后,旧的 session 在 aimux 本地有记录、但 bridge 上已失效:
aimux new --reuse → error: session 'X' already exists # 本地有记录
aimux capture X → error: session not found # bridge 上没有
aimux kill X → error: session not found # kill 走 bridge 通道也失败,清不掉本地记录
解法:直接换一个新 session 名(sw→sw2→sw3…),绕开僵尸记录。不要在 kill/new 上死磕。
坑 2:capture 报 client replaced
detached 脚本 kill exe 时,当前 capture 会报 bridge remote disconnected: client replaced。这是预期(新 exe 已重连替换旧连接),不是错误。等 20s 后 aimux new 新会话即可。
坑 3:bridge remote 必须带 --profile
反向 Windows 设备的 aimux new 必须带 --profile(cmd / powershell / mingw64,见 aimux remote ls 的 PROFILES 列)。推荐 powershell(脚本兼容性最好)。
6. titleBarOverlay 陷阱 + 自绘窗口按钮方案
陷阱
Windows 上 titleBarStyle:"hidden" + titleBarOverlay:{color,symbolColor,height} 理论上叠原生 min/max/close 按钮。但在未签名 exe(signAndEditExecutable:false)+ 高 DPI 缩放的真机上,overlay 只渲染背景色块、按钮符号(symbolColor)不显示。用户将无法最小化/关闭窗口。
方案:前端自绘按钮(VSCode 同款,完全可控)
- 主进程
main.ts:titleBarStyle:"hidden",不用 titleBarOverlay;加window:minimize/window:toggle-maximize/window:close/window:is-maximizedIPC;maximize/unmaximize事件经broadcast推前端。 - preload:
mobiusDesktop暴露windowMinimize/windowToggleMaximize/windowClose/windowIsMaximized/onMaximizeChange。 - 前端
window-controls.tsx:仅!IS_MAC_PLATFORM渲染(macOS 用系统交通灯hiddenInset);图标色var(--text-primary)→ 天然随主题;关闭键 hover 红#e81123。 - 顶栏 drag:
.mobius-topnav加-webkit-app-region:drag,内部交互元素no-drag(仅window.mobiusDesktop.isDesktop时挂 class,Web 端零影响)。
主题自适应
顶栏背景本就是 var(--bg-primary)(随主题切换的 CSS 变量)。隐藏原生标题栏后,顶栏直接充当标题栏 → 切主题自动变色,零额外逻辑。这是「让前端既有顶栏充当标题栏」相比「自绘独立标题栏条」的最大优势。
7. 回滚
真机保留了两个备份(在 resources\ 下):
app.asar.orig—— 真机出厂原版(永久,首次 swap 时存)。最稳回滚点。app.asar.bak—— 上一次替换前的版本(每次 swap 覆盖)。
回滚:Copy-Item app.asar.orig app.asar -Force → 重启 exe(再跑一次 swap-asar.ps1,或改脚本只重启不替换)。
8. 速查表(一次迭代)
# 0. PATH
export PATH="$HOME/.local/bin:$PATH"
REMOTE=<remote>; BASE='C:\tmp\mobius-desktop-<version>-win-x64'
# 1. 改代码 + 类型检查
cd mobius/desktop && npx tsc --noEmit
# 2. 重打包(只 win-x64)
python3 build.py --build-electron --targets win-x64 --skip-menu-sync
# 前端改动另加: python3 start.py --only-update-frontend
# 3. 推 asar + 脚本到临时目录
aimux send_files $REMOTE 'C:\tmp\new-asar' 'mobius/desktop/release/win-unpacked/resources/app.asar'
aimux send_files $REMOTE 'C:\tmp\new-asar' '/tmp/swap-asar.ps1'
# 4. detached 原子替换 + 重启
aimux new --remote $REMOTE --profile powershell --name sw --reuse
aimux send-keys "$REMOTE/sw" -- 'Start-Process powershell -WindowStyle Hidden -ArgumentList "-NoProfile","-ExecutionPolicy","Bypass","-File","C:\tmp\new-asar\swap-asar.ps1"; echo GO' Enter
# 5. 等重连 + 验证
sleep 20 && aimux remote ls | grep $REMOTE
aimux new --remote $REMOTE --profile powershell --name chk
aimux send-keys "$REMOTE/chk" -- "Write-Output ((Get-Item '$BASE\resources\app.asar').Length)" Enter
sleep 3 && aimux capture "$REMOTE/chk" --lines 6
# 6. 截图 → 下载 → 裁剪 → 看
aimux send-keys "$REMOTE/chk" -- 'powershell -ExecutionPolicy Bypass -File C:\tmp\new-asar\screenshot.ps1' Enter
sleep 6
aimux get_files $REMOTE /tmp/host-screen 'C:\tmp\new-asar\screen.png'
cd /tmp/host-screen && ffmpeg -y -loglevel error -i screen.png -filter "crop=380:130:3460:0,scale=1140:390" topright.png
# Read topright.png 看效果; 不满意回到步骤 1
9. 收尾
- 任务完成后销毁 aimux 会话:
aimux kill "<remote>/chk"等(exe 多次重启后旧会话已是 zombie,kill 报 not found 属正常)。 - 真机临时文件
C:\tmp\new-asar\*可留(下次迭代复用脚本);app.asar.orig务必保留。 - 壳改动入 git(
mobius/desktop/electron/**被跟踪;只有release/、node_modules/、desktop-builds/被 gitignore)。
Operate deliberately
Install and manage
Prerequisites and target Profile
Target: Terminal Ui Profile
Delivery: Skill Files — https://raw.githubusercontent.com/nutshellai-tech/mobius/1eb8750d2d9012e1f50a18f7c60c2ad040c04889/skills/mobius-electron-debug/SKILL.md。
Compatibility and access
Mobius Electron desktop client with an aimux Connected Windows machine: Not declared in supplied evidence。
Review compatibility evidence ↗
Risk facts
Stops and restarts the remote Mobius Desktop process and replaces its app.asar file.
Evidence ↗The supplied license permits non-commercial use; commercial use requires a separate license.
Evidence ↗Evidence and editorial reviewManifest, Bundle patch, distribution and freshness
Immutable evidence
Review status and source activity
Approved for publication after reviewing the source-linked content and immutable release record. AI assisted with the draft; the publication decision was human.
Human reviewed Sep 4, 2026, 11:38 AM UTC。GitHub facts last checked Sep 3, 2026, 3:47 PM UTC。
No material source change has been recorded since this evidence baseline.