Skip to content

✨ feat(plugin): 落地可独立开发分发安装运行的开放插件体系 - #1562

Merged
Syngnat merged 7 commits into
devfrom
dev-plugin-ecosystem
Oct 21, 2026
Merged

Syngnat merged 7 commits into
devfrom
dev-plugin-ecosystem

Conversation

@Syngnat

@Syngnat Syngnat commented Oct 21, 2026

Copy link
Copy Markdown
Owner

变更概述

落地一套可供第三方独立开发、分发、安装和运行的插件体系,参考 DSH 的插件机制:公开契约、扩展点、权限与生命周期、双语言 SDK、示例、管理入口与回归测试齐备,现有驱动与安全策略未改动。

契约与文档

  • docs/plugins/ 新增协议、SDK、权限、生命周期、宿主能力与排障文档,链接全部可解析
  • 协议方法表、SDK 导出与公开类型、权限清单均由契约测试与文档双向校验

运行时

  • 插件在独立子进程运行,崩溃由宿主隔离回收,不拖垮主程序;代次围栏防止旧实例越权
  • 期望启用态与实际运行态分离,支持安全模式(GONAVI_DISABLE_PLUGINS=1)、故障隔离与重试
  • 安装绑定确切字节摘要,替换保留原有启用状态,移除需先禁用

扩展点

  • 命令与面板、独立窗口、Skill 打包、只读数据源适配器、AI 提供方(含流式工具调用)、导出器快照

SDK 与示例

  • sdk/go、sdk/typescript 与 examples/plugins 七个可运行示例

管理入口

  • 桌面工具中心插件面板与市场面板、CLI 九个命令(list/inspect/check/install/replace/enable/disable/remove/invoke)
  • 失败统一映射为具体错误码,不再退化成通用失败

市场

  • 服务端、发布审核、一次性审批令牌与安装摘要校验;市场更新对已安装插件走替换,不再要求先禁用

验证

范围 结果
internal/plugin 通过 101.356s
internal/app -run Plugin|MarketInstall 通过 66.733s
internal/cli -run Plugin 通过 24.224s
internal/pluginmarket / internal/market 通过 3.916s / 38.831s
PostgreSQL 16(Docker postgres:16) internal/market 5 个集成用例真实执行并通过
internal/db / ai/provider / dataexport 的 -run ^TestPlugin 通过 8.974s / 26.135s / 20.259s
sdk/go、examples/plugins(7 包) 通过 3.479s / 全绿
TypeScript SDK 30 文件 / 277 测试通过
前端插件切片 64 文件 / 385 测试通过;tsc --noEmit 干净
npm run build 528 文件 → 4.63 MB
go build ./...、go vet 干净

新增契约测试均做过反向验证:故意改坏实现或文档后测试会失败。

已知限制

  • -race 未在本地执行:本机 CGO_ENABLED=0 且无 C 编译器,需由 CI 的 Linux 作业覆盖
  • 仅构建验证了 Windows amd64,macOS/Linux 产物未生成
  • 插件市场需自行部署 cmd/gonavi-market-server;本地安装不依赖市场
  • 数据源插件为只读设计,不提供写入/事务/流式能力

- 公开契约:新增 JSON-RPC 协议、SDK 导出、权限与生命周期文档,覆盖扩展点入口、公开类型与常量
- 进程隔离:插件在独立子进程运行并受代次围栏约束,崩溃不拖垮主程序,提供故障隔离与安全模式
- 扩展点:命令与面板、独立窗口、Skill 打包、只读数据源适配器、AI 提供方、导出器快照
- 双语言 SDK:Go 与 TypeScript SDK 及七个可运行示例,声明与实际实现双向校验
- 管理入口:桌面工具中心插件面板、市场面板与 CLI 九个命令,替换时保留原有启用状态
- 市场:服务端与发布审核落地,安装绑定确切字节摘要与一次性审批令牌,更新不再要求先手动禁用
- 兼容与安全:现有驱动与安全策略未改动,安装后默认禁用,权限按宿主强制清单逐项校验
- 回归测试:新增协议、SDK、权限、文档链接、失败码映射与换行风格契约测试,均带反向验证
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

