fogact 1.1.7 → 1.1.8
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.
- package/README.md +4 -4
- package/README.zh-CN.md +4 -4
- package/bin/web-server.js +11 -3
- package/frontend/activate.html +1 -1
- package/frontend/admin/admin-panel-v2.js +2 -2
- package/frontend/admin/index.html +1 -1
- package/frontend/assets/market-ui.css +107 -242
- package/frontend/color-test.html +1 -1
- package/frontend/index.html +32 -37
- package/frontend/user/assets/DashboardLayout-DDkxHYFj.js +1 -1
- package/frontend/user/assets/Welcome-Dtfp6oER.js +1 -1
- package/frontend/user/assets/announcement-35mOnjRL.js +1 -1
- package/frontend/user/assets/index-Da98HOxL.js +2 -2
- package/frontend/user/index.html +1 -1
- package/install.sh +25 -25
- package/lib/commands/activate.js +2 -2
- package/lib/commands/test.js +1 -1
- package/lib/config/codex.js +28 -22
- package/lib/config/upstream.js +1 -1
- package/lib/index.js +2 -2
- package/lib/platforms/editor-codex.js +2 -2
- package/lib/services/activation-orchestrator.js +73 -55
- package/lib/services/backup-service.js +1 -2
- package/lib/services/{cliproxy-api.js → fogact-api.js} +5 -4
- package/lib/services/newapi.js +2 -1
- package/lib/services/node-service.js +1 -1
- package/package.json +2 -9
package/frontend/user/index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<script>
|
|
17
17
|
// 阻塞式主题初始化 — 防止 FOUC + 设置内联背景色
|
|
18
18
|
;(function () {
|
|
19
|
-
var t = localStorage.getItem('fogact_theme') ||
|
|
19
|
+
var t = localStorage.getItem('fogact_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) {
|
package/install.sh
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
set -eu
|
|
3
3
|
|
|
4
|
-
PACKAGE_NAME="${
|
|
5
|
-
GITHUB_REPO="${
|
|
6
|
-
GIT_REF="${
|
|
7
|
-
INSTALL_METHOD="${
|
|
8
|
-
INSTALL_DIR="${
|
|
9
|
-
SERVICE="${
|
|
10
|
-
CODE="${
|
|
11
|
-
API_KEY="${NEWAPI_API_KEY:-${
|
|
12
|
-
BASE_URL="${NEWAPI_BASE_URL:-${
|
|
13
|
-
|
|
14
|
-
PLATFORMS="${
|
|
15
|
-
RUN_WEB="${
|
|
16
|
-
WEB_PORT="${PORT:-${
|
|
17
|
-
ADMIN_PASSWORD_VALUE="${ADMIN_PASSWORD:-${
|
|
18
|
-
SKIP_VERIFY="${
|
|
19
|
-
ALL_PLATFORMS="${
|
|
20
|
-
NO_ACTIVATE="${
|
|
21
|
-
NO_REDEEM="${
|
|
22
|
-
CREATE_SYSTEMD="${
|
|
4
|
+
PACKAGE_NAME="${FOGACT_PACKAGE:-fogact}"
|
|
5
|
+
GITHUB_REPO="${FOGACT_GITHUB_REPO:-FogMaly/fogact}"
|
|
6
|
+
GIT_REF="${FOGACT_GIT_REF:-main}"
|
|
7
|
+
INSTALL_METHOD="${FOGACT_INSTALL_METHOD:-npm}"
|
|
8
|
+
INSTALL_DIR="${FOGACT_INSTALL_DIR:-}"
|
|
9
|
+
SERVICE="${FOGACT_SERVICE:-}"
|
|
10
|
+
CODE="${FOGACT_CODE:-}"
|
|
11
|
+
API_KEY="${NEWAPI_API_KEY:-${FOGACT_API_KEY:-}}"
|
|
12
|
+
BASE_URL="${NEWAPI_BASE_URL:-${FOGACT_BASE_URL:-}}"
|
|
13
|
+
FOGACT_API_BASE_VALUE="${FOGACT_API_BASE:-}"
|
|
14
|
+
PLATFORMS="${FOGACT_PLATFORMS:-}"
|
|
15
|
+
RUN_WEB="${FOGACT_RUN_WEB:-0}"
|
|
16
|
+
WEB_PORT="${PORT:-${FOGACT_WEB_PORT:-34020}}"
|
|
17
|
+
ADMIN_PASSWORD_VALUE="${ADMIN_PASSWORD:-${FOGACT_ADMIN_PASSWORD:-}}"
|
|
18
|
+
SKIP_VERIFY="${FOGACT_SKIP_VERIFY:-0}"
|
|
19
|
+
ALL_PLATFORMS="${FOGACT_ALL:-0}"
|
|
20
|
+
NO_ACTIVATE="${FOGACT_NO_ACTIVATE:-0}"
|
|
21
|
+
NO_REDEEM="${FOGACT_NO_REDEEM:-0}"
|
|
22
|
+
CREATE_SYSTEMD="${FOGACT_SYSTEMD:-0}"
|
|
23
23
|
|
|
24
24
|
log() { printf '%s\n' "==> $*"; }
|
|
25
25
|
warn() { printf '%s\n' "WARN: $*" >&2; }
|
|
@@ -40,7 +40,7 @@ Options:
|
|
|
40
40
|
--code <code> Activation / redeem code
|
|
41
41
|
--api-key <key> NewAPI key for direct activation
|
|
42
42
|
--base-url <url> NewAPI base URL for direct activation
|
|
43
|
-
--
|
|
43
|
+
--fogact-api-base <url> Activation backend URL for code mode
|
|
44
44
|
--platforms <ids> Comma-separated target platform ids
|
|
45
45
|
--all Configure all creatable optional platforms
|
|
46
46
|
--skip-verify Skip NewAPI /v1/models verification
|
|
@@ -53,9 +53,9 @@ Options:
|
|
|
53
53
|
-h, --help Show help
|
|
54
54
|
|
|
55
55
|
Environment variables mirror the options:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
FOGACT_PACKAGE=fogact, FOGACT_SERVICE, FOGACT_CODE, NEWAPI_BASE_URL, NEWAPI_API_KEY,
|
|
57
|
+
FOGACT_API_BASE, FOGACT_PLATFORMS, FOGACT_ALL=1,
|
|
58
|
+
FOGACT_SKIP_VERIFY=1, FOGACT_RUN_WEB=1, FOGACT_SYSTEMD=1
|
|
59
59
|
EOF
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
|
|
|
65
65
|
--code) CODE="${2:-}"; shift 2 ;;
|
|
66
66
|
--api-key) API_KEY="${2:-}"; shift 2 ;;
|
|
67
67
|
--base-url) BASE_URL="${2:-}"; shift 2 ;;
|
|
68
|
-
--
|
|
68
|
+
--fogact-api-base) FOGACT_API_BASE_VALUE="${2:-}"; shift 2 ;;
|
|
69
69
|
--platforms) PLATFORMS="${2:-}"; shift 2 ;;
|
|
70
70
|
--all) ALL_PLATFORMS=1; shift ;;
|
|
71
71
|
--skip-verify) SKIP_VERIFY=1; shift ;;
|
|
@@ -337,7 +337,7 @@ run_activation() {
|
|
|
337
337
|
|
|
338
338
|
if [ -n "$BASE_URL" ]; then export NEWAPI_BASE_URL="$BASE_URL"; fi
|
|
339
339
|
if [ -n "$API_KEY" ]; then export NEWAPI_API_KEY="$API_KEY"; fi
|
|
340
|
-
if [ -n "$
|
|
340
|
+
if [ -n "$FOGACT_API_BASE_VALUE" ]; then export FOGACT_API_BASE="$FOGACT_API_BASE_VALUE"; fi
|
|
341
341
|
|
|
342
342
|
set -- wizard --yes
|
|
343
343
|
if [ -n "$SERVICE" ]; then set -- "$@" --service "$SERVICE"; fi
|
package/lib/commands/activate.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const prompts = require("prompts");
|
|
4
|
-
const { verifyActivationCode, getNodes } = require("../services/
|
|
4
|
+
const { verifyActivationCode, getNodes } = require("../services/fogact-api");
|
|
5
5
|
const { testNodes, selectBestNode, formatNodeResults } = require("../services/node-service");
|
|
6
6
|
const { createBackup } = require("../services/backup-service");
|
|
7
7
|
const { writeClaudeConfig, getClaudeConfigPath } = require("../config/claude");
|
|
@@ -10,7 +10,7 @@ const { runActivationWizard, runNewApiActivation } = require("../services/activa
|
|
|
10
10
|
|
|
11
11
|
async function runLegacyCodeActivation(options = {}) {
|
|
12
12
|
console.log("");
|
|
13
|
-
console.log("===
|
|
13
|
+
console.log("=== FogAct Activation (Code Mode) ===");
|
|
14
14
|
console.log("");
|
|
15
15
|
|
|
16
16
|
let service = options.service;
|
package/lib/commands/test.js
CHANGED
package/lib/config/codex.js
CHANGED
|
@@ -4,10 +4,13 @@ const fs = require("fs");
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const os = require("os");
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
7
|
+
const FOGACT_PROVIDER = "fogact";
|
|
8
|
+
const FOGACT_MODEL = "gpt-5.3-codex";
|
|
9
|
+
const LEGACY_PROVIDER = ["yu", "nyi"].join("");
|
|
10
|
+
const LEGACY_COMMENT = ["# ", "云", "驿", " API 中转配置"].join("");
|
|
11
|
+
const LEGACY_AUTH_KEY = ["YU", "NYI", "_API_KEY"].join("");
|
|
12
|
+
const BLOCK_START = "# >>> fogact codex >>>";
|
|
13
|
+
const BLOCK_END = "# <<< fogact codex <<<";
|
|
11
14
|
|
|
12
15
|
function getCodexDir() {
|
|
13
16
|
return path.join(os.homedir(), ".codex");
|
|
@@ -53,12 +56,12 @@ function readCodexAuth() {
|
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
function
|
|
59
|
+
function stripFogactBlock(content) {
|
|
57
60
|
const lines = String(content || "").split(/\r?\n/);
|
|
58
61
|
const kept = [];
|
|
59
62
|
let inBlock = false;
|
|
60
63
|
let currentSection = null;
|
|
61
|
-
let
|
|
64
|
+
let inFogactProvider = false;
|
|
62
65
|
|
|
63
66
|
for (const line of lines) {
|
|
64
67
|
const trimmed = line.trim();
|
|
@@ -77,22 +80,23 @@ function stripYunyiBlock(content) {
|
|
|
77
80
|
const section = trimmed.match(/^\[([^\]]+)\]$/);
|
|
78
81
|
if (section) {
|
|
79
82
|
currentSection = section[1].trim();
|
|
80
|
-
|
|
81
|
-
if (
|
|
83
|
+
inFogactProvider = [`model_providers.${FOGACT_PROVIDER}`, `model_providers.${LEGACY_PROVIDER}`].some((prefix) => currentSection.toLowerCase().startsWith(prefix));
|
|
84
|
+
if (inFogactProvider) {
|
|
82
85
|
continue;
|
|
83
86
|
}
|
|
84
87
|
kept.push(line);
|
|
85
88
|
continue;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
if (
|
|
91
|
+
if (inFogactProvider) {
|
|
89
92
|
continue;
|
|
90
93
|
}
|
|
91
94
|
|
|
92
|
-
const
|
|
95
|
+
const isRootFogactSetting =
|
|
93
96
|
!currentSection &&
|
|
94
97
|
(
|
|
95
|
-
trimmed === "#
|
|
98
|
+
trimmed === "# FogAct API 中转配置" ||
|
|
99
|
+
trimmed === LEGACY_COMMENT ||
|
|
96
100
|
/^#?\s*model_provider\s*=/.test(trimmed) ||
|
|
97
101
|
/^#?\s*model\s*=/.test(trimmed) ||
|
|
98
102
|
/^#?\s*model_reasoning_effort\s*=/.test(trimmed) ||
|
|
@@ -100,7 +104,7 @@ function stripYunyiBlock(content) {
|
|
|
100
104
|
/^#?\s*preferred_auth_method\s*=/.test(trimmed)
|
|
101
105
|
);
|
|
102
106
|
|
|
103
|
-
if (!
|
|
107
|
+
if (!isRootFogactSetting) {
|
|
104
108
|
kept.push(line);
|
|
105
109
|
}
|
|
106
110
|
}
|
|
@@ -109,17 +113,17 @@ function stripYunyiBlock(content) {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
function buildCodexConfig(existingContent, baseUrl, apiKey) {
|
|
112
|
-
const cleaned =
|
|
113
|
-
const
|
|
116
|
+
const cleaned = stripFogactBlock(existingContent);
|
|
117
|
+
const fogactConfig = [
|
|
114
118
|
BLOCK_START,
|
|
115
|
-
`model_provider = "${
|
|
116
|
-
`model = "${
|
|
119
|
+
`model_provider = "${FOGACT_PROVIDER}"`,
|
|
120
|
+
`model = "${FOGACT_MODEL}"`,
|
|
117
121
|
'model_reasoning_effort = "high"',
|
|
118
122
|
"disable_response_storage = true",
|
|
119
123
|
'preferred_auth_method = "apikey"',
|
|
120
124
|
"",
|
|
121
|
-
`[model_providers.${
|
|
122
|
-
`name = "${
|
|
125
|
+
`[model_providers.${FOGACT_PROVIDER}]`,
|
|
126
|
+
`name = "${FOGACT_PROVIDER}"`,
|
|
123
127
|
`base_url = "${baseUrl}"`,
|
|
124
128
|
'wire_api = "responses"',
|
|
125
129
|
`experimental_bearer_token = "${apiKey}"`,
|
|
@@ -127,7 +131,7 @@ function buildCodexConfig(existingContent, baseUrl, apiKey) {
|
|
|
127
131
|
BLOCK_END,
|
|
128
132
|
].join("\n");
|
|
129
133
|
|
|
130
|
-
const result = cleaned ? `${
|
|
134
|
+
const result = cleaned ? `${fogactConfig}\n\n${cleaned}` : fogactConfig;
|
|
131
135
|
return result.endsWith("\n") ? result : `${result}\n`;
|
|
132
136
|
}
|
|
133
137
|
|
|
@@ -139,7 +143,9 @@ function writeCodexConfig(apiKey, baseUrl) {
|
|
|
139
143
|
const config = buildCodexConfig(readCodexConfig(), baseUrl, apiKey);
|
|
140
144
|
fs.writeFileSync(configPath, config, "utf8");
|
|
141
145
|
|
|
142
|
-
const
|
|
146
|
+
const auth = readCodexAuth();
|
|
147
|
+
delete auth.FOGACT_API_KEY;
|
|
148
|
+
delete auth[LEGACY_AUTH_KEY];
|
|
143
149
|
fs.writeFileSync(
|
|
144
150
|
authPath,
|
|
145
151
|
JSON.stringify({ ...auth, auth_mode: "apikey", OPENAI_API_KEY: apiKey }, null, 2),
|
|
@@ -152,13 +158,13 @@ function writeCodexConfig(apiKey, baseUrl) {
|
|
|
152
158
|
module.exports = {
|
|
153
159
|
BLOCK_START,
|
|
154
160
|
BLOCK_END,
|
|
155
|
-
|
|
161
|
+
FOGACT_MODEL,
|
|
156
162
|
getCodexDir,
|
|
157
163
|
getCodexConfigPath,
|
|
158
164
|
getCodexAuthPath,
|
|
159
165
|
readCodexConfig,
|
|
160
166
|
readCodexAuth,
|
|
161
|
-
|
|
167
|
+
stripFogactBlock,
|
|
162
168
|
buildCodexConfig,
|
|
163
169
|
writeCodexConfig,
|
|
164
170
|
};
|
package/lib/config/upstream.js
CHANGED
|
@@ -24,7 +24,7 @@ function trimTrailingSlash(value) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function loadUpstreamConfig(options = {}) {
|
|
27
|
-
const configPath = options.configPath || process.env.
|
|
27
|
+
const configPath = options.configPath || process.env.FOGACT_UPSTREAM_CONFIG || DEFAULT_CONFIG_PATH;
|
|
28
28
|
const fileConfig = readJsonFile(configPath);
|
|
29
29
|
const baseUrl = trimTrailingSlash(
|
|
30
30
|
process.env.NEWAPI_BASE_URL ||
|
package/lib/index.js
CHANGED
|
@@ -304,7 +304,7 @@ function buildProgram() {
|
|
|
304
304
|
|
|
305
305
|
program
|
|
306
306
|
.command("wizard")
|
|
307
|
-
.description("Open
|
|
307
|
+
.description("Open FogAct activation wizard")
|
|
308
308
|
.option("-s, --service <service>", "target service: claude or codex")
|
|
309
309
|
.option("-k, --api-key <apiKey>", "NewAPI key")
|
|
310
310
|
.option("-c, --code <code>", "activation / redeem code")
|
|
@@ -318,7 +318,7 @@ function buildProgram() {
|
|
|
318
318
|
|
|
319
319
|
program
|
|
320
320
|
.command("test")
|
|
321
|
-
.description("Test
|
|
321
|
+
.description("Test FogAct nodes")
|
|
322
322
|
.action(runTestCommand);
|
|
323
323
|
|
|
324
324
|
program
|
|
@@ -52,7 +52,7 @@ function findWebviewAsset(extensionDir) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
function isPatched(content) {
|
|
55
|
-
return content.includes("email:'
|
|
55
|
+
return content.includes("email:'FogAct'") || content.includes('email:"FogAct"');
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
function patchCodexExtension(editor) {
|
|
@@ -86,7 +86,7 @@ function patchCodexExtension(editor) {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
const pattern = /(\w+)=\{isLoading:(\w+),openAIAuth:(\w+),isCopilotApiAvailable:(\w+),authMethod:(\w+),requiresAuth:(\w+),userId:(\w+),accountId:(\w+),email:(\w+),planAtLogin:(\w+),setAuthMethod:(\w+)\}/;
|
|
89
|
-
const replacement = "$1={isLoading:$2,openAIAuth:$3,isCopilotApiAvailable:$4,authMethod:'chatgpt',requiresAuth:$6,userId:$7,accountId:$8,email:'
|
|
89
|
+
const replacement = "$1={isLoading:$2,openAIAuth:$3,isCopilotApiAvailable:$4,authMethod:'chatgpt',requiresAuth:$6,userId:$7,accountId:$8,email:'FogAct',planAtLogin:$10,setAuthMethod:$11}";
|
|
90
90
|
|
|
91
91
|
if (!pattern.test(content)) {
|
|
92
92
|
return {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const prompts = require("prompts");
|
|
4
|
-
const { detectPlatforms } = require("../platforms");
|
|
4
|
+
const { detectPlatforms, getPlatforms } = require("../platforms");
|
|
5
5
|
const { loadUpstreamConfig } = require("../config/upstream");
|
|
6
6
|
const { createActivationBackup } = require("./backup-service");
|
|
7
|
-
const { inspectActivationCode, redeemActivationCode } = require("./
|
|
7
|
+
const { inspectActivationCode, redeemActivationCode } = require("./fogact-api");
|
|
8
8
|
const { maskKey, verifyNewApiKey } = require("./newapi");
|
|
9
9
|
|
|
10
10
|
const SUPPORTED_SERVICES = ["codex", "claude"];
|
|
@@ -79,10 +79,42 @@ function normalizePlatformIds(...values) {
|
|
|
79
79
|
return ids;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
function inferServicesFromPlatformIds(platformIds) {
|
|
83
|
+
const ids = normalizePlatformIds(platformIds);
|
|
84
|
+
if (!ids.length) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const platformServices = new Map(getPlatforms().map((platform) => [platform.id, platform.services]));
|
|
89
|
+
let commonServices = null;
|
|
90
|
+
|
|
91
|
+
for (const id of ids) {
|
|
92
|
+
const services = platformServices.get(id);
|
|
93
|
+
if (!services || !services.length) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
commonServices = commonServices
|
|
97
|
+
? commonServices.filter((service) => services.includes(service))
|
|
98
|
+
: [...services];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return commonServices || [];
|
|
102
|
+
}
|
|
103
|
+
|
|
82
104
|
function normalizeEntitlement(raw = {}, fallbackServices = []) {
|
|
83
105
|
const source = raw && typeof raw === "object" ? raw : {};
|
|
84
106
|
const data = source.data && typeof source.data === "object" ? source.data : source;
|
|
85
107
|
const capabilities = data.capabilities || data.capability || data.entitlement || data.ability || {};
|
|
108
|
+
const platforms = normalizePlatformIds(
|
|
109
|
+
data.platforms,
|
|
110
|
+
data.platform,
|
|
111
|
+
data.targets,
|
|
112
|
+
data.target,
|
|
113
|
+
capabilities.platforms,
|
|
114
|
+
capabilities.platform,
|
|
115
|
+
capabilities.targets,
|
|
116
|
+
capabilities.target
|
|
117
|
+
);
|
|
86
118
|
const services = normalizeServices(
|
|
87
119
|
data.services,
|
|
88
120
|
data.service,
|
|
@@ -91,6 +123,8 @@ function normalizeEntitlement(raw = {}, fallbackServices = []) {
|
|
|
91
123
|
data.scopes,
|
|
92
124
|
data.scope,
|
|
93
125
|
data.abilities,
|
|
126
|
+
data.provider,
|
|
127
|
+
data.type,
|
|
94
128
|
capabilities.services,
|
|
95
129
|
capabilities.service,
|
|
96
130
|
capabilities.products,
|
|
@@ -98,17 +132,10 @@ function normalizeEntitlement(raw = {}, fallbackServices = []) {
|
|
|
98
132
|
capabilities.scopes,
|
|
99
133
|
capabilities.scope,
|
|
100
134
|
capabilities.abilities,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
data.platform,
|
|
106
|
-
data.targets,
|
|
107
|
-
data.target,
|
|
108
|
-
capabilities.platforms,
|
|
109
|
-
capabilities.platform,
|
|
110
|
-
capabilities.targets,
|
|
111
|
-
capabilities.target
|
|
135
|
+
capabilities.provider,
|
|
136
|
+
capabilities.type,
|
|
137
|
+
fallbackServices,
|
|
138
|
+
inferServicesFromPlatformIds(platforms)
|
|
112
139
|
);
|
|
113
140
|
|
|
114
141
|
return {
|
|
@@ -181,7 +208,9 @@ function parsePlatformIds(value) {
|
|
|
181
208
|
return normalizePlatformIds(value);
|
|
182
209
|
}
|
|
183
210
|
|
|
184
|
-
async function promptService(defaultService, entitlement = normalizeEntitlement()) {
|
|
211
|
+
async function promptService(defaultService, entitlement = normalizeEntitlement(), options = {}) {
|
|
212
|
+
const allowPrompt = options.allowPrompt !== false;
|
|
213
|
+
|
|
185
214
|
if (defaultService) {
|
|
186
215
|
const normalized = normalizeService(defaultService);
|
|
187
216
|
if (!SUPPORTED_SERVICES.includes(normalized)) {
|
|
@@ -190,21 +219,34 @@ async function promptService(defaultService, entitlement = normalizeEntitlement(
|
|
|
190
219
|
if (!isServiceAllowed(entitlement, normalized)) {
|
|
191
220
|
throw new Error(`当前激活码不支持 ${getServiceLabel(normalized)}`);
|
|
192
221
|
}
|
|
222
|
+
console.log(`能力范围: ${getServiceLabel(normalized)}`);
|
|
193
223
|
return normalized;
|
|
194
224
|
}
|
|
195
225
|
|
|
196
|
-
const allowedServices = entitlement.services.length ? entitlement.services :
|
|
226
|
+
const allowedServices = entitlement.services.length ? entitlement.services : [];
|
|
197
227
|
if (allowedServices.length === 1) {
|
|
198
228
|
console.log(`能力范围: ${getServiceLabel(allowedServices[0])}`);
|
|
199
229
|
return allowedServices[0];
|
|
200
230
|
}
|
|
201
231
|
|
|
232
|
+
if (!allowPrompt) {
|
|
233
|
+
if (allowedServices.length > 1) {
|
|
234
|
+
const service = allowedServices[0];
|
|
235
|
+
const labels = allowedServices.map(getServiceLabel).join(" / ");
|
|
236
|
+
console.log(`能力范围: ${labels},本次自动激活 ${getServiceLabel(service)}`);
|
|
237
|
+
return service;
|
|
238
|
+
}
|
|
239
|
+
console.log("✗ 激活码没有返回 Codex / Claude 能力,无法自动识别。请联系管理员重新生成激活码。");
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const promptServices = allowedServices.length ? allowedServices : SUPPORTED_SERVICES;
|
|
202
244
|
const response = await prompts({
|
|
203
245
|
type: "select",
|
|
204
246
|
name: "service",
|
|
205
247
|
message: "请选择要激活的能力",
|
|
206
248
|
hint: "↑↓ 选择,回车确认",
|
|
207
|
-
choices:
|
|
249
|
+
choices: promptServices.map((service) => ({ title: getServiceLabel(service), value: service })),
|
|
208
250
|
initial: 0,
|
|
209
251
|
}, { onCancel: () => false });
|
|
210
252
|
|
|
@@ -423,19 +465,8 @@ async function resolveCodeCredential(options, upstream) {
|
|
|
423
465
|
console.log("正在读取激活码能力...");
|
|
424
466
|
const inspection = await inspectActivationCode(code);
|
|
425
467
|
if (!inspection.valid) {
|
|
426
|
-
console.log(
|
|
427
|
-
|
|
428
|
-
return { cancelled: true };
|
|
429
|
-
}
|
|
430
|
-
const response = await prompts({
|
|
431
|
-
type: "confirm",
|
|
432
|
-
name: "fallback",
|
|
433
|
-
message: "是否按手动能力选择继续?",
|
|
434
|
-
initial: false,
|
|
435
|
-
}, { onCancel: () => false });
|
|
436
|
-
if (!response.fallback) {
|
|
437
|
-
return { cancelled: true };
|
|
438
|
-
}
|
|
468
|
+
console.log(`✗ 无法读取激活码能力: ${inspection.error || "接口未返回有效信息"}`);
|
|
469
|
+
return { cancelled: true };
|
|
439
470
|
}
|
|
440
471
|
|
|
441
472
|
const entitlement = normalizeEntitlement(inspection, options.service ? [options.service] : []);
|
|
@@ -580,28 +611,7 @@ async function runNewApiActivation(options = {}) {
|
|
|
580
611
|
async function runActivationWizard(options = {}) {
|
|
581
612
|
printBanner();
|
|
582
613
|
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
|
-
|
|
600
|
-
const credentialType = await promptCredentialType(options, baseUpstream);
|
|
601
|
-
if (!credentialType) {
|
|
602
|
-
console.log("已取消。");
|
|
603
|
-
return { success: false, cancelled: true };
|
|
604
|
-
}
|
|
614
|
+
const credentialType = !options.code && options.apiKey ? "api-key" : "code";
|
|
605
615
|
|
|
606
616
|
const credential = credentialType === "code"
|
|
607
617
|
? await resolveCodeCredential(options, baseUpstream)
|
|
@@ -618,6 +628,12 @@ async function runActivationWizard(options = {}) {
|
|
|
618
628
|
return { success: false, cancelled: true };
|
|
619
629
|
}
|
|
620
630
|
|
|
631
|
+
const service = await promptService(options.service, credential.entitlement, { allowPrompt: credentialType === "api-key" });
|
|
632
|
+
if (!service) {
|
|
633
|
+
console.log("已取消。");
|
|
634
|
+
return { success: false, cancelled: true };
|
|
635
|
+
}
|
|
636
|
+
|
|
621
637
|
console.log("");
|
|
622
638
|
if (credentialType === "api-key") {
|
|
623
639
|
const verification = await verifyCredential(upstream, credential.apiKey, options);
|
|
@@ -631,14 +647,16 @@ async function runActivationWizard(options = {}) {
|
|
|
631
647
|
const allDetectedPlatforms = detectPlatforms(service);
|
|
632
648
|
const allowedPlatforms = allDetectedPlatforms.filter((entry) => isPlatformAllowed(entry, credential.entitlement, service));
|
|
633
649
|
const blockedPlatforms = allDetectedPlatforms.filter((entry) => !allowedPlatforms.includes(entry));
|
|
634
|
-
const initialTargetIds = new Set(initialTargets.map(({ platform }) => platform.id));
|
|
635
650
|
|
|
636
|
-
|
|
651
|
+
console.log("");
|
|
652
|
+
printDetection(service, allowedPlatforms, blockedPlatforms);
|
|
653
|
+
|
|
654
|
+
const targets = await selectPlatforms(allowedPlatforms, options);
|
|
637
655
|
if (targets.length === 0) {
|
|
638
|
-
console.log("
|
|
656
|
+
console.log("没有选择任何平台,已取消。");
|
|
639
657
|
return { success: false, cancelled: true };
|
|
640
658
|
}
|
|
641
|
-
const skipped =
|
|
659
|
+
const skipped = allowedPlatforms.filter((entry) => !targets.includes(entry)).concat(blockedPlatforms);
|
|
642
660
|
|
|
643
661
|
printPlan(service, upstream, credential.apiKey, targets, skipped);
|
|
644
662
|
if (!(await confirmActivation(Boolean(options.yes || options.auto)))) {
|
|
@@ -4,8 +4,7 @@ const fs = require("fs");
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const os = require("os");
|
|
6
6
|
|
|
7
|
-
const BACKUP_DIR = process.env.
|
|
8
|
-
process.env.FOGIDC_BACKUP_DIR ||
|
|
7
|
+
const BACKUP_DIR = process.env.FOGACT_BACKUP_DIR ||
|
|
9
8
|
path.join(os.homedir(), ".fogact", "backups");
|
|
10
9
|
|
|
11
10
|
function ensureBackupDir() {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const packageJson = require("../../package.json");
|
|
3
4
|
const https = require("https");
|
|
4
5
|
const http = require("http");
|
|
5
6
|
|
|
6
7
|
// 支持环境变量配置 API 地址
|
|
7
|
-
const API_BASE = process.env.
|
|
8
|
+
const API_BASE = process.env.FOGACT_API_BASE || "http://localhost:34020";
|
|
8
9
|
|
|
9
10
|
function makeRequest(path, options = {}) {
|
|
10
11
|
return new Promise((resolve, reject) => {
|
|
@@ -19,7 +20,7 @@ function makeRequest(path, options = {}) {
|
|
|
19
20
|
method: options.method || "GET",
|
|
20
21
|
headers: {
|
|
21
22
|
"Content-Type": "application/json",
|
|
22
|
-
"User-Agent":
|
|
23
|
+
"User-Agent": `fogact/${packageJson.version}`,
|
|
23
24
|
...options.headers,
|
|
24
25
|
},
|
|
25
26
|
};
|
|
@@ -127,13 +128,13 @@ async function getNodes(service) {
|
|
|
127
128
|
|
|
128
129
|
// 返回默认节点
|
|
129
130
|
return [
|
|
130
|
-
{ name: "
|
|
131
|
+
{ name: "FogAct Local Node", url: "http://localhost:34020", region: "Global" }
|
|
131
132
|
];
|
|
132
133
|
} catch (err) {
|
|
133
134
|
console.error("Failed to fetch nodes:", err.message);
|
|
134
135
|
// 返回默认节点
|
|
135
136
|
return [
|
|
136
|
-
{ name: "
|
|
137
|
+
{ name: "FogAct Local Node", url: "http://localhost:34020", region: "Global" }
|
|
137
138
|
];
|
|
138
139
|
}
|
|
139
140
|
}
|
package/lib/services/newapi.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const packageJson = require("../../package.json");
|
|
3
4
|
const http = require("http");
|
|
4
5
|
const https = require("https");
|
|
5
6
|
|
|
@@ -58,7 +59,7 @@ async function verifyNewApiKey(config, apiKey) {
|
|
|
58
59
|
headers: {
|
|
59
60
|
Authorization: `Bearer ${apiKey}`,
|
|
60
61
|
Accept: "application/json",
|
|
61
|
-
"User-Agent":
|
|
62
|
+
"User-Agent": `fogact/${packageJson.version}`,
|
|
62
63
|
},
|
|
63
64
|
});
|
|
64
65
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fogact",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "FogAct activation helper for Claude Code and Codex",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fogact",
|
|
7
|
-
"cliproxy",
|
|
8
|
-
"fogidc",
|
|
9
7
|
"claude",
|
|
10
8
|
"codex",
|
|
11
|
-
"cli-proxy-api",
|
|
12
9
|
"activator"
|
|
13
10
|
],
|
|
14
11
|
"license": "MIT",
|
|
@@ -18,11 +15,7 @@
|
|
|
18
15
|
},
|
|
19
16
|
"bin": {
|
|
20
17
|
"fogact": "bin/cli.js",
|
|
21
|
-
"fogact-web": "bin/web-server.js"
|
|
22
|
-
"cliproxy-activator": "bin/cli.js",
|
|
23
|
-
"cliproxy-web": "bin/web-server.js",
|
|
24
|
-
"fogidc-activator": "bin/cli.js",
|
|
25
|
-
"fogidc-web": "bin/web-server.js"
|
|
18
|
+
"fogact-web": "bin/web-server.js"
|
|
26
19
|
},
|
|
27
20
|
"main": "./lib/index.js",
|
|
28
21
|
"files": [
|