mirror of
https://gitcode.com/JianFeeeee/homeagent-sdk.git
synced 2026-10-31 14:27:30 +00:00
## 修的是真实事故(2026-10-18)
模板里原来是:
stageHandlers[string(stage)] = handler // stage 名为键,后者覆盖前者
有人写了两次同 stage 注册:
RegisterStage(BeforeToolcall, 权限门) ← 被下一条覆盖
RegisterStage(BeforeToolcall, 切状态) ← 实际生效
后果不只是状态不切换 —— **权限门被静默关掉了**(那几版 QQ 插件里
任何人发消息都能调任何工具)。而内核侧日志显示 `2 handlers [qq qq]`,
看起来完全正常 —— 这是最难查的一类 bug,我为它白烧了十几轮。
## 处置(按用户要求:告警 + 默认合并)
禁止重复 → 存量插件可能直接起不来(它们的重复常是本意)
静默覆盖 → 就是当前 bug
默认合并 → 两件事都做,且告警让开发者知道该优化写法 ← 选这个
合并语义三条:
1. **按注册顺序链式执行**(先注册的先跑)
2. **prev 返回 error 就中止**(与内核 RunStage 一致:权限门拒了
就不该再切状态)
3. **留痕**:注册期打 log.Printf 告警,开发者在插件启动时就能看见
★ 重复注册**不再**上报 stage.register:内核已经登记过一条,再报一条
会让它记两条 handler 而实际只派发一次 —— 那正是
`2 handlers [qq qq]` 假象的来源。
## 为什么改模板而不是 SDK
用户明确要求「工具链对同stage多handler注册给出告警」。模板是生成
proc_main 的地方,也就是 map 覆盖实际发生的地方;在源头拦,告警
直接出现在**插件启动日志**里。
## 判据(5 条,变异 3/3 咬)
· 有"已存在"判断(不是无条件赋值)
· 链式调用 prev(合并后旧 handler 不丢)
· prev 出错中止
· **告警是代码行**(跳过注释再找)+ 给出行动建议
· `if dup` 分支内不含 stage.register
## 判据第一版是假绿
裸 `strings.Contains(body, "重复注册")` 把**注释里的解释**也算进去了,
于是删掉 log.Printf 后判据照样通过(变异不咬,实测)。
改成逐行跳过注释再找 log.Printf。这不是第一次栽在
「注释里有、代码里没有」上。
# {{.Plg.Name}}
{{.Plg.Description}}
## Build
```bash
plugindev build
```
## Install
Upload the `.hmap` file through the Plugin Manager API:
```bash
curl -X POST http://localhost:8080/api/v1/plugins \
-H "Content-Type: application/octet-stream" \
--data-binary @dist/<name_en_snake>_linux_amd64.hmap
```
## Lifecycle
- `RegisterStopHandler` — runs on every stop (including reload/disable), before `Stop()`.
- `RegisterOnRemoveHandler` — runs **only on uninstall (remove)**, after `Stop()`; clean up the plugin's own data files here. Reload/disable do NOT trigger it. See the onRemove demo in `main.go`.