fogact 1.1.9 → 1.2.0
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/bin/web-server.js +23 -0
- package/frontend/assets/market-ui.css +11 -84
- package/frontend/index.html +2 -2
- 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 +4 -4
- package/lib/commands/restore.js +41 -38
- package/lib/commands/test.js +15 -21
- package/lib/index.js +20 -18
- package/lib/platforms/openclaw.js +4 -4
- package/lib/platforms/opencode.js +2 -2
- package/lib/services/activation-orchestrator.js +154 -118
- package/lib/services/backup-service.js +65 -13
- package/lib/services/fogact-api.js +28 -17
- package/lib/services/node-service.js +85 -14
- package/package.json +1 -1
package/frontend/user/index.html
CHANGED
|
@@ -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>
|
|
12
|
-
<meta name="description" content="
|
|
11
|
+
<title>CLIProxy - API 使用监控</title>
|
|
12
|
+
<meta name="description" content="CLIProxy 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('
|
|
19
|
+
var t = 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=20260619-
|
|
34
|
+
<link rel="stylesheet" href="/assets/market-ui.css?v=20260619-user-restore" />
|
|
35
35
|
</head>
|
|
36
36
|
<body class="market-user min-h-screen">
|
|
37
37
|
<span class="market-mouse-light" aria-hidden="true"></span>
|
package/lib/commands/restore.js
CHANGED
|
@@ -3,98 +3,101 @@
|
|
|
3
3
|
const prompts = require("prompts");
|
|
4
4
|
const { listBackups, restoreBackup, clearBackups } = require("../services/backup-service");
|
|
5
5
|
|
|
6
|
+
function formatBackupTitle(backup) {
|
|
7
|
+
const service = backup.service === "codex" ? "Codex" : backup.service === "claude" ? "Claude Code" : backup.service;
|
|
8
|
+
const time = backup.timestamp ? new Date(backup.timestamp).toLocaleString("zh-CN") : "未知时间";
|
|
9
|
+
const count = Array.isArray(backup.files) ? ` · ${backup.files.length} 个文件` : "";
|
|
10
|
+
return `${service || "未知服务"} · ${time}${count}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
async function runRestoreCommand(options = {}) {
|
|
7
14
|
console.log("");
|
|
8
|
-
console.log("
|
|
9
|
-
console.log("");
|
|
15
|
+
console.log(" 恢复备份");
|
|
16
|
+
console.log(" ─────────────────────────────────────");
|
|
10
17
|
|
|
11
|
-
// Step 1: Select service
|
|
12
18
|
let service = options.service;
|
|
13
19
|
if (!service) {
|
|
14
20
|
const response = await prompts({
|
|
15
21
|
type: "select",
|
|
16
22
|
name: "service",
|
|
17
|
-
message: "
|
|
23
|
+
message: "请选择要查看的备份",
|
|
18
24
|
choices: [
|
|
19
25
|
{ title: "Claude Code", value: "claude" },
|
|
20
26
|
{ title: "Codex", value: "codex" },
|
|
21
|
-
{ title: "
|
|
27
|
+
{ title: "全部备份", value: null },
|
|
22
28
|
],
|
|
23
|
-
|
|
29
|
+
initial: 2,
|
|
30
|
+
}, { onCancel: () => false });
|
|
24
31
|
|
|
25
32
|
if (response.service === undefined) {
|
|
26
|
-
console.log("
|
|
33
|
+
console.log("");
|
|
34
|
+
console.log(" 已取消");
|
|
35
|
+
console.log("");
|
|
27
36
|
return;
|
|
28
37
|
}
|
|
29
|
-
|
|
30
38
|
service = response.service;
|
|
31
39
|
}
|
|
32
40
|
|
|
33
|
-
// Step 2: List backups
|
|
34
41
|
const backups = listBackups(service);
|
|
35
|
-
|
|
36
42
|
if (backups.length === 0) {
|
|
37
|
-
console.log("
|
|
43
|
+
console.log("");
|
|
44
|
+
console.log(" ℹ 暂无可恢复备份");
|
|
38
45
|
console.log("");
|
|
39
46
|
return;
|
|
40
47
|
}
|
|
41
48
|
|
|
42
|
-
console.log(`Found ${backups.length} backup(s):`);
|
|
43
|
-
console.log("");
|
|
44
|
-
|
|
45
|
-
// Step 3: Select backup or clear all
|
|
46
|
-
const choices = backups.map((backup, index) => ({
|
|
47
|
-
title: `${backup.service} - ${new Date(backup.timestamp).toLocaleString()}`,
|
|
48
|
-
value: backup.path,
|
|
49
|
-
}));
|
|
50
|
-
|
|
51
|
-
choices.push({ title: "Clear all backups", value: "__clear__" });
|
|
52
|
-
|
|
53
49
|
const response = await prompts({
|
|
54
50
|
type: "select",
|
|
55
51
|
name: "backup",
|
|
56
|
-
message: "
|
|
57
|
-
choices
|
|
58
|
-
|
|
52
|
+
message: "请选择要恢复的备份",
|
|
53
|
+
choices: [
|
|
54
|
+
...backups.map((backup) => ({ title: formatBackupTitle(backup), value: backup.path })),
|
|
55
|
+
{ title: "清空当前筛选的备份", value: "__clear__" },
|
|
56
|
+
],
|
|
57
|
+
}, { onCancel: () => false });
|
|
59
58
|
|
|
60
59
|
if (!response.backup) {
|
|
61
|
-
console.log("
|
|
60
|
+
console.log("");
|
|
61
|
+
console.log(" 已取消");
|
|
62
|
+
console.log("");
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
// Step 4: Handle clear all
|
|
66
66
|
if (response.backup === "__clear__") {
|
|
67
67
|
const confirm = await prompts({
|
|
68
68
|
type: "confirm",
|
|
69
69
|
name: "value",
|
|
70
|
-
message: "
|
|
70
|
+
message: "确认清空这些备份?",
|
|
71
71
|
initial: false,
|
|
72
|
-
});
|
|
72
|
+
}, { onCancel: () => false });
|
|
73
73
|
|
|
74
74
|
if (!confirm.value) {
|
|
75
|
-
console.log("
|
|
75
|
+
console.log("");
|
|
76
|
+
console.log(" 已取消");
|
|
77
|
+
console.log("");
|
|
76
78
|
return;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
const count = clearBackups(service);
|
|
80
82
|
console.log("");
|
|
81
|
-
console.log(
|
|
83
|
+
console.log(` ✓ 已清理 ${count} 个备份`);
|
|
82
84
|
console.log("");
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
// Step 5: Restore backup
|
|
87
88
|
console.log("");
|
|
88
|
-
console.log("
|
|
89
|
-
|
|
89
|
+
console.log(" 正在恢复备份...");
|
|
90
90
|
try {
|
|
91
|
-
const
|
|
92
|
-
console.log(
|
|
91
|
+
const restoredPaths = restoreBackup(response.backup);
|
|
92
|
+
console.log(" ✓ 备份已恢复");
|
|
93
|
+
for (const restoredPath of restoredPaths) {
|
|
94
|
+
console.log(` ${restoredPath}`);
|
|
95
|
+
}
|
|
93
96
|
console.log("");
|
|
94
|
-
console.log("
|
|
97
|
+
console.log(" 请重启相关工具以应用恢复后的配置");
|
|
95
98
|
console.log("");
|
|
96
99
|
} catch (err) {
|
|
97
|
-
console.log(
|
|
100
|
+
console.log(` ✗ 恢复失败: ${err.message}`);
|
|
98
101
|
console.log("");
|
|
99
102
|
}
|
|
100
103
|
}
|
package/lib/commands/test.js
CHANGED
|
@@ -5,33 +5,27 @@ const { testNodes, formatNodeResults } = require("../services/node-service");
|
|
|
5
5
|
|
|
6
6
|
async function runTestCommand() {
|
|
7
7
|
console.log("");
|
|
8
|
-
console.log("
|
|
9
|
-
console.log("");
|
|
8
|
+
console.log(" 测试节点");
|
|
9
|
+
console.log(" ─────────────────────────────────────");
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const services = [
|
|
12
|
+
{ key: "claude", label: "Claude Code" },
|
|
13
|
+
{ key: "codex", label: "Codex" },
|
|
14
|
+
];
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
const claudeResults = await testNodes(claudeNodes);
|
|
16
|
+
for (const service of services) {
|
|
17
17
|
console.log("");
|
|
18
|
-
console.log(
|
|
19
|
-
|
|
20
|
-
console.log(" No Claude nodes available");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
console.log("");
|
|
18
|
+
console.log(` 正在测试 ${service.label} 节点...`);
|
|
19
|
+
const nodes = await getNodes(service.key);
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
if (nodes.length === 0) {
|
|
22
|
+
console.log(" ℹ 暂无可用节点");
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
const codexResults = await testNodes(codexNodes);
|
|
26
|
+
const results = await testNodes(nodes);
|
|
31
27
|
console.log("");
|
|
32
|
-
console.log(formatNodeResults(
|
|
33
|
-
} else {
|
|
34
|
-
console.log(" No Codex nodes available");
|
|
28
|
+
console.log(formatNodeResults(results));
|
|
35
29
|
}
|
|
36
30
|
|
|
37
31
|
console.log("");
|
package/lib/index.js
CHANGED
|
@@ -171,7 +171,7 @@ function printBanner() {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
async function runInteractiveMenu() {
|
|
174
|
-
await
|
|
174
|
+
await runToolsMenu();
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
function selectMenuAction() {
|
|
@@ -244,23 +244,25 @@ function selectMenuAction() {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
async function runToolsMenu() {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
247
|
+
for (;;) {
|
|
248
|
+
const action = await selectMenuAction();
|
|
249
|
+
|
|
250
|
+
switch (action) {
|
|
251
|
+
case "activate":
|
|
252
|
+
await runActivationWizard();
|
|
253
|
+
break;
|
|
254
|
+
case "test":
|
|
255
|
+
await runTestCommand();
|
|
256
|
+
break;
|
|
257
|
+
case "restore":
|
|
258
|
+
await runRestoreCommand();
|
|
259
|
+
break;
|
|
260
|
+
default:
|
|
261
|
+
console.log("");
|
|
262
|
+
console.log(" 再见!");
|
|
263
|
+
console.log("");
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
264
266
|
}
|
|
265
267
|
}
|
|
266
268
|
|
|
@@ -22,7 +22,7 @@ function buildClaudeConfig(existingConfig, baseUrl, apiKey) {
|
|
|
22
22
|
models: {
|
|
23
23
|
mode: "merge",
|
|
24
24
|
providers: {
|
|
25
|
-
"
|
|
25
|
+
"fogact-claude": {
|
|
26
26
|
baseUrl,
|
|
27
27
|
apiKey,
|
|
28
28
|
auth: "api-key",
|
|
@@ -37,7 +37,7 @@ function buildClaudeConfig(existingConfig, baseUrl, apiKey) {
|
|
|
37
37
|
...agentRest,
|
|
38
38
|
defaults: {
|
|
39
39
|
model: {
|
|
40
|
-
primary: "
|
|
40
|
+
primary: "fogact-claude/claude-opus-4-6",
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
},
|
|
@@ -52,7 +52,7 @@ function buildCodexConfig(existingConfig, baseUrl, apiKey) {
|
|
|
52
52
|
models: {
|
|
53
53
|
mode: "merge",
|
|
54
54
|
providers: {
|
|
55
|
-
"
|
|
55
|
+
"fogact-codex": {
|
|
56
56
|
baseUrl,
|
|
57
57
|
apiKey,
|
|
58
58
|
auth: "api-key",
|
|
@@ -77,7 +77,7 @@ function buildCodexConfig(existingConfig, baseUrl, apiKey) {
|
|
|
77
77
|
...agentRest,
|
|
78
78
|
defaults: {
|
|
79
79
|
model: {
|
|
80
|
-
primary: "
|
|
80
|
+
primary: "fogact-codex/gpt-5.2",
|
|
81
81
|
},
|
|
82
82
|
},
|
|
83
83
|
},
|
|
@@ -18,7 +18,7 @@ function buildClaudeConfig(existingConfig, baseUrl, apiKey) {
|
|
|
18
18
|
const { model, small_model, ...rest } = existingConfig || {};
|
|
19
19
|
const provider = rest.provider || {};
|
|
20
20
|
provider.anthropic = {
|
|
21
|
-
name: "
|
|
21
|
+
name: "fogact-claude",
|
|
22
22
|
npm: "@ai-sdk/anthropic",
|
|
23
23
|
options: {
|
|
24
24
|
baseURL: `${baseUrl.replace(/\/+$/, "")}/v1`,
|
|
@@ -38,7 +38,7 @@ function buildCodexConfig(existingConfig, baseUrl, apiKey) {
|
|
|
38
38
|
const { model, small_model, ...rest } = existingConfig || {};
|
|
39
39
|
const provider = rest.provider || {};
|
|
40
40
|
provider.openai = {
|
|
41
|
-
name: "
|
|
41
|
+
name: "fogact-codex",
|
|
42
42
|
npm: "@ai-sdk/openai",
|
|
43
43
|
api: "responses",
|
|
44
44
|
options: {
|