mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 17:38:10 +00:00
docs: correct plugindev toolchain usage, Lua execution model, and stale plugin examples
- 工具链:修正 bundle 默认开启(plugindev build 默认多平台合集)、补充 --no-bundle/debug/--target/--outdir/--sdk-path/--replace 用法、Lua 打包内容、安装端点语义 - 新增「执行模型」节:Lua 插件为被动回调模型,无常驻服务能力 - OVERVIEW/ARCHITECTURE:示例列表与 Lua 加载描述修正(internal/plugin gopher-lua,非 internal/lua VM;无热加载)
This commit is contained in:
@ -259,13 +259,13 @@ VM built-ins: `json.encode` / `json.decode` / `log` / `http_get` / `http_post`.
|
|||||||
| Method | Registration Mechanism | Compilation | Usage |
|
| Method | Registration Mechanism | Compilation | Usage |
|
||||||
|--------|----------------------|-------------|-------|
|
|--------|----------------------|-------------|-------|
|
||||||
| Built-in | `init()` → `RegisterFactory` | `internal/plugins/` compiled into kernel | webui/cli/timer/mcp etc. |
|
| Built-in | `init()` → `RegisterFactory` | `internal/plugins/` compiled into kernel | webui/cli/timer/mcp etc. |
|
||||||
| External `.so` | C ABI dynamic loading | `-buildmode=c-shared` + bridge | qq/files/web/memo etc. |
|
| External `.so` | C ABI dynamic loading | `-buildmode=c-shared` + bridge | qq/browser/files etc. |
|
||||||
| Lua script plugin | Parse `main.lua` to register tools | No compilation, hot-reload | luaplugintest/testlua 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 |
|
| SKILL plugin | Parse `SKILL.md` | Markdown definition | Loaded via clawhubadapter |
|
||||||
|
|
||||||
Built-in plugin registration: `internal/plugins/all.go` blank imports → each plugin `init()` → `Registry.Load()` scans directory to match factory.
|
Built-in plugin registration: `internal/plugins/all.go` blank imports → each plugin `init()` → `Registry.Load()` scans directory to match factory.
|
||||||
External plugin loading: `internal/plugin/dynamic.go` → copy to SHA256 temp path (bypass `plugin.Open` path cache) → `Open` + `Lookup("NewPlugin")`.
|
External plugin loading: `internal/plugin/dynamic.go` → copy to SHA256 temp path (bypass `plugin.Open` path cache) → `Open` + `Lookup("NewPlugin")`.
|
||||||
Lua script plugin loading: `internal/lua/` → parse `main.lua` via Lua VM, call `start()` to register tools.
|
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.
|
||||||
|
|
||||||
### Built-in vs External Plugins
|
### Built-in vs External Plugins
|
||||||
|
|
||||||
|
|||||||
@ -79,5 +79,5 @@ Code is in the project root, implemented in Go.
|
|||||||
Core functionality is operational. Plugin system and SDK are ready for independent external plugin development.
|
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: webui / cli / timer / cmd / mcp / agentcli / healthcheck / pluginmgr / clawhubadapter / files / cfgmgr
|
||||||
- External plugin examples ([homeagent-sdk](https://gitcode.com/JianFeeeee/homeagent-sdk) repo `example/`, both Go and Lua types): qq / files / web / memo / bili / editdoc / a2a / ocr / sanitizer / luaplugintest / testlua
|
- External plugin examples ([homeagent-sdk](https://gitcode.com/JianFeeeee/homeagent-sdk) 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
|
- Distribution: `.hmap` plugin package format, installable via WebUI
|
||||||
|
|||||||
@ -64,6 +64,14 @@ plugindev sdk path # show current SDK path
|
|||||||
|
|
||||||
SDK is stored at `~/.homeagent/plugindev/sdk/<version>/`; `plugindev init` reads the current SDK version for `go.mod`.
|
SDK is stored at `~/.homeagent/plugindev/sdk/<version>/`; `plugindev init` reads the current SDK version for `go.mod`.
|
||||||
|
|
||||||
|
### Source Debugging
|
||||||
|
|
||||||
|
`plugindev debug` interprets plugin source and prints a call trace, no compilation environment needed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
plugindev debug [dir] # dir defaults to the current directory
|
||||||
|
```
|
||||||
|
|
||||||
### Creating a Go Plugin
|
### Creating a Go Plugin
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -71,8 +79,11 @@ plugindev init myplugin
|
|||||||
cd myplugin
|
cd myplugin
|
||||||
# Edit plugin code
|
# Edit plugin code
|
||||||
vim plugin.go
|
vim plugin.go
|
||||||
# Build and package
|
# Build and package (default is a multi-platform bundle, see below)
|
||||||
plugindev build
|
plugindev build
|
||||||
|
# Output: dist/myplugin_bundle.hmap
|
||||||
|
# Single-platform build:
|
||||||
|
plugindev build --no-bundle
|
||||||
# Output: dist/myplugin_linux_amd64.hmap (or windows_amd64)
|
# Output: dist/myplugin_linux_amd64.hmap (or windows_amd64)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -121,14 +132,19 @@ myluaplugin/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd myplugin
|
cd myplugin
|
||||||
plugindev build
|
plugindev build # default bundle mode (multi-platform)
|
||||||
|
plugindev build --no-bundle # single-target build (per plg.json targets)
|
||||||
|
plugindev build --target linux/amd64 # append a target on top of plg.json targets
|
||||||
|
plugindev build --outdir dist # output directory (default: dist)
|
||||||
|
plugindev build --sdk-path <path> # SDK path override (go.mod replace)
|
||||||
|
plugindev build --replace <mod@path> # append a go.mod replace directive (repeatable)
|
||||||
```
|
```
|
||||||
|
|
||||||
Execution process:
|
Execution process:
|
||||||
1. Reads `plg.json` `targets` field to determine target platforms
|
1. Reads `plg.json` `targets`/`bundle` fields to determine build targets (bundle takes priority, see below)
|
||||||
2. Auto-generates C ABI bridge code (`z_bridge_gen.go` + `z_entry.c`)
|
2. Auto-generates C ABI bridge code (`z_bridge_gen.go` + `z_entry.c`; Windows only `z_bridge_gen.go`)
|
||||||
3. **Go plugin**: Runs `go build -buildmode=c-shared` (produces `.so` / `.dylib` / `.dll`)
|
3. **Go plugin**: Runs `go build -buildmode=c-shared` (produces `.so` / `.dylib` / `.dll`)
|
||||||
4. **Lua plugin**: Packages source code directly, no compilation needed
|
4. **Lua plugin**: Packages source code directly, no compilation needed (contents: `plugin.json` + `main.lua`, plus optional `README.md`, `LICENSE`, `thirdpart/*.lua`)
|
||||||
5. Generates `plugin.json` output manifest
|
5. Generates `plugin.json` output manifest
|
||||||
6. Packages as `.hmap` distribution (zip format, containing `plugin.json` + binary)
|
6. Packages as `.hmap` distribution (zip format, containing `plugin.json` + binary)
|
||||||
|
|
||||||
@ -136,7 +152,7 @@ Execution process:
|
|||||||
|
|
||||||
| File | Purpose | Key fields |
|
| File | Purpose | Key fields |
|
||||||
|------|---------|------------|
|
|------|---------|------------|
|
||||||
| `plg.json` | Project metadata, maintained by developer | `targets` — build targets (e.g. `"linux/amd64,windows/amd64"`) |
|
| `plg.json` | Project metadata, maintained by developer | `targets` — single-target build list (e.g. `"linux/amd64,windows/amd64"`); `bundle` — multi-platform bundle switch (default `true`) |
|
||||||
| `plugin.json` | Build artifact manifest, auto-generated | `entry` — entry filename; `platforms` — declared platforms |
|
| `plugin.json` | Build artifact manifest, auto-generated | `entry` — entry filename; `platforms` — declared platforms |
|
||||||
|
|
||||||
Each target produces a separate `.hmap`; binary name by platform:
|
Each target produces a separate `.hmap`; binary name by platform:
|
||||||
@ -147,23 +163,28 @@ Each target produces a separate `.hmap`; binary name by platform:
|
|||||||
| macOS | `plugin.dylib` |
|
| macOS | `plugin.dylib` |
|
||||||
| Windows | `plugin.dll` |
|
| Windows | `plugin.dll` |
|
||||||
|
|
||||||
### Multi-platform bundle: --bundle
|
### Build Targets & Multi-platform Bundle
|
||||||
|
|
||||||
|
**`plugindev build` defaults to bundle mode** (unless `plg.json` explicitly sets `"bundle": false`): it builds linux/amd64 + darwin/amd64 + windows/amd64 in one pass, producing a single `.hmap` with all platform binaries. The output manifest includes a `platforms` field. The kernel auto-selects the correct binary during installation.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
plugindev build --bundle
|
plugindev build # default bundle, outputs dist/myplugin_bundle.hmap
|
||||||
|
plugindev build --bundle # explicitly enable bundle (same as above)
|
||||||
|
plugindev build --no-bundle # disable bundle, build per plg.json targets
|
||||||
```
|
```
|
||||||
|
|
||||||
Builds linux/amd64 + darwin/amd64 + windows/amd64 in one pass, producing a single `.hmap`
|
Notes:
|
||||||
with all platform binaries. The output manifest includes a `platforms` field.
|
- In bundle mode the `plg.json` `targets` field is ignored; the three platforms above are always built
|
||||||
The kernel auto-selects the correct binary during installation.
|
- Cross-compilation needs the corresponding toolchains (e.g. building darwin on Linux requires clang/macOS SDK); if a toolchain is missing the build fails — use `--no-bundle` to build only the current platform
|
||||||
|
- Single-target output naming: `{name}_{os}_{arch}.hmap`, e.g. `myplugin_linux_amd64.hmap`
|
||||||
|
|
||||||
Output in `dist/` directory:
|
Output in `dist/` directory:
|
||||||
```
|
```
|
||||||
dist/
|
dist/
|
||||||
├── myplugin_linux_amd64.hmap # Single platform: Linux
|
├── myplugin_bundle.hmap # default bundle: multi-platform
|
||||||
├── myplugin_windows_amd64.hmap # Single platform: Windows
|
├── myplugin_linux_amd64.hmap # after --no-bundle: Linux
|
||||||
├── myplugin_darwin_amd64.hmap # Single platform: macOS
|
├── myplugin_windows_amd64.hmap # after --no-bundle: Windows
|
||||||
├── myplugin_bundle.hmap # Multi-platform bundle
|
├── myplugin_darwin_amd64.hmap # after --no-bundle: macOS
|
||||||
└── myplugin_lua.hmap # Lua plugin
|
└── myplugin_lua.hmap # Lua plugin
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -172,12 +193,12 @@ dist/
|
|||||||
Install via PluginMgr HTTP API (three methods):
|
Install via PluginMgr HTTP API (three methods):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Install from URL (auto-cleanup)
|
# 1. Install from URL (http/https only, streamed, no local temp file)
|
||||||
curl -X POST http://127.0.0.1:9876/plugins \
|
curl -X POST http://127.0.0.1:9876/plugins \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"url": "https://example.com/myplugin.hmap"}'
|
-d '{"url": "https://example.com/myplugin.hmap"}'
|
||||||
|
|
||||||
# 2. Install from local path (keeps source file)
|
# 2. Install from local path (reads the given file, source file untouched)
|
||||||
curl -X POST http://127.0.0.1:9876/plugins \
|
curl -X POST http://127.0.0.1:9876/plugins \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"path": "/path/to/myplugin.hmap"}'
|
-d '{"path": "/path/to/myplugin.hmap"}'
|
||||||
@ -187,9 +208,18 @@ curl -X POST http://127.0.0.1:9876/plugins \
|
|||||||
--data-binary @dist/myplugin.hmap
|
--data-binary @dist/myplugin.hmap
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`9876` is the pluginmgr local port (defaults to listening on 127.0.0.1 only, no auth).
|
||||||
|
|
||||||
Reload plugins via `/api/v1/plugins/reload` or restart the kernel to activate.
|
Reload plugins via `/api/v1/plugins/reload` or restart the kernel to activate.
|
||||||
|
|
||||||
Or upload via WebUI plugin management page.
|
Or upload via the WebUI plugin management page, or through the WebUI HTTP API (default port 8080, requires the `api_key` bearer token; it proxies to pluginmgr):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:8080/api/v1/plugins \
|
||||||
|
-H "Authorization: Bearer <api_key>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"path": "/path/to/myplugin.hmap"}'
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -491,6 +521,14 @@ outputCh := s.OutputChan()
|
|||||||
|
|
||||||
Lua plugins are suitable for lightweight rapid prototyping, requiring no Go compilation environment. Changes take effect after kernel restart.
|
Lua plugins are suitable for lightweight rapid prototyping, requiring no Go compilation environment. Changes take effect after kernel restart.
|
||||||
|
|
||||||
|
### Execution Model
|
||||||
|
|
||||||
|
Lua plugins run inside the kernel process on a gopher-lua interpreter (single Lua state guarded by a mutex). This differs fundamentally from Go plugins:
|
||||||
|
|
||||||
|
- **Passive callback model**: `main.lua` executes only once at load time. Afterward, tools, stage hooks, output/input channels, and registered APIs are all invoked by the kernel via callbacks into Lua functions. Plugins cannot start background tasks on their own.
|
||||||
|
- **No concurrency / no long-running services**: Lua has no goroutines, coroutine scheduling, `os`/`io` libraries, or socket listening. The only outbound capability is `sdk.http.get/post` (synchronous). Any blocking loop will stall every call of that plugin while holding the lock.
|
||||||
|
- **For long-running services (listening on a port, background polling, timers) use a Go plugin** (`.so`/`.dll` built with the toolchain, which may spawn goroutines — see the webui/cli plugins). The Lua equivalent is event-driven: register tools/stage hooks/channels to be called back by the kernel, or interact with external processes via `sdk.http`.
|
||||||
|
|
||||||
### Plugin Structure
|
### Plugin Structure
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
|||||||
@ -257,13 +257,13 @@ VM 内置 `json.encode` / `json.decode` / `log` / `http_get` / `http_post`。
|
|||||||
| 方式 | 注册机制 | 编译 | 用途 |
|
| 方式 | 注册机制 | 编译 | 用途 |
|
||||||
|------|----------|------|------|
|
|------|----------|------|------|
|
||||||
| 内置插件 | `init()` → `RegisterFactory` | `internal/plugins/` 编译进内核 | webui/cli/timer/mcp 等 |
|
| 内置插件 | `init()` → `RegisterFactory` | `internal/plugins/` 编译进内核 | webui/cli/timer/mcp 等 |
|
||||||
| 外部 `.so` | C ABI 动态加载 | `-buildmode=c-shared` + bridge | qq/files/web/memo 等 |
|
| 外部 `.so` | C ABI 动态加载 | `-buildmode=c-shared` + bridge | qq/browser/files 等 |
|
||||||
| Lua 脚本插件 | 解析 `main.lua` 注册工具 | 无需编译,热加载 | luaplugintest/testlua 等 |
|
| Lua 脚本插件 | 执行 `main.lua` 注册工具 | 无需编译,重启/重载生效 | luademo 等 |
|
||||||
| SKILL 插件 | 解析 `SKILL.md` | Markdown 定义 | clawhubadapter 兼容加载 |
|
| SKILL 插件 | 解析 `SKILL.md` | Markdown 定义 | clawhubadapter 兼容加载 |
|
||||||
|
|
||||||
内置插件注册:`internal/plugins/all.go` 空白导入 → 各插件 `init()` → `Registry.Load()` 扫描目录匹配工厂。
|
内置插件注册:`internal/plugins/all.go` 空白导入 → 各插件 `init()` → `Registry.Load()` 扫描目录匹配工厂。
|
||||||
外部插件加载:`internal/plugin/dynamic.go` → 复制到 SHA256 临时路径(绕过 `plugin.Open` 路径缓存)→ `Open` + `Lookup("NewPlugin")`。
|
外部插件加载:`internal/plugin/dynamic.go` → 复制到 SHA256 临时路径(绕过 `plugin.Open` 路径缓存)→ `Open` + `Lookup("NewPlugin")`。
|
||||||
Lua 脚本插件加载:`internal/lua/` → 通过 Lua VM 解析 `main.lua`,调用 `start()` 注册工具。
|
Lua 脚本插件加载:`internal/plugin/` → gopher-lua 解释器执行 `main.lua`(加载期 `sdk.register_*` 仅暂存 handler),`Start()` 时替换为真实 SDK 实现并批量注册。脚本只在加载时读取一次,运行期通过回调执行。
|
||||||
|
|
||||||
### 内置插件 vs 外部插件
|
### 内置插件 vs 外部插件
|
||||||
|
|
||||||
|
|||||||
@ -79,5 +79,5 @@ HomeAgent 是一个持续运行的个人智能 Agent 框架。
|
|||||||
核心功能已可运行。插件系统和 SDK 已就绪,可独立开发外部插件。
|
核心功能已可运行。插件系统和 SDK 已就绪,可独立开发外部插件。
|
||||||
|
|
||||||
- 内置插件:webui / cli / timer / cmd / mcp / agentcli / healthcheck / pluginmgr / clawhubadapter / files / cfgmgr
|
- 内置插件:webui / cli / timer / cmd / mcp / agentcli / healthcheck / pluginmgr / clawhubadapter / files / cfgmgr
|
||||||
- 外部插件示例([homeagent-sdk](https://gitcode.com/JianFeeeee/homeagent-sdk) 仓库 `example/`,含 Go 和 Lua 两种类型):qq / files / web / memo / bili / editdoc / a2a / ocr / sanitizer / luaplugintest / testlua
|
- 外部插件示例([homeagent-sdk](https://gitcode.com/JianFeeeee/homeagent-sdk) 仓库 `example/`,含 Go 和 Lua 两种类型):qq / files / a2a / ai_image / bili / browser / calendar / editdoc / memo / music / ocr / rss / sanitizer / weather / luademo
|
||||||
- 打包分发:`.hmap` 插件包格式,通过 WebUI 安装
|
- 打包分发:`.hmap` 插件包格式,通过 WebUI 安装
|
||||||
|
|||||||
@ -65,6 +65,14 @@ plugindev sdk path # 显示当前 SDK 路径
|
|||||||
|
|
||||||
SDK 存储在 `~/.homeagent/plugindev/sdk/<version>/`,`plugindev init` 自动读取当前 SDK 版本填充 `go.mod`。
|
SDK 存储在 `~/.homeagent/plugindev/sdk/<version>/`,`plugindev init` 自动读取当前 SDK 版本填充 `go.mod`。
|
||||||
|
|
||||||
|
### 源码调试
|
||||||
|
|
||||||
|
`plugindev debug` 直接用解释器执行插件源码并输出调用轨迹,无需编译环境:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
plugindev debug [dir] # dir 默认当前目录
|
||||||
|
```
|
||||||
|
|
||||||
### 创建 Go 插件
|
### 创建 Go 插件
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -73,7 +81,10 @@ cd myplugin
|
|||||||
# 编辑插件代码
|
# 编辑插件代码
|
||||||
vim plugin.go
|
vim plugin.go
|
||||||
# 编译打包
|
# 编译打包
|
||||||
plugindev build
|
plugindev build # 默认多平台 bundle(见下节)
|
||||||
|
# 输出: dist/myplugin_bundle.hmap
|
||||||
|
# 单平台构建:
|
||||||
|
plugindev build --no-bundle
|
||||||
# 输出: dist/myplugin_linux_amd64.hmap (或 windows_amd64)
|
# 输出: dist/myplugin_linux_amd64.hmap (或 windows_amd64)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -122,14 +133,19 @@ myluaplugin/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd myplugin
|
cd myplugin
|
||||||
plugindev build
|
plugindev build # 默认 bundle 模式(多平台合集)
|
||||||
|
plugindev build --no-bundle # 单平台构建(仅当前 plg.json targets)
|
||||||
|
plugindev build --target linux/amd64 # 在 targets 基础上追加一个目标
|
||||||
|
plugindev build --outdir dist # 指定输出目录(默认 dist)
|
||||||
|
plugindev build --sdk-path <path> # 指定 SDK 路径(覆盖 go.mod replace)
|
||||||
|
plugindev build --replace <mod@path> # 追加 go.mod replace 指令(可多次)
|
||||||
```
|
```
|
||||||
|
|
||||||
执行过程:
|
执行过程:
|
||||||
1. 读取 `plg.json` 的 `targets` 字段确定目标平台
|
1. 读取 `plg.json` 的 `targets`/`bundle` 字段确定构建目标(bundle 模式优先,见下节)
|
||||||
2. 自动生成 C ABI bridge 代码(`z_bridge_gen.go` + `z_entry.c`)
|
2. 自动生成 C ABI bridge 代码(`z_bridge_gen.go` + `z_entry.c`,Windows 仅 `z_bridge_gen.go`)
|
||||||
3. **Go 插件**:执行 `go build -buildmode=c-shared`(生成 `.so` / `.dylib` / `.dll`)
|
3. **Go 插件**:执行 `go build -buildmode=c-shared`(生成 `.so` / `.dylib` / `.dll`)
|
||||||
4. **Lua 插件**:直接打包源码,无需编译
|
4. **Lua 插件**:直接打包源码,无需编译(打包内容:`plugin.json` + `main.lua`,以及可选的 `README.md`、`LICENSE`、`thirdpart/*.lua`)
|
||||||
5. 生成 `plugin.json` 输出清单
|
5. 生成 `plugin.json` 输出清单
|
||||||
6. 打包为 `.hmap` 分发包(zip 格式,内含 `plugin.json` + 二进制)
|
6. 打包为 `.hmap` 分发包(zip 格式,内含 `plugin.json` + 二进制)
|
||||||
|
|
||||||
@ -137,7 +153,7 @@ plugindev build
|
|||||||
|
|
||||||
| 文件 | 用途 | 关键字段 |
|
| 文件 | 用途 | 关键字段 |
|
||||||
|------|------|---------|
|
|------|------|---------|
|
||||||
| `plg.json` | 项目元信息,由开发者维护 | `targets` — 构建目标(如 `"linux/amd64,windows/amd64"`)|
|
| `plg.json` | 项目元信息,由开发者维护 | `targets` — 单平台构建目标(如 `"linux/amd64,windows/amd64"`);`bundle` — 多平台合集开关(默认 `true`)|
|
||||||
| `plugin.json` | 构建产物清单,`plugindev build` 自动生成 | `entry` — 入口文件名;`platforms` — 声明的支持平台 |
|
| `plugin.json` | 构建产物清单,`plugindev build` 自动生成 | `entry` — 入口文件名;`platforms` — 声明的支持平台 |
|
||||||
|
|
||||||
每个目标生成单独的 `.hmap`,二进制文件名由平台决定:
|
每个目标生成单独的 `.hmap`,二进制文件名由平台决定:
|
||||||
@ -148,22 +164,28 @@ plugindev build
|
|||||||
| macOS | `plugin.dylib` |
|
| macOS | `plugin.dylib` |
|
||||||
| Windows | `plugin.dll` |
|
| Windows | `plugin.dll` |
|
||||||
|
|
||||||
### 多平台打包:--bundle
|
### 构建目标与多平台打包(bundle)
|
||||||
|
|
||||||
|
**`plugindev build` 默认就是 bundle 模式**(`plg.json` 未显式写 `"bundle": false` 时):一次编译 linux/amd64 + darwin/amd64 + windows/amd64,生成包含所有平台二进制的单 `.hmap`,输出清单自动添加 `platforms` 字段。安装时核心自动选择当前平台的二进制,跳过其他平台。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
plugindev build --bundle
|
plugindev build # 默认 bundle,输出 dist/myplugin_bundle.hmap
|
||||||
|
plugindev build --bundle # 显式开启 bundle(同上)
|
||||||
|
plugindev build --no-bundle # 关闭 bundle,按 plg.json 的 targets 逐平台构建
|
||||||
```
|
```
|
||||||
|
|
||||||
一次编译 linux/amd64 + darwin/amd64 + windows/amd64,生成包含所有平台二进制的单 `.hmap`,
|
注意:
|
||||||
输出清单自动添加 `platforms` 字段。安装时核心自动选择当前平台的二进制,跳过其他平台。
|
- bundle 模式下 `plg.json` 的 `targets` 字段被忽略,固定构建上述三个平台
|
||||||
|
- 跨平台交叉编译需要对应工具链(如 Linux 上构建 darwin 需 clang/macOS SDK);缺少工具链时编译会失败,此时使用 `--no-bundle` 只构建当前平台
|
||||||
|
- 单平台输出文件名:`{name}_{os}_{arch}.hmap`,如 `myplugin_linux_amd64.hmap`
|
||||||
|
|
||||||
输出在 `dist/` 目录:
|
输出在 `dist/` 目录:
|
||||||
```
|
```
|
||||||
dist/
|
dist/
|
||||||
├── myplugin_linux_amd64.hmap # 单平台:Linux 版
|
├── myplugin_bundle.hmap # 默认 bundle:多平台合集
|
||||||
├── myplugin_windows_amd64.hmap # 单平台:Windows 版
|
├── myplugin_linux_amd64.hmap # --no-bundle 后:Linux 版
|
||||||
├── myplugin_darwin_amd64.hmap # 单平台:macOS 版
|
├── myplugin_windows_amd64.hmap # --no-bundle 后:Windows 版
|
||||||
├── myplugin_bundle.hmap # 多平台合集
|
├── myplugin_darwin_amd64.hmap # --no-bundle 后:macOS 版
|
||||||
└── myplugin_lua.hmap # Lua 插件
|
└── myplugin_lua.hmap # Lua 插件
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -172,12 +194,12 @@ dist/
|
|||||||
通过 PluginMgr HTTP API 安装,支持三种方式:
|
通过 PluginMgr HTTP API 安装,支持三种方式:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. 从 URL 安装(自动清理安装包)
|
# 1. 从 URL 安装(仅支持 http/https,流式下载不落盘)
|
||||||
curl -X POST http://127.0.0.1:9876/plugins \
|
curl -X POST http://127.0.0.1:9876/plugins \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"url": "https://example.com/myplugin.hmap"}'
|
-d '{"url": "https://example.com/myplugin.hmap"}'
|
||||||
|
|
||||||
# 2. 从本地路径安装(保留安装包)
|
# 2. 从本地路径安装(读取指定文件,不移动原文件)
|
||||||
curl -X POST http://127.0.0.1:9876/plugins \
|
curl -X POST http://127.0.0.1:9876/plugins \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"path": "/path/to/myplugin.hmap"}'
|
-d '{"path": "/path/to/myplugin.hmap"}'
|
||||||
@ -187,9 +209,18 @@ curl -X POST http://127.0.0.1:9876/plugins \
|
|||||||
--data-binary @dist/myplugin.hmap
|
--data-binary @dist/myplugin.hmap
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`9876` 为 pluginmgr 本地监听端口(默认仅监听 127.0.0.1,无鉴权)。
|
||||||
|
|
||||||
安装后需调用 `/api/v1/plugins/reload` 或重启内核生效。
|
安装后需调用 `/api/v1/plugins/reload` 或重启内核生效。
|
||||||
|
|
||||||
也可通过 WebUI 插件管理页面上传安装。
|
也可通过 WebUI 插件管理页面上传安装,或走 WebUI 的 HTTP API(端口默认 8080,需 `api_key` 鉴权,内部代理到 pluginmgr):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:8080/api/v1/plugins \
|
||||||
|
-H "Authorization: Bearer <api_key>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"path": "/path/to/myplugin.hmap"}'
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -489,6 +520,14 @@ outputCh := s.OutputChan()
|
|||||||
|
|
||||||
Lua 插件适合轻量级快速原型,无需 Go 编译环境,修改后直接重启内核即可生效。
|
Lua 插件适合轻量级快速原型,无需 Go 编译环境,修改后直接重启内核即可生效。
|
||||||
|
|
||||||
|
### 执行模型
|
||||||
|
|
||||||
|
Lua 插件运行在内核进程内的 gopher-lua 解释器中(单 Lua 状态 + 互斥锁),与 Go 插件的执行模型有本质区别:
|
||||||
|
|
||||||
|
- **被动回调模型**:`main.lua` 仅在加载时执行一次,此后插件的工具、阶段钩子、输出/输入通道、注册 API 全部由内核事件驱动回调 Lua 函数;插件不能自己启动后台任务。
|
||||||
|
- **无并发/无常驻服务能力**:Lua 侧没有 goroutine、协程调度、`os`/`io` 库和 socket 监听能力,唯一主动出站通道是 `sdk.http.get/post`(同步请求)。任何阻塞循环都会持锁卡死该插件的所有调用。
|
||||||
|
- **常驻服务(如监听端口、后台轮询、定时任务)请使用 Go 插件**(工具链编译的 `.so`/`.dll`,可自行启动 goroutine,参见 webui/cli 插件)。Lua 插件的等价做法是事件驱动:注册工具/阶段钩子/通道由内核回调,或经 `sdk.http` 与外部进程交互。
|
||||||
|
|
||||||
### 插件结构
|
### 插件结构
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
|||||||
Reference in New Issue
Block a user