DBX 插件开发宿主dev-host深度解析无需启动桌面端即可调试插件工作台与 Rust/Go Sidecar【免费下载链接】dbx15MB轻量级跨平台数据库客户端、数据库管理工具。支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server 等。15MB, lightweight, cross-platform database client. Supports MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, SQL Server and more.项目地址: https://gitcode.com/t8y2/dbx导读本文以 DBX 开源仓库中 dev-host 运行时文档 为核心骨架深入讲解dbx-plugin dev背后通用浏览器开发宿主的工作原理、配置方式与安全边界。读者将掌握如何用一条命令拉起不依赖 DBX 桌面应用的插件调试环境、如何通过dbx-plugin.toml声明 UI 构建与后端 Sidecar、如何理解工作台/连接的生命周期与安全隔离模型以及如何使用 Agent 诊断 API 在浏览器外采集运行时日志。一、什么是 dev-host为插件开发而生的浏览器运行时plugins/sdk/dev-host是 DBX 仓库中的插件开发运行时Plugin development runtime。它是一个通用的浏览器开发宿主专门服务于dbx-plugin dev命令加载插件声明的 workbench工作台、运行可选的 Rust/Go Sidecar而不启动 DBX 桌面应用程序本体。dbx-plugin dev --path /path/to/plugin --port 5190运行环境要求Node.js 22npm 包在 package.json 中通过engines: { node: 22 }声明纯前端插件frontend-only不需要 Rust 或 Go 环境直接由宿主加载沙箱 UI原生插件需要自带编译器和对应语言依赖Rust 需要 cargoGo 需要 go 工具链npm 分发的 CLI 已经内置了本运行时与预构建 UI使用者无需自行安装 Vite、Vue也无需从源码构建开发外壳——只有当你需要开发 dev-host 本身时才需要走从源码构建路线。从源码结构看dev-host 目录 由三部分构成模块文件职责运行时入口runtime.mjs构建/监听进程管理、信号清理、运行时启动HTTP/SSE 服务server.mjs会话管理、声明式生命周期、工作台路由Sidecar 进程sidecar.mjsJSONL/framed 编解码、并发请求关联、事件、超时与进程清理数据与资源connections.mjs、assets.mjs类型化绑定、原子化配置写入、受限资源访问前端外壳ui/Vue 3沙箱 API、连接表单、标签页、主题、重载控件UI 部分使用 Vue 3 Vite Tailwind 4 daisyUI 构建并通过vite-plugin-singlefile打包为单文件产物见 package.json。二、从源码构建与运行 dev-host在 DBX 仓库检出中构建 dev-host 的命令序列如下npm ci --prefix plugins/sdk/dev-host npm run build --prefix plugins/sdk/dev-host cargo run --manifest-path plugins/sdk/cli/Cargo.toml -- dev --path /path/to/plugin其中npm ci依据锁文件安装 dev-host 的前端构建依赖npm run build将 Vue 外壳打包为dist/runtime.mjs单文件产物cargo run启动 Rust CLI 并执行dev子命令。环境变量覆盖运行时与 Node 解释器Rust CLI 默认会在其源码检出目录的相对位置查找dist/runtime.mjs。从 dev.rs 的实现可以看到let runtime std::env::var_os(DBX_PLUGIN_DEV_RUNTIME) .map(PathBuf::from) .unwrap_or_else(|| Path::new(env!(CARGO_MANIFEST_DIR)).join(../dev-host/dist/runtime.mjs));两个关键环境变量DBX_PLUGIN_DEV_RUNTIME指向已构建的运行时入口dist/runtime.mjs。独立发布的原生 CLI 必须显式设置它DBX_PLUGIN_NODE选择 Node 可执行文件默认取node。npm 分发的 launcher 会自动为两者提供路径因此普通用户无需关心。此外CLI 启动时还会校验 Node 大版本号必须 22见 dev.rs不满足会直接报错退出。三、项目配置manifest.json 与 dbx-plugin.tomldev子命令启动时会读取插件的两份配置文件manifest.json声明插件 ID、名称、入口点UI 根目录与入口文件、后端入口、贡献connection-provider / workbench、权限、本地化信息dbx-plugin.tomlschema_version、[backend]与[dev]配置。从 dev.rs 的build_config逻辑可以看到配置校验流程schema_version必须为 1否则报 Unsupported project configuration versionmanifest.json必须包含entrypoints.ui.entrydev requires a UI entrypoint且 UI entry 必须位于声明的 root 之下dbx-plugin.toml中的[dev]命令数组必须以非空可执行文件开头空字符串会被拒绝若 manifest 声明了 backend则dbx-plugin.toml必须提供对应的[backend]配置反之亦然。[backend] 元数据选择 Rust 或 Go Sidecar[backend] language rust # 或 go directory backend binary my_pluginRustCLI 会以--target-dir指向缓存调试目标目录默认data-dir/rust-target执行cargo build --manifest-path ...若存在Cargo.lock则追加--locked。仅当依赖中没有显式指定git/path来源的 SDK 时才会注入 crates.io 的dbx-plugin-sdkpatch显式 Git/path 依赖不会被替换Go要求backend/go.mod存在以go build -trimpath -o data-dir/bin/binary .编译到缓存输出目录若传入 SDK 根目录运行时会在私有数据目录内物化goWorkspace工作区文件。从 Rust 模板的 Cargo.toml 可以看到官方模板对产物体积与可诊断性的取舍profile.release开启strip true、lto true、codegen-units 1同时保持panic unwind以便 Sidecar 协议能把 panic 作为错误上报。[dev] 可选 UI 命令[dev] ui_build [npm, run, build] ui_watch [npm, run, build:watch]规则要点命令是可执行文件/参数数组在插件目录下不带 shell直接执行不做框架检测也不会自动安装依赖npm ci需要开发者自行执行不配置时dev-host 直接加载并监听已有的 UI 静态产物manifest 或运行时本身的改动需要重启dev才能生效。DBX_UI_BUILD_SUCCESSUI 热更新的唯一信号当配置了ui_watch时构建进程的stdout 必须在每次完整成功写出构建产物后单独输出一行DBX_UI_BUILD_SUCCESS。只有这行信号会触发自动 UI 重载部分输出、构建失败不会触发重载应把信号挂到构建工具的成功完成钩子上而不是无条件退出钩子该协议与前端框架无关——Vite、esbuild、webpack、Rollup 皆适用未配置ui_watch时静态 UI 文件走的是防抖debounced输出监听逻辑。四、dev 命令参数与默认值从 dev.rs 的参数解析实现可以确认全部默认值参数默认值说明--path当前目录.插件项目根目录会被canonical_directory规范化为绝对路径--port5190监听端口被占用时自动回退到可用端口显式传0表示申请任意可用端口--data-dirproject/.dbx-dev/开发数据目录连接配置、设置、缓存打包约束dbx-plugin package会拒绝包含.dbx-dev的输入包括嵌套目录。自定义数据目录必须位于包 include 路径之外位于 UI 资源根目录之外server.mjs 会在启动时检查数据目录不能位于 UI 资源根目录内部或子目录中被排除出版本控制加入.gitignore。五、工作台与连接无需真实数据库的调试体验工作台可独立于连接打开Workbench 贡献可以在没有任何连接的情况下直接打开包括纯前端插件。连接提供者connection-provider会根据 manifest 中声明的字段、默认值、选项和绑定binding自动生成表单。从模板的 manifest.json 可以看到一个典型连接提供者声明display_name绑定name、host绑定host、port绑定port并声明capabilities: [test, connect, disconnect]。端口 0 在框架层是合法值connections.mjs 中端口校验范围为 0–65535插件自行校验自己的连接语义。图标回退链工作台条目、标签页和连接行显示其贡献的icon缺失时回退到插件级icon图标路径是相对插件项目的路径不是相对 UI 根目录远程 URL 和逃逸出项目目录的路径会被拒绝缺失或不可读的图标保留通用宿主图标自定义连接图标会保留独立的连接状态圆点。生命周期与标签页行为连接测试、连接、断开连接均走标准生命周期方法自定义 RPC 方法与结果原样转发不做业务语义解释工作台标签页以贡献 可选连接 ID为键切换标签页时保留其 iframe再次打开时复用已有标签页关闭某连接的最后一个标签页时会在确认后断开该连接生命周期回复中success: false一律视为失败与真实宿主一致——对应 server.mjs 的ensureSucceeded检查浏览器页面拥有独立的工作台所有权页面的事件流断开后其 frame 保留30 秒重连宽限期超时后移除仍被其他页面使用的连接保持打开。已保存的连接配置不受影响manifest 的本地化仅由外壳shell执行bootstrap 返回的是未经修改的原始 Manifest。导入连接配置JSON 文件选择器{ connections: [ { providerId: example.connection, values: { display_name: Example, host: localhost, port: 0 }, readOnly: false } ] }字段名来自插件 manifest而非运行时validateRecord 会校验字段必须存在于提供者声明中、类型正确、选项值合法导入的记录会获得新的 IDdev-host没有内置协议预设、文件系统 RPC 或插件专属适配器。六、支持边界Supported boundarydev-host 刻意实现了宿主能力的子集保证开发体验与真实宿主一致的同时不越界Host API 1.0 子集ready、context、locale、theme、request、invoke、notify、onInit、onContext、onEvent、onBinary、sendBinary、资源读取readAssetUrl与openWorkbench后端传输默认stdio-jsonl显式stdio-framed协议版本 1。初始化时校验插件身份与版本server.mjs 会拒绝不支持的传输方式或协议版本二进制通道要求 framed 传输权限事件、二进制、工作台导航权限都会强制校验requirePermission未实现的方法如host.openFilesystem返回错误不模拟原生连接动作、查询结果贡献与 DBX 组件套件消息体积上限JSON bridge 参数2 MiB、UI 二进制消息8 MiB、Sidecar JSON8 MiB、Sidecar 二进制64 MiB对应 server.mjs 中的BRIDGE_LIMIT与UI_BINARY_LIMIT显式 bridge 超时被钳制在1–120000 ms与宿主基线一致UI 资源必须内联或经readAssetUrl加载相对模块 URL不能替代声明的资源桥iframe 使用sandboxallow-scripts、严格 CSP 与纯数据上下文快照开发运行时不启用直连网络。重建语义宁可失败也不丢数据UI 重建通过显式重载应用以保护草稿后端重建会断开会话失败不会回退到旧二进制超时不代表写入被取消请求永远不会自动重放后端重启后需要重连必要时刷新插件页面。七、数据与隔离自动重载、语言切换与调试面板自动重载默认关闭且对连接到本服务器的所有浏览器生效开启即确认可能丢失草稿稳定的 UI 输出变化会重载所有打开的插件 frame编译型 UI 仍需[dev].ui_watch配置的后端目录内.rs/.go文件与 Cargo/Go 模块文件变化触发防抖、串行化的重建/重启生成的target、.dbx-dev、vendor、node_modules目录被忽略已保存的连接会持久化但后端重启后需要重连构建失败时后端保持停止写入不重放关闭该选项会取消待执行的工作不会中断已开始的构建重启 dev 服务器后选项重置为关闭本质是重载/重启不是保留状态的 HMR。语言切换按钮调试按钮左侧在zh-CN与en之间切换开发外壳与插件 locale外壳控件、对话框、诊断标签和 manifest 本地化贡献同步更新已保存的连接名称与 RPC 数据不翻译有活动页面时先确认可能丢失草稿然后自动重载该页面取消则语言保持不变其他打开的 frame 收到标准env消息新页面使用所选 locale插件内容必须自带翻译dev-host 不负责。调试按钮重载页面右侧底部日志面板打开底部面板提供最新500 条环形缓冲日志Ring Buffer级别过滤、本地视图清空、自动滚动日志同时以[dbx-dev]前缀打印到终端覆盖监听端口、项目/UI/后端路径、HTTP 路由/状态码、RPC ID/方法/耗时、可展开的 JSON 参数/结果、结构化错误数据、事件、会话拒绝原因。脱敏规则关键安全设计密码/令牌/凭据字段与 manifest 声明的 secret 字段递归脱敏二进制/base64 内容省略大值/深值截断普通业务值保持可见——务必只使用开发数据原始后端错误消息不进入日志历史仅存于内存重启即清空。网络与访问边界服务器只监听127.0.0.1校验 Host、Origin、浏览器会话、CSRF、资源穿越与符号链接边界路由消息前校验 frame 来源与 generation旧文档的响应无法解决新请求。凭据的明文存储警示开发配置含凭据以明文存储在.dbx-dev/connections.json目录/文件权限在支持平台上为0700/0600凭据被排除在列表摘要与 iframe 上下文之外诊断按上述规则脱敏敏感字段显式编辑时表单值仅返回给本地开发外壳Sidecar 的 stderr 被消费而不转发到日志——因为任意插件可能输出凭据。⚠️重要边界dev-host不是操作系统沙箱——Sidecar 以当前用户权限运行它不读取 DBX 配置文件不模拟 Keychain、签名、安装、生产生命周期保证或桌面标签页恢复。这些能力必须在真实宿主中验证。八、Agent 诊断 API无 Cookie 的浏览器外日志读取本地 Agent或任何本机程序无需浏览器 Cookie 即可读取与面板同源的脱敏内存诊断日志curl -sS \ http://127.0.0.1:5190/api/diagnostics?after0limit100要点仅支持GET端口使用dev实际打印的端口无需自定义头或浏览器会话URL 可直接在浏览器打开Host/Origin 校验仍然启用且不授予 CORS 访问权。查询参数参数说明默认after排他式数字条目 ID上一响应的nextAfter0limit1–500100leveldebug/info/error精确匹配全部instanceId来自上一响应用于检测服务器实例变化无响应字段entries、nextAfter、hasMore、instanceId、reset、truncated、oldestId、latestId、plugin、backendState、port。轮询约定下一次轮询传递nextAfter与instanceId保持相同过滤器hasMore true时立即抓下一页否则以适度间隔轮询例如每秒一次reset表示服务器实例已变化或游标超出当前历史——响应已从可用历史开始truncated表示旧条目从 500 条环形缓冲中被丢弃切换过滤器应重新开始新游标轮询不会产生诊断条目历史不持久化该端点不能调用插件操作。九、架构地图与测试验证dev-host 的架构模块与对应文件均位于仓库内cli/src/dev.rs兄弟 crateCLI 参数、配置校验、构建规范与运行时定位runtime.mjs构建/监听进程、信号清理与运行时启动server.mjsHTTP/SSE 会话、声明式生命周期与工作台路由sidecar.mjsJSONL/framed 编解码、并发请求关联、事件、超时与进程清理connections.mjs、assets.mjs类型化绑定、原子化配置写入与受限资源访问browser-bridge.mjs 与ui/沙箱 API、表单、标签页、主题与重载控件。运行测试npm test --prefix plugins/sdk/dev-host cargo test --locked --manifest-path plugins/sdk/cli/Cargo.toml npm test --prefix packages/plugin-cli DBX_PLUGIN_CLI_VERIFY_NATIVE1 node scripts/verify-plugin-cli-package.mjsdev-host/tests 覆盖 auto-reload、browser-bridge、diagnostics、i18n、process-tree、runtime、server、sidecar 等模块运行时单元测试使用与插件无关的 echo-sidecar.mjs 作为回显进程包验证器会把 CLI 打包并安装到临时目录演练官方 frontend/Rust/Go 模板并启动其开发运行时且不依赖源码树中的运行时DBX_PLUGIN_CLI_VERIFY_NATIVE1第三方插件只是外部验收样本不是生产运行时依赖。如上图所示dev-host 的外壳围绕连接管理 工作台标签页 调试/重载控制组织左侧边栏承载连接的新增/编辑/删除与导入导出中央区域是沙箱化的工作台页面右上角依次是重建后端 / 重载页面 / 语言切换 / 调试面板 / 自动重载开关配合右下角的调试面板即可完成完整的插件联调闭环。十、最佳实践小结纯前端插件无需安装 Rust/Go 工具链dbx-plugin dev直接可用原生插件先把依赖cargo / go装好再首次启动触发缓存构建UI 构建优先在构建工具的成功钩子中输出独立行DBX_UI_BUILD_SUCCESS让ui_watch可靠触发自动重载不要把它挂在无条件退出钩子上开发数据目录默认.dbx-dev/会被打包器拒绝自定义目录务必放在包 include 与 UI 资源根之外并加入版本控制忽略敏感信息以明文存于.dbx-dev/connections.json务必只用开发数据日志与诊断已做递归脱敏但普通业务值可见Agent 自动化可通过/api/diagnostics端点轮询脱敏日志配合nextAfterinstanceId游标协议实现无浏览器会话的观测生产行为验证签名、安装、Keychain、桌面标签恢复等必须在真实 DBX 宿主中进行——dev-host 只覆盖 Host API 1.0 子集未模拟的能力会返回错误或缺失。【免费下载链接】dbx15MB轻量级跨平台数据库客户端、数据库管理工具。支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server 等。15MB, lightweight, cross-platform database client. Supports MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, SQL Server and more.项目地址: https://gitcode.com/t8y2/dbx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考