Skip to content

OpenClaw 入口核心重构的目标是让插件总行数净减少至少 1500 行,核心新增行数不超过 1500 行。本文档定义了预算阈值、九个工作包、删除波次以及验证命令(git diff --shortstatpnpm lint:extensions:no-deprecated-channel-access)。重构遵循删除优先原则:每个新的核心辅助函数必须立即删除等量或两倍以上的插件生产代码。当前状态(测试基准 commit 1671e7532adb)插件生产已减少 1240 行,但还需再减 260 行才能进入最小预算。重点清理目标包括 Telegram、Discord、Signal、飞书等 15 个插件的包装层。

OpenClaw 入口核心重构:删除优先的执行计划

入口重构在多轮迭代中净增了数千行代码,这并不健康。核心集中的价值只有在打包插件生产代码变小、旧第三方 SDK 兼容性被隔离到 SDK/核心垫片时才成立。

期望的运行形态:

text
打包插件事件
  -> 本地提取平台事实
  -> 事实可用时一次解析共享入口
  -> 分支处理通用入口投影/结果
  -> 本地执行平台副作用

旧第三方辅助函数
  -> SDK 兼容垫片
  -> 尽可能映射到共享入口兼容投影
  -> 保留旧返回形状

打包插件不应再将入口翻译回本地 AccessResultGroupAccessDecisionCommandAuthDecisionDmCommandAccess{ allowed, reasonCode } 等类型,除非该类型是插件公共 API。

预算

以 PR 合并基准 origin/main 为基准(含未跟踪文件):

text
合并基准            1671e7532adb

当前状态:
核心生产            +3,922 / -546    = +3,376
文档                +601 / -17       = +584
其他                +145 / -2        = +143
插件生产            +4,148 / -5,388  = -1,240
测试                +2,326 / -2,414  = -88
总计                +11,142 / -8,367 = +2,775

要求:
插件生产            <= -1,500
核心生产            <= +1,500,或由更大插件删除补偿
测试                <= +1,000
总计                <= +2,000

理想:
插件生产            <= -2,500
核心生产            <= +1,200
总计                <= 0

最小剩余清理量:

text
插件生产    还需净删 260 行
总计        还需净删 775 行
核心生产    仍超独立预算 1,876 行(除非由插件删除补偿)

仅删除注释不计入清理。上一次预算评估因恢复了 QQBot 解释性注释而过于宽松;本文档仅跟踪可执行/文档/测试代码移动。

每轮清理后重新测量:

sh
base=$(git merge-base HEAD origin/main)
git diff --shortstat "$base"
git diff --numstat "$base" -- src/channels/message-access src/plugin-sdk extensions | sort -nr -k1 | head -n 80
pnpm lint:extensions:no-deprecated-channel-access

诊断

第一轮添加了共享入口内核,但在其旁边留下了太多插件本地的授权代码:

text
平台事实
  -> 共享入口状态和决策
  -> 本地 DTO 或旧投影
  -> 本地 if/else 分支

这导致模型重复。核心生产增加了约 3,376 行,而打包插件生产减少了 1,240 行。这比第一轮好,但仍未进入最小预算。修复方向依然是删除优先:

  • 删除仅重命名入口字段的插件 DTO
  • 删除仅测试包装形状的测试
  • 仅在同一个补丁中删除打包插件代码时才添加核心辅助函数
  • 将旧 SDK 兼容性仅保留在 SDK/核心垫片中
  • 在包装删除暴露出稳定形状后重新打包核心

热点

仍需收缩的正向插件生产文件:

text
extensions/telegram/src/ingress.ts                        +126
extensions/discord/src/monitor/dm-command-auth.ts         +101
extensions/signal/src/monitor/access-policy.ts             +92
extensions/feishu/src/policy.ts                            +85
extensions/slack/src/monitor/auth.ts                       +64
extensions/googlechat/src/monitor-access.ts                +59
extensions/nextcloud-talk/src/inbound.ts                   +51
extensions/matrix/src/matrix/monitor/access-state.ts       +49
extensions/irc/src/inbound.ts                              +44
extensions/imessage/src/monitor/inbound-processing.ts      +36
extensions/qa-channel/src/inbound.ts                       +34
extensions/qqbot/src/bridge/sdk-adapter.ts                 +33
extensions/tlon/src/monitor/utils.ts                       +30
extensions/twitch/src/access-control.ts                    +22
extensions/qqbot/src/engine/commands/slash-command-handler.ts +20
extensions/telegram/src/bot-handlers.runtime.ts            +19

分支尚未进入最小预算。剩余的审查相关工作应在添加新的核心抽象之前删除重复的授权流程、临时脚手架或包装测试。

当前代码审查

