refactor(plugins): 按「内置插件判定标准」收敛内置清单 16 → 11

## 判定标准(写进 all.go 与 ARCHITECTURE)

**只有必须使用内部 SDK 能力(公开 SDK 没有的接口面)的插件,才留在
编译期内置清单**;其余一律外置为 .hmap 插件,独立编译、独立发版。

依据是 internal/plugin/proc/capability.go 的 withheldCapabilities:
内部 SDK 的 TerminalAPI/TrackerAPI/StatusAPI/SupervisorAPI/AdapterAPI/
SelftestAPI/ToolAPI/Publish 等能力面,外部插件在类型层就不存在。
需要它们的插件外置后功能会**静默消失**(不报错),必须内置;
只要公开能力的插件,留在内核里是白付重编成本。

## 内置 11 个(all.go 单一权威清单)

  cli webui       TerminalAPI/Tracker/Status/Supervisor/Adapter
  agentcli        EventPublish(终端输出走 Publish,公开 SDK 无此方法)
  healthcheck     SelftestAPI
  pluginmgr       failback 恢复链必需
  seq             ToolAPI
  remotedevice    RegisterChannel
  clawhubadapter  InjectInputSync
  cfgmgr skillmgr seemedia(保留)

## 外置 8 个(源码保留,.hmap 由 SDK 仓 example/ 提供)

  timer(此前)ai_image files cmd kbtree localuse mcp multimodal

## 同步修正

- kbtree 归位:它一直是编译期内置插件,却长期被 main.go 单独导入,
  游离在 all.go 清单之外(文档盘点因此数错)。现移入 all.go,
  main.go 不再单独导入任何插件,并加注释禁止该做法。
- integration_test:外置插件的 7 个用例(cmd_run/terminal_*)加
  requireExternalTool 跳过保护——用例保留(行为判据仍有价值),
  在纯内置装配下 Skip,不造假失败。
- 全部文档同步 11 个的清单与判定标准(中英四份 + 两份 README)。

## 已核实不做的事

- 保留的 11 个内置插件无一在代码里硬依赖被外置的插件:
  cli 对 terminal_* 是 ExecuteTool 按名动态调用(运行时依赖);
  healthcheck/seq 只在白名单与示例文本里出现;webui 只订阅事件。
- kernelmod/(内核模块)与 plugins/(插件)严格区分:
  kernelmod/multimodal 是内核装配模块,与外置的 multimodal 插件无关。

验证:go build ./... 全绿;go test ./internal/plugins/... 全绿;
webui 新增 5 条命令历史渲染回归判据(TestCmdHistory*)全绿。
This commit is contained in:
root
2026-10-19 21:13:23 +08:00
parent 515cf2deb1
commit 835688c94a
11 changed files with 442 additions and 74 deletions

View File

