@vocmarket/voc-skill 0.3.24 → 0.3.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "voc-intelligence",
3
3
  "description": "VOC intelligence skills for Claude Code: end-to-end VOC business workflows, Xiaohongshu and Douyin trend reports, live social VOC collection, Fmode Doubao image analysis, token/recharge checks, evidence-card outputs, prioritized issue pools, single-problem deep dives, competitor maps, 7-day content plans, VOC-backed speaking script co-creation, boss/operator action plans, and multi-turn memory.",
4
- "version": "0.3.24",
4
+ "version": "0.3.25",
5
5
  "author": {
6
6
  "name": "nkkj-BrainHack"
7
7
  }
package/bin/claude-voc.js CHANGED
@@ -124,6 +124,40 @@ function ensureDir(dirPath) {
124
124
  fs.mkdirSync(dirPath, { recursive: true });
125
125
  }
126
126
 
127
+ // Remove an existing install dir, resilient to Windows locks.
128
+ // A normal recursive remove fails with EPERM/EBUSY when the directory is held
129
+ // by a running process — most commonly a Claude Code session / VSCode terminal
130
+ // whose current working directory is inside the plugin dir. Such a directory
131
+ // can still be *renamed* even though it cannot be deleted, so on failure we move
132
+ // it aside and install fresh, then best-effort delete the moved-aside copy.
133
+ function removeDirResilient(targetDir) {
134
+ try {
135
+ fs.rmSync(targetDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 200 });
136
+ return;
137
+ } catch (err) {
138
+ if (!['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY'].includes(err.code)) throw err;
139
+ const asidePath = `${targetDir}.held-${Date.now()}`;
140
+ try {
141
+ fs.renameSync(targetDir, asidePath);
142
+ } catch (renameErr) {
143
+ const e = new Error(
144
+ `无法更新技能目录(被占用):${targetDir}\n` +
145
+ `原因:该目录正被一个运行中的进程占用(常见是该工作区里仍开着的 Claude Code 会话或 VSCode 终端,其当前目录在该插件目录内)。\n` +
146
+ `请关闭占用该目录的 Claude Code 会话/终端后重试安装。\n` +
147
+ `(${err.code}: ${err.message}; rename fallback failed: ${renameErr.code || renameErr.message})`
148
+ );
149
+ e.code = err.code;
150
+ throw e;
151
+ }
152
+ console.log(`Existing skill directory was in use; moved aside to: ${asidePath}`);
153
+ try {
154
+ fs.rmSync(asidePath, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 });
155
+ } catch (cleanupErr) {
156
+ console.log(`Note: moved-aside copy is still in use and was not deleted. Remove it later: ${asidePath}`);
157
+ }
158
+ }
159
+ }
160
+
127
161
  function isInside(parentDir, childDir) {
128
162
  const relative = path.relative(path.resolve(parentDir), path.resolve(childDir));
129
163
  return relative === '' || (!!relative && !relative.startsWith('..') && !path.isAbsolute(relative));
@@ -264,8 +298,8 @@ function workspaceTrendSkillText(options) {
264
298
  '',
265
299
  `- 用户要求${options.platform}趋势情报、内容趋势、评论分析、真实采集、live采集或社媒 VOC 时,必须运行本技能包的工具或 MCP,不要只凭经验回答。`,
266
300
  '- 用户说“live / 真实采集 / 进入 live / 实时采集 / 抓真实数据”时,必须运行 live 模式工具。不要回复“我不能实时抓取外部数据”。本技能包已经提供本地 VOC 采集入口。',
267
- '- live 模式返回 `needs_token`、`needs_recharge` 或 `needs_valid_token` 时,必须把工具输出里的 `assistantMessage` 原样转述给用户,尤其不能省略充值/开通链接。',
268
- '- 如果工具输出里有 `nextActions`,至少转述其中带 `apig-pay` 的充值链接。',
301
+ '- live 模式返回 `needs_token`、`needs_recharge` 或 `needs_valid_token` 时,必须把工具输出里的 `assistantMessage` 原样转述给用户。`needs_token` 是缺 token、不是没钱:先引导自救(读 `~/.claude/settings.json` 的 `sk-` token),不要劝充值。',
302
+ '- 如果工具输出里有 `nextActions`,转述其中的自救/充值链接(以工具实际返回为准,不要写死某个链接)。',
269
303
  '- 第一轮只说“初步判断 / 机会假设 / 待校准”,不要说成最终结论。',
270
304
  '- 后续用户说“保留、不要、更偏、这个不准”等反馈时,运行偏好更新命令沉淀记忆。',
271
305
  '',
@@ -273,8 +307,8 @@ function workspaceTrendSkillText(options) {
273
307
  '',
274
308
  '- If the user asks for live collection, real collection, or entering live mode, run the local VOC tool in live mode.',
275
309
  '- Do not answer that you cannot fetch external data. The local VOC tool is the approved collection entry.',
276
- '- If the tool returns `needs_token`, `needs_recharge`, or `needs_valid_token`, paste its `assistantMessage` to the user and keep the payment URL visible.',
277
- '- The payment URL must be shown when there is no token or insufficient balance: `https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF`',
310
+ '- If the tool returns `needs_token`, `needs_recharge`, or `needs_valid_token`, paste its `assistantMessage` to the user verbatim.',
311
+ '- `needs_token` is recoverable: an `sk-` fmode key (Claude Code `ANTHROPIC_AUTH_TOKEN`) lets collection run — guide self-rescue first, do not push recharge. Only on a real `402` show the fmode-api recharge link `https://app.fmode.cn/dev/studio/?balance=fmodeapi`.',
278
312
  '',
279
313
  '## sample 命令',
280
314
  '',
@@ -296,18 +330,19 @@ function workspaceTrendSkillText(options) {
296
330
  `node ${quotedPath(preferenceUpdater)} --message "<用户反馈原文>" --memory ${quotedPath(defaultMemoryPath)} --result-prefix ${options.resultPrefix}`,
297
331
  '```',
298
332
  '',
299
- '## 充值链接口径',
333
+ '## 充值 / 计费口径',
300
334
  '',
301
- '没有 token 或余额不足时,用户必须看到:',
335
+ '- **缺 token(`needs_token`)不是没钱,不要直接给充值链接**:先自救——读 `~/.claude/settings.json` 的 `env.ANTHROPIC_AUTH_TOKEN`(`sk-` 开头的 fmode key),或 `~/.fmode/config.json` / `~/.claude/voc-credentials.json`。',
336
+ '- **只有真正 `402 余额不足` 才引导充值**;本技能走 NewAPI(fmode-api)计费,充值入口用 fmode-api:',
302
337
  '',
303
338
  '```text',
304
- 'https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF',
339
+ 'https://app.fmode.cn/dev/studio/?balance=fmodeapi',
305
340
  '```',
306
341
  '',
307
- '套餐入口可作为补充:',
342
+ '- `apig-pay` 仅用于「VOC 数据服务会话 token(`r:` 开头)余额」这一特定场景的补充,不是缺 token / 默认充值入口:',
308
343
  '',
309
344
  '```text',
310
- 'https://app.fmode.cn/dev/apig-pay/#/workshop/99',
345
+ 'https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF',
311
346
  '```',
312
347
  ''
313
348
  ].join('\n');
@@ -328,53 +363,6 @@ function workspaceSkillText(targetDir) {
328
363
  liveOutput: 'outputs/claude-code-xhs-live',
329
364
  resultPrefix: 'XHS_PREF_RESULT'
330
365
  });
331
- const trendRunner = path.join(targetDir, 'mcp', 'src', 'tools', 'xiaohongshu-trend-run.js');
332
- const preferenceUpdater = path.join(targetDir, 'mcp', 'src', 'tools', 'xiaohongshu-preference-update.js');
333
- const profilePath = path.join(targetDir, 'memory-templates', 'xiaohongshu-trend-profile.json');
334
- const defaultMemoryPath = path.join(WORKSPACE_ROOT, 'outputs', 'claude-code-xhs-memory', 'xiaohongshu-trend-memory.json');
335
-
336
- return [
337
- '---',
338
- 'name: xiaohongshu-trend-intelligence',
339
- 'description: Build Xiaohongshu trend intelligence reports from industry direction, audience, keywords, notes, and comments. Use when the user asks for 小红书趋势情报、行业趋势、女性客户消费决策、设计元素洞察、家装全屋定制趋势、内容选题 or social VOC analysis.',
340
- 'allowed-tools: Read Write Bash(node *)',
341
- '---',
342
- '',
343
- '# 小红书趋势情报官',
344
- '',
345
- '你是面向业务用户的“小红书趋势情报官”。用户要的是第一轮样本观察、机会假设和待确认问题,不是技术日志。',
346
- '',
347
- '## 必须执行',
348
- '',
349
- '- 当用户要求做小红书趋势情报、行业趋势、女性客户消费决策、家装全屋定制趋势、设计元素洞察或内容选题时,优先运行下面的 sample 工具命令。',
350
- '- 不要只凭经验回答,也不要只返回文件路径。',
351
- '- 工具输出里会有 `assistantMessage`,请把它的正文直接发给用户。',
352
- '- 第一轮只能说“初步判断 / 机会假设 / 待校准”,不要说成最终结论。',
353
- '- 后续用户说“保留、不要、更偏、这个不准”等反馈时,运行偏好更新命令沉淀记忆。',
354
- '',
355
- '## sample 趋势情报命令',
356
- '',
357
- '```bash',
358
- `node ${quotedPath(trendRunner)} --collection-mode sample --profile ${quotedPath(profilePath)} --output "outputs/claude-code-xhs-sample" --assistant-message-only`,
359
- '```',
360
- '',
361
- '运行后把命令输出正文直接发给用户。不要展示 JSON、summary、data、files 或调试日志。',
362
- '',
363
- '## 偏好更新命令',
364
- '',
365
- '```bash',
366
- `node ${quotedPath(preferenceUpdater)} --message "<用户反馈原文>" --memory ${quotedPath(defaultMemoryPath)} --result-prefix XHS_PREF_RESULT`,
367
- '```',
368
- '',
369
- '## 推荐用户启动话术',
370
- '',
371
- '```text',
372
- '帮我做一份家装全屋定制行业的小红书趋势情报。',
373
- '先用演示样例跑通流程,不要真实采集。',
374
- '在聊天里给我第一轮样本观察和待确认问题。',
375
- '```',
376
- ''
377
- ].join('\n');
378
366
  }
379
367
 
380
368
  function workspaceDouyinSkillText(targetDir) {
@@ -392,53 +380,6 @@ function workspaceDouyinSkillText(targetDir) {
392
380
  liveOutput: 'outputs/claude-code-douyin-live',
393
381
  resultPrefix: 'DOUYIN_PREF_RESULT'
394
382
  });
395
- const trendRunner = path.join(targetDir, 'mcp', 'src', 'tools', 'douyin-trend-run.js');
396
- const preferenceUpdater = path.join(targetDir, 'mcp', 'src', 'tools', 'douyin-preference-update.js');
397
- const profilePath = path.join(targetDir, 'memory-templates', 'douyin-trend-profile.json');
398
- const defaultMemoryPath = path.join(WORKSPACE_ROOT, 'outputs', 'claude-code-douyin-memory', 'douyin-trend-memory.json');
399
-
400
- return [
401
- '---',
402
- 'name: douyin-trend-intelligence',
403
- 'description: Build Douyin trend intelligence reports from industry direction, audience, keywords, videos, and comments. Use when the user asks for 抖音趋势情报、视频评论、口播选题、短视频开头、内容趋势 or social VOC analysis.',
404
- 'allowed-tools: Read Write Bash(node *)',
405
- '---',
406
- '',
407
- '# 抖音趋势情报官',
408
- '',
409
- '你是面向业务用户的“抖音趋势情报官”。用户要的是第一轮样本观察、机会假设和待确认问题,不是技术日志。',
410
- '',
411
- '## 必须执行',
412
- '',
413
- '- 当用户要求做抖音趋势情报、视频评论、口播选题、短视频开头或内容趋势时,优先运行下面的 sample 工具命令。',
414
- '- 不要只凭经验回答,也不要只返回文件路径。',
415
- '- 工具输出里会有 `assistantMessage`,请把它的正文直接发给用户。',
416
- '- 第一轮只能说“初步判断 / 机会假设 / 待校准”,不要说成最终结论。',
417
- '- 后续用户说“保留、不要、更偏、这个不准”等反馈时,运行偏好更新命令沉淀记忆。',
418
- '',
419
- '## sample 趋势情报命令',
420
- '',
421
- '```bash',
422
- `node ${quotedPath(trendRunner)} --collection-mode sample --profile ${quotedPath(profilePath)} --output "outputs/claude-code-douyin-sample" --assistant-message-only`,
423
- '```',
424
- '',
425
- '运行后把命令输出正文直接发给用户。不要展示 JSON、summary、data、files 或调试日志。',
426
- '',
427
- '## 偏好更新命令',
428
- '',
429
- '```bash',
430
- `node ${quotedPath(preferenceUpdater)} --message "<用户反馈原文>" --memory ${quotedPath(defaultMemoryPath)} --result-prefix DOUYIN_PREF_RESULT`,
431
- '```',
432
- '',
433
- '## 推荐用户启动话术',
434
- '',
435
- '```text',
436
- '帮我做一份家装全屋定制行业的抖音趋势情报。',
437
- '先用演示样例跑通流程,不要真实采集。',
438
- '在聊天里给我第一轮样本观察和待确认问题。',
439
- '```',
440
- ''
441
- ].join('\n');
442
383
  }