健康的核心接缝已存在于 src/channels/message-access/runtime.ts:它管理身份适配器、有效的允许列表、配对存储读取、路由描述符、命令/事件预设、访问组以及最终解析的 ResolvedChannelMessageIngress 投影。

剩余增长主要是建立在该接缝之上的插件胶水:

  • extensions/telegram/src/ingress.ts 在 Telegram 特定命令/事件辅助中包装核心决策,调用方仍然传递预计算的标准允许列表和所有者列表。
  • extensions/discord/src/monitor/dm-command-auth.tsextensions/feishu/src/policy.tsextensions/googlechat/src/monitor-access.tsextensions/matrix/src/matrix/monitor/access-state.ts 仍然在入口旁保留本地策略 DTO 或旧决策名称。
  • extensions/signal/src/monitor/access-policy.ts 正确地将 Signal 身份规范化和配对回复保留本地,但仍有包装接缝应该折叠为直接消费入口。
  • extensions/nextcloud-talk/src/inbound.tsextensions/irc/src/inbound.tsextensions/qa-channel/src/inbound.tsextensions/zalo/src/monitor.tsextensions/zalouser/src/monitor.ts 仍然重复路由/信封/轮组装,这些可以移到入口内核之外的共享辅助函数中。

结论:将更多代码移入核心只有在同一补丁中删除这些插件包装层时才有效。添加另一个抽象而保留包装返回则重复了错误。

边界

核心拥有通用策略:

  • 允许列表规范化和匹配
  • 访问组展开和诊断
  • 配对存储 DM 允许列表读取
  • 路由、发送者、命令、事件和激活门控
  • 准入映射:dispatch、drop、skip、observe、pairing
  • 脱敏状态、决策、诊断和 SDK 兼容投影
  • 可复用的通用描述符:身份、路由、命令、事件、激活和结果

插件拥有传输事实和副作用:

  • webhook/socket/请求真实性
  • 平台身份提取和 API 查询
  • 渠道特定策略默认值
  • 配对挑战投递、回复、确认、反应、打字、媒体、历史、setup、doctor、status、logs 和面向用户的文案

核心必须保持渠道无关:src/channels/message-access 中不能包含 Discord、Slack、Telegram、Matrix、room、guild、space、API 客户端或插件特定默认值。

验收规则

每个新的核心辅助函数必须立即删除打包插件生产代码。

text
一个打包调用者       拒绝;保留插件本地
两个打包调用者       仅当插件生产行数下降时接受
三个及以上调用者     插件删除量必须至少是新增核心行数的两倍
仅用于兼容的辅助函数 放在 SDK/核心垫片中,永远不要放在打包热点路径上

遇到以下情况应停止并重新设计:

  • 插件生产行数增加
  • 测试增长快于生产缩小
  • 打包热点路径返回一个仅重命名 ResolvedChannelMessageIngress 的 DTO
  • 核心辅助函数需要渠道 ID、平台对象、API 客户端或渠道特定默认值

工作包

  1. 冻结预算。在 PR 中显示行数,保持 deprecated-ingress lint 绿色,在清理提交中包含前后行数。

  2. 删除薄 DTO 接缝。将插件本地的包装返回替换为直接使用 ResolvedChannelMessageIngresssenderAccesscommandAccessrouteAccessingress。先处理 QQBot、Telegram、Slack、Discord、Signal、飞书、Matrix、iMessage、Tlon。删除包装形状的测试;保留行为测试。

  3. 仅在有删除时添加结果分类。通用分类器可以暴露 dispatchpairing-requiredskip-activationdrop-commanddrop-routedrop-senderdrop-ingress。它必须源自决策图,而非理由字符串,并且在同一个补丁中至少迁移三个插件。

  4. 仅在有删除时添加路由描述符构建器。通用路由目标和路由发送者辅助函数只有在能立即缩减路由密集型插件时才可接受:Google Chat、IRC、Microsoft Teams、Nextcloud Talk、Mattermost、Slack、Zalo、Zalo Personal。

  5. 仅在有删除时添加命令/事件预设。集中化文本命令、本地命令、回调和原始主题形状。命令消费者在未运行命令门控时必须默认拒绝;事件不得启动配对。

  6. 仅在去除样板代码时添加身份预设。稳定 ID、稳定 ID 加别名、电话/e164 和多标识符辅助函数允许在原始值仅进入适配器输入且脱敏状态保持不透明 ID/计数时使用。

  7. 共享已授权的轮组装。在入口内核之外,移除 QA Channel、IRC、Nextcloud Talk、Zalo、Zalo Personal 中重复的路由/信封/上下文/回复脚手架。核心可以拥有路由/会话/信封/调度顺序;插件保留投递和渠道特定上下文。

  8. 隔离兼容性。废弃的 SDK 辅助函数保持源代码兼容,但打包热点路径不能导入废弃的 ingress 或 command-auth 外观。兼容性测试应使用假的第三方插件,而非打包插件内部实现。

  9. 重新打包核心。包装删除后,折叠只使用一次的模块,移除未使用的导出,将兼容性投影移出热点路径,保留针对身份、路由、命令/事件、激活、访问组和兼容垫片的专注测试。

