Files
FlowPilot/md/openai手机号接码-MaDao统一接入与侧边栏样式重构开发方案.md
T
2026-05-29 00:44:30 +08:00

26 KiB
Raw Blame History

OpenAI 手机号接码 MaDao 统一接入与侧边栏样式重构开发方案

1. 文档定位

本文用于指导后续重新实现 PR #288 相关能力,并同时收敛侧边栏里文本框、按钮、接码 provider 显隐和无用保存按钮问题。目标不是照搬 PR,而是在现有项目真实结构上重新设计一次,保证 OpenAI 手机号注册、后置手机号验证、provider 接码生命周期、设置持久化和侧边栏 UI 一致落地。

本文只是一份开发方案,不直接修改功能代码。后续实现时应按本文的阶段清单逐段开发、逐段自检,发现现有代码与本文冲突时,先修正方案或明确取舍,再改代码。

2. 分析基线

已确认的当前工程基线:

  • 当前扩展是 Chrome MV3manifest.json 的后台入口是 background.js,侧边栏入口是 sidepanel/sidepanel.html
  • OpenAI flow 定义在 flows/openai/index.jsflows/openai/workflow.js,并声明 supportsPhoneSignup: truesupportsPhoneVerificationSettings: true
  • Kiro/Grok 当前不支持手机号注册和接码设置,flows/kiro/index.jsflows/grok/index.js 均为 supportsPhoneSignup: falsesupportsPhoneVerificationSettings: false
  • 手机接码目前在架构上仍是 OpenAI 私有能力。docs/多注册流程架构边界.md 明确指出 HeroSMS / 5sim / NexSMS、取号、复用、轮询、换号、释放、手机号注册和后置 add-phone 暂不进入 core 通用服务。
  • 当前 provider 注册表是 phone-sms/providers/registry.js,已有 hero-sms5simnexsms
  • 当前接码主编排是 background/phone-verification-flow.js,实际运行还要同步考虑 background.js 内联后的运行入口。
  • 当前侧边栏已有统一表单布局基础:--data-label-width: 76px--data-field-height: 34px.data-inline 作为右侧弹性控制区、.btn.data-input / .data-select 共用高度。
  • tests/sidepanel-form-layout.test.js 已保护“每个 .data-row 只有 label + 一个控制区”“按钮/输入框高度统一”“不再出现 icon-action-btn”等约束。

PR #288 的已知结论:

  • PR 标题为“接入 MaDao 统一接码并收敛 provider 换号链路”。
  • PR 增加了 phone-sms/providers/madao.js,并在 provider registry 中注册 MaDao。
  • PR 的 MaDao 适配层包含 acquireActivationpollActivationreleaseActivationrotateActivationreplaceRoutingActivation,核心 API 为 /api/acquire/api/poll/api/release/api/routing/replace
  • PR 中值得保留的是 MaDao provider 模块边界、routing_plan / direct 两种模式、路由换号 /api/routing/replace 的行为。
  • PR 中不应照搬的是主流程里 MaDao 特例函数、sidepanel 里散落的 MaDao 专用行和 GitHub 图标按钮,以及任何绕过 provider adapter 契约的判断。

3. 需求与硬边界

必须满足的需求:

  • 重新实现 MaDao 接码接入,不直接复制 PR #288 的堆叠式 UI 和主流程特例。
  • 不留旧的无用代码。被新 provider 契约、统一 UI descriptor、自动保存机制取代的分支、按钮、样式和测试夹具都要清理干净。
  • 文本框与按钮高度、边框、宽度体系统一;按钮不需要图标。
  • 表单布局采用“固定 label 宽度 + 右侧控制区占剩余宽度 + 可选按钮固定最小宽度”的模型,而不是固定文本框宽度。
  • 即使某些文本框右侧新增按钮,也不能挤乱同一组布局;输入框应继续占剩余宽度。
  • 项目地址必须正确:CPA 为 https://github.com/router-for-me/CLIProxyAPIsub2api 为 https://github.com/Wei-Shaw/sub2api
  • GitHub 按钮使用普通文字按钮并纳入统一按钮样式,不做图标按钮。
  • 自动保存已经存在时,纯“保存设置”按钮应删除;但查询价格、查余额、刷新列表、清空、记录运行时号码等有明确动作语义的按钮可以保留。
  • OpenAI 手机号注册模式必须和后置 add-phone 区分,不能混用状态字段。