变更概览

  • 变更规模:1000 个文件,+72441 / -1485(大型变更)
  • 测试行占比:54%(测试 +37689 / 源码 +32056)
  • 规约扫描覆盖:47%(逐行扫描 34752 / 新增 72441,测试与生成文件只做文件级检查)
  • 规约命中:需要处理 0 · 建议 3

建议

  • frontend/wailsjs/go/app/App.d.ts:frontend/wailsjs 由 Wails 生成,禁止手改。请确认这次变更来自生成命令。
  • frontend/wailsjs/go/app/App.js:frontend/wailsjs 由 Wails 生成,禁止手改。请确认这次变更来自生成命令。
  • frontend/wailsjs/go/models.ts:frontend/wailsjs 由 Wails 生成,禁止手改。请确认这次变更来自生成命令。

模型评审

模型评审本次不可用:groq: 模型接口返回 HTTP 413

CI 门禁

  • CI Gate:成功
    • Frontend clean build:成功
    • Full backend suite:成功
    • Platform-sensitive tests (macos-latest):成功
    • Platform-sensitive tests (windows-latest):成功
    • Plugin and marketplace contract tests:成功

门禁已通过。

规约意见不会代替 CI 门禁。这条评论会在后续推送和测试完成后更新。

# Conflicts:
#	frontend/src/components/Sidebar.locate-toolbar.drop-targets-and-sql-file-progress.test.tsx
#	frontend/src/components/sidebar/commandSearchDestinations.test.tsx
#	frontend/src/utils/resolvedBackground.test.ts
#	shared/i18n/catalog.zip
- 工作流把插件前端用例从四个子目录扩到整个 src/plugins,守卫断言仍指向旧命令
- 断言改为覆盖整个插件树与 i18n key 解析用例,脚本 5 项检查全部通过
activate 先持久化 StateRunning、后设置 inst.ready,List() 从状态文件读到的
running 因此可能早于运行时真正可服务,调用方在这个窗口内立刻 Invoke 或
ReadSkillGeneration 会被判定为 not enabled and running。

在 Linux/macOS 上该窗口稳定命中:golang:1.25 容器内
TestPluginRecoversAfterReplacingFaultedPackage 等用例count=5 全部失败,
本地 Windows 因计时器粒度而掩盖。

改为先在同一把锁内确认实例归属并置 ready,再持久化 running;持久化失败时
回滚 ready,避免把不可服务的代次宣传成可调用。
macOS 作业报 lstat /dev/fd/3: bad file descriptor:/dev/fd 在 darwin 上
不是可枚举目录,扫描期间任一 fd 关闭就让整次读取失败,导致
TestSkillNativeHandleCloseAndRejectedOpenCleanup 与
TestSkillReadHandlesCloseOnRepeatedFailure 直接挂在计数助手上。

改为按 RLIMIT_NOFILE 逐个 F_GETFD 探测存活描述符,不依赖平台描述符目录;
Linux 容器内三例连跑 3 轮通过(before=7 after=7)。
exec.Cmd.Wait 会先关闭父侧管道再返回退出码,读协程必然先看到文件已关闭或
协议流结束,并在与退出工作线程的竞争中把终止原因写成管道诊断。CI 里因此
只看到 "read |0: file already closed",无法判断插件到底为何崩溃。

读协程收尾时给退出工作线程一个有界优先权(processExitGrace),退出码优先;
stdout 关闭但进程仍在跑时仍按管道诊断判失败。新增用例用 crash 夹具锁定
终止原因必须是 exit status 23。
原 500ms 上界在负载较高的 Windows 运行器上会被关闭记账挤爆,而该断言
真正要证明的是「禁用在 2s 查询自然结束前就中断了调用」。放宽到 1s 仍远低于
查询时长,语义不变。
@Syngnat
Syngnat merged commit 8d63e62 into dev Oct 21, 2026
13 checks passed
Syngnat added a commit that referenced this pull request Oct 23, 2026
## 发布目标