删除波次

按顺序执行。每波必须降低打包插件生产行数。

  1. 包装折叠,预期插件增量:-400 至 -600。
    将插件本地的 resolveXAccessresolveXCommandAccessaccessFromIngress 结果类型替换为直接读取 ResolvedChannelMessageIngress。首批目标:Discord DM 命令授权、飞书策略、Matrix 访问状态、Telegram 入口、Signal 访问策略、QQBot SDK 适配器。

  2. 共享结果辅助函数,预期插件增量:-200 至 -350。
    仅当能删除至少三个插件中重复的 shouldBlockControlCommand、配对、激活跳过、路由阻止、发送者阻止等阶梯时,才添加通用分类器。

  3. 路由描述符构建器,预期插件增量:-200 至 -350。
    将重复的路由目标和路由发送者描述符组装移入核心辅助函数。首批目标:Google Chat、IRC、Microsoft Teams、Nextcloud Talk、Mattermost、Slack、Zalo、Zalo Personal。

  4. 轮组装共享,预期插件增量:-250 至 -450。
    对简单的入站插件使用通用路由/会话/信封/调度顺序。首批目标:QA Channel、IRC、Nextcloud Talk、Zalo、Zalo Personal。

  5. 核心重打包,预期核心增量:-300 至 -700。
    插件直接消费运行时投影后,删除只使用一次的模块,将小文件合并回 runtime.ts 或专注的同级文件,保持 SDK 兼容性文件与打包热点路径分离。

  6. 测试修剪,预期测试增量:-300 至 -600。
    删除仅断言已删除包装形状的测试。保留命令拒绝、组回退、原始主题匹配、激活跳过、访问组、配对和脱敏的行为测试。

执行这些波次后期望的最小落地形状:

text
插件生产     <= -1,500
核心生产     约 +1,800 至 +2,200(最终重打包前)
测试         <= +500
总计         <= +2,000

不要移动的内容

不要移动平台配置默认值、设置 UX、doctor/fix 文案、API 查询、Slack 所有者在线检查、Matrix 别名/验证处理、Telegram 回调解析、命令语法解析、本地命令注册、反应负载解析、配对回复、命令回复、确认、打字、媒体、历史或日志。

验证

本地目标循环:

sh
pnpm lint:extensions:no-deprecated-channel-access
pnpm test src/channels/message-access/message-access.test.ts src/plugin-sdk/channel-ingress-runtime.test.ts src/plugin-sdk/access-groups.test.ts
pnpm test extensions/<changed-plugin>/src/...
pnpm plugin-sdk:api:check
pnpm config:docs:check
pnpm check:docs
git diff --check

当行数趋势进入预算后,使用 Testbox 进行广泛变更门控/全套证明。

每个工作包记录:

  • 按分类的前后行数
  • 删除的插件包装
  • 新增核心辅助函数行数(如有)
  • 执行的目标测试
  • 剩余的热点列表

退出标准

  • 打包生产代码不再导入弃用的 channel-access 或 command-auth 外观
  • 兼容性代码隔离到 SDK/核心接缝
  • 打包插件直接消费入口投影或通用结果
  • 插件生产行数相对于 origin/main 至少净减 1,500
  • 核心生产行数 <= +1,500,或超出的部分由总计 <= +2,000 补偿
  • 代表性测试覆盖脱敏、路由、命令/事件、激活、访问组和渠道特定回退行为

常见问题

如何检查当前重构是否进入预算?

运行 git diff --shortstat $(git merge-base HEAD origin/main) 查看整体行数变化,再用 git diff --numstat 按目录查看插件生产和核心生产,确保插件净减至少 1500、核心净增不超过 1500。

为什么我的插件行数没有减少?

可能是因为你只添加了核心辅助函数却没有删除等量的包装代码。根据验收规则,每个新核心辅助必须立即删除至少等量的插件生产行数(三个调用者时需两倍)。应先删除薄 DTO 接缝和包装测试。

QQBot 的注释恢复影响了预算怎么办?

文档明确说明仅注释删除不计入清理。预算测量应基于可执行/文档/测试代码移动,之前因包含恢复的 QQBot 解释性注释而过高评估了清理进度。建议重新测量时排除纯注释变更。