fogact 1.1.4 → 1.1.6

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.
@@ -3,13 +3,22 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>FogIDC Activator | 动态激活控制台</title>
7
- <meta name="description" content="FogIDC Activator 的用户中心、管理后台与激活码入口。" />
6
+ <title>FogAct | 多平台激活与配额管理</title>
7
+ <meta name="description" content="FogAct 提供用户中心、激活码管理、配额查看和多平台 CLI 接入入口。" />
8
+ <script>
9
+ ;(function () {
10
+ var theme = localStorage.getItem('fogact_theme') || localStorage.getItem('admin_theme') || localStorage.getItem('yunyi_user_theme') || 'system';
11
+ var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
12
+ var isDark = theme === 'dark' || (theme === 'system' && prefersDark);
13
+ document.documentElement.classList.toggle('dark', isDark);
14
+ document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';
15
+ })();
16
+ </script>
8
17
  <link rel="preconnect" href="https://fonts.googleapis.com" />
9
18
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
19
  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@600;700;800&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
11
20
  <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet" />
12
- <link rel="stylesheet" href="/assets/market-ui.css?v=20260616-upstream2" />
21
+ <link rel="stylesheet" href="/assets/market-ui.css?v=20260619-theme1" />
13
22
  </head>
14
23
  <body class="market-page">
15
24
  <span class="market-mouse-light" aria-hidden="true"></span>
@@ -19,8 +28,8 @@
19
28
  <a class="market-brand" href="/">
20
29
  <span class="market-logo">F</span>
21
30
  <span>
22
- <span class="market-brand-title">FogIDC Activator</span>
23
- <span class="market-brand-subtitle">Motion control surface</span>
31
+ <span class="market-brand-title">FogAct</span>
32
+ <span class="market-brand-subtitle">多平台激活工作台</span>
24
33
  </span>
25
34
  </a>
26
35
 
@@ -31,6 +40,9 @@
31
40
  </nav>
32
41
 
33
42
  <div class="market-actions">
43
+ <button type="button" class="market-button market-theme-toggle" data-theme-toggle aria-label="切换暗黑模式">
44
+ <span class="material-symbols-outlined" data-theme-icon>light_mode</span>
45
+ </button>
34
46
  <a class="market-button" href="/api/stats">API</a>
35
47
  <a class="market-button market-button-primary" href="/user/">
36
48
  <span class="material-symbols-outlined">bolt</span>
@@ -42,10 +54,10 @@
42
54
  <main>
43
55
  <section class="market-hero" aria-labelledby="hero-title">
44
56
  <div class="market-hero-main">
45
- <div class="market-kicker"><span class="market-kicker-dot"></span> living interface for CLI activation</div>
46
- <h1 id="hero-title" class="market-title">不是工具页,是一个会呼吸的 <span>激活工作台</span></h1>
57
+ <div class="market-kicker"><span class="market-kicker-dot"></span> CLI 激活与配额管理</div>
58
+ <h1 id="hero-title" class="market-title">统一管理 Codex、Claude 与更多 <span>CLI 服务</span></h1>
47
59
  <p class="market-copy">
48
- 参考 21st.dev 的浏览式组件结构,但不照搬卡片模板:这里用轨道、错位、光扫、浮动组件和指针跟随做出更有辨识度的首页。
60
+ 在一个入口完成激活码发放、用户绑定、额度查看和服务配置,减少来回切换。
49
61
  </p>
50
62
 
51
63
  <label class="market-search" aria-label="搜索功能入口">
@@ -70,31 +82,31 @@
70
82
  </div>
71
83
  </div>
72
84
 
73
- <aside class="market-hero-side" aria-label="动态状态概览">
85
+ <aside class="market-hero-side" aria-label="服务状态概览">
74
86
  <div class="market-preview-stack">
75
87
  <div class="market-mini-card">
76
- <span class="market-icon material-symbols-outlined">auto_awesome_motion</span>
88
+ <span class="market-icon material-symbols-outlined">hub</span>
77
89
  <div>
78
- <p class="market-mini-title">动效层已启用</p>
79
- <p class="market-mini-copy">光扫、浮动、错位网格、指针光晕、卡片内组件各自运动。</p>
90
+ <p class="market-mini-title">服务接入</p>
91
+ <p class="market-mini-copy">统一承载 Codex、Claude Code、OpenCode 与 OpenClaw 等 CLI 场景。</p>
80
92
  </div>