@ -318,7 +318,7 @@ VM built-ins: `json.encode` / `json.decode` / `log` / `http_get` / `http_post`.
| Method | Registration Mechanism | Compilation | Usage |
|--------|----------------------|-------------|-------|
| Built-in | `init()` → `RegisterFactory` | `internal/plugins/` compiled into kernel | webui/cli/cmd/mcp etc. (17 total) |
| Built-in | `init()` → `RegisterFactory` | `internal/plugins/` compiled into kernel | webui/cli/agentcli etc. (11 total; see the criteria section below) |
| External subprocess plugin | Handshake + stdio JSON-RPC reverse registration | `hmapdev build` → `plugin.bin` (ordinary Go binary) | qq/browser/files etc. |
| Lua script plugin | Execute `main.lua` to register tools | No compilation, takes effect after restart/reload | luademo etc. |
| SKILL plugin | Parse `SKILL.md` | Markdown definition | Loaded via clawhubadapter |
@ -333,6 +333,53 @@ the old `plugin.Open` path-cache workarounds (SHA256 temp-path copies) retired w
Lua script plugin loading: `internal/plugin/` → the gopher-lua interpreter executes `main.lua` (at load time `sdk.register_*` only buffers handlers), then `Start()` swaps in the real SDK implementation and registers them in batch. The script is read only once at load time; runtime execution happens via callbacks.
### Which Plugins Stay Built-in (criteria, finalized 2026-10-19)
**A plugin stays in the compiled-in list only if it requires internal-SDK-only
capabilities — API surfaces the public SDK does not have.**
The internal SDK (`internal/sdk`) exposes several capability surfaces that are
**never granted to external plugins**: `TerminalAPI` / `TrackerAPI` /
`StatusAPI` / `SupervisorAPI` / `AdapterAPI` / `SelftestAPI` / `ToolAPI`, and
**`Publish` (event publishing)**. External plugins run over the proc bridge's
narrowed capability set where those interfaces simply do not exist at the type
level (authoritative list: `withheldCapabilities` in
`internal/plugin/proc/capability.go`).
This yields a clean binary rule:
- **Plugin needs a withheld capability ⇒ it must stay built-in.** Externalizing
it makes the feature **fail silently** — no error, no crash, just a data link
broken between plugin and kernel. The hardest class of bug to trace.
- **Plugin only uses public SDK ⇒ it should be externalized** (.hmap package).
Independent build and release; a one-line fix no longer means recompiling the
87 MB kernel.
Positive examples (kept built-in, each for a reason it cannot do without):
| Plugin | Internal capability it needs |
|---|---|
| cli / webui | TerminalAPI (the /terminal command and terminal panel), TrackerAPI, StatusAPI, SupervisorAPI, AdapterAPI |
| agentcli | **EventPublish**: reports terminal output and lifecycle via `Publish(EventTerminalOutput)`; the public SDK has no Publish |
| healthcheck | SelftestAPI (can build a virtual kernel instance for self-checks) |
| pluginmgr | required by the failback recovery chain (`core.agent.failback_plugins` defaults to webui/pluginmgr/recoverydiag) |
| seq | ToolAPI (direct tool-table access; in-group parallel steps invoke tools by name) |
| remotedevice | RegisterChannel (kernel IO channel registration) |
| clawhubadapter | InjectInputSync (OC-plugin proactive injection) |
Counter-examples (externalized, because public capabilities suffice):
| Plugin | Actual dependencies |
|---|---|
| timer | RegisterTool + Settings + InjectText (public) |
| ai_image / files / cmd / kbtree / localuse / mcp / multimodal | RegisterTool + Settings (+ public APIs such as s.Knowledge()) |
> ⚠️ Both copies existing at once is forbidden: `loadOne` checks the built-in
> factory table first and never looks at the external `plugin.bin` if it hits
> ⇒ the built-in version always wins and the external one **installs but never
> takes effect**. When externalizing a plugin, remove it from
> `internal/plugins/all.go` (the single authoritative list) in the same change.
### Built-in vs External Plugins
| Dimension | Built-in Plugin | External Plugin |
@ -594,19 +641,24 @@ internal/
│ ├── registry.go — Registry + lifecycle
│ ├── dynamic.go — Load-channel dispatch (proc / lua / skill); .so only remains to error loudly
│ └── manifest.go — plugin.json metadata
├── plugins/ — Built-in plugin implementations
│ ├── all.go — Blank imports
├── plugins/ — Built-in plugin implementations (11; see "Which Plugins Stay Built-in")
│ ├── all.go — Blank imports (**the single authoritative list**; edit only this)
│ ├── webui/ — HTTP server + embedded SPA
│ ├── cli/ — Unix socket CLI
│ ├── cmd/ — Command execution
│ ├── mcp/ — MCP protocol
│ ├── files/ — File operations
│ ├── clawhubadapter/ — ClawHub adapter (OC plugin/SKILL/JS/Python sidecar)
│ ├── agentcli/ — PTY terminal
│ ├── healthcheck/ — Health check
│ ├── pluginmgr/ — Plugin manager
│ ├── skillmgr/ — Skill plugin management
│ └── cfgmgr/ — Config manager
│ ├── cfgmgr/ — Config manager
│ ├── remotedevice/ — Remote device bridge
│ ├── seemedia/ — Direct media view
│ ├── seq/ — Sequence orchestration
│ ├── data/ plugin_data/ — Plugin static assets (non-Go, shipped with the kernel)
│ ├── kbtree/ cmd/ localuse/ mcp/ multimodal/ ai_image/ files/
│ │ — Source remains but **not listed in all.go**: externalized
│ │ on 2026-10-19 as .hmap packages (projects in the SDK repo's
│ │ example/); directories to be removed once external projects stabilize
├── sdk/ — PluginSDK definitions
│ ├── plugin.go — Plugin interface + PluginSDK
│ ├── memory.go — MemoryAPI

View File

@ -100,6 +100,7 @@ Code is in the project root, implemented in Go.
Core functionality is operational. Plugin system and SDK are ready for independent external plugin development.
- Built-in plugins: webui / cli / timer / cmd / mcp / agentcli / healthcheck / pluginmgr / clawhubadapter / files / cfgmgr
- Built-in plugins (11): webui / cli / agentcli / cfgmgr / healthcheck / pluginmgr / clawhubadapter / remotedevice / skillmgr / seemedia / seq
- Criterion: **a plugin stays built-in only if it requires internal-SDK-only capabilities**; everything else ships as an .hmap external plugin (see ARCHITECTURE)
- External plugin examples ([homeagent-sdk](https://github.com/JianFeeeee/homeagentsdk) repo `example/`, both Go and Lua types): qq / files / a2a / ai_image / bili / browser / calendar / editdoc / memo / music / ocr / rss / sanitizer / weather / luademo
- Distribution: `.hmap` plugin package format, installable via WebUI