bunwv
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesebunwv
bunwv
Headless browser automation using a persistent WebView session. The daemon keeps a single WebView instance alive so page state (DOM, modals, forms, SPA routes, scroll position) persists across commands.
基于持久化WebView会话的无头浏览器自动化工具。守护进程会维持单个WebView实例的存活状态,因此页面状态(DOM、模态框、表单、SPA路由、滚动位置)可在多个命令间保持。
Commands
命令
Run all commands with (installed globally via ).
bunwv <command>bun install -g @naticha/bunwvAll commands accept to target a named session (default: "default").
--session <name>bunwv start [--width N] [--height N] [--data-store PATH] [--idle-timeout ms]
[--backend webkit|chrome] [--chrome-path PATH]
bunwv navigate <url>
bunwv click <selector> | <x> <y>
bunwv click-text <text> [--tag <selector>]
bunwv type <text>
bunwv press <key> [--mod meta,ctrl,shift]
bunwv clear <selector>
bunwv submit [--form <selector>] [--button <text>]
bunwv scroll <dx> <dy> | <selector>
bunwv screenshot [filename] [--format png|jpeg|webp] [--quality 0-100]
bunwv eval <expression>
bunwv console [--clear] [--since <timestamp>]
bunwv cdp <method> [--params '{}']
bunwv wait-for <selector> [--timeout ms]
bunwv wait-for-gone <selector> [--timeout ms]
bunwv status
bunwv resize <width> <height>
bunwv back
bunwv forward
bunwv reload
bunwv sessions
bunwv stopDefault viewport is 1920x1080 for readable screenshots.
所有命令通过运行(可通过全局安装)。
bunwv <command>bun install -g @naticha/bunwv所有命令均支持参数,用于指定目标命名会话(默认值:"default")。
--session <name>bunwv start [--width N] [--height N] [--data-store PATH] [--idle-timeout ms]
[--backend webkit|chrome] [--chrome-path PATH]
bunwv navigate <url>
bunwv click <selector> | <x> <y>
bunwv click-text <text> [--tag <selector>]
bunwv type <text>
bunwv press <key> [--mod meta,ctrl,shift]
bunwv clear <selector>
bunwv submit [--form <selector>] [--button <text>]
bunwv scroll <dx> <dy> | <selector>
bunwv screenshot [filename] [--format png|jpeg|webp] [--quality 0-100]
bunwv eval <expression>
bunwv console [--clear] [--since <timestamp>]
bunwv cdp <method> [--params '{}']
bunwv wait-for <selector> [--timeout ms]
bunwv wait-for-gone <selector> [--timeout ms]
bunwv status
bunwv resize <width> <height>
bunwv back
bunwv forward
bunwv reload
bunwv sessions
bunwv stop默认视口尺寸为1920x1080,以确保截图清晰可读。
Session Management
会话管理
Sessions are named and isolated. Each session runs its own daemon on a separate Unix socket. The default session is named "default".
bunwv start # starts "default" session
bunwv start --session cmais # starts a separate "cmais" session
bunwv navigate http://localhost:3000 --session cmais
bunwv sessions # list all running sessions
bunwv stop --session cmais # stop a specific sessionAuto-shutdown: Daemons automatically exit after 30 minutes of inactivity. Override with :
--idle-timeoutbunwv start --idle-timeout 3600000 # 1 hour
bunwv start --idle-timeout 0 # never auto-shutdownReuse detection: If you a session that's already running, it reports the existing session's URL so you know its current state:
start$ bunwv start
Reusing existing session "default" (PID: 12345)
URL: http://localhost:3000/dashboardBest practice: Always run at the start of a testing session to check for orphaned daemons from previous conversations. Stop any you don't need.
bunwv sessions会话支持命名与隔离。每个会话会在独立的Unix套接字上运行自己的守护进程。默认会话名称为"default"。
bunwv start # 启动"default"会话
bunwv start --session cmais # 启动独立的"cmais"会话
bunwv navigate http://localhost:3000 --session cmais
bunwv sessions # 列出所有运行中的会话
bunwv stop --session cmais # 停止指定会话自动关闭:守护进程在闲置30分钟后会自动退出。可通过参数覆盖默认设置:
--idle-timeoutbunwv start --idle-timeout 3600000 # 1小时
bunwv start --idle-timeout 0 # 永不自动关闭复用检测:如果尝试启动一个已在运行的会话,工具会返回该会话当前的URL,以便你了解其状态:
$ bunwv start
Reusing existing session "default" (PID: 12345)
URL: http://localhost:3000/dashboard最佳实践:在测试会话开始时,务必运行检查之前操作遗留的孤儿守护进程,并停止不需要的进程。
bunwv sessionsCore Interaction Loop
核心交互流程
Always follow this pattern: look, then act, then look again.
- Start the daemon if not running:
bunwv start - Navigate:
bunwv navigate http://localhost:3000 - Screenshot:
bunwv screenshot /tmp/bunwv-screenshot.png - Read the screenshot with the Read tool to see the page
- Decide what to do (click, type, etc.)
- Act:
bunwv click "button.submit" - Screenshot again to verify the result
- Repeat steps 4-7 as needed
- Stop when done:
bunwv stop
请始终遵循以下模式:查看→操作→再次查看。
- 若守护进程未运行则启动:
bunwv start - 导航至目标页面:
bunwv navigate http://localhost:3000 - 截图:
bunwv screenshot /tmp/bunwv-screenshot.png - 使用读取工具查看截图内容
- 决定下一步操作(点击、输入等)
- 执行操作:
bunwv click "button.submit" - 再次截图以验证操作结果
- 根据需要重复步骤4-7
- 完成后停止会话:
bunwv stop
Clicking Elements by Text
通过文本点击元素
When you don't know the CSS selector, use to click by visible text:
click-textbunwv click-text "Save Changes"
bunwv click-text "Sign In"
bunwv click-text "Delete" --tag "button, a, div"By default searches . Use to widen the search to other elements.
button, a, [role='button'], input[type='submit']--tag当你不知道CSS选择器时,可使用命令通过可见文本点击元素:
click-textbunwv click-text "Save Changes"
bunwv click-text "Sign In"
bunwv click-text "Delete" --tag "button, a, div"默认搜索范围为。可使用参数扩大搜索范围至其他元素。
button, a, [role='button'], input[type='submit']--tagClearing and Editing Input Fields
清除与编辑输入字段
IMPORTANT: Do NOT use Cmd+A / Backspace to clear React inputs — it does not reliably update React state. Use the command instead, which uses the native value setter and dispatches proper React-compatible events:
clearbunwv clear "input[name='email']"
bunwv click "input[name='email']"
bunwv type "new-value@example.com"Always then then when editing existing input values.
clearclicktype重要提示:请勿使用Cmd+A/退格键清除React输入框内容——这种方式无法可靠更新React状态。请改用命令,该命令会使用原生值设置器并触发符合React要求的事件:
clearbunwv clear "input[name='email']"
bunwv click "input[name='email']"
bunwv type "new-value@example.com"编辑已有输入值时,请始终遵循“清除→点击→输入”的步骤。
Waiting for Elements
等待元素加载
Use after actions that trigger page changes (navigation, form submission, modal open):
wait-forbunwv click-text "Save Changes"
bunwv wait-for-gone "[role='dialog']" # wait for modal to close
bunwv screenshot /tmp/bunwv-screenshot.png # then screenshot
bunwv click-text "Edit"
bunwv wait-for "[role='dialog']" # wait for modal to appear
bunwv screenshot /tmp/bunwv-screenshot.pngDefault timeout is 10 seconds. Override with :
--timeoutbunwv wait-for ".results" --timeout 30000在触发页面变化的操作(导航、表单提交、模态框打开)后,使用命令等待元素状态变化:
wait-forbunwv click-text "Save Changes"
bunwv wait-for-gone "[role='dialog']" # 等待模态框关闭
bunwv screenshot /tmp/bunwv-screenshot.png # 然后截图
bunwv click-text "Edit"
bunwv wait-for "[role='dialog']" # 等待模态框出现
bunwv screenshot /tmp/bunwv-screenshot.png默认超时时间为10秒。可通过参数覆盖:
--timeoutbunwv wait-for ".results" --timeout 30000Extracting Page Data
提取页面数据
Use to get text content, check elements, or read form values. Statements (, , , , etc.) are auto-wrapped in an IIFE — no need to manually wrap:
evalconstletvarifbunwv eval "document.title"
bunwv eval "document.querySelector('h1')?.textContent"
bunwv eval "document.querySelectorAll('.error').length"
bunwv eval "const rows = document.querySelectorAll('tr'); return rows.length;"使用命令获取文本内容、检查元素或读取表单值。语句(、、、等)会自动包装在IIFE中——无需手动包装:
evalconstletvarifbunwv eval "document.title"
bunwv eval "document.querySelector('h1')?.textContent"
bunwv eval "document.querySelectorAll('.error').length"
bunwv eval "const rows = document.querySelectorAll('tr'); return rows.length;"Submitting Forms
提交表单
IMPORTANT: Use instead of for form submission. uses JS which produces events — many React forms ignore these. The command uses which properly triggers React form handlers.
submitclick-textclick-text.click()isTrusted: falsesubmitform.requestSubmit()bunwv submit # submit the first form on the page
bunwv submit --button "Save Changes" # submit via a specific button
bunwv submit --form "form.edit-quote" # target a specific form
bunwv submit --form "form" --button "Save" # bothAfter submitting, use to wait for the dialog/form to close, or to wait for a success message:
wait-for-gonewait-forbunwv submit --button "Save Changes"
bunwv wait-for-gone "[role='dialog']"
bunwv screenshot /tmp/bunwv-screenshot.png重要提示:提交表单时请使用命令而非。使用JS的方法,会产生的事件——许多React表单会忽略这类事件。命令使用方法,可正确触发React表单处理程序。
submitclick-textclick-text.click()isTrusted: falsesubmitform.requestSubmit()bunwv submit # 提交页面上的第一个表单
bunwv submit --button "Save Changes" # 通过指定按钮提交表单
bunwv submit --form "form.edit-quote" # 提交指定表单
bunwv submit --form "form" --button "Save" # 同时指定表单和按钮提交后,使用等待对话框/表单关闭,或使用等待成功消息出现:
wait-for-gonewait-forbunwv submit --button "Save Changes"
bunwv wait-for-gone "[role='dialog']"
bunwv screenshot /tmp/bunwv-screenshot.pngFilling Forms
填写表单
Click the input first, then type. Use Tab to move between fields:
bunwv click "input[name='email']"
bunwv type "user@example.com"
bunwv press Tab
bunwv type "password123"
bunwv submit --button "Sign In"For credentials, use environment variables in (Bun auto-loads them). The shell expands in CLI args:
.env$VARbunwv type "$TEST_EMAIL"先点击输入框,再输入内容。使用Tab键在字段间切换:
bunwv click "input[name='email']"
bunwv type "user@example.com"
bunwv press Tab
bunwv type "password123"
bunwv submit --button "Sign In"对于凭据信息,可在文件中使用环境变量(Bun会自动加载)。Shell会在CLI参数中展开:
.env$VARbunwv type "$TEST_EMAIL"Persistent Auth
持久化认证
Use to preserve cookies and localStorage across daemon restarts:
--data-storebunwv start --data-store ./bunwv-sessionLog in once, and future sessions with the same data store stay authenticated. Note: DOM state (open modals, form inputs) only persists within a single daemon session, not across restarts.
使用参数可在守护进程重启后保留Cookie和localStorage:
--data-storebunwv start --data-store ./bunwv-session登录一次后,使用相同数据存储的后续会话会保持已认证状态。注意:DOM状态(打开的模态框、表单输入内容)仅在单个守护进程会话内保持,无法跨重启保留。
Debugging with Console Capture
通过控制台捕获调试
Page console output (, , etc.) is automatically captured. Use this to debug page behavior without writing eval hacks:
console.logconsole.errorbunwv navigate http://localhost:3000
bunwv click "button.submit"
bunwv console # see any errors or logs from the page
bunwv console --clear # read and clear the bufferUse to only see new messages since your last check. The buffer holds 1000 messages.
--since <timestamp>页面控制台输出(、等)会被自动捕获。可使用此功能调试页面行为,无需编写eval代码:
console.logconsole.errorbunwv navigate http://localhost:3000
bunwv click "button.submit"
bunwv console # 查看页面的错误或日志
bunwv console --clear # 读取并清空缓冲区使用参数可仅查看自上次检查以来的新消息。缓冲区最多可存储1000条消息。
--since <timestamp>Screenshot Format Options
截图格式选项
Screenshots default to PNG. Use and for smaller file sizes:
--format--qualitybunwv screenshot --format jpeg --quality 80 # saves /tmp/bunwv-screenshot.jpg
bunwv screenshot --format webp --quality 90 # saves /tmp/bunwv-screenshot.webp
bunwv screenshot output.jpg --format jpeg # custom filename截图默认格式为PNG。可使用和参数减小文件大小:
--format--qualitybunwv screenshot --format jpeg --quality 80 # 保存为/tmp/bunwv-screenshot.jpg
bunwv screenshot --format webp --quality 90 # 保存为/tmp/bunwv-screenshot.webp
bunwv screenshot output.jpg --format jpeg # 自定义文件名Chrome Backend & CDP
Chrome后端与CDP
On macOS, bunwv defaults to WebKit. On Linux/Windows, it automatically uses Chrome. You can override on any platform:
bunwv start --backend chrome # force Chrome on macOS
bunwv start --chrome-path /path/to/chromium # custom Chrome pathWith Chrome, you can make raw DevTools Protocol calls:
bunwv cdp "Page.getLayoutMetrics"
bunwv cdp "Network.enable"
bunwv cdp "Runtime.evaluate" --params '{"expression": "1+1"}'CDP is only available with the Chrome backend — it will error on WebKit.
在macOS上,bunwv默认使用WebKit。在Linux/Windows上,会自动使用Chrome。你可在任意平台上手动指定:
bunwv start --backend chrome # 在macOS上强制使用Chrome
bunwv start --chrome-path /path/to/chromium # 指定自定义Chrome路径使用Chrome时,你可直接调用DevTools Protocol(CDP):
bunwv cdp "Page.getLayoutMetrics"
bunwv cdp "Network.enable"
bunwv cdp "Runtime.evaluate" --params '{"expression": "1+1"}'CDP仅在使用Chrome后端时可用——使用WebKit时会报错。
Error Recovery
错误恢复
If a command fails or times out:
- Take a screenshot to see what the page looks like
- Use to inspect the DOM
eval - If the daemon crashed, start it again (the data store preserves auth)
若命令执行失败或超时:
- 截图查看当前页面状态
- 使用命令检查DOM
eval - 若守护进程崩溃,重新启动它(数据存储会保留认证状态)
Screenshot Default
截图默认设置
Screenshots default to (or / when using ). Use the Read tool to view them. The same path is overwritten each time, keeping the project directory clean.
/tmp/bunwv-screenshot.png.jpg.webp--format截图默认保存路径为(使用参数时会变为或)。可使用读取工具查看截图。每次截图会覆盖同一路径,保持项目目录整洁。
/tmp/bunwv-screenshot.png--format.jpg.webpKnown Limitations
已知限制
- macOS: defaults to WebKit (no dependencies). Linux/Windows: automatically uses Chrome (must be installed). Override with .
--backend - with CSS selector auto-waits for actionability (visible, stable, unobscured) but times out after 10s
click - uses JS
click-text(isTrusted: false) — use it for navigation links and non-form buttons. For form submission, always use.click()instead.submit - is required for React inputs — keyboard-based clearing (Cmd+A, Backspace) doesn't update React's internal state
clear - Coordinate clicks () produce native
click x yevents but require knowing exact coordinates. UseisTrusted: truewithevalto find them when CSS selectors don't work.getBoundingClientRect()
- macOS:默认使用WebKit(无依赖)。Linux/Windows:自动使用Chrome(需预先安装)。可通过参数覆盖。
--backend - 使用CSS选择器的命令会自动等待元素可交互(可见、稳定、未被遮挡),但超时时间为10秒
click - 使用JS的
click-text方法(isTrusted: false)——适用于导航链接和非表单按钮。表单提交请始终使用.click()命令。submit - React输入框必须使用命令——基于键盘的清除方式(Cmd+A、退格键)无法更新React内部状态
clear - 坐标点击()会产生原生
click x y事件,但需要知道精确坐标。当CSS选择器无效时,可使用isTrusted: true结合eval获取坐标。getBoundingClientRect()