81
- <span class="market-status-pill">Motion</span>
93
+ <span class="market-status-pill">已接入</span>
82
94
  </div>
83
95
  <div class="market-mini-card">
84
- <span class="market-icon material-symbols-outlined">gesture</span>
96
+ <span class="market-icon material-symbols-outlined">key_vertical</span>
85
97
  <div>
86
- <p class="market-mini-title">非模板化卡片</p>
87
- <p class="market-mini-copy">每张卡片的预览内容、节奏和视觉重心都不同。</p>
98
+ <p class="market-mini-title">激活码管理</p>
99
+ <p class="market-mini-copy">支持生成、导出、绑定、过期状态追踪,方便批量运营。</p>
88
100
  </div>
89
- <span class="market-status-pill">Custom</span>
101
+ <span class="market-status-pill">CDK</span>
90
102
  </div>
91
103
  <div class="market-mini-card">
92
104
  <span class="market-icon material-symbols-outlined">speed</span>
93
105
  <div>
94
- <p class="market-mini-title">轻量 CSS 动画</p>
95
- <p class="market-mini-copy">保留静态部署,不引入新前端构建链。</p>
106
+ <p class="market-mini-title">配额监控</p>
107
+ <p class="market-mini-copy">快速查看请求、额度、用户状态和服务健康度。</p>
96
108
  </div>
97
- <span class="market-status-pill">CSS</span>
109
+ <span class="market-status-pill">监控</span>
98
110
  </div>
99
111
  </div>
100
112
 
@@ -104,7 +116,7 @@
104
116
  <span class="market-status-pill"><span class="market-kicker-dot"></span> 34020</span>
105
117
  </div>
106
118
  <p class="market-mini-copy" style="margin-top: 14px; font-size: 14px; line-height: 1.7;">
107
- 这一版把“统一样式”换成“动态产品感”:首页负责记忆点,后台和用户端继承氛围但不打断功能。
119
+ 本地 Web 服务默认运行在 34020 端口,提供首页、用户中心、管理中心和激活入口。
108
120
  </p>
109
121
  </div>
110
122
  </aside>
@@ -114,7 +126,7 @@
114
126
  <div class="market-section-head">
115
127
  <div>
116
128
  <h2 id="section-title">工作区入口</h2>
117
- <p>卡片不再是同一个模板复制三次,而是分别表达“监控、管理、激活”的动作状态。</p>
129
+ <p>按使用角色拆分入口:查看用量、管理资源、完成激活,各自保持清晰路径。</p>
118
130
  </div>
119
131
  <a class="market-button" href="/admin/">打开管理中心</a>
120
132
  </div>
@@ -126,9 +138,9 @@
126
138
  <span class="market-widget market-widget-graph"><i></i><i></i><i></i><i></i></span>
127
139
  </div>
128
140
  <div class="market-card-content">
129
- <h3>用户用量雷达</h3>
130
- <p>用浮动指标卡和脉冲柱状图表达实时额度、请求量和用户状态。</p>
131
- <div class="market-card-footer"><span class="market-tag">Portal</span><span class="market-arrow">→</span></div>
141
+ <h3>用户中心</h3>
142
+ <p>查看额度、请求趋势、公告和个人配置,适合作为用户自助入口。</p>
143
+ <div class="market-card-footer"><span class="market-tag">用户入口</span><span class="market-arrow">→</span></div>
132
144
  </div>
133
145
  </a>
134
146
 
@@ -139,8 +151,8 @@
139
151
  </div>
140
152
  <div class="market-card-content">
141
153
  <h3>管理控制台</h3>
142
- <p>像组件面板一样管理用户、激活码、日志和设置,重点是效率而不是装饰。</p>
143
- <div class="market-card-footer"><span class="market-tag">Console</span><span class="market-arrow">→</span></div>
154
+ <p>集中维护用户、激活码、日志和系统设置,适合管理员日常操作。</p>
155
+ <div class="market-card-footer"><span class="market-tag">管理入口</span><span class="market-arrow">→</span></div>
144
156
  </div>
145
157
  </a>
146
158
 
@@ -151,9 +163,9 @@
151
163
  <span class="market-widget market-widget-badge material-symbols-outlined">bolt</span>
152
164
  </div>
