全部插件

DSH / BUNDLE / CLIENT-UI

dsh-agent-browser

v0.1.0guanhaisen / dsh-agent-browser0ae65b5492

可安装组合包UI 与客户端插件社区 · Topic 自动分析Web UI

概览

dsh-agent-browser

Agent-driven control of the DSH right-Sidebar browser: read page content, act on it, size the viewport, and take screenshots from model tools (Desktop only)

README / ZH

插件文档

目录摘要

Agent-driven control of the DSH right-Sidebar browser: read page content, act on it, size the viewport, and take screenshots from model tools (Desktop only)

dsh.pub 核对固定版本的组合包契约、运行时事实与分发语义;完整 README 请查看源仓库。

在 GitHub 阅读完整 README

LIMITATIONS

已知限制

- **仅限桌面端**,如上所述。 - **仅限已挂载的 tab。**已打开但尚未挂载的 tab 无法驱动;工具会说明这一点,并请你先点击该 tab 一次。(实际上 tab 一经打开或恢复就会挂载。)设置视口是例外:它会被保存,并在 tab 挂载时应用。 - **打开新 tab 需要该对话的侧边栏已经存在。**对于侧边栏 store 从未被 adopt 的 Session,按 Session 寻址的 open 是静默 no-op,因此在从未显示过右侧边栏的对话里,不带 `tabId` 的 `browser_navigate` 可能以「未创建」失败。先打开该对话的侧边栏一次再重试。导航已有 tab 不受影响。 - **`shortcuts.register` 必须提供 `defaults`。**遗漏它会在 `apply()` 期间抛错,从而让整个 client 半身(含 Inspect provider)失效,且只表现为 `web boot: … did not activate`。本插件提供 `defaults: {}`;`test/apply-check.cjs` 守护这个形状,使该故障无法静默重现。 - **菜单项从标准 slot prop 读取 `sessionId`。**仅当未来的 shell 不再提供它时,才回退到外层的 `[data-sidebar-right-session]`,因此两条路径下控件都可用。 - **tab 菜单是右键菜单,不是“⋯”按钮。**kit 的 tab 栏没有溢出按钮;菜单由 tab 的 `onContextMenu` 处理器打开。自定义尺寸表单刻意**未使用** `Modal`:kit 会在其元素之外的任何 `pointerdown` 时关闭菜单,而 `Modal` 会 portal 到 `document.body`,因此 portal 出来的对话框会在首次点击时自我销毁。该表单改为内联渲染,并拦截指针事件。 - **`jsx(type, props, key)` 的第三个参数是 React key,而非 children。**本插件曾经正是因此出过 bug:把标签文字传到第三个参数,编译通过却渲染出*空白*按钮(线上菜单显示了六行空项)。children 始终应放进 `props.children`。`test/apply-check.cjs` 断言每个菜单项都带有非空标签。 - **一个 `store` handle 只能挂载在一个 slot scope 下。**在注册项上声明 `store` 会让渲染器绑定 `useStore`/`actions`,但同一个 handle 无法挂在两个不同 scope 下 —— 本插件需要把状态同时用于 session scope 的座位(tab 菜单)与 root scope 的座位(设置 → 通用),这样做会抛出 `store handle mounted under … is already mounted under scope …`。因此 store 以普通 prop 传递,组件直接用 `React.useSyncExternalStore` 订阅。快照必须保持引用稳定;`test/apply-check.cjs` 断言组件未声明 `store` handle。 - **无法交付的截图仍会正常作答。**若未挂载 attachment store,或 store 拒绝了该图片(例如截图过大),结果会丢弃字节并在 `note` 中说明原因,而不是让调用失败。 - **每次 guest 调用都受插件自身预算约束。**读取与动作 6 秒,截图 15 秒,每个方法都会做的那次身份探测 1 秒。Electron 的 `executeJavaScript`、`capturePage` 与 `loadURL` 都不接受 abort signal,也没有超时,因此无响应的渲染进程永远不会 settle;与定时器竞速是插件唯一能掌握的界限。裸 await 它们,正是让一个卡死页面每次调用固定花掉 60 秒的原因(Inspect 通道的默认超时)—— 一位 agent 撞上 8 次,等了约 8 分钟。该预算不可配置:client 半身读不到插件配置,所以它是常量而非设置项;外层的 `clientInspectTimeoutMs` 依然生效。 - **`browser_tabs` 整次列举共享一个截止时间。**每个 tab 都需要自己的身份探测,否则一个满是卡死标签的 Session 会按 tab 数各花掉一整份预算 —— 对一个本该用来「便宜地看看开了什么」的问题给出无界答案。每个 tab 只分到剩余时间的公平份额,并设下限以免小列表被饿死。 - **超时并不等于取消。**因为 Electron 无法中止,操作可能在调用报告超时之后仍在后台完成。那条消息说的是插件等了多久,绝不是声称工作已经停止。 - **截图默认使用 Sidebar 栏宽。**`auto` 通常是 400–700 CSS 像素,并非真实设备尺寸。当版面重要时,请传 `preset`(或先用 `browser_viewport` 设好)。 - **截图只含视口** —— 没有整页截图。 - **`ref` 会在页面重新渲染后失效。**过期的 ref 会被拒绝,并提示你重新读取元素;绝不猜测。 - **多窗口。**client Inspect 查询是广播的,第一个有效的页面回答胜出,因此开多个窗口时,回答可能来自另一个窗口。单窗口使用不受影响。 - **文本提取使用 `innerText`** —— 它反映的是渲染结果,因此屏幕外或虚拟化列表的内容可能缺失。需要更多内容时用 `mode: 'html'` 或 `browser_eval`。 - **`active` 需要有屏幕上的 Session。**它来自应用自身的 `sidebarRight.commandTarget()`,后者报告聚焦分栏的 tab 或屏幕上 Session 的活动 tab。对于当前未显示的 Session,它无法作答,此时每个 tab 的 `active` 都退化为“是否已挂载”—— 与未来版本移除该方法时使用的是同一套回退。 - **视口尺寸在构造上仅限桌面端。**预设写入的是 guest 自身的盒子,只有 `<webview>` 载体具备该盒子;Web profile 的 `<iframe>` tab 会报告其已保存的预设,但永远不会被调整尺寸。 - **Inspect 通道的文档定位是只读**,而本插件用它承载写操作(点击、输入、导航)。目前没有任何机制强制这一点,但若未来版本加入该约束,本插件将需要自己的传输层。 - **插件代码改动需要重启。**profile 配置受监视,因此 `config:` 改动会实时重新应用,但 loader 会保留已导入的模块;修改 `index.js` 或 `client.js` 需要下次启动才生效(`client.js` 可通过刷新页面生效)。 - **自动选中 bundle 是安装器的行为,不是保证。**新安装的包若声明了 `dsh.bundle`,会被追加到 `dsh.profile.bundles`,这也是「一条命令就够」的原因。若未来版本不再这样做,请手工把 `"dsh-agent-browser"` 加入 `dsh.profile.bundles` 并重启。 - **应用运行期间,CLI 无法向 profile 安装。**请改用 Plugins 页或 agent 工具,或先完全退出应用。 <a id="install"></a>