ghost-him/zerolaunch-rs/dev-verify-cdp

Claude Code and agent skill by ghost-him/zerolaunch-rs

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

在 Windows 下启动 ZeroLaunch-rs dev 实例并用 WebView2 CDP 真实驱动做 UI/行为验证的完整流程:清理残留实例、带调试端口启动、双窗口精确目标定位、真实键鼠驱动、断言选择器、面板接管与 OS 副作用取证、收尾清理。改动了 UI/设置页/面板/搜索链路后需要真机验证时使用。

Install

npx vskill@latest install ghost-him/zerolaunch-rs/dev-verify-cdp

SKILL.md

dev-verify-cdp — dev 实例 + CDP 真实验证

前提:Windows;仓库根目录;已装 Bun 与 Rust 工具链。

适用:.rs / src-ui/ 改动后需要真实驱动验证(禁止用离线 mock 替代真机结论)。前端改动经 vite HMR 实时生效,后端 .rs 改动需等 cargo 增量重编译。


1. 启动 dev 实例

1.1 先清残留(必做)

tauri-plugin-single-instance 会让新实例在旧实例存在时静默退出(exit 0、无窗口、无提示),表现为「启动了但连不上 CDP」。

bash
tasklist | grep -i zerolaunch # 应无输出
taskkill /F /IM zerolaunch-rs.exe # 结束旧实例(先确认不是用户正在用的实例)
netstat -ano | grep LISTENING | grep -E "9222|12345" # 确认端口已释放
1.2 带调试端口启动
bash
WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS="--remote-debugging-port=9222 --remote-allow-origins=*" bun run tauri dev
  • 用支持后台服务的终端工具启动时:就绪条件用端口 9222(或日志 应用启动完成),不要在命令里加 &、也不要给很短的超时,否则会被判为「进程已立即退出」。
  • 就绪 ≠ 可以连接:端口开了之后主窗口 target 可能还没出现;.rs 改动触发自动重建重启期间 target 列表会短暂为空。fetch /json/list 为空时先用 curl 确认端口真实在监听,再重连一次。

2. 目标定位(双窗口)

ZeroLaunch 有两个 WebView2 page target:

窗口URLwindow label
搜索窗口http://localhost:12345/#/main
设置窗口http://localhost:12345/setting_window.htmlsetting_window
bash
curl -s http://127.0.0.1:9222/json/list # 直接看原始 JSON,按 url 字段挑目标
  • 按 URL 精确匹配选 target,不要按 title 子串:"ZeroLaunch" 会先命中 "ZeroLaunch 设置",导致反复连到设置窗口。(下面的 JS 骨架即按 url 字段筛选,无需 jq 等额外工具。)
  • 两窗口默认都隐藏,操作前先显示:window.__TAURI_INTERNALS__.invoke('plugin:window|show', { label: 'main' })(设置窗把 label 换成 setting_window,之后等约 2s 让异步内容加载完)。

3. CDP 驱动骨架

Runtime.evaluate 查/改 DOM;Input.* 发真实事件。WebSocket 客户端(在 eval 里用 JS):

js
const t = (await (await fetch('http://127.0.0.1:9222/json/list')).json())
.find(x => x.type === 'page' && x.url.includes('#/')) // 设置窗用 'setting_window.html'
const ws = new WebSocket(t.webSocketDebuggerUrl)
await new Promise((res, rej) => { ws.onopen = res; ws.onerror = rej })
let id = 0
const pending = new Map()
ws.onmessage = (e) => { const m = JSON.parse(e.data); if (m.id && pending.has(m.id)) { pending.get(m.id)(m); pending.delete(m.id) } }
const send = (method, params = {}) => new Promise((res) => { const i = ++id; pending.set(i, res); ws.send(JSON.stringify({ id: i, method, params })) })
const evaluate = async (expr) => {
const r = await send('Runtime.evaluate', { expression: expr, awaitPromise: true, returnByValue: true })
if (r.result?.exceptionDetails) throw new Error(JSON.stringify(r.result.exceptionDetails))
return r.result?.result?.value
}

驱动原语:

js
// 真实按键(Tab 需要 virtualKeyCode=9;modifiers: Alt=1 Ctrl=2 Meta=4 Shift=8)
const key = (k, code, vk, modifiers = 0) => send('Input.dispatchKeyEvent', { type: 'rawKeyDown', key: k, code, windowsVirtualKeyCode: vk, modifiers })
.then(() => send('Input.dispatchKeyEvent', { type: 'keyUp', key: k, code, windowsVirtualKeyCode: vk, modifiers }))
// Enter=13, Escape=27, Ctrl+A = key('a','KeyA',65,2)
await send('Input.insertText', { text: '查询内容' }) // 真实插入字符
await send('Input.dispatchMouseEvent', { type: 'mousePressed', x, y, button: 'left', clickCount: 1 })
await send('Input.dispatchMouseEvent', { type: 'mouseReleased', x, y, button: 'left', clickCount: 1 })

必守三条:

  1. 换查询前 Ctrl+A 再 `insertText`:否则新旧文本拼接,形态/关键词判定会失败。
  2. naive-ui 组件必须真实鼠标事件(取 getBoundingClientRect() 中心):element.click() 对下拉/开关无效;下拉选项展开后才存在于 .n-base-select-option。
  3. 进插件面板(第三方面板 / Shadow DOM)前开焦点仿真:send('Emulation.setFocusEmulationEnabled', { enabled: true });否则 focus() 不落地、键盘事件打到 DIV 上,面板键盘处理永不触发。
  4. Runtime.evaluate 返回 {} 或空而期望字符串,通常是 IPC 调用静默失败:打印完整响应(含 exceptionDetails)重试一次,不要当作「行为没发生」。