153
165
  <div class="market-card-content">
154
- <h3>CDK 点火流程</h3>
155
- <p>把激活动作做成“点火”体验,强调输入、校验、开通的连续反馈。</p>
156
- <div class="market-card-footer"><span class="market-tag">Activation</span><span class="market-arrow">→</span></div>
166
+ <h3>CDK 激活</h3>
167
+ <p>输入激活码即可完成服务绑定,并返回额度、服务类型和有效期。</p>
168
+ <div class="market-card-footer"><span class="market-tag">激活入口</span><span class="market-arrow">→</span></div>
157
169
  </div>
158
170
  </a>
159
171
  </div>
@@ -179,6 +191,8 @@
179
191
  });
180
192
  });
181
193
 
194
+ initThemeToggle();
195
+
182
196
  document.querySelectorAll('.market-card-lab').forEach((card) => {
183
197
  card.addEventListener('pointermove', (event) => {
184
198
  const rect = card.getBoundingClientRect();
@@ -186,6 +200,28 @@
186
200
  card.style.setProperty('--my', `${((event.clientY - rect.top) / rect.height) * 100}%`);
187
201
  });
188
202
  });
203
+
204
+ function initThemeToggle() {
205
+ const button = document.querySelector('[data-theme-toggle]');
206
+ const icon = document.querySelector('[data-theme-icon]');
207
+ if (!button || !icon) return;
208
+
209
+ const sync = () => {
210
+ const isDark = document.documentElement.classList.contains('dark');
211
+ icon.textContent = isDark ? 'dark_mode' : 'light_mode';
212
+ button.setAttribute('aria-label', isDark ? '切换浅色模式' : '切换暗黑模式');
213
+ };
214
+
215
+ button.addEventListener('click', () => {
216
+ const isDark = !document.documentElement.classList.contains('dark');
217
+ document.documentElement.classList.toggle('dark', isDark);
218
+ document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';
219
+ localStorage.setItem('fogact_theme', isDark ? 'dark' : 'light');
220
+ sync();
221
+ });
222
+
223
+ sync();
224
+ }
189
225
  </script>
190
226
  </body>
191
227
  </html>
@@ -8,15 +8,15 @@
8
8
  href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z'%3E%3C/path%3E%3C/svg%3E"
9
9
  />
10
10
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
- <title>CLIProxy - API 使用监控</title>
12
- <meta name="description" content="CLIProxy API 使用量监控平台" />
11
+ <title>FogAct 用户中心 | 用量与配额监控</title>
12
+ <meta name="description" content="FogAct 用户中心用于查看 API 用量、配额状态、公告和个人配置。" />
13
13
  <link rel="preconnect" href="https://fonts.googleapis.com" />
14
14
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15
15
  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@600;700;800&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
16
16
  <script>
17
17
  // 阻塞式主题初始化 — 防止 FOUC + 设置内联背景色
