
以下为本文档的中文说明agent-browser-electron智能体浏览器Electron版是moeru-ai开发的一款技能专门用于通过Chrome DevTools ProtocolCDP检查和调试Electron应用中的渲染器窗口。该技能解决了agent-browser在处理Electron应用时的局限性当多个BrowserWindow实例共享相同URL、窗口懒加载创建、或agent-browser的tab列表输出不完整时该技能提供更可靠的窗口定位方案。其核心思想是使用原始CDP目标发现raw CDP target discovery而非依赖agent-browser的tab列表视图。通过直接访问Chrome DevTools Protocol的/json/list端点获取所有CDP目标的完整清单包括title、url、type和webSocketDebuggerUrl等关键字段。相比agent-browser的简化输出原始CDP数据提供了更精确的窗口到目标的映射关系。该技能提供了完整的工作流程确认应用暴露CDP端口、确保Electron窗口已创建、通过curl检查原始CDP目标、根据URL路径或标题匹配目标窗口、使用agent-browser的稳定标签ID切换和验证。它还列出了常见故障模式及应对方案tab列表遗漏目标时使用原始/json/list窗口未出现时需触发窗口创建路径多个窗口共享相同URL时使用截图和标题区分eval返回空对象时优先使用get url和snapshot等命令。该技能以AIRI stage-tamagotchi应用为具体示例详细展示了从启动调试模式到最终验证窗口内容的完整操作流程。Agent Browser ElectronOverviewInspect Electron renderer windows reliably whenagent-browseralone is not enough to tell which CDP target maps to which visible app window.Prefer raw CDP target discovery over guessing fromtab list, then useagent-browser --cdp port tabstable tab IDs to interact with the renderer target you want.Why Raw CDP DiscoveryUse raw CDP target discovery becauseagent-browseris operating as a convenience layer on top of Chrome DevTools Protocol, and that layer can hide or flatten details that matter in Electron.Raw/json/listis the source of truth for CDP target discovery because it exposes Chromium’s target inventory without extra interpretation. It is not the same thing as Electron’sBrowserWindow.getAllWindows().In Electron, that distinction matters because:multipleBrowserWindowinstances can share the same URLsome windows are created lazily and appear only after an app actiona visible Electron window is inspectable only after its renderer/webContents exists and is exposed as a CDP targetdetached DevTools pages and workers add noiseagent-browser tab listmay show only a subset of targets or present them with reduced metadatasession state insideagent-browsercan keep you attached to a previous renderer unless you reset and verifyIn practice, the higher-leveltab listview is useful for quick browsing, but not reliable enough for window-to-target mapping when:two Electron windows both look likehttp://localhost:5173/#/the title is empty or collapseda chat or settings window exists in CDP but is not obvious in the simplified tab outputUsecurl http://127.0.0.1:port/json/listfirst whenever correct target selection matters. Treatagent-browseras the interaction client after target discovery, not as the only discovery source.If/json/listdoes not contain a window that the user says exists, do not assumeagent-browserhid it. First consider that the window may not have been created yet, may not have loaded a renderer route yet, or may not currently be exposed as a CDP target. Trigger the window from the app UI or Electron main-process action, then enumerate/json/listagain.WorkflowConfirm the app exposes a CDP port.The CDP port is project- and run-command-specific. Do not assume9222,9250, or any other value is universal. If an Electron process is running but no CDP port responds, tell the user to relaunch the app with the project’s remote-debug environment variables or launch flags.For AIRI stage-tamagotchi on POSIX shells:APP_REMOTE_DEBUGtrueAPP_REMOTE_DEBUG_PORT9250pnpmdev:tamagotchiFor Windows PowerShell:$env:APP_REMOTE_DEBUG true$env:APP_REMOTE_DEBUG_PORT 9250pnpm dev:tamagotchiFor Windows Git Bash:APP_REMOTE_DEBUGtrueAPP_REMOTE_DEBUG_PORT9250pnpmdev:tamagotchiAdjust the port to match what the user actually started. If the project uses a different mechanism, inspect its Electron launch code before giving command advice.Ensure the Electron window exists.If the app uses lazy window creation,agent-browsercannot inspect a window that has not been created yet. Open it from the app UI or trigger its Electron-side open handler first.Inspect raw CDP targets instead of trustingagent-browser --cdp port tab.curl-sShttp://127.0.0.1:port/json/listRead these fields:titleurltypewebSocketDebuggerUrlUse/json/versionif you need to confirm the port is a Chromium/Electron CDP endpoint or need the browser-level debugger URL:curl-sShttp://127.0.0.1:port/json/versionMatch the target to the Electron window.Common patterns:Distinct route: chat may behttp://localhost:5173/#/chatwhile the main window ishttp://localhost:5173/#/.Distinct title: Electron window titles may surface in the target list.Duplicate URLs: two windows may both reporthttp://localhost:5173/#/; in that case use screenshots, snapshots, and Electron app knowledge to disambiguate.Hidden noise: worker targets and detached DevTools targets are not your app window.List the targets throughagent-browserand switch with stable tab IDs.agent-browser--cdpporttab agent-browser--cdpporttab t2Do not use positional integers. Ifagent-browser tabprints[t2], switch withtab t2.Verify the target immediately.agent-browser--cdpportget url agent-browser--cdpportget title agent-browser--cdpportsnapshot-iIf stable tab switching is not enough, reset session state and reconnect.agent-browser close--allagent-browser connectwebSocketDebuggerUrlagent-browser get urlIf needed:agent-browser--cdpportscreenshot /tmp/electron-target.png--annotateagent-browser--cdpportconsole agent-browser--cdpporterrorsFast TriageUse this order when the Electron app has multiple windows:curl /json/listFind the renderer page target with the route or title you expectIgnoreworkertargets unless the task is specifically about workersIgnoreDevToolspage targets unless debugging DevTools itselfagent-browser --cdp port tabSwitch with the stable tab ID, for exampleagent-browser --cdp port tab t3agent-browser --cdp port get urlagent-browser --cdp port snapshot -iIf the expected route is missing, trigger the lazy window from the UI and repeat from step 1AIRI ExampleInapps/stage-tamagotchi, some windows are lazy-created. The main window loads/#/; settings loads/#/settings; chat loads/#/chat; BeatSync loads/beat-sync.html.The9250examples below assume the app was started by the person running it with:APP_REMOTE_DEBUGtrueAPP_REMOTE_DEBUG_PORT9250pnpmdev:tamagotchiThat port is not intrinsic to AIRI or Electron. It depends on the current command and environment. Most stage-tamagotchi code lives underapps/stage-tamagotchi; inspect that app’s Electron startup and window code when the port, routes, or remote-debug behavior differ.Relevant files:apps/stage-tamagotchi/src/main/windows/chat/index.tsapps/stage-tamagotchi/src/main/windows/main/index.tsapps/stage-tamagotchi/src/main/libs/electron/window-manager/reusable.tsapps/stage-tamagotchi/src/renderer/components/stage-islands/controls-island/index.vueThat means:chat does not exist in CDP until something callschatWindow()settings and chat can be opened from the main window controlsonce created, raw CDP target discovery will show page targets such ashttp://localhost:5173/#/settingsandhttp://localhost:5173/#/chatthe stable way to inspect a window is to enumerate raw CDP targets, map them toagent-browserstable tab IDs, switch, and verify withget urlExample:curl-sShttp://127.0.0.1:9250/json/list agent-browser--cdp9250tab agent-browser--cdp9250tab t4 agent-browser--cdp9250get url agent-browser--cdp9250snapshot-iIf settings or chat is missing, start from the main window:agent-browser--cdp9250tab t2 agent-browser--cdp9250snapshot-i# Click the main window control that opens the panel or launcher.# In AIRI this is the arrow-up control in the bottom-right controls island.# Re-snapshot after every click because refs are stale after UI changes.agent-browser--cdp9250click[i-solar\\:alt-arrow-up-line-duotone]agent-browser--cdp9250snapshot-iThen open the desired entry from the expanded controls and enumerate again:agent-browser--cdp9250click[i-solar\\:settings-minimalistic-outline]agent-browser--cdp9250click[i-solar\\:chat-line-line-duotone]curl-sShttp://127.0.0.1:9250/json/list agent-browser--cdp9250tabIf the controls island is visible but the accessibility refs or CSS icon click do not expand it, inspect the Vue component as a diagnostic fallback. AIRI currently nests tooltip trigger buttons around icon buttons, so a CDP click can report success while landing on the wrapper instead of the VueCont rolButtonlistener. This fallback is for automation/debugging only; do not use it as evidence that end-user clicking works.agent-browser--cdp9250eval(() { const icon document.querySelector([i-solar\\\\:alt-arrow-up-line-duotone]) let controls icon.__vueParentComponent for (let i 0; i 10; i) controls controls.parent controls.devtoolsRawSetupState.expanded.value true controls.proxy.$nextTick() return controls.devtoolsRawSetupState.expanded.value })()Expected verification for chat:agent-browser --cdp 9250 get urlreturnshttp://localhost:5173/#/chatthe snapshot exposes chat UI controls such as the message textbox or send buttonExpected verification for settings:agent-browser --cdp 9250 get urlreturnshttp://localhost:5173/#/settingsthe snapshot exposes settings navigation or configuration controlsFailure Modesagent-browser tabomits or flattens the target you need: use raw/json/list./json/listand browser-level target discovery both omit the window: the renderer target is not currently exposed. Trigger the window creation/loading path, then enumerate again.connect webSocketDebuggerUrlappears to succeed but later commands still point at another renderer: switch withagent-browser --cdp port tab tN, or runagent-browser close --all, reconnect, and verify withget url.multiple windows share the same URL: use the target title, annotated screenshots, and app code to correlate them.evalreturns{}for object values: preferget url,get title,snapshot -i, or primitive-only eval return values.no chat or settings target appears: the window may not have been created yet, or may exist as an Electron object without an inspectable renderer target.