Commit Graph

2 Commits

Author SHA1 Message Date
2353d43c16 feat(channels): 全量厂商接入 —— Cline/Buddy/Gemini/LobsterAI/OpenCode/CodeArts/Qoder/ZCode/Loomy/Raccoon + 新流程 + WebUI 补齐
新增 10 个真实厂商平台(端点/模型/流程逐字照抄参考 channel-pack):

device-poll(已有执行器):
  minimax  保留(MiniMax 形态:看 status 字段,slow_down +5s)
  cline    WorkOS 设备码(判据看 error 字段、HTTP 可非 2xx;slow_down +1s;
           access_denied/invalid_grant 同组失败;成功后 register 第二跳
           /api/v1/auth/register 换 Cline token)。新增 deviceRegister。

state-poll(新流程):
  buddy    CodeBuddy(腾讯)。POST /v2/plugin/auth/state → authUrl+state;
           轮询 GET /v2/plugin/auth/token?state=,业务码 11217 = 未就绪继续等
           (对齐参考 loopGetToken:网络错误同样继续不中断);token 就绪后
           拿账号(失败不阻塞)。

callback:
  gemini   标准 OAuth code 交换(oauth2.googleapis.com/token,六 scope 照抄);
           oauth_callback 增 code→token 交换分支(Gemini/LobsterAI 复用)。
  lobsterai 本地回调 + authCode 换 token(lobsterai-server.youdao.com)。
  trae     保留(token 直传 + ExchangeToken,已 8938574)。

paste:
  opencode 直接贴 API key(无登录流)。
  codearts 企业凭据 + SDK-HMAC-SHA256 签到(claim_fn 钩子,canonical request
           + 派生密钥链 kDate→kNonce→kSigning→signature)。

manual(后端给 manual_hint,明确说明而非假装成功):
  qoder    WASM 签名头(纯 Lua 无法生成)
  zcode    captcha 求解
  loomy    微信扫码
  raccoon  图片二维码

WebUI(之前只覆盖 vnc/url+轮询/device-poll):
  chLogin 增 manual / paste 两个分支:manual_hint 展示 + 凭据粘贴框 +
           提交按钮。新增 chComplete 调 channels/login/complete 落保险库,
           凭据不回显、失败给可读错误不重载页面。node --check 过。

set_endpoints 增 register/state 覆盖(运维能力 + 测试缝,与 device/checkin 同语义)。

行为测试(照参考逐行):
  TestClineWorkOSBehavior  5 行:非200 authorization_pending 继续等 /
    slow_down 退避 1s(interval=2)/ access_denied 失败 / 成功 register 凭据
    是 CLINE-AT-1(不是 WorkOS token)/ 非200无 error 失败。
  TestBuddyStatePollBehavior 3 行:state 申请给 authUrl / 首拍 11217 pending
    次拍 token completed / account 查询失败不阻塞回退默认名。

变异测试修复(deviceOneStep 拆 workos/minimax 两分支后幸存体暴露):
  锚点 +step / authorization_pending 现两处同形,strings.Replace(,,1) 只改
  workos 分支、minimax 决策表没杀到 → 改 ReplaceAll 全改;删冗余第 6 变异体。
  5 变异体全杀。回归:channels/device/cline/buddy/trae/legacy/保险库/e2e 全绿。
2026-10-12 00:28:26 +08:00
da0282a3db test: 四类验收 —— 加密解密 / 变异 / 压力 / 旧通路
用户要求的四类测试全部落地,且每类都抓到了真问题:

## 0) 测试暴露的真实缺陷(先修后测)

**保险库明文落盘**(加密解密测试的目标缺陷):.secrets/<plugin>.json 此前
是明文 JSON。接入 SecretBox(与 config.yaml 同一把 master key、同 enc:v1
形态):SetSecretBox 注入(secretSealer 接口,测试可桩);写盘逐值加密、
读盘逐值解密;无前缀旧值原样通过 —— 旧明文库可读、下次写整体重封。
core 注入点在 store 创建之后(NewPlugins 时 box 还不存在 —— 顺序 load-bearing,
修掉了一个 nil-deref)。

## 1) 加密解密(internal/lua/secrets_crypto_test.go)
- EncryptedAtRest:磁盘字节不含明文 token、带 enc:v1、文件 0600/目录 0700
- PlaintextFallbackAndUpgrade:旧明文库可读 + 任意一次写整体重封为密文
- WrongMasterKey:换 key 后读库必须报错(静默空会让插件重登覆盖凭据)
- ConcurrentPlugins:8 插件×2 goroutine 并发读写,无串台/丢写/文件数正确

## 2) 变异(internal/core/device_mutate_test.go + device_harness_test.go)
- 决策表抽成 deviceHarness.runDecisionTable(行为测试与变异测试共用,
  单一事实源)
- 5 个语义变异逐个杀:slow_down 不加 interval / denied 不识别 /
  expired_token 不识别 / authorization_pending 当失败 / 成功分支禁用
- 行3/行4 断言 message 区分(用户拒绝/过期)—— 初版只断 state=failed 时
  两个变异体幸存(落进通用 failed 分支),加 message 后全杀。
  这正是变异测试的价值:暴露断言太弱。
- 基准(未变异)必须全过 —— 防止测试自身失效的假阳性

## 3) 压力(internal/core/channels_stress_test.go)
- ConcurrentLogins:12 轮并发 device-poll,会话互不串台、全部终态
- ClaimStress:30 并发领签到,上游收到恰 30 次(无登录态丢失)

## 4) 旧通路(channels_stress_test.go 后半 + 复用 lua 包测试)
- LegacyVaultPlaintextLoad:老版本明文库 → 新版本可读 → 下次写重封
- LegacySourceSealedConfig:明文 api_key 的旧 config.yaml → 运行期解密、
  落盘 seal、master.key 0600 生成

全量 lua/core/gateway/types/scheduler/provider/config 测试通过;build+vet 绿。
2026-10-11 20:50:52 +08:00