443
384
 
444
385
  function workspaceProblemDeepDiveSkillText(targetDir) {
@@ -468,19 +409,19 @@ function workspaceProblemDeepDiveSkillText(targetDir) {
468
409
  '## 命令',
469
410
  '',
470
411
  '```bash',
471
- `node ${quotedPath(deepDiveRunner)} --issue "怎么选" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --assistant-message-only`,
412
+ `node ${quotedPath(deepDiveRunner)} --issue "怎么选" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --assistant-message-only`,
472
413
  '```',
473
414
  '',
474
415
  '## 带记忆的多轮迭代',
475
416
  '',
476
417
  '```bash',
477
- `node ${quotedPath(deepDiveRunner)} --issue "怎么选" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --memory "outputs/voc-problem-memory.json" --feedback "老板不想做直播带看,更想先改评论区回复和方案说明" --blocked-actions "直播带看" --preferred-actions "评论区回复,方案说明" --assistant-message-only`,
418
+ `node ${quotedPath(deepDiveRunner)} --issue "怎么选" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --memory "outputs/voc-problem-memory.json" --feedback "老板不想做直播带看,更想先改评论区回复和方案说明" --blocked-actions "直播带看" --preferred-actions "评论区回复,方案说明" --assistant-message-only`,
478
419
  '```',
479
420
  '',
480
421
  '自然语言反馈也可以直接传入 `feedback`,工具会尝试自动提取偏好和屏蔽动作:',
481
422
  '',
482
423
  '```bash',
483
- `node ${quotedPath(deepDiveRunner)} --issue "怎么选" --project "示例品牌A" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --feedback "这个品牌不想做直播带看,更想先改评论区回复和方案说明" --assistant-message-only`,
424
+ `node ${quotedPath(deepDiveRunner)} --issue "怎么选" --project "示例品牌A" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --feedback "这个品牌不想做直播带看,更想先改评论区回复和方案说明" --assistant-message-only`,
484
425
  '```',
485
426
  '',
486
427
  '运行后把命令输出正文直接发给用户。不要展示 JSON、summary、data、files 或调试日志。',
@@ -513,13 +454,13 @@ function workspaceIssuePoolSkillText(targetDir) {
513
454
  '## 命令',
514
455
  '',
515
456
  '```bash',
516
- `node ${quotedPath(issuePoolRunner)} --project "示例品牌A" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --evidence "第一次买不知道怎么选,怕踩雷。,价格有点高,不确定值不值。,咨询的时候没人理。" --assistant-message-only`,
457
+ `node ${quotedPath(issuePoolRunner)} --project "示例品牌A" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --evidence "第一次买不知道怎么选,怕踩雷。,价格有点高,不确定值不值。,咨询的时候没人理。" --assistant-message-only`,
517
458
  '```',
518
459
  '',
519
460
  '带报告文件:',
520
461
  '',
521
462
  '```bash',
522
- `node ${quotedPath(issuePoolRunner)} --project "示例品牌A" --industry "家居定制" --report "outputs/douyin-trend-report.md" --assistant-message-only`,
463
+ `node ${quotedPath(issuePoolRunner)} --project "示例品牌A" --industry "<你的行业>" --report "outputs/douyin-trend-report.md" --assistant-message-only`,
523
464
  '```',
524
465
  '',
525
466
  '运行后把命令输出正文直接发给用户。不要展示 JSON、summary、data、files 或调试日志。',
@@ -545,7 +486,7 @@ function workspaceContentPlanSkillText(targetDir) {
545
486
  '## 命令',
546
487
  '',
547
488
  '```bash',
548
- `node ${quotedPath(runner)} --brand "示例品牌A" --industry "家居定制" --issues "第一次买怕踩雷;觉得价格贵;怕质量不稳定" --assistant-message-only`,
489
+ `node ${quotedPath(runner)} --brand "示例品牌A" --industry "<你的行业>" --issues "第一次买怕踩雷;觉得价格贵;怕质量不稳定" --assistant-message-only`,
549
490
  '```',
550
491
  '',
551
492
  '运行后把正文直接发给用户,不要展示 JSON。',
@@ -571,7 +512,7 @@ function workspaceSpeakingScriptSkillText(targetDir) {
571
512
  '## 命令',
572
513
  '',
573
514
  '```bash',
574
- `node ${quotedPath(runner)} --brand "示例品牌A" --industry "家居定制" --topic "第一次买怎么选不踩雷" --user-issue "第一次买怕选错" --evidence "第一次买不知道怎么选,怕踩雷" --assistant-message-only`,
515
+ `node ${quotedPath(runner)} --brand "示例品牌A" --industry "<你的行业>" --topic "第一次买怎么选不踩雷" --user-issue "第一次买怕选错" --evidence "第一次买不知道怎么选,怕踩雷" --assistant-message-only`,
575
516
  '```',
576
517
  '',
577
518
  '改稿:',
@@ -603,7 +544,7 @@ function workspaceCompetitorMapSkillText(targetDir) {
603
544
  '## 命令',
604
545
  '',
605
546
  '```bash',
606
- `node ${quotedPath(runner)} --brand "示例品牌A" --city "本地" --category "家居定制" --assistant-message-only`,
547
+ `node ${quotedPath(runner)} --brand "示例品牌A" --city "本地" --category "<你的品类>" --assistant-message-only`,
607
548
  '```',
608
549
  '',
609
550
  '运行后把正文直接发给用户,不要展示 JSON。',
@@ -627,7 +568,7 @@ function workspaceBusinessWorkflowSkillText(targetDir) {
627
568
  '## 命令',
628
569
  '',
629
570
  '```bash',
630
- `node ${quotedPath(runner)} --brand "示例品牌A" --industry "家居定制" --platform douyin --collection-mode sample --keywords "家居定制怎么选,第一次买怎么对比,售后" --assistant-message-only`,
571
+ `node ${quotedPath(runner)} --brand "示例品牌A" --industry "<你的行业>" --platform douyin --collection-mode sample --keywords "<你的品类>怎么选,第一次买怎么对比,售后" --assistant-message-only`,
631
572
  '```',
632
573
  '',
633
574
  '真实采集时把 `--collection-mode sample` 换成 `--collection-mode live`。如果工具提示没有 token、余额不足或没有样本,直接把工具正文发给用户,并保留充值/降级建议。',
@@ -717,15 +658,15 @@ function printNextSteps(targetDir) {
717
658
  }
718
659
  console.log('');
719
660
  console.log('Try this prompt in Claude Code:');
720
- console.log(' 帮我看一下家装全屋定制最近用户在关心什么,并告诉我先改哪里、下周发什么。');
661
+ console.log(' 帮我看一下 {你的行业/品类} 最近用户在关心什么,并告诉我先改哪里、下周发什么。');
721
662
  console.log('');
722
663
  console.log('Or try:');
723
- console.log(' 帮我做一份家装全屋定制行业的小红书趋势情报。');
664
+ console.log(' 帮我做一份 {你的行业/品类} 的小红书趋势情报。');
724
665
  console.log(' 先用演示样例跑通流程,不要真实采集。');
725
666
  console.log(' 在聊天里给我第一轮样本观察和待确认问题。');
726
667
  console.log('');
727
668
  console.log('Or try:');
728
- console.log(' 帮我做一份家装全屋定制行业的抖音趋势情报。');
669
+ console.log(' 帮我做一份 {你的行业/品类} 的抖音趋势情报。');
729
670
  console.log(' 先用演示样例跑通流程,不要真实采集。');
730
671
  console.log(' 在聊天里给我第一轮样本观察和待确认问题。');
731
672
  console.log('');
@@ -739,7 +680,7 @@ function install(opts) {
739
680
  if (!canOverwriteTarget(opts.target, opts)) {
740
681
  throw new Error(`Target already exists. Use --force to overwrite custom target: ${opts.target}`);
741
682
  }
742
- fs.rmSync(opts.target, { recursive: true, force: true });
683
+ removeDirResilient(opts.target);
743
684
  }
744
685
  ensureDir(opts.target);
745
686
  const copied = copyDirRecursive(SOURCE_ROOT, opts.target);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vocmarket/voc-skill",
3
- "version": "0.3.24",
3
+ "version": "0.3.25",
4
4
  "description": "Claude Code VOC intelligence skills for Xiaohongshu and Douyin trend reports, live social VOC collection, Fmode image analysis, single-issue deep dives, boss/operator action plans, and multi-turn memory.",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-voc-intelligence",
3
- "version": "0.3.24",
3
+ "version": "0.3.25",
4
4
  "description": "Claude Code native VOC intelligence package for cross-industry social VOC workflows. Includes Xiaohongshu and Douyin trend intelligence, live token checks, evidence-card reports, single-issue VOC deep dives, boss/operator action plans, and scoped multi-turn memory.",
5
5
  "plugin": "voc-intelligence",
6
6
  "skills": [
@@ -13,7 +13,7 @@ allowed-tools: Read Write Bash(node *)
13
13
  - 用户要求抖音趋势情报、视频评论、口播选题、短视频开头、内容趋势或社媒 VOC 时,必须运行本技能包的工具或 MCP,不要只凭经验回答。
14
14
  - 用户说“live / 真实采集 / 进入 live / 实时采集 / 抓真实数据”时,必须运行 live 模式工具。不要回复“我不能实时抓取外部数据”。本技能包已经提供本地 VOC 采集入口。
15
15
  - live 模式返回 `needs_token`、`needs_recharge` 或 `needs_valid_token` 时,必须把工具输出里的 `assistantMessage` 原样转述给用户,尤其不能省略充值/开通链接。
16
- - 如果工具输出里有 `nextActions`,至少转述其中带 `apig-pay` 的充值链接。
16
+ - 如果工具输出里有 `nextActions`,转述其中的自救/充值链接(以工具实际返回为准,不要写死某个链接)。
17
17
  - 第一轮只说“初步判断 / 机会假设 / 待校准”,不要说成最终结论。
18
18
  - 后续用户说“保留、不要、更偏、这个不准”等反馈时,运行偏好更新命令沉淀记忆。
19
19
 
@@ -21,8 +21,8 @@ allowed-tools: Read Write Bash(node *)
21
21
 
22
22
  - If the user asks for live collection, real collection, or entering live mode, run the local VOC tool in live mode.
23
23
  - Do not answer that you cannot fetch external data. The local VOC tool is the approved collection entry.
24
- - If the tool returns `needs_token`, `needs_recharge`, or `needs_valid_token`, paste its `assistantMessage` to the user and keep the payment URL visible.
25
- - The payment URL must be shown when there is no token or insufficient balance: `https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF`
24
+ - If the tool returns `needs_token`, `needs_recharge`, or `needs_valid_token`, paste its `assistantMessage` to the user verbatim, including whatever self-rescue/recharge link the tool returns.
25
+ - `needs_token` is recoverable: an `sk-` fmode newapi key (Claude Code's `ANTHROPIC_AUTH_TOKEN` in `~/.claude/settings.json`, or `~/.fmode/config.json` / `~/.claude/voc-credentials.json`) lets collection run — guide self-rescue first, do not push the user to recharge. Only on a real `402` (insufficient balance) show the fmode-api recharge link `https://app.fmode.cn/dev/studio/?balance=fmodeapi`.
26
26
 
27
27
  ## 禁止事项(Hard Guardrails)
28
28
 
@@ -30,14 +30,14 @@ live 采集失败时,严禁做以下任何一件事:
30
30
 
31
31
  - 严禁退回/降级到联网搜索(web search)、`yt-dlp`、`ffmpeg`、手动让用户上传 mp4,或任何“绕过 VOC 接口”的抓取方式。本技能包的 VOC 本地采集是唯一批准的真实数据入口。
32
32
  - 严禁输出“VOC 只支持某些类目”“律师/某赛道不可用”“系统设计上有类目限制”这类结论。这是错误结论:任何关键词(律师、法律、医美、教育、专业服务等)都能采集,与类目无关。
33
- - live 失败的真正原因只可能是这几类:token 无效或类型不对(需要 `r:` 开头的会话 token,而不是 `sk-` 开头的 AIGate API Key)、未开通或额度不足、上游接口抖动(5xx,需重试)。必须如实把工具返回的 `assistantMessage` 转述给用户,不要自行编造原因。
33
+ - live 失败的真正原因只可能是这几类:缺 token 或 token 无效(**`sk-` 开头的 fmode newapi key 即可采集**——它就是 `~/.claude/settings.json` 的 `ANTHROPIC_AUTH_TOKEN`,也可来自 `~/.fmode/config.json` / `~/.claude/voc-credentials.json`;缺 token 先按提示自救读取,不要劝充值)、额度不足(真 402 才充值)、上游接口抖动(5xx,需重试)。必须如实把工具返回的 `assistantMessage` 转述给用户,不要自行编造原因。
34
34
  - 只有在工具明确返回 `needs_keyword_fix` 时才允许调整关键词;返回 `needs_valid_token` / `needs_token` / `needs_recharge` 时不要换关键词,要转述充值/开通链接。
35
35
 
36
36
  English (same rules):
37
37
 
38
38
  - On live failure, NEVER fall back to web search, `yt-dlp`, `ffmpeg`, or asking the user to upload an mp4. The local VOC tool is the only approved real-data path.
39
39
  - NEVER conclude that VOC is limited to certain categories or that a vertical (e.g. lawyers) is unsupported. Any keyword works; this is never a category problem.
40
- - The only real causes are: invalid/wrong-type token (need an `r:` session token, not an `sk-` AIGate key), not activated / no balance, or upstream 5xx jitter (retry). Relay the tool's `assistantMessage` verbatim instead of inventing a reason.
40
+ - The only real causes are: missing/invalid token (an `sk-` fmode newapi key — Claude Code's `ANTHROPIC_AUTH_TOKEN` — is valid for collection; self-rescue by reading it first, don't push recharge), insufficient balance (only a real 402 needs recharge), or upstream 5xx jitter (retry). Relay the tool's `assistantMessage` verbatim instead of inventing a reason.
41
41
  - Only adjust keywords when the tool returns `needs_keyword_fix`. For `needs_valid_token` / `needs_token` / `needs_recharge`, do not change keywords — surface the payment/activation link.
42
42
 
43
43
  ## Douyin Live Quick Repair
@@ -71,24 +71,27 @@ node "<插件目录>/mcp/src/tools/douyin-trend-run.js" --collection-mode live -
71
71
 
72
72
  运行后把命令输出正文直接发给用户。不要展示 JSON、summary、data、files 或调试日志。
73
73
 
74
- ## 充值链接口径
74
+ ## 充值 / 计费口径
75
75
 
76
- 没有 token 或余额不足时,用户必须看到:
76
+ - **缺 token(`needs_token`)不是没钱,不要直接给充值链接**:先自救——读 `~/.claude/settings.json` 的 `env.ANTHROPIC_AUTH_TOKEN`(`sk-` 开头的 fmode key),或 `~/.fmode/config.json` / `~/.claude/voc-credentials.json` 里的 fmode key,用 `FMODE_API_KEY=sk-…` 重试即可。
77
+ - **只有真正 `402 余额不足` 才引导充值**;本技能走 NewAPI(fmode-api)计费,充值入口用 fmode-api:
77
78
 
78
79
  ```text
79
- https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF
80
+ https://app.fmode.cn/dev/studio/?balance=fmodeapi
80
81
  ```
81
82
 
82
- 套餐入口可作为补充:
83
+ - `apig-pay` 仅用于「VOC 数据服务会话 token(`r:` 开头)余额」这一特定场景的补充,不是缺 token / 默认充值入口:
83
84
 
84
85
  ```text
85
- https://app.fmode.cn/dev/apig-pay/#/workshop/99
86
+ https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF
86
87
  ```
87
88
 
88
89
  ## 推荐用户启动话术
89
90
 
91
+ > 通用模板:把 `{你的行业/品类}` 替换成用户真实所在的行业或品类,不要内置任何特定行业。
92
+
90
93
  ```text
91
- 帮我做一份家装全屋定制行业的抖音趋势情报。
94
+ 帮我做一份 {你的行业/品类} 的抖音趋势情报。
92
95
  先用演示样例跑通流程,不要真实采集。
93
96
  在聊天里给我第一轮样本观察和待确认问题。
94
97
  ```
@@ -2,10 +2,9 @@
2
2
 
3
3
  ## 默认规则
4
4
 
5
- - 先检查 token
6
5
  - 样本量保持小
7
- - 没 token 时给充值链接,不要暴露 403
8
- - 余额不足时也给充值链接,不要暴露底层错误
6
+ - 缺 token 时先自救:读 `~/.claude/settings.json` 的 `ANTHROPIC_AUTH_TOKEN`(`sk-` 开头的 fmode key),或 `~/.fmode/config.json` / `~/.claude/voc-credentials.json`,用 `FMODE_API_KEY=sk-…` 重试;不要直接甩充值链接,也不要暴露 403
7
+ - 只有真正余额不足(402)才给充值链接,且用 fmode-api 入口 `https://app.fmode.cn/dev/studio/?balance=fmodeapi`,不要暴露底层错误
9
8
  - 用户只需要看到“怎么继续”
10
9
 
11
10
  ## 推荐默认参数
@@ -5,6 +5,8 @@ description: Analyze images, screenshots, posters, UI captures, charts, product
5
5
 
6
6
  # Fmode Image Analysis
7
7
 
8
+ > 图像/视频分析**推荐改用 `fmode-vision` 技能包**(功能更完整:单轮/多轮聚焦分析、视频帧分析、批量处理)。本技能是 Claude Code 内置 MCP 工具 `fmode_image_analysis` 的轻量图片识别入口/回退,适合“当前对话里已有图片、需要快速识图”的场景;需要更精细或视频/批量处理时,引导用户/Agent 改用 `fmode-vision`。
9
+
8
10
  ## Core Rule
9
11
 
10
12
  Use MCP tool `fmode_image_analysis` for image understanding. Do not ask the user to install a VS Code image-recognition plugin when this installed Fmode tool can handle the image.
@@ -15,7 +17,7 @@ Default to:
15
17
 
16
18
  - `baseUrl`: `https://api.fmode.cn`
17
19
  - `path`: `v1/chat/completions`
18
- - `model`: `doubao-seed-2-0-pro-260215`
20
+ - `model`: `doubao-seed-2-0-pro-260215`(默认/推荐,**不强制使用单一模型**——可按可用权限改用其他多模态模型,如 `gpt-4o` 等;通过工具入参 `model` 覆盖即可)
19
21
 
20
22
  Auth and billing should use the configured platform user token. Never hardcode or echo tokens.
21
23
 
@@ -84,11 +86,11 @@ Environment variables:
84
86
  - `DOUBAO_VISION_TOKEN`
85
87
  - `VIDEO_ANALYSIS_TOKEN`
86
88
 
87
- Friendly states:
89
+ Friendly states (aligned with the fmode-api billing 口径 — self-rescue first, recharge only on a real 402):
88
90
 
89
- - Missing token: return `needs_token` with the platform open/recharge link and `errors=[]`.
91
+ - Missing token (`needs_token`): this is not a balance problem — guide self-rescue first. Read the `sk-` fmode key from `~/.claude/settings.json` (`env.ANTHROPIC_AUTH_TOKEN`), `~/.fmode/config.json`, or `~/.claude/voc-credentials.json`. Do NOT push a recharge link here.
90
92
  - Invalid token: return `needs_valid_token` and ask for a valid platform token.
91
- - Not opened or quota exhausted: return `needs_recharge` with the open/recharge link and `errors=[]`.
93
+ - Quota exhausted / real 402: return `needs_recharge` with the fmode-api recharge link `https://app.fmode.cn/dev/studio/?balance=fmodeapi` and `errors=[]`.
92
94
  - Success: return `ok` with the analysis in chat.
93
95
 
94
96
  Do not expose raw upstream errors, `Authorization`, bearer tokens, session tokens, stack traces, or model keys.
@@ -40,7 +40,7 @@ description: Run the full VOC business workflow from natural boss language: coll
40
40
  ## 用户可说的话
41
41
 
42
42
  ```text
43
- 帮我看一下家居定制最近用户在关心什么,并告诉我先改哪里、下周发什么。
43
+ 帮我看一下 {你的行业/品类} 最近用户在关心什么,并告诉我先改哪里、下周发什么。
44
44
  ```
45
45
 
46
46
  ```text
@@ -21,13 +21,13 @@ allowed-tools: Read Write Bash(node *)
21
21
  ## CLI 命令
22
22
 
23
23
  ```bash
24
- node "<插件目录>/mcp/src/tools/voc-competitor-map-run.js" --brand "示例品牌A" --city "本地" --category "家居定制" --assistant-message-only
24
+ node "<插件目录>/mcp/src/tools/voc-competitor-map-run.js" --brand "示例品牌A" --city "本地" --category "<你的品类>" --assistant-message-only
25
25
  ```
26
26
 
27
27
  带竞品名单:
28
28
 
29
29
  ```bash
30
- node "<插件目录>/mcp/src/tools/voc-competitor-map-run.js" --brand "示例品牌A" --city "本地" --category "家居定制" --competitors "竞品A,竞品B,竞品C" --assistant-message-only
30
+ node "<插件目录>/mcp/src/tools/voc-competitor-map-run.js" --brand "示例品牌A" --city "本地" --category "<你的品类>" --competitors "竞品A,竞品B,竞品C" --assistant-message-only
31
31
  ```
32
32
 
33
33
  ## 输出结构
@@ -48,7 +48,7 @@ node "<插件目录>/mcp/src/tools/voc-competitor-map-run.js" --brand "示例品
48
48
  ## 典型用户话术
49
49
 
50
50
  ```text
51
- 我是做家居定制的,不知道竞品是谁,帮我先做一份竞品图谱。
51
+ 我是做 {你的行业/品类} 的,不知道竞品是谁,帮我先做一份竞品图谱。
52
52
  ```
53
53
 
54
54
  ```text
@@ -22,7 +22,7 @@ allowed-tools: Read Write Bash(node *)
22
22
  ## CLI 命令
23
23
 
24
24
  ```bash
25
- node "<插件目录>/mcp/src/tools/voc-content-plan-run.js" --brand "示例品牌A" --industry "家居定制" --issues "第一次买怕踩雷;觉得价格贵;怕质量不稳定" --evidence-text "用户评论:第一次买不知道怎么选,怕踩雷;价格有点高,不知道方案值不值。" --assistant-message-only
25
+ node "<插件目录>/mcp/src/tools/voc-content-plan-run.js" --brand "示例品牌A" --industry "<你的行业>" --issues "第一次买怕踩雷;觉得价格贵;怕质量不稳定" --evidence-text "用户评论:第一次买不知道怎么选,怕踩雷;价格有点高,不知道方案值不值。" --assistant-message-only
26
26
  ```
27
27
 
28
28
  带报告文件:
@@ -34,7 +34,7 @@ node "<插件目录>/mcp/src/tools/voc-content-plan-run.js" --brand "示例品
34
34
  多问题示例:
35
35
 
36
36
  ```bash
37
- node "<插件目录>/mcp/src/tools/voc-content-plan-run.js" --brand "示例品牌A" --industry "家居定制" --issues "第一次买怎么选最稳;贵在哪/值在哪;怎么对比才不踩雷;质量怎么判断;哪几种方案更适合;售后怎么兜底;优惠规则怎么讲清楚" --evidence-text "用户评论:第一次买不知道怎么选,怕踩雷;价格有点高,不确定值不值;担心质量和售后。" --assistant-message-only
37
+ node "<插件目录>/mcp/src/tools/voc-content-plan-run.js" --brand "示例品牌A" --industry "<你的行业>" --issues "第一次买怎么选最稳;贵在哪/值在哪;怎么对比才不踩雷;质量怎么判断;哪几种方案更适合;售后怎么兜底;优惠规则怎么讲清楚" --evidence-text "用户评论:第一次买不知道怎么选,怕踩雷;价格有点高,不确定值不值;担心质量和售后。" --assistant-message-only
38
38
  ```
39
39
 
40
40
  ## 输出结构
@@ -27,19 +27,19 @@ allowed-tools: Read Write Bash(node *)
27
27
  - When the user asks for a VOC report around business pain points, first build or request a clean evidence set, then run `voc_issue_pool_run`; only after that should a single top issue be sent to `voc_problem_deep_dive_run`.
28
28
 
29
29
  ```bash
30
- node "<插件目录>/mcp/src/tools/voc-issue-pool-run.js" --project "示例品牌A" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --evidence "第一次买不知道怎么选,怕踩雷。,价格有点高,不确定值不值。,咨询忙起来没人理。" --assistant-message-only
30
+ node "<插件目录>/mcp/src/tools/voc-issue-pool-run.js" --project "示例品牌A" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --evidence "第一次买不知道怎么选,怕踩雷。,价格有点高,不确定值不值。,咨询忙起来没人理。" --assistant-message-only
31
31
  ```
32
32
 
33
33
  带报告文件:
34
34
 
35
35
  ```bash
36
- node "<插件目录>/mcp/src/tools/voc-issue-pool-run.js" --project "示例品牌A" --industry "家居定制" --report "outputs/douyin-trend-report.md" --assistant-message-only
36
+ node "<插件目录>/mcp/src/tools/voc-issue-pool-run.js" --project "示例品牌A" --industry "<你的行业>" --report "outputs/douyin-trend-report.md" --assistant-message-only
37
37
  ```
38
38
 
39
39
  更新状态:
40
40
 
41
41
  ```bash
42
- node "<插件目录>/mcp/src/tools/voc-issue-pool-run.js" --project "示例品牌A" --industry "家居定制" --resolved-issues "选择门槛/决策" --assistant-message-only
42
+ node "<插件目录>/mcp/src/tools/voc-issue-pool-run.js" --project "示例品牌A" --industry "<你的行业>" --resolved-issues "选择门槛/决策" --assistant-message-only
43
43
  ```
44
44
 
45
45
  ## 输出结构
@@ -38,19 +38,19 @@ allowed-tools: Read Write Bash(node *)
38
38
  - If live collection returns `needs_token`, `needs_recharge`, or `needs_valid_token`, repeat the tool's user-facing `assistantMessage` and do not replace it with a generic strategy suggestion.
39
39
 
40
40
  ```bash
41
- node "<插件目录>/mcp/src/tools/voc-problem-deep-dive-run.js" --issue "怎么选" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --assistant-message-only
41
+ node "<插件目录>/mcp/src/tools/voc-problem-deep-dive-run.js" --issue "怎么选" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --assistant-message-only
42
42
  ```
43
43
 
44
44
  带记忆的多轮迭代:
45
45
 
46
46
  ```bash
47
- node "<插件目录>/mcp/src/tools/voc-problem-deep-dive-run.js" --issue "怎么选" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --memory "outputs/voc-problem-memory.json" --feedback "老板不想做试用体验,更想先改评论区回复和案例展示" --blocked-actions "试用体验" --preferred-actions "评论区回复,案例展示" --assistant-message-only
47
+ node "<插件目录>/mcp/src/tools/voc-problem-deep-dive-run.js" --issue "怎么选" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --memory "outputs/voc-problem-memory.json" --feedback "老板不想做试用体验,更想先改评论区回复和案例展示" --blocked-actions "试用体验" --preferred-actions "评论区回复,案例展示" --assistant-message-only
48
48
  ```
49
49
 
50
50
  自然语言反馈也可以直接传入 `feedback`,工具会尝试自动提取偏好和屏蔽动作:
51
51
 
52
52
  ```bash
53
- node "<插件目录>/mcp/src/tools/voc-problem-deep-dive-run.js" --issue "怎么选" --project "示例品牌A" --industry "家居定制" --scenario "线上获客" --audience "意向用户" --feedback "这个品牌不想做试用体验,更想先改评论区回复和案例展示" --assistant-message-only
53
+ node "<插件目录>/mcp/src/tools/voc-problem-deep-dive-run.js" --issue "怎么选" --project "示例品牌A" --industry "<你的行业>" --scenario "线上获客" --audience "意向用户" --feedback "这个品牌不想做试用体验,更想先改评论区回复和案例展示" --assistant-message-only
54
54
  ```
55
55
 
56
56
  如果用户反馈“这个有效”“这个无效”“跑了 7 天有效果/没效果”,要把对应动作传入 `validatedActions` 或 `rejectedActions`,也可以直接放进 `feedback`。工具会沉淀动作验证次数,后续排序会自动提高有效动作、降低无效动作,并说明“为什么优先推荐这些动作”。
@@ -28,7 +28,7 @@ VOC 问题 -> 7 天内容计划 -> 选择一条选题 -> 口播脚本共创 ->
28
28
  ```bash
29
29
  node "<插件目录>/mcp/src/tools/voc-speaking-script-run.js" \
30
30
  --brand "示例品牌A" \
31
- --industry "家居定制" \
31
+ --industry "<你的行业>" \
32
32
  --topic "第一次买怎么选不踩雷" \
33
33
  --user-issue "第一次买怕选错" \
34
34
  --evidence "第一次买不知道怎么选,怕踩雷" \
@@ -13,7 +13,7 @@ allowed-tools: Read Write Bash(node *)
13
13
  - 用户要求小红书趋势情报、行业趋势、内容选题、销售话术或社媒 VOC 时,必须运行本技能包的工具或 MCP,不要只凭经验回答。
14
14
  - 用户说“live / 真实采集 / 进入 live / 实时采集 / 抓真实数据”时,必须运行 live 模式工具。不要回复“我不能实时抓取外部数据”。本技能包已经提供本地 VOC 采集入口。
15
15
  - live 模式返回 `needs_token`、`needs_recharge` 或 `needs_valid_token` 时,必须把工具输出里的 `assistantMessage` 原样转述给用户,尤其不能省略充值/开通链接。
16
- - 如果工具输出里有 `nextActions`,至少转述其中带 `apig-pay` 的充值链接。
16
+ - 如果工具输出里有 `nextActions`,转述其中的自救/充值链接(以工具实际返回为准,不要写死某个链接)。
17
17
  - 第一轮只说“初步判断 / 机会假设 / 待校准”,不要说成最终结论。
18
18
  - 后续用户说“保留、不要、更偏、这个不准”等反馈时,运行偏好更新命令沉淀记忆。
19
19
 
@@ -21,8 +21,8 @@ allowed-tools: Read Write Bash(node *)
21
21
 
22
22
  - If the user asks for live collection, real collection, or entering live mode, run the local VOC tool in live mode.
23
23
  - Do not answer that you cannot fetch external data. The local VOC tool is the approved collection entry.
24
- - If the tool returns `needs_token`, `needs_recharge`, or `needs_valid_token`, paste its `assistantMessage` to the user and keep the payment URL visible.
25
- - The payment URL must be shown when there is no token or insufficient balance: `https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF`
24
+ - If the tool returns `needs_token`, `needs_recharge`, or `needs_valid_token`, paste its `assistantMessage` to the user verbatim, including whatever self-rescue/recharge link the tool returns.
25
+ - `needs_token` is recoverable: an `sk-` fmode newapi key (Claude Code's `ANTHROPIC_AUTH_TOKEN` in `~/.claude/settings.json`, or `~/.fmode/config.json` / `~/.claude/voc-credentials.json`) lets collection run — guide self-rescue first, do not push the user to recharge. Only on a real `402` (insufficient balance) show the fmode-api recharge link `https://app.fmode.cn/dev/studio/?balance=fmodeapi`.
26
26
 
27
27
  ## 禁止事项(Hard Guardrails)
28
28
 
@@ -30,14 +30,14 @@ live 采集失败时,严禁做以下任何一件事:
30
30
 
31
31
  - 严禁退回/降级到联网搜索(web search)、`yt-dlp`、`ffmpeg`、手动让用户上传图片/视频,或任何“绕过 VOC 接口”的抓取方式。本技能包的 VOC 本地采集是唯一批准的真实数据入口。
32
32
  - 严禁输出“VOC 只支持某些类目”“律师/某赛道不可用”“系统设计上有类目限制”这类结论。这是错误结论:任何关键词(律师、法律、医美、教育、专业服务等)都能采集,与类目无关。
33
- - live 失败的真正原因只可能是这几类:token 无效或类型不对(需要 `r:` 开头的会话 token,而不是 `sk-` 开头的 AIGate API Key)、未开通或额度不足、上游接口抖动(5xx,需重试)。必须如实把工具返回的 `assistantMessage` 转述给用户,不要自行编造原因。
33
+ - live 失败的真正原因只可能是这几类:缺 token 或 token 无效(**`sk-` 开头的 fmode newapi key 即可采集**——它就是 `~/.claude/settings.json` 的 `ANTHROPIC_AUTH_TOKEN`,也可来自 `~/.fmode/config.json` / `~/.claude/voc-credentials.json`;缺 token 先按提示自救读取,不要劝充值)、额度不足(真 402 才充值)、上游接口抖动(5xx,需重试)。必须如实把工具返回的 `assistantMessage` 转述给用户,不要自行编造原因。
34
34
  - 只有在工具明确返回 `needs_keyword_fix` 时才允许调整关键词;返回 `needs_valid_token` / `needs_token` / `needs_recharge` 时不要换关键词,要转述充值/开通链接。
35
35
 
36
36
  English (same rules):
37
37
 
38
38
  - On live failure, NEVER fall back to web search, `yt-dlp`, `ffmpeg`, or asking the user to upload media. The local VOC tool is the only approved real-data path.
39
39
  - NEVER conclude that VOC is limited to certain categories or that a vertical (e.g. lawyers) is unsupported. Any keyword works; this is never a category problem.
40
- - The only real causes are: invalid/wrong-type token (need an `r:` session token, not an `sk-` AIGate key), not activated / no balance, or upstream 5xx jitter (retry). Relay the tool's `assistantMessage` verbatim instead of inventing a reason.
40
+ - The only real causes are: missing/invalid token (an `sk-` fmode newapi key — Claude Code's `ANTHROPIC_AUTH_TOKEN` — is valid for collection; self-rescue by reading it first, don't push recharge), insufficient balance (only a real 402 needs recharge), or upstream 5xx jitter (retry). Relay the tool's `assistantMessage` verbatim instead of inventing a reason.
41
41
  - Only adjust keywords when the tool returns `needs_keyword_fix`. For `needs_valid_token` / `needs_token` / `needs_recharge`, do not change keywords — surface the payment/activation link.
42
42
 
43
43
  ## sample 命令
@@ -54,24 +54,27 @@ node "<插件目录>/mcp/src/tools/xiaohongshu-trend-run.js" --collection-mode l
54
54
 
55
55
  运行后把命令输出正文直接发给用户。不要展示 JSON、summary、data、files 或调试日志。
56
56
 
57
- ## 充值链接口径
57
+ ## 充值 / 计费口径
58
58
 
59
- 没有 token 或余额不足时,用户必须看到:
59
+ - **缺 token(`needs_token`)不是没钱,不要直接给充值链接**:先自救——读 `~/.claude/settings.json` 的 `env.ANTHROPIC_AUTH_TOKEN`(`sk-` 开头的 fmode key),或 `~/.fmode/config.json` / `~/.claude/voc-credentials.json` 里的 fmode key,用 `FMODE_API_KEY=sk-…` 重试即可。
60
+ - **只有真正 `402 余额不足` 才引导充值**;本技能走 NewAPI(fmode-api)计费,充值入口用 fmode-api:
60
61
 
61
62
  ```text
62
- https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF
63
+ https://app.fmode.cn/dev/studio/?balance=fmodeapi
63
64
  ```
64
65
 
65
- 套餐入口可作为补充:
66
+ - `apig-pay` 仅用于「VOC 数据服务会话 token(`r:` 开头)余额」这一特定场景的补充,不是缺 token / 默认充值入口:
66
67
 
67
68
  ```text
68
- https://app.fmode.cn/dev/apig-pay/#/workshop/99
69
+ https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF
69
70
  ```
70
71
 
71
72
  ## 推荐用户启动话术
72
73
 
74
+ > 通用模板:把 `{你的行业/品类}` 替换成用户真实所在的行业或品类,不要内置任何特定行业。
75
+
73
76
  ```text
74
- 帮我做一份家装全屋定制行业的小红书趋势情报。
77
+ 帮我做一份 {你的行业/品类} 的小红书趋势情报。
75
78
  先用演示样例跑通流程,不要真实采集。
76
79
  在聊天里给我第一轮样本观察和待确认问题。
77
80
  ```
@@ -25,10 +25,10 @@ live 模式默认保持小规模:
25
25
 
26
26
  系统也会尝试从本机环境读取 token。
27
27
 
28
- 如果没有 token,或者余额不足,不要直接把底层报错甩给用户,应该返回:
28
+ 不要直接把底层报错甩给用户:
29
29
 
30
- - 充值链接
31
- - 下一步操作
30
+ - 缺 token:先自救——读 `~/.claude/settings.json` 的 `ANTHROPIC_AUTH_TOKEN`(`sk-` 开头的 fmode key),或 `~/.fmode/config.json` / `~/.claude/voc-credentials.json`,用 `FMODE_API_KEY=sk-…` 重试;不要直接给充值链接。
31
+ - 只有真正余额不足(402)才给充值链接 + 下一步操作。
32
32
 
33
33
  不要把 `403`、授权失败文案、原始响应体直接暴露给用户。
34
34
 
@@ -41,19 +41,15 @@ live 模式默认保持小规模:
41
41
 
42
42
  保留 `xsec_token`,否则网页端可能打不开。
43
43
 
44
- ## 充值入口
44
+ ## 充值入口(仅 402 余额不足时)
45
45
 
46
- 常见充值入口示例:
46
+ 本技能走 NewAPI(fmode-api)计费,充值入口用 fmode-api:
47
47
 
48
48
  ```text
49
- https://app.fmode.cn/dev/apig-pay/#/workshop
50
- https://app.fmode.cn/dev/apig-pay/#/workshop/19-9
51
- https://app.fmode.cn/dev/apig-pay/#/workshop/99
52
- https://app.fmode.cn/dev/apig-pay/#/workshop/299
53
- https://app.fmode.cn/dev/apig-pay/#/workshop/699
49
+ https://app.fmode.cn/dev/studio/?balance=fmodeapi
54
50
  ```
55
51
 
56
- 如果只是 VOC 数据服务余额,也可以用:
52
+ `apig-pay` 仅用于「VOC 数据服务会话 token(`r:` 开头)余额」这一特定场景的补充:
57
53
 
58
54
  ```text
59
55
  https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF