# VOC-03 设计方案(重写版):多渠道一键安装 + 安装即弹付费 > 真实场景:教练现场用 VOC 技能做电商数据采集,**不走飞马平台 UI**;现场可能是 Claude Code / Codex / Workbuddy。 > 关键诉求:**每个渠道一段「一键复制安装提示词」**;**安装一完成就在浏览器弹付费页**——必须在进入工作流、消耗 LLM token 之前弹,避免「跑了半天报告、到取数那步才 402」。 ## 0. 现状(基于 Parse `Skill` 表 + voc-api-catalog 代码实读) - `Skill` 表(78 行):`name`=`voc-skill`、`type`=`claude`、`category`=`claude-code`(**单值**)、`cdnPrefix`=安装命令、`cdnUrls`={npm,global,install}、`apig`→APIG `Vo3ROWEvDy`。 - **token 检测逻辑(权威出处:`claude-code/claude-code-voc-intelligence/mcp/src/core/credentials.js`)**:不存在 `~/.openclaw/` 路径。实际有**两条计费链 + 两种 token**: - `readNewApiToken()` → **NewAPI / fmode-api 计费 token(`sk-` 开头),现为主计费链**。取值优先级:入参 → `.env.local`/环境变量 `FMODE_API_KEY`/`NEWAPI_TOKEN` → `~/.claude/voc-credentials.json` `.fmodeApiKey` → `~/.fmode/config.json` → **`~/.claude/settings.json` 的 `env.ANTHROPIC_AUTH_TOKEN`**(经 `pickFmodeAnthropicToken` 门控:必须 `sk-`、非 `sk-ant-`、`ANTHROPIC_BASE_URL` 指向 fmode)。 - `readVocToken()` → **平台 apig 会话 token(`r:` 开头),旧链路回退**。取值:入参 → `.env.local` `VOC_TOKEN`/`VOC_SOCIAL_TOKEN` → 环境变量 → `~/.claude/voc-credentials.json` `.vocToken`/`.token`。 - **两种充值入口不同(`payment-links.js` 权威常量)**: - sk-(NewAPI)余额不足 → `https://app.fmode.cn/dev/studio/?balance=fmodeapi`(自动开余额充值弹窗) - r:(apig 会话)→ `https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF`(+ workshop 套餐页),`resolveVocUserId()` 调 `/parse/users/me` 拿 objectId - **状态分类(代码里已区分)**:缺 NewApi token / 缺 voc token / token 类型错(给了 sk- 但需 r:)/ 真 402 余额不足 / 403 无权限。"缺 token"是**配置/读取**问题,不等于余额不足,**优先自愈读 settings.json 的 sk-,不要直接甩人去充值**。 > 结论修正:付费解析、计费链、状态分类都已在 `voc-api-catalog` 代码里实现且权威。VOC-03 不要重写 token 逻辑,只需:① `Skill` 表支持多渠道话术;② 新增 `--activate` 入口,在 bootstrap 阶段**复用 `credentials.js`/`payment-links.js`** 做激活检查与开页。 ## 1. 核心决策:①不动 `--smoke` ②新增专用入口 ③弹窗按 token/余额状态触发 ### 1.1 为什么不能改 `--smoke` `--smoke` 是健康自检,飞马 UI 用户 / 内部 / CI 都在用——他们**已经有 token**。若把弹付费塞进 `--smoke`,这些人每次都被强弹付费页,打断操作;CI 里弹浏览器更是错误。所以 **`--smoke` 保持原样,绝不加开浏览器**。 ### 1.2 新增「其他 AI 编程器专用」入口(带后缀) 给外部渠道单开一个入口,只有它会触发激活/弹付费。命名建议 `--activate`(也可叫 `--onboard` / `--ide`): ``` voc-skill workspace --activate # 外部 AI IDE 安装话术里用这个 1. 安装/拷贝技能文件(含一次轻量 smoke 自检) 2. ensureActivated() ← 仅此入口执行 3. 之后才进入任何取数/工作流 ``` `--smoke`(内部/飞马/CI 用)行为完全不变。 ### 1.3 弹窗按「状态」触发,而不是按命令——双保险(复用现有 token 逻辑) 关键:`ensureActivated()` **必须复用 `credentials.js` 的 `readNewApiToken()`/`readVocToken()`**,不能另建 `~/.openclaw/...`——否则会把已通过 `~/.claude/settings.json` 配好的 Claude Code 用户误判为“缺 token”而误弹(正是你担心的场景)。 ``` ensureActivated(): newApi = readNewApiToken() # sk-(含 settings.json 的 ANTHROPIC_AUTH_TOKEN 自愈) voc = readVocToken() # r: 会话 token if !newApi && !voc: # 真「缺 token」(onMissing) 开 fmode-api 余额页 studio/?balance=fmodeapi(优先)或登录页,并提示可配 FMODE_API_KEY 自愈 else: 跳一次轻量探测(catalog 自检/getApig)判状态: ok → print "✅ 已激活",不开浏览器,放行 402 → 按链路选充值页:sk-链→studio/?balance=fmodeapi;r:链→apig-pay/?user=..&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF 401/403 → 不充值,原样转述 assistantMessage 开页 URL 追加 &channel={CH}&src=install 归因;始终打印 URL 兜底(headless) 跨平台开浏览器: win `cmd /c start ""` / mac `open` / linux `xdg-open`;VOC_OPEN_PAYMENT=0 强制关 ``` 注:本地拿不到“余额数字”,402 以实际探测响应为准;“已激活”= 探测不报 402/401/403。 这样:现场新教练(无任何 token)→ 装完立刻引导激活/充值;Claude Code 已配 sk-(或飞马已充值)→ 探测 ok,**永不被打扰**。命令隔离 + 状态隔离,双重防误弹。 提示词职责因此变薄:「粘贴→运行 `--activate` 命令→若弹出付费页就先充值/登录,再继续;若提示已激活就直接用」。弹付费稳定发生在烧 token 之前,且只对真正需要的人弹。 ## 2. `Skill` 表多渠道改造(最小非破坏性) 现状 `category` 是单值 `claude-code`。两种做法,推荐 A: ### 方案 A(推荐):给 `Skill` 加一个 Object 字段 `installPrompts` 一行 skill 承载所有渠道,不改主键、不拆行: ```json installPrompts: { "claude-code": { "prompt": "<一键复制话术>", "command": "npx --yes @vocmarket/voc-skill@latest workspace --activate", "verified": true, "verifiedAt": "2026-06-29" }, "codex": { "prompt": "...", "command": "...", "verified": false, "verifiedAt": null }, "workbuddy": { "prompt": "...", "command": "...", "verified": false, "verifiedAt": null } } ``` 再加 `paymentConfig: { apigid, funId }`(按渠道可不同 funId,做分渠道定价/归因)。 前端按 `installPrompts` 的 key 渲染「渠道 Tab + 一键复制 + 已测试徽标」。 ### 方案 B:每渠道一行 Skill 复用现有 `category` 字段,新增 `category=codex`/`workbuddy` 的行。优点是贴合现有结构,缺点是同一技能多行、话术/版本要同步维护。**仅当前端/计费已强依赖按 category 取单行时才用。** ## 3. 三套一键复制安装提示词(话术模板) 共同结构(占位 `{CH}`): > 「请在当前项目文件夹的终端执行:`npx --yes @vocmarket/voc-skill@latest workspace --activate`。 > 安装完成后:若显示「✅ 已激活」(你在 Claude Code 配了 fmode 的 `sk-`、或已在飞马充值),直接继续; > 若浏览器自动弹出充值页(sk- 链:`studio/?balance=fmodeapi`;r: 会话链:`apig-pay`),说明尚未激活,请先扫码登录/充值; > **在付费页完成前,不要进入任何取数/报告流程**(避免空耗 token)。 > 拿到 token 后写入 `.env.local`(`FMODE_API_KEY=sk-...` 或 `VOC_TOKEN=r:...`)或 `~/.claude/voc-credentials.json`,再继续。 > 全程以工具实际返回的 assistantMessage 为准。」 渠道差异(仅薄薄一层): - **Claude Code**:作为 skill/plugin 安装,附 `.mcp.json` 注册说明 - **Codex**:在 Codex CLI 终端粘贴运行;说明其 config 注册方式 - **Workbuddy**:对应其技能/命令注册入口 ## 4. 安全(更正我之前的误判) - **收回之前的警告**:读 `~/.claude/settings.json` 的 `env.ANTHROPIC_AUTH_TOKEN`(sk-) **是本产品正常的计费 token 解析路径**,已由 `pickFmodeAnthropicToken` 门控(必须 sk-、非 sk-ant-、base 指向 fmode)。那是用户自己的 fmode 计费 key、本地鉴权,不是跨应用抓取——之前是我理解错了,这段不用从话术里删。 - 代码里已守住的红线:**token 绝不回显**到报告/日志/聊天;不发往第三方。保持这两点即可。 - 401/403 不走充值,原样转述 assistantMessage;仅「真缺 token」与真 402 引导付费,且缺 token 优先自愈读 sk-。 ## 5. 待你确认/我可执行的落地项 1. 给 `Skill` 表加 `installPrompts`(Object)、`paymentConfig`(Object) 字段,并回填 voc-skill 三渠道话术(用你给的 masterKey 可直接写)。 2. 改 `@vocmarket/voc-skill` 包:新增 `workspace --activate` + `ensureActivated()`,**复用 `mcp/src/core/credentials.js` 与 `payment-links.js`**(readNewApiToken/readVocToken/buildVocRechargeInfo/buildFmodeApiRechargeUrl),加跨平台开浏览器 + URL 兜底 + `VOC_OPEN_PAYMENT` 开关;`--smoke` 不动。 3. 产出 Claude Code / Codex / Workbuddy 三套提示词并各自冒烟,回写 `verified/verifiedAt`。 4. ~~apigid 不一致~~ 已澄清:`payment-links.js` 权威常量 `VOC_SOCIAL_APIG_ID='Vo3ROWEvDy'`、`VOC_RECHARGE_FUN_ID='HOkkX72PMF'`;旧 api-config.json 里的 `7HwdQZk55B` 是另一个/陈旧 apig,`--activate` 以 `payment-links.js` 为准。