18
18
  ;(function () {
19
- var t = localStorage.getItem('yunyi_user_theme') || 'system'
19
+ var t = localStorage.getItem('fogact_theme') || localStorage.getItem('yunyi_user_theme') || 'system'
20
20
  var d = t === 'dark' || (t === 'system' && matchMedia('(prefers-color-scheme: dark)').matches)
21
21
  var el = document.documentElement
22
22
  if (d) {
@@ -31,7 +31,7 @@
31
31
  <script type="module" crossorigin src="assets/index-Da98HOxL.js"></script>
32
32
  <link rel="modulepreload" crossorigin href="assets/chart-vendor-CULJE59K.js">
33
33
  <link rel="stylesheet" crossorigin href="assets/index-B8QSyYhS.css">
34
- <link rel="stylesheet" href="/assets/market-ui.css?v=20260616-upstream2" />
34
+ <link rel="stylesheet" href="/assets/market-ui.css?v=20260619-theme1" />
35
35
  </head>
36
36
  <body class="market-user min-h-screen">
37
37
  <span class="market-mouse-light" aria-hidden="true"></span>
package/install.sh CHANGED
@@ -359,20 +359,11 @@ run_activation() {
359
359
  print_next_steps() {
360
360
  cat <<EOF
361
361
 
362
- Next commands:
363
- fogact --help
364
- fogact wizard --code YOUR_CODE --yes
365
- fogact activate --service codex --yes
366
- fogact-web
367
-
368
- For code mode with a remote activation backend:
369
- export CLIPROXY_API_BASE="https://your-activator.example.com"
370
- fogact wizard --code YOUR_CODE --yes
371
-
372
- For direct NewAPI mode:
373
- export NEWAPI_BASE_URL="https://newapi.example.com"
374
- export NEWAPI_API_KEY="sk-your-key"
375
- fogact activate --service codex --yes
362
+ Next command:
363
+ fogact
364
+
365
+ This opens the same interactive activation menu as:
366
+ npx fogact
376
367
  EOF
377
368
  }
378
369
 
package/lib/index.js CHANGED
@@ -8,37 +8,129 @@ const { runTestCommand } = require("./commands/test");
8
8
  const { runRestoreCommand } = require("./commands/restore");
9
9
  const { runActivationWizard } = require("./services/activation-orchestrator");
10
10
 
11
+ const MENU_CHOICES = [
12
+ { title: "1. 激活服务", value: "activate" },
13
+ { title: "2. 测试节点", value: "test" },
14
+ { title: "3. 恢复备份", value: "restore" },
15
+ { title: "4. 退出", value: "exit" },
16
+ ];
17
+
18
+ function displayWidth(value) {
19
+ return Array.from(value).reduce((width, char) => {
20
+ return width + (char.charCodeAt(0) > 0xff ? 2 : 1);
21
+ }, 0);
22
+ }
23
+
24
+ function padLine(value, width) {
25
+ const padding = Math.max(0, width - displayWidth(value));
26
+ const left = Math.floor(padding / 2);
27
+ const right = padding - left;
28
+ return `${" ".repeat(left)}${value}${" ".repeat(right)}`;
29
+ }
30
+
31
+ function renderMenu(cursor = 0) {
32
+ const version = packageJson.version;
33
+ const title = `FogAct 激活器 v${version}`;
34
+ const lines = [
35
+ "",
36
+ " ╭─────────────────────────────────────╮",
37
+ ` │${padLine(title, 37)}│`,
38
+ " │ Claude Code / Codex 配置工具 │",
39
+ " ╰─────────────────────────────────────╯",
40
+ "",
41
+ "? 请选择操作:",
42
+ ];
43
+
44
+ MENU_CHOICES.forEach((choice, index) => {
45
+ lines.push(`${index === cursor ? "❯" : " "} ${choice.title}`);
46
+ });
47
+
48
+ lines.push("");
49
+ lines.push("↑↓ navigate • ⏎ select");
50
+ return lines.join("\n");
51
+ }
52
+
11
53
  function printBanner() {
12
- console.log("FogAct 多平台激活器");
13
- console.log("一键激活 Codex / Claude / OpenCode / OpenClaw");
14
- console.log("");
54
+ console.log(renderMenu(0));
15
55
  }
16
56
 
17
57
  async function runInteractiveMenu() {
18
58
  await runActivationWizard();
19
59
  }
20
60
 
61
+ function selectMenuAction() {
62
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
63
+ printBanner();
64
+ return Promise.resolve(null);
65
+ }
66
+
67
+ return new Promise((resolve) => {
68
+ let cursor = 0;
69
+ let renderedLines = 0;
70
+ const stdin = process.stdin;
71
+
72
+ const render = () => {
73
+ if (renderedLines > 0) {
74
+ process.stdout.write(`\x1b[${renderedLines}A`);
75
+ process.stdout.write("\x1b[J");
76
+ }
77
+ const output = renderMenu(cursor);
78
+ renderedLines = output.split("\n").length;
79
+ process.stdout.write(output);
80
+ };
81
+
82
+ const cleanup = () => {
83
+ stdin.off("data", onData);
84
+ if (stdin.isRaw) stdin.setRawMode(false);
85
+ stdin.pause();
86
+ process.stdout.write("\x1b[?25h\n");
87
+ };
88
+
89
+ const submit = () => {
90
+ const choice = MENU_CHOICES[cursor];
91
+ cleanup();
92
+ resolve(choice.value);
93
+ };
94
+
95
+ const cancel = () => {
96
+ cleanup();
97
+ resolve("exit");
98
+ };
99
+
100
+ const onData = (data) => {
101
+ const key = data.toString("utf8");
102
+ if (key === "\u0003" || key === "\u001b") {
103
+ cancel();
104
+ return;
105
+ }
106
+ if (key === "\r" || key === "\n") {
107
+ submit();
108
+ return;
109
+ }
110
+ if (key === "\u001b[A") {
111
+ cursor = cursor === 0 ? MENU_CHOICES.length - 1 : cursor - 1;
112
+ render();
113
+ return;
114
+ }
115
+ if (key === "\u001b[B") {
116
+ cursor = cursor === MENU_CHOICES.length - 1 ? 0 : cursor + 1;
117
+ render();
118
+ }
119
+ };
120
+
121
+ process.stdout.write("\x1b[?25l");
122
+ render();
123
+ stdin.resume();
124
+ stdin.setEncoding("utf8");
125
+ stdin.setRawMode(true);
126
+ stdin.on("data", onData);
127
+ });
128
+ }
129
+
21
130
  async function runToolsMenu() {
22
- printBanner();
23
-
24
- const response = await prompts(
25
- {
26
- type: "select",
27
- name: "action",
28
- message: "请选择操作",
29
- choices: [
30
- { title: "多平台激活", value: "activate" },
31
- { title: "测试节点", value: "test" },
32
- { title: "恢复备份", value: "restore" },
33
- { title: "启动 Web UI", value: "web" },
34
- { title: "退出", value: "exit" },
35
- ],
36
- initial: 0,
37
- },
38
- { onCancel: () => false }
39
- );
40
-
41
- switch (response.action) {
131
+ const action = await selectMenuAction();
132
+
133
+ switch (action) {
42
134
  case "activate":
43
135
  await runActivationWizard();
44
136
  break;
@@ -48,10 +140,8 @@ async function runToolsMenu() {
48
140
  case "restore":
49
141
  await runRestoreCommand();
50
142
  break;
51
- case "web":
52
- runWebServer();
53
- break;
54
143
  default:
144
+ console.log("");
55
145
  console.log("再见。");
56
146
  console.log("");
57
147
  break;
@@ -76,11 +166,7 @@ function buildProgram() {
76
166
  "Examples:",
77
167
  " npx fogact",
78
168
  " fogact",
79
- " fogact activate --service codex --yes --all",
80
- " fogact activate --service claude --api-key sk-... --yes",
81
- " fogact activate --code K1DHPY3P-4B2W-F1A4-DC4P-Y74TCQZXPNYT",
82
- " fogact test",
83
- " fogact restore --service claude",
169
+ " fogact web",
84
170
  ].join("\n")
85
171
  );
86
172
 
@@ -144,7 +230,7 @@ function buildProgram() {
144
230
  }
145
231
 
146
232
  async function runCli(argv = process.argv) {
147
- const args = argv.slice(2);
233
+ const args = argv.slice(2).filter((arg) => arg !== "--help" && arg !== "-h");
148
234
 
149
235
  if (args.length === 0) {
150
236
  await runToolsMenu();
@@ -203,6 +203,7 @@ async function promptService(defaultService, entitlement = normalizeEntitlement(
203
203
  type: "select",
204
204
  name: "service",
205
205
  message: "请选择要激活的能力",
206
+ hint: "↑↓ 选择,回车确认",
206
207
  choices: allowedServices.map((service) => ({ title: getServiceLabel(service), value: service })),
207
208
  initial: 0,
208
209
  }, { onCancel: () => false });
@@ -267,9 +268,10 @@ async function promptCredentialType(options, upstream) {
267
268
  type: "select",
268
269
  name: "credentialType",
269
270
  message: "请选择激活方式",
271
+ hint: "↑↓ 选择,回车确认",
270
272
  choices: [
271
- { title: "输入 NewAPI API Key", value: "api-key" },
272
273
  { title: "输入激活码 / 兑换码", value: "code" },
274
+ { title: "输入 NewAPI API Key", value: "api-key" },
273
275
  ],
274
276
  initial: 0,
275
277
  }, { onCancel: () => false });
@@ -312,8 +314,8 @@ function getBackupPaths(targets) {
312
314
  function printBanner() {
313
315
  console.log("");
314
316
  console.log("╭────────────────────────────────────────╮");
315
- console.log("│ FogIDC 多平台激活器 │");
316
- console.log("│ 一次检测,按能力激活 Codex / Claude │");
317
+ console.log("│ FogAct 激活向导 │");
318
+ console.log("│ Claude Code / Codex 配置工具 │");
317
319
  console.log("╰────────────────────────────────────────╯");
318
320
  console.log("");
319
321
  }
@@ -578,6 +580,23 @@ async function runNewApiActivation(options = {}) {
578
580
  async function runActivationWizard(options = {}) {
579
581
  printBanner();
580
582
  const baseUpstream = loadUpstreamConfig({ configPath: options.upstreamConfig });
583
+
584
+ const service = await promptService(options.service, normalizeEntitlement());
585
+ if (!service) {
586
+ console.log("已取消。");
587
+ return { success: false, cancelled: true };
588
+ }
589
+
590
+ const initialDetectedPlatforms = detectPlatforms(service);
591
+ console.log("");
592
+ printDetection(service, initialDetectedPlatforms);
593
+
594
+ const initialTargets = await selectPlatforms(initialDetectedPlatforms, options);
595
+ if (initialTargets.length === 0) {
596
+ console.log("没有选择任何平台,已取消。");
597
+ return { success: false, cancelled: true };
598
+ }
599
+
581
600
  const credentialType = await promptCredentialType(options, baseUpstream);
582
601
  if (!credentialType) {
583
602
  console.log("已取消。");
@@ -599,12 +618,6 @@ async function runActivationWizard(options = {}) {
599
618
  return { success: false, cancelled: true };
600
619
  }
601
620
 
602
- const service = await promptService(options.service, credential.entitlement);
603
- if (!service) {
604
- console.log("已取消。");
605
- return { success: false, cancelled: true };
606
- }
607
-
608
621
  console.log("");
609
622
  if (credentialType === "api-key") {
610
623
  const verification = await verifyCredential(upstream, credential.apiKey, options);
@@ -618,16 +631,14 @@ async function runActivationWizard(options = {}) {
618
631
  const allDetectedPlatforms = detectPlatforms(service);
619
632
  const allowedPlatforms = allDetectedPlatforms.filter((entry) => isPlatformAllowed(entry, credential.entitlement, service));
620
633
  const blockedPlatforms = allDetectedPlatforms.filter((entry) => !allowedPlatforms.includes(entry));
634
+ const initialTargetIds = new Set(initialTargets.map(({ platform }) => platform.id));
621
635
 
622
- console.log("");
623
- printDetection(service, allowedPlatforms, blockedPlatforms);
624
-
625
- const targets = await selectPlatforms(allowedPlatforms, options);
636
+ const targets = allowedPlatforms.filter((entry) => initialTargetIds.has(entry.platform.id));
626
637
  if (targets.length === 0) {
627
- console.log("没有选择任何平台,已取消。");
638
+ console.log("当前激活能力不包含已选择的平台,已取消。");
628
639
  return { success: false, cancelled: true };
629
640
  }
630
- const skipped = allowedPlatforms.filter((entry) => !targets.includes(entry));
641
+ const skipped = allDetectedPlatforms.filter((entry) => !targets.includes(entry) || blockedPlatforms.includes(entry));
631
642
 
632
643
  printPlan(service, upstream, credential.apiKey, targets, skipped);
633
644
  if (!(await confirmActivation(Boolean(options.yes || options.auto)))) {
@@ -19,7 +19,7 @@ function makeRequest(path, options = {}) {
19
19
  method: options.method || "GET",
20
20
  headers: {
21
21
  "Content-Type": "application/json",
22
- "User-Agent": "fogact/1.1.4",
22
+ "User-Agent": "fogact/1.1.6",
23
23
  ...options.headers,
24
24
  },
25
25
  };
@@ -58,7 +58,7 @@ async function verifyNewApiKey(config, apiKey) {
58
58
  headers: {
59
59
  Authorization: `Bearer ${apiKey}`,
60
60
  Accept: "application/json",
61
- "User-Agent": "fogact/1.1.4",
61
+ "User-Agent": "fogact/1.1.6",
62
62
  },
63
63
  });
64
64
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fogact",
3
- "version": "1.1.4",
4
- "description": "FogAct multi-platform activator Activate Codex, Claude Code, OpenCode and OpenClaw",
3
+ "version": "1.1.6",
4
+ "description": "FogAct activation helper for Claude Code and Codex",
5
5
  "keywords": [
6
6
  "fogact",
7
7
  "cliproxy",