feat(herdr): 提示并安装 traex 集成插件#397
Conversation
|
Babysit update: I checked the contribution rules and the PR already has the required Chinese summary/impact/validation sections and a valid I also synced the branch with latest
The reason CI appears to have “no response” is that the GitHub Actions run is in |
deepcoldy
left a comment
There was a problem hiding this comment.
Hi @Phoobobo,感谢这个 PR!我做了一轮 review。功能方向没问题,spawnHerdr 重构很干净(还顺手改进了 ENOENT 报错)、warn-only 非阻塞设计是对的、i18n/help 文案也准确。pnpm build + 相关 setup/herdr 单测(merge master 后)本地都绿。
但有一个合并前需要重做的点,maintainer 已拍板:改成 dashboard 可选的 opt-in,而不是自动安装 fork 版本。下面是具体反馈。
🔴 主要问题:daemon 启动路径自动 --yes 安装并执行「个人仓库」插件(供应链风险)
当前 ensureTraexPlugin() 会在每次 botmux start/restart(存在 herdr+traex bot 时)于 ensureDependencies 同步执行:
herdr plugin install Phoobobo/herdr-traex-integration --yes && herdr plugin action invoke com.traex.herdr-integration.install
- 源是个人 GitHub 账号的仓库、无版本钉死(裸
user/repo永远拉默认分支最新),且 install action 会执行任意代码(写~/.traehooks)。账号改名 / 删库 / 内容变更 / 被盗,botmux 都会无声拉取并执行。 - 和现有行为性质不同:现有
herdr integration install claude/codex/...装的是 herdr.dev 官方 curate 的集成;这里是 botmux 源码里写死并自动执行一个第三方个人 repo。 - 即使是非阻塞、只 warn,「默认自动执行外部代码」这条本身就不应该发生。
✅ 需要的改法:dashboard opt-in(maintainer 决定)
1) 触发改 opt-in —— 全局开关,默认关
- 用全局配置开关,不要做成 per-bot:插件写的是 host 级
~/.traehooks,是整机一次性的东西,per-bot 语义会打架。 - 仓库里有现成模式可以直接抄 ——
chatBotDiscovery:见src/config.ts的resolveChatBotDiscoveryConfig(存~/.botmux/config.json的dashboard.chatBotDiscovery+ env 兜底 + 合理默认),dashboard Settings 开关通过src/dashboard/settings-write-applier.ts的applySettingsWrite持久化。 ensureTraexPlugin在「herdr+traex bot 存在」之外,再加这个开关做 gate;默认关 = 什么都不装。
2) 别在 botmux 源码里写死 fork spec
- 就算加了开关,如果「开」仍等于装写死的
Phoobobo/...,botmux 还是在背书一个 unpinned 个人 repo。 - 推荐:botmux 不带默认 spec,开关打开后由 operator 在 dashboard 自己填信得过的 plugin spec,botmux 保持中立。
- 次选:保留默认但钉 tag/SHA,且 UI 明确标注「第三方 / 社区源」;等这个插件被 herdr 官方收编后再换成官方 pinned 默认。
🟡 顺带修两个 correctness 点
#2 install action 每次启动都重跑 —— ensureTraexPlugin 里 plugin action invoke ...install 在 if (!alreadyInstalled) 块之外,所以即使插件已装也每次重写 hooks。这既给 start/restart 关键路径加了同步 spawn,又完全依赖那个外部 action 幂等;若它是 append 而非 replace,反复重启会污染 ~/.trae。建议仅 fresh install 时 invoke,或先廉价探测 hooks 是否已在。
#3 isTraexPluginInstalled 写死 herdr JSON 结构 —— 假设 parsed.result.plugins[].plugin_id。注意 catch 里的 substring 兜底只覆盖 JSON.parse 抛错:如果 JSON 能解析但结构不同(比如顶层是 plugins 而非 result.plugins),会直接返回 false 且不走兜底 → 「已安装」永远检测不到 → 每次重启都重试 install(120s 网络超时风险)。建议对着真实 herdr plugin list --json 输出核一下结构,并让 shape 不符时也走兜底。
🟢 测试
src/setup/ensure-herdr-integrations.ts 目前没有单测,而这个 PR 加了实打实的分支(装成功 / 已装 / 装失败 / action 失败 / JSON 兜底)。按仓库规范请补 mock spawnSync 的单测;PR 描述目前只有 pnpm build,建议补上测试运行结果。
辛苦!方向是对的,核心就是把「自动装 fork」换成「dashboard 开关(默认关)+ 源不写死」,另外把 #2 / #3 一起收一下。有问题欢迎在这里讨论 👌
287ec9f to
d3dc591
Compare
|
Addressed the review feedback in the latest force-push (
Validation:
Freshness after push verified with CI is still |
改动
Phoobobo/herdr-traex-integration默认源;支持 env 兜底BOTMUX_HERDR_TRAEX_PLUGIN_ENABLED=true+BOTMUX_HERDR_TRAEX_PLUGIN_SPEC=<spec>。~/.traehooks。herdr plugin list --json解析支持多种 shape,并在未知 JSON 结构时回退 substring 兜底。ensureHerdrIntegrationsmockspawnSync单测覆盖装成功 / 已装 / 装失败 / action 失败 / JSON 兜底等分支。影响面
backendType: "herdr"且 cliId 为traex的 bot 的可选依赖 bootstrap;非 herdr 后端、非 traex CLI 不改变行为。dashboard.herdrTraexPlugin,这是机器级开关(插件写 host 级~/.traehooks),不是 per-bot。验证
pnpm build✅pnpm vitest run --project unit test/ensure-herdr-integrations.test.ts test/settings-write-applier.test.ts test/global-config.test.ts test/herdr-discovery.test.ts test/herdr-session-discovery.test.ts test/cli-selection.test.ts✅pnpm test:大多数通过,但test/sandbox.test.ts有 2 个既有 macOS 本地失败(rmSyncsymlink 目录 / opaque dir 断言),与本 PR 的 herdr/traex/dashboard 配置改动无关。