不能突破的边界:

  • MaDao 只接入 OpenAI 手机接码能力,不把接码提升为 core 通用服务。
  • Kiro/Grok 不显示 OpenAI 接码、Plus、平台绑定相关配置。
  • 主流程不得写 MaDao 专用大分支;新增能力应通过 provider registry 和 provider adapter 暴露。
  • 不能因为接入 MaDao 破坏现有 HeroSMS、5sim、NexSMS 行为和存量配置。
  • 不能只修改 background/phone-verification-flow.js 而忘记实际加载的 background.js,也不能只改 background.js 导致模块测试失真。

4. 当前真实实现现状

4.1 OpenAI 手机号注册模式

OpenAI flow 当前不是单一注册路径,而是多个 variant:

  • normal:邮箱注册 -> 邮箱验证码 -> 登录验证码 -> 后置手机号验证 -> OAuth -> 平台回调。
  • normalPhone:手机号注册 -> 手机验证码 -> 登录验证码 -> 绑定邮箱 -> 绑定邮箱验证码 -> OAuth -> 平台回调。
  • normalPhoneRelogin:手机号注册并绑定邮箱后,切入绑定邮箱重登链路。

因此“手机号注册”和“后置手机号验证”虽然都依赖接码 provider,但状态槽位不同:

  • 手机号注册使用 signupPhoneNumbersignupPhoneActivationsignupPhoneCompletedActivation
  • 后置 add-phone 使用 currentPhoneActivation

后续 MaDao 接入必须同时覆盖这两条链路,并在日志、换号、释放、成功完成时保持状态字段不串线。

4.2 provider 当前模型

当前 provider 顺序为 hero-sms5simnexsmsDEFAULT_PHONE_SMS_PROVIDER_ORDER 和相关 normalize 函数会按 provider 数量截断,所以接入 MaDao 时必须同步扩展 provider 常量、顺序、registry、测试 fixture,否则 UI 选中了 MaDao 也可能被 normalize 回退或截断。

当前 background/phone-verification-flow.js 仍有较多 provider 内联逻辑。后续应把 MaDao 做成 adapter,并逐步收敛公共生命周期:

  • acquire:取号。
  • poll:轮询短信。
  • releasecancel / ban / finish。
  • rotate:失败换号,允许 provider 自己决定是先 release 再 acquire,还是走路由替换。
  • normalize:把 provider 返回值转成统一 activation。

4.3 侧边栏 UI 当前模型

侧边栏接码区已经存在 HeroSMS、5sim、NexSMS 的配置行,且很多字段复用了 HeroSMS 命名或布局类。后续实现不应继续在 sidepanel.js 里追加大量 if provider === ... 片段,而应引入 provider UI descriptor 或至少集中式字段矩阵,让“显示哪些行、保存哪些字段、切换 provider 时保留哪些值”有统一来源。

当前布局已有正确方向:

  • .data-row 负责一行。
  • .data-label 固定 label 宽度。
  • .data-inline 作为右侧 control areaflex: 1 1 0
  • .data-input.data-select.btn 统一高度。
  • .data-inline-btn 用固定最小宽度承接右侧动作按钮。

需要避免的是:

  • 直接在 .data-row 里放多个并列控制元素,导致 label 后布局不可预测。
  • 单独给某些按钮做无边框、特殊高度、图标按钮或内联 style。
  • 为某个 provider 写独立布局,造成切换 provider 后高度、宽度、边框不一致。

5. PR #288 取舍

5.1 保留的设计

