@vocmarket/voc-skill 0.3.29 → 0.3.30

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.29",
4
+ "version": "0.3.30",
5
5
  "author": {
6
6
  "name": "nkkj-BrainHack"
7
7
  }
package/bin/claude-voc.js CHANGED
@@ -3,6 +3,7 @@ const fs = require('fs');
3
3
  const os = require('os');
4
4
  const path = require('path');
5
5
  const { spawnSync } = require('child_process');
6
+ const { ensureActivated } = require('../mcp/src/core/activation');
6
7
 
7
8
  const SOURCE_ROOT = path.resolve(__dirname, '..');
8
9
  const WORKSPACE_ROOT = process.cwd();
@@ -34,6 +35,7 @@ function usage() {
34
35
  'Usage:',
35
36
  ' claude-voc install',
36
37
  ' claude-voc workspace',
38
+ ' claude-voc workspace --activate',
37
39
  ' claude-voc install --workspace --smoke',
38
40
  ' claude-voc check',
39
41
  ' claude-voc smoke',
@@ -43,6 +45,7 @@ function usage() {
43
45
  'npx:',
44
46
  ' npx @vocmarket/voc-skill install',
45
47
  ' npx @vocmarket/voc-skill workspace --smoke',
48
+ ' npx @vocmarket/voc-skill workspace --activate (其他 AI 编程器渠道专用:安装并按状态弹付费)',
46
49
  '',
47
50
  'Options:',
48
51
  ' --workspace Install into ./.claude/plugins/voc-intelligence',
@@ -50,6 +53,8 @@ function usage() {
50
53
  ' --force Allow overwriting an existing custom target',
51
54
  ' --skip-install Skip npm install after copying files',
52
55
  ' --smoke Run sample/preference/MCP smoke checks after install',
56
+ ' --activate 安装后按 token 状态激活:无 token 弹付费/登录页,有 token 直接放行(外部 AI IDE 专用,不影响 --smoke)',
57
+ ' --channel <name> 付费归因渠道名(claude-code/codex/workbuddy)',
53
58
  ' --help, -h Show help'
54
59
  ].join('\n');
55
60
  }
@@ -65,6 +70,8 @@ function parseArgs(argv) {
65
70
  target: DEFAULT_TARGET,
66
71
  skipInstall: false,
67
72
  smoke: false,
73
+ activate: false,
74
+ channel: 'external',
68
75
  force: false,
69
76
  help: false
70
77
  };
@@ -88,6 +95,12 @@ function parseArgs(argv) {
88
95
  opts.skipInstall = true;
89
96
  } else if (token === '--smoke') {
90
97
  opts.smoke = true;
98
+ } else if (token === '--activate') {
99
+ opts.activate = true;
100
+ } else if (token === '--channel') {
101
+ opts.channel = argv[++i];
102
+ } else if (token.startsWith('--channel=')) {
103
+ opts.channel = token.slice('--channel='.length);
91
104
  } else if (token === '--help' || token === '-h') {
92
105
  opts.help = true;
93
106
  }
@@ -716,7 +729,7 @@ function printPath(opts) {
716
729
  }
717
730
  }
718
731
 
