适配器: login_admin.go(StartLogin 幂等取二维码/LoginStatus idle-waiting-confirmed-failed); login.go 重写 Connect 委托 StartLogin+等待,后台 runLogin 轮询,completeLogin/failLogin (锁序 loginMu->a.mu 不嵌套反向无死锁); adapter.go 加登录会话字段 网关: admin_channels_weixin.go(2 端点 login-qr/login-status owner+审计, confirmed 合并写回 channels.json 保留 base_url/cdn/黑白名单 + Reload 热重载连接; qrImage best-effort Base64, token 掩码) + server.go 路由 前端: WeixinLogin.tsx(token空→扫码按钮→二维码→1.5s轮询→confirmed提示已登录+显示bot_id), AdapterDetailPage 渲染, api/types 补类型 必需偏离(最小化): 允许空token的weixin账号被构建/持久化(channels.go+runtimeconfig移出 tokenRequiringPlatforms),否则空token账号无法注册调用StartLogin; 空token保持断开(configured 仍要求token非空),确认后才持久化连接——守红线。 测试: login_admin/admin端点用例; 后端 build/vet/test 全绿 + 前端 build 101模块绿.
agent-119 后端: - buildAccountAdapter: token平台(kook/telegram/weixin)BotToken空→跳过build(不注册不占名), channelAccountsFromEnv 无tokenenv不合成账号(杜绝裸kook id="") - runtimeconfig cleanAccounts: LoadChannels/SaveChannels 丢弃token平台空token账号(清理channels.json现有裸kook, 下次保存抹掉) - findChannel: 裸平台名(kook)回退到该平台第一个带token账号, open"kook"不再命中裸的missing token 我补 前端token掩码不就覆真值: - openConfig 不再把'(已配置,仅掩码显示)'当token回填(setToken空)→save token空不写bot_token保留真值 - 加 tokenHint(显示'已配置留空不改'/重填换); 修之前channels.json kook:3fc8 token变掩码串的bug 全仓 build/vet/test绿+前端build绿(463行)
- runtimeconfig/channels.go: channels.json 承载 map[platform][]ChannelAccount(token/baseURL/黑白名单/群聊限流), LoadChannels 优先文件/回退env, SaveChannels(0600+tmp原子写), Upsert/Delete/Masked脱敏 - channelbridge/reload.go: adapterManager 热替换——工厂重建新adapter先连接, 再原子断旧adapter(独立readCtx/进行中不中断); Bridge.Reload(platform) 逐账号增删 - 面板 PUT/DELETE /admin/channels/{platform}/config(owner+审计) 落盘channels.json+Reload热更新; GET /admin/channels 附账号掩码不泄裸token - 前端 Channels.tsx 配置表单(id/token/baseURL/黑白名单/限流+config JSON)+保存热更新提示+掩码展示/删除 - .gitignore 加 channels.json; .env 退兜底(.env.example注明); token不打印/Config()脱敏 - channelbridge.go 拆 logic→reload.go(742→731); 全仓 go build/vet/test绿+前端build绿 - 未做真token端到端(需渠道凭据,不读.env)——如实标注待凭据