保留 MaDao 作为独立 provider 模块的方向。建议文件为 phone-sms/providers/madao.js,暴露 createProvider(),并返回统一方法:

  • acquireActivation(state, options, deps)
  • pollActivation(state, activation, deps)
  • releaseActivation(state, activation, action, deps)
  • rotateActivation(state, activation, options, deps)
  • replaceRoutingActivation(state, activation, options, deps)

保留 MaDao 默认配置:

  • provider id: madao
  • label: MaDao
  • baseUrl 默认 http://127.0.0.1:7822
  • service 默认 openai
  • HTTP Secret 通过 Authorization: Bearer <secret> 传递

保留两种模式:

  • routing_plan:使用 madaoRoutingPlanId,取号只提交 routing_plan_idservice,失败换号优先走 /api/routing/replace
  • direct:使用 madaoProviderIdmadaoCountrymadaoAutoPickCountrymadaoReusePhonemadaoMinPricemadaoMaxPrice

5.2 不照搬的内容

不照搬主流程里的 MaDao 专用函数,例如 requestMaDaoActivationgetMaDaoProviderForState 这类把 provider 逻辑重新塞回编排层的写法。

不照搬 sidepanel 中大量散落的 MaDao row/handler。MaDao 字段应通过 provider UI descriptor 或集中显隐矩阵接入:

  • provider 选择变更只触发一套 applyPhoneSmsProviderUi(provider, state)
  • 保存 payload 只走一套 collectPhoneSmsProviderSettings(provider)
  • 恢复 UI 只走一套 restorePhoneSmsProviderSettings(state)

不增加 btn-open-madao-github。MaDao 本地服务不是当前目标项目地址入口,GitHub 入口只保留已有项目来源按钮,且按钮样式应统一为普通文字按钮。

6. 最终设计

6.1 provider 契约

新增或收敛 provider adapter 契约:

{
  id,
  label,
  defaultProduct,
  acquireActivation(state, options, deps),
  pollActivation(state, activation, deps),
  releaseActivation(state, activation, action, deps),
  rotateActivation(state, activation, options, deps)
}

编排层只依赖契约,不依赖 provider 私有字段。activation 可以携带 provider 私有字段,但编排层只把它们原样保留和回传,最多读取统一字段:

  • activationId
  • phoneNumber
  • provider
  • serviceCode
  • countryId
  • countryLabel

MaDao 私有字段例如 madaoRoutingPlanIdmadaoRoutingItemIdmadaoAcquirePathmadaoStatus 只由 MaDao adapter 或展示层使用。

6.2 MaDao 设置字段

新增设置字段建议如下:

  • madaoBaseUrl
  • madaoHttpSecret
  • madaoMode: routing_plandirect
  • madaoRoutingPlanId
  • madaoProviderId
  • madaoCountry
  • madaoAutoPickCountry
  • madaoReusePhone
  • madaoMinPrice
  • madaoMaxPrice

madaoServiceName 不建议作为普通可编辑项显示。OpenAI flow 下 service 固定为 openai 更符合当前边界,也能减少用户误配。如果确实需要保留兼容字段,可以内部默认和持久化,但 UI 只显示只读说明或不显示。

这些字段必须进入:

  • 默认 state。
  • 导入导出和最新设置合并 key。
  • sidepanel 恢复、保存、消息更新。
  • background 模块与实际 background.js 同步入口。
  • 相关单元测试 fixture。

6.3 MaDao 模式显隐

MaDao 选中时显示:

  • Base URL。
  • HTTP Secret。
  • 模式选择。

routing_plan 模式显示:

  • 路由方案选择或路由方案 ID。
  • 刷新路由方案按钮,如果 MaDao 后端提供列表接口;如果没有列表接口,只保留 ID 输入框,不做假刷新按钮。

routing_plan 模式隐藏:

  • direct provider。
  • country。
  • auto pick country。
  • reuse phone。
  • min/max price。

direct 模式显示:

  • MaDao provider。
  • country。
  • auto pick country。
  • reuse phone。
  • min/max price。