719
- function main() {
732
+ async function main() {
720
733
  const directCommand = process.argv[2];
721
734
  if (directCommand === 'image' || directCommand === 'fmode-image') {
722
735
  run(process.execPath, ['mcp/src/tools/fmode-image-analysis.js', ...process.argv.slice(3)], SOURCE_ROOT);
@@ -728,17 +741,23 @@ function main() {
728
741
  console.log(usage());
729
742
  return;
730
743
  }
731
- if (opts.command === 'install') return install(opts);
744
+ if (opts.command === 'install') {
745
+ install(opts);
746
+ if (opts.activate) {
747
+ await ensureActivated({ channel: opts.channel });
748
+ }
749
+ return;
750
+ }
732
751
  if (opts.command === 'check') return check(opts);
733
752
  if (opts.command === 'smoke') return smoke(opts);
734
753
  if (opts.command === 'path') return printPath(opts);
735
754
  throw new Error(`Unknown command: ${opts.command}\n\n${usage()}`);
736
755
  }
737
756
 
738
- try {
739
- main();
740
- } catch (error) {
757
+ main().catch((error) => {
741
758
  console.error('');
742
759
  console.error(`claude-voc failed: ${error.message}`);
743
760
  process.exit(1);
744
- }
761
+ });
762
+
763
+
@@ -0,0 +1,104 @@
1
+ 'use strict';
2
+
3
+ // 安装收尾激活检查(仅供外部 AI IDE 渠道的 `workspace --activate` 调用)。
4
+ //
5
+ // 设计要点(与 voc-api-catalog 计费链一致,复用同一套凭证解析,绝不另建路径):
6
+ // - 复用 credentials.js 的 readNewApiToken()(sk- 主链)/ readVocToken()(r: 会话回退)。
7
+ // - 按「是否已有可用 token」这一状态触发,而不是按命令触发:
8
+ // * 已检测到 token(飞马 UI 已写入,或 Claude Code 已配 sk-)→ 打印「✅ 已激活」,不弹浏览器。
9
+ // * 完全没有 token(现场新教练)→ 安装收尾立刻打开充值/登录页,避免进入取数流程后才弹、空耗 token。
10
+ // - 不主动发计费请求做探测(探测会真扣费);余额不足留给真实取数时由 catalog 的 402 分支处理。
11
+ // - VOC_OPEN_PAYMENT=0 可强制关闭弹窗(CI / 冒烟 / 无头环境)。
12
+ // - 始终把 URL 打印到终端兜底;并追加 &channel=&src=install 做渠道归因。
13
+ // - token 绝不回显到终端 / 日志。
14
+
15
+ const { spawn } = require('child_process');
16
+ const { readNewApiToken, readVocToken } = require('./credentials');
17
+ const { buildVocRechargeInfo } = require('./payment-links');
18
+
19
+ function appendAttribution(rawUrl, channel, src) {
20
+ try {
21
+ const url = new URL(rawUrl);
22
+ if (channel) url.searchParams.set('channel', String(channel));
23
+ if (src) url.searchParams.set('src', String(src));
24
+ return url.toString();
25
+ } catch {
26
+ return rawUrl;
27
+ }
28
+ }
29
+
30
+ function openBrowser(url) {
31
+ try {
32
+ let command;
33
+ let args;
34
+ if (process.platform === 'win32') {
35
+ command = 'cmd';
36
+ // 空字符串是 start 的窗口标题占位,避免带引号的 URL 被当成标题
37
+ args = ['/d', '/s', '/c', 'start', '', url];
38
+ } else if (process.platform === 'darwin') {
39
+ command = 'open';
40
+ args = [url];
41
+ } else {
42
+ command = 'xdg-open';
43
+ args = [url];
44
+ }
45
+ const child = spawn(command, args, { stdio: 'ignore', detached: true });
46
+ child.on('error', () => {});
47
+ child.unref();
48
+ return true;
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ // channel: 渠道名(claude-code / codex / workbuddy),用于付费归因
55
+ // src: 来源标记,默认 install
56
+ async function ensureActivated({ channel = 'external', src = 'install' } = {}) {
57
+ if (process.env.VOC_OPEN_PAYMENT === '0') {
58
+ console.log('');
59
+ console.log('VOC_OPEN_PAYMENT=0:已跳过激活弹窗(CI/无头环境)。');
60
+ return { status: 'skipped' };
61
+ }
62
+
63
+ const newApiToken = readNewApiToken();
64
+ const vocToken = readVocToken();
65
+
66
+ if (newApiToken || vocToken) {
67
+ console.log('');
68
+ console.log('✅ 已激活:检测到 VOC 计费/会话 token,可直接开始取数,无需充值。');
69
+ console.log('(若取数时返回 402 余额不足,再按工具提示充值即可。)');
70
+ return { status: 'activated' };
71
+ }
72
+
73
+ // 完全没有 token:现场新用户。打开充值/登录页,引导先付费再进流程。
74
+ // 无 token 时 buildVocRechargeInfo 不会发起网络请求(resolveVocUserId 对空 token 直接返回)。
75
+ let recharge;
76
+ try {
77
+ recharge = await buildVocRechargeInfo({ token: '' });
78
+ } catch {
79
+ recharge = {};
80
+ }
81
+ const primaryUrl = appendAttribution(
82
+ recharge.recommendedPackageUrl || recharge.paymentUrl || 'https://app.fmode.cn/dev/apig-pay/',
83
+ channel,
84
+ src
85
+ );
86
+
87
+ console.log('');
88
+ console.log('⚠️ 尚未检测到 VOC token —— 你还没有激活。');
89
+ console.log('为避免进入取数流程后才发现需要付费、白白消耗 token,请先在浏览器完成登录并充值/开通:');
90
+ console.log(` ${primaryUrl}`);
91
+ if (recharge.paymentUrl) {
92
+ console.log(` (充值入口:${appendAttribution(recharge.paymentUrl, channel, src)})`);
93
+ }
94
+ console.log('完成付费后,再让 AI 进入取数/报告流程。');
95
+ console.log('如本机无法自动打开浏览器,请手动复制上面的链接到浏览器打开。');
96
+
97
+ const opened = openBrowser(primaryUrl);
98
+ if (!opened) {
99
+ console.log('(自动打开浏览器失败,请手动打开上面的链接。)');
100
+ }
101
+ return { status: 'needs_activation', url: primaryUrl };
102
+ }
103
+
104
+ module.exports = { ensureActivated, openBrowser, appendAttribution };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vocmarket/voc-skill",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
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.29",
3
+ "version": "0.3.30",
4
4
  "capabilities": {
5
5
  "summary": "三类情报源同源接入:①社媒内容 ②国内电商+创作者情报 ③海外选品。统一 search→doc→call、鉴权计费一致。",
6
6
  "channels": [