4. 断言选择器

目标选择器
结果条数.result-item(面板接管时应为 0)
结果标题 / 选中态.item-title / .result-item.selected
搜索框值与容器.search-bar-wrapper input
Footer.footer
插件面板宿主.plugin-panel-host(沉浸式另有 --immersive 修饰类)
智能目标(路径/网址)面板.smart-target-panel / .st-title / .st-subtitle / .st-actions button
计算器面板.calculator-panel
naive-ui 下拉选项.n-base-select-option(展开后)
设置页子页签textContent.trim() === '<页签名>' 的 SPAN.n-tabs-tab__label 叶元素(.n-tab 不可靠)
错误通知.n-notification / .n-message

5. 验证配方

5.1 搜索窗口唤出 / 主页 / 清空
  • OS 全局热键(如 Alt+Space)CDP 打不到。后端 show_window 事件(bootstrap.rs 的 show 回调与托盘双击同契约)可从页内发射,足以驱动前端 onShowWindow 全部逻辑:

``js await evaluate(window.__TAURI_INTERNALS__.invoke('plugin:event|emit', { event: 'show_window', payload: {} })) ``

  • 清空输入框不能用合成 Backspace(WebView2 实测不触发删除)。用原生 setter + input 事件驱动 Vue v-model(走真实 doQuery('') 路径):

``js const input = document.querySelector('.search-bar-wrapper input') Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set.call(input, '') input.dispatchEvent(new Event('input', { bubbles: true })) ``

5.2 面板接管类特性 + OS 副作用

面板内按 Enter/点动作执行成功后窗口会被隐藏:下一次输入前必须重新 plugin:window|show。

  • 资源管理器取证(只读,绝不要 `.Quit()`——Win11 单进程多标签,关一个会连带关掉用户其它窗口):

``powershell (New-Object -ComObject Shell.Application).Windows() | ForEach-Object { $_.LocationURL } ``

  • 浏览器导航取证:只看进程存在不可靠,用窗口标题判断是否真的导航(打开可辨识 URL,如 https://example.com → 标题变 Example Domain):

``powershell Get-Process msedge,chrome,vivaldi -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowTitle } | Select-Object ProcessName,MainWindowTitle ``

  • 裸域名不导航(实测):ShellExecuteW(open, "example.com") 返回成功但浏览器不导航;https://example.com 正常。此类特性必须标题法验证,不能凭返回值判定成功。
5.3 实时切换配置与启停(不经设置页 UI)

直接调宿主 IPC(与设置页同一命令),可顺带验证 config-changed → 前端刷新链路:

js
const s = await evaluate(`window.__TAURI_INTERNALS__.invoke('config_get_settings', { componentId: 'window-behavior-config' })`)
await evaluate(`window.__TAURI_INTERNALS__.invoke('config_apply_settings', { componentId: 'window-behavior-config', settings: ${JSON.stringify({ ...s, is_show_home_on_empty_query: true })} })`)
await evaluate(`window.__TAURI_INTERNALS__.invoke('config_set_enabled', { componentId, enabled })`)
await evaluate(`window.__TAURI_INTERNALS__.invoke('plugin_set_enabled', { pluginId, enabled })`)

6. 收尾清理

bash
# 1) 停后台服务/进程
# 2) 看残留
tasklist | grep -iE "zerolaunch|vite"
# 3) 精确杀:app 按镜像名(安全);vite(node) 按 PID
taskkill /F /IM zerolaunch-rs.exe
L=$(netstat -ano | grep LISTENING | grep ":12345" | awk '{print $5}' | head -1); [ -n "$L" ] && taskkill /F /PID "$L"
# 4) 校验:无进程 + 9222/12345 无 LISTEN

两条禁令:

  • 禁止 taskkill /IM bun.exe|node.exe:当前会话自身的 JS 运行时与工具链就是 bun/node 进程,按镜像名杀会连带打断本会话(含 eval 内核)。只按 PID 杀已确认归属的进程。
  • 禁止 MSYS 下写 taskkill //F //IM ...:转义后报「无效参数」,用 /F /IM。

另注:停掉后台服务后子进程可能仍在运行(app / 插件 / vite),必须再按上面第 2–4 步确认一次,不要留实例给用户自己关。若用户正在使用该实例,则保留并在汇报里说明。


7. 其他已知陷阱

  • 配置位置:标准模式 %USERPROFILE%\.ZeroLaunch-rs\config\zerolaunch_config.json(便携模式改为可执行文件同目录)。%APPDATA%\ZeroLaunch-rs\zerolaunch_config.json 可能是旧版拆分键名的残留,当前版本不加载它,别被误导;组件键名用 *-config 形式(如 general-config、appearance-config)。
  • msys 路径:Git Bash 下 CARGO_TARGET_DIR=/c/... 会被拼成 C:\c\...;隔离构建目录时用完整 Windows 路径。
  • naive-ui tabs 布局:.n-tab-pane 直接挂在 .n-tabs 下(无 .n-tabs-pane-wrapper 中间层);组件级 overflow: hidden 与外层同特异性规则冲突时按源顺序覆盖,内层滚动会失效——修复靠提高特异性 + flex: 1; min-height: 0。
  • 截图目视复核:Page.captureScreenshot 落盘后自行查看;注意 msys 路径写法。
  • 日志:宿主 %USERPROFILE%\.ZeroLaunch-rs\logs\;判定错误时 grep ERROR|panic。

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
572
Repository forks
30
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/ghost-him/zerolaunch-rs/dev-verify-cdp/badge)](https://verified-skill.com/skills/ghost-him/zerolaunch-rs/dev-verify-cdp)

Something wrong with this skill or its page? Tell us.