direct 模式隐藏:

  • routing plan 字段。
  • routing replace 相关交互。

6.4 其他 provider 显隐矩阵

HeroSMS 显示:

  • API Key。
  • 国家优先级。
  • 生效顺序。
  • 拿号优先级。
  • 运营商。
  • 价格区间:min、max、preferred。
  • 号码复用。
  • 白嫖复用。
  • 查询价格。
  • 查余额。

5sim 显示:

  • API Key。
  • 国家优先级。
  • 生效顺序。
  • 运营商。
  • 产品代码。
  • 价格区间:min、max。
  • 号码复用。

5sim 不显示:

  • preferred price。
  • HeroSMS 价格档位查询。
  • 白嫖复用。

NexSMS 显示:

  • API Key。
  • 国家优先级。
  • 生效顺序。
  • 服务代码。

NexSMS 不显示:

  • preferred price。
  • operator。
  • product。
  • 号码复用。
  • 白嫖复用。

MaDao 按 6.3 显隐,不复用 HeroSMS 的价格预览区,不显示无意义的国家多选和 provider 顺序内的 HeroSMS 专属说明。

6.5 换号与释放

步骤 9 和手机号注册验证码链路中的失败换号都应走统一 provider 方法:

  • provider 有 rotateActivation 时优先调用。
  • MaDao routing_plan 且 activation 带 madaoRoutingPlanId 时,rotateActivation 内部走 /api/routing/replace 并返回 nextActivation
  • MaDao direct 或没有可替换路由信息时,先 release 当前 ticket,再让编排层按 provider 顺序重新 acquire。
  • HeroSMS、5sim、NexSMS 可以先维持现状,但调用入口要向统一契约靠拢。

编排层不应关心 MaDao 的 /api/routing/replace endpoint,只应理解 rotateActivation 的返回:

{
  currentTicketId,
  currentTicketRelease,
  nextActivation
}

6.6 OpenAI 手机号注册状态

后续实现必须分别覆盖:

  • Step 2 手机号注册取号和填手机号。
  • Step 4 手机注册验证码轮询和提交。
  • Step 8 登录验证码、绑定邮箱状态分支。
  • Step 9 后置 add-phone 取号、轮询、失败换号、成功释放或保留。

关键约束:

  • signupPhoneActivation 不写入 currentPhoneActivation
  • currentPhoneActivation 不覆盖 signupPhoneActivation
  • signupPhoneCompletedActivation 用于手机号注册完成后的记录,不用于后置 add-phone 的当前订单。
  • 页面已经在等手机验证码但 state 没有 activation 时,应给出明确错误,不自动构造虚假订单。

6.7 按钮与文本框统一设计

采用固定 label 宽度,不固定文本框宽度:

| 76px label | flex:1 控制区 |

控制区规则:

  • 普通单输入:input.data-input 直接作为第二个子元素,宽度占满剩余。
  • 输入 + 按钮:使用 div.data-inline 包裹,输入 flex: 1 1 0,按钮使用 .data-inline-btn
  • 多按钮动作组:仍放入一个 .data-inline,按钮高度统一,必要时允许换行,但不破坏 label + control 的两列结构。
  • 密码显示按钮属于输入框内部交互,保留 input-with-icon,但不使用 GitHub 图标或 provider 图标。

按钮规则:

  • 所有普通按钮使用 .btn 基础类,必须有 border: 1px solid var(--border)min-height: var(--data-field-height)
  • 小按钮可以用 btn-sm / btn-xs 调整字体和 padding,但高度仍应由统一变量约束。
  • 行内动作按钮使用 .data-inline-btn,统一最小宽度,不按文案临时写 style。
  • 不再新增 icon-action-btn,已有图标按钮若不是密码显隐这种输入内部控制,应改成文字按钮。
  • GitHub 按钮显示为 GitHub 文本,使用 btn btn-outline btn-sm data-inline-btn

删除按钮规则:

  • 删除纯保存设置按钮,因为当前 saveSettings({ silent: true }) 和 autosave 已覆盖设置变更。
  • 保留“记录”“清除”“查询价格”“查余额”“拉取”“下一条”“检测出口”等命令按钮,因为它们触发的不是单纯保存。
  • 删除按钮时必须同步删除 DOM 引用、事件监听、CSS、测试断言和无用 helper。

6.8 项目 GitHub 按钮

项目地址入口只保留一套:

  • CPA: https://github.com/router-for-me/CLIProxyAPI
  • sub2api: https://github.com/Wei-Shaw/sub2api

按钮不做图标,不使用 SVG,不新增 MaDao GitHub 入口。tests/sidepanel-flow-source-registry.test.js 需要继续保护 URL 和按钮 class。

7. 方案自检

7.1 是否符合需求

符合。方案明确处理了 PR #288 的重新实现、MaDao provider 接入、OpenAI 手机号注册模式、不同 provider 显隐、文本框和按钮统一、GitHub 按钮去图标化、无用保存按钮删除、旧代码清理等要求。

7.2 是否完善

基本完善。方案覆盖后台 provider 生命周期、侧边栏显示、设置持久化、自动保存、测试和实际运行入口。需要在实现阶段继续用代码验证的点是 MaDao 后端是否提供路由方案列表接口;如果没有,则 UI 不能设计“刷新路由方案”按钮,只能提供 ID 输入。

7.3 是否完整

完整性满足本次开发目标。方案没有只看 sidepanel,也覆盖了 OpenAI workflow、Step 2/4/8/9、provider registry、settings schema、background.js 实际入口和测试。未纳入范围的是把整个接码系统抽成 core 服务,因为这与现有架构边界冲突。

7.4 是否正确

方向正确。MaDao 被设计为 OpenAI 接码 provider,不污染 Kiro/Grokrouting replace 被封装在 provider adapter 内,不让主流程理解 MaDao endpoint;手机号注册和后置 add-phone 状态分离,避免订单串线。

7.5 是否规范一致

一致。UI 沿用当前 .data-row.data-label.data-inline.btn.data-inline-btn 体系;provider 沿用 phone-sms/providers/registry.js;测试沿用 node --test tests/*.test.js;中文文档风格与 md 目录已有方案保持一致。

7.6 是否存在设计冲突

已识别并规避以下冲突:

  • “接码通用化”与现有架构边界冲突:本方案不通用化到 core。
  • “固定文本框宽度”与行内按钮扩展冲突:本方案固定 label 和按钮最小宽度,让输入框占剩余。
  • “MaDao routing_plan”与 direct 参数冲突:两种模式显隐互斥,payload 也互斥。
  • “自动保存”与保存按钮冲突:纯保存按钮删除,命令按钮保留。
  • “PR #288 直接 diff”与当前本地 UI 改动冲突:只吸收 provider 行为,不照搬 sidepanel 和主流程特例。
  • “模块测试文件”与 background.js 实际入口冲突:实现阶段必须同步两边或使用现有生成/同步方式验证。

7.7 方案自身缺陷和风险

仍需在实现阶段验证的风险:

  • MaDao 后端接口返回字段可能和 PR 样例不完全一致,需要 provider 单测覆盖异常 payload、空 ticket、空 phone、HTTP 错误和超时。
  • 当前 background/phone-verification-flow.js provider 内联较多,完全一次性抽象所有 provider 风险较高。建议本次只为 MaDao 建立统一入口,并把会影响 MaDao 的 acquire/poll/release/rotate 入口收敛,不做无关大重构。
  • sidepanel 当前文件较大,集中 descriptor 改造要控制范围。优先让接码设置区 descriptor 化,不顺手重构 Plus、代理、邮箱等其他区域。
  • 删除按钮时容易误删命令按钮。判断标准必须是“是否只保存当前设置”,不是“按钮文案里是否有保存/记录”。
  • provider 顺序扩展到 4 个后,测试 fixture 中硬编码 3 个 provider 的地方较多,必须全局搜索更新。

8. 分阶段开发清单

阶段 1:基线保护与差异确认

开发内容:

  • 确认当前分支状态,记录本地 ahead commit,不回退已有改动。
  • 对比 PR #288,只提取 MaDao provider、routing replace 行为和测试意图。
  • 运行现有定向测试,建立失败/通过基线。
  • 全局搜索旧图标按钮、保存按钮、provider 顺序硬编码、MaDao 残留。

阶段自检:

  • 确认没有改动功能代码。
  • 确认 CPA / sub2api GitHub URL 未被误改。
  • 确认没有把 PR #288 中删除大量无关文件的改动纳入本次范围。
  • 确认终端和文档无乱码。

阶段 2MaDao provider 模块与 registry

开发内容:

  • 新增 phone-sms/providers/madao.js
  • phone-sms/providers/registry.js 注册 madao
  • 扩展 DEFAULT_PHONE_SMS_PROVIDER_ORDER 为 4 个 provider。
  • 更新 provider normalize、label、moduleKey、provider ids 测试。

阶段自检:

  • MaDao 未加载时错误信息明确。
  • provider order 不截断 MaDao。
  • HeroSMS、5sim、NexSMS normalize 行为不变。
  • 单测覆盖未知 provider 回退默认 provider。
  • 检查新文件 UTF-8 中文错误信息无乱码。

阶段 3:接码编排层接入统一 rotate

开发内容:

  • background/phone-verification-flow.js 中接入 MaDao adapter。
  • 收敛 acquire/poll/release/rotate 的调用入口,让 MaDao 走 provider 契约。
  • Step 9 换号优先调用 rotateActivationrouting plan 返回 nextActivation 时直接继续使用新号。
  • direct 模式或没有 nextActivation 时走现有释放后重新取号流程。
  • 同步实际运行入口 background.js

阶段自检:

  • 手机号注册 Step 2/4 使用 signupPhoneActivation
  • 后置 add-phone Step 9 使用 currentPhoneActivation
  • 失败换号不会把 signup activation 写入 current activation。
  • MaDao routing replace 的 cancel/ban action 传参正确。
  • HeroSMS、5sim、NexSMS 原有换号、释放、成功完成行为不回退。

阶段 4:设置默认值、导入导出与状态同步

开发内容:

  • 新增 MaDao 设置默认值。
  • 更新 settings schema、最新设置 key、导入导出、消息保存 payload。
  • 更新 sidepanel restore 和后台 state merge。
  • madaoModemadaoBaseUrlmadaoHttpSecretmadaoRoutingPlanId、direct 字段加 normalize。

阶段自检:

  • 空配置下 MaDao 使用默认 http://127.0.0.1:7822
  • routing_plan 不提交 direct 字段。
  • direct 不提交 routing plan 字段。
  • 导入旧配置不会丢 HeroSMS / 5sim / NexSMS 设置。
  • 自动保存不会在用户输入数字半成品时强行格式化造成体验问题。

阶段 5:侧边栏 provider UI descriptor

开发内容:

  • 建立接码 provider 字段矩阵或 descriptor。
  • 将 HeroSMS、5sim、NexSMS、MaDao 的行显隐集中到一处。
  • provider 切换时保存当前 provider 独立字段,再恢复目标 provider 字段。
  • MaDao mode 切换时刷新 routing/direct 显隐。
  • 删除散落的 provider 专用重复判断。

阶段自检:

  • HeroSMS 只显示 HeroSMS 相关字段。
  • 5sim 不显示 preferred price 和白嫖复用。
  • NexSMS 不显示 operator/product/复用。
  • MaDao routing plan 不显示 direct 字段。
  • MaDao direct 不显示 routing plan 字段。
  • 切换 provider 不丢失其他 provider 已填 API key 和价格字段。
  • Kiro/Grok 下不显示接码设置。

阶段 6:文本框和按钮样式统一

开发内容:

  • 清理接码区和项目地址区不一致按钮样式。
  • 删除无用纯保存按钮及对应 JS/CSS/测试。
  • 所有行改为 label + 单一 control area。
  • 有右侧按钮的文本框统一使用 .data-inline + .data-inline-btn
  • GitHub 按钮保持文字按钮,不使用图标。

阶段自检:

  • tests/sidepanel-form-layout.test.js 通过。
  • 全局不存在 icon-action-btn
  • .data-row 没有超过两个直接子元素。
  • .btn.data-input.data-select 高度一致。
  • 按钮都有边框,除输入框内部密码显隐按钮外不出现无边框图标按钮。
  • 文案较长按钮不撑破布局,必要时按统一规则换行。

阶段 7:测试完善

开发内容:

  • 增加 MaDao provider 单测:acquire、poll、release、routing replace、direct fallback、超时、HTTP 错误。
  • 增加 provider registry 测试:MaDao 注册、顺序、label、moduleKey。
  • 增加 phone verification flow 测试:Step 9 routing replace 成功、routing replace 返回无效 next ticket、direct 模式释放后重新取号。
  • 增加 sidepanel 测试:MaDao 字段显隐、mode 切换、保存 payload、provider 切换字段保留。
  • 更新现有 provider order 和 settings schema 测试。

阶段自检:

  • 定向测试全部通过。
  • 全量 npm test 通过。
  • 没有只为测试通过而保留旧死代码。
  • 测试名称准确描述行为,不写和实现不符的宽泛断言。

阶段 8:最终清理与人工核验

开发内容:

  • 全局搜索 MaDao 旧函数名、旧按钮 id、旧 icon 类、无用 CSS。
  • 全局搜索 provider 顺序硬编码的 3 provider 残留。
  • 检查 sidepanel 渲染效果,确认按钮、文本框、select 高度和边框一致。
  • 检查 OpenAI / Kiro / Grok 各 flow 显隐。
  • 检查 CPA / sub2api 项目地址按钮。

阶段自检:

  • rg -n "requestMaDaoActivation|getMaDaoProviderForState|btn-open-madao-github|icon-action-btn" . 无结果。
  • rg -n "hero-sms.*5sim.*nexsms" tests sidepanel background phone-sms 中需要 4 provider 的地方已包含 MaDao。
  • 文档、源码、测试无乱码字符;乱码样本不要写进方案正文,避免检查命令命中自身。
  • git diff 中没有无关删除、无关格式化或用户未要求的重构。
  • 最终运行全量测试并记录结果。

9. 验证命令

建议按阶段使用以下命令:

node --test tests/phone-sms-provider-registry.test.js
node --test tests/phone-verification-flow.test.js
node --test tests/sidepanel-phone-verification-settings.test.js
node --test tests/sidepanel-form-layout.test.js
node --test tests/sidepanel-flow-source-registry.test.js
npm test

建议的清理检查:

rg -n "requestMaDaoActivation|getMaDaoProviderForState|btn-open-madao-github|icon-action-btn" .
$staleMarkers = @('T' + 'ODO', '待' + '补', '以后' + '再说', '占' + '位') -join '|'
rg -n $staleMarkers md sidepanel background phone-sms tests
git status --short --branch
git diff --check

10. 最终结论

本次应按“OpenAI 私有接码 provider 扩展 + 侧边栏 provider descriptor + 表单统一布局”三条线并行收敛。MaDao 的价值在于统一接码后端和 routing replace,不应把它变成主流程里的新特例;UI 的价值在于固定 label、固定按钮最小宽度、输入框占剩余,而不是继续给每个 provider 单独堆宽高和按钮风格。

后续实现完成的标准是:MaDao 能在手机号注册和后置 add-phone 两条链路中稳定取号、轮询、释放、换号;不同 provider 只显示自己需要的字段;按钮和文本框视觉一致;自动保存下没有多余保存按钮;旧的 MaDao 特例和图标按钮代码完全清理。