- 正式版本:v1.1.5
- 发布来源:dev 当前已合并代码 `a788abe67`(API Route 供应商预设)
- 上一正式版本:v1.1.4

## 本次准备

- 将 Wails 产品版本(`wails.json`)及 npm CLI
包版本(`npm/gonavi-cli/package.json`)对齐到 1.1.5。
- 同步版本契约测试断言,保持正式 tag 与 npm 包版本严格一致。
- 本 PR 收口 v1.1.4 之后 dev 的 145 个已合并提交,不含任何本地未提交工作。
- `main` 当前无 `dev` 之外的新提交,合入为 fast-forward 语义的常规合并。

## 主要变更

**新功能**

- 新增 XXL-JOB 任务调度中心工作台(#1576)
- 落地可独立开发、分发、安装、运行的开放插件体系(#1562),插件入口提级为设置中心顶层入口
- 新增 Cheaper Inference(#1547)、API Route(#1580)AI 供应商预设
- AI 聊天模型菜单改为供应商子菜单并加入推理滑块(#1552)
- Nacos 配置编辑器支持 JSON 解析器(#1548)
- 字体画廊:与选择器一致的单选框布局并支持选中即预览、打开面板即拉取远程目录、下载字体可设为界面/代码字体、推荐名单扩充并默认展开
- Kafka 列表只取元数据,详情按需加载 payload(#1570)

**问题修复**

- 查询编辑器:输入时光标逐步右偏(#1579)、自动补全后重复输入右括号(#1553)、过程定义与批量执行误切库(#1545)
- 数据同步:Oracle 迁移字符长度语义丢失(#1544)
- 驱动代理:超大响应只让当前请求失败,不再终止连接(#1578)
- 消息队列:Kafka 预览截断、详情加载与发布不可用(#1577)
- 数据源:MongoDB SSH 隧道因 channel 不支持 deadline 一直超时(#1555)、Chroma 部分版本 v2 无
databases 列表端点(#1557)
- 表概览:MongoDB / 消息队列 / Redis 回落 `information_schema`、向量库与时序库表名列表路径(#1556
/ #1558 / #1559)
- 数据库加载失败后的重试(#1563);内置 AI 刷新响应丢失导致强制重新登录(#1571)
- Kingbase 维护库报错自助引导、调度作业源探测改为验证关系可解析;XXL-JOB 描述表补全 agent 声明;无 agent
的数据源描述视为合法

**界面与体验**

- 统一顶栏样式联动设置(#1575)、工具栏横向滚动条自动隐藏(#1561)、连接树滚动条悬停显示(#1550)
- 信息面板开关移到状态栏左下角(#1546);只读与可编辑结果集统一双击查看判定(#1543)
- 收窄工作台页签样式作用域,修复设置中心嵌套页签布局

## 验证

- 来源 dev 提交(`a788abe6`)的 Backend Tests 已成功;Dev Build 与 Docker Images
在其上运行中/已通过上一提交。
- 本地 7 组发版合同测试中 5 组共 38
项通过:`validate-npm-cli-package-version`、`legal-release-assets`、`generate-update-latest-manifest`、`generate-release-notes`、`validate-gui-update-manifest`、`download-mirror-config`。
- `cli-release-assets.test.py` 本机固定 2
项失败(`test_checksum_generation_keeps_cli_staging_separate`、`test_release_workflow_bash_blocks_are_syntax_checked`),原因与
v1.1.4 发版时一致:Windows 下子进程输出按 UTF-8 解码失败,与版本号无关,CI 在 Linux 上通过。
- 本次版本号提交 `git diff --check` 通过;`v1.1.4..HEAD`
区间的空白告警均来自既有生成文件(`wailsjs/go/models.ts`、`star-history.yml`、`sdk/typescript/src/index.ts`),非本
PR 引入。

## 发布计划

- 校验并合并到 main 后,在该合并提交创建不可变 v1.1.5 tag。
- 跟踪 Release 与 Publish Draft Release 工作流,验收正式资产、Latest、更新清单及下载镜像。
- 发布结束后将 main 同步回 dev。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant