fogact 1.2.2 → 1.2.4
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/bin/web-server.js +557 -141
- package/config/upstream.example.json +1 -1
- package/frontend/user/assets/AnnouncementDetail-Dvxmwz0A-fogact-live.js +12 -0
- package/frontend/user/assets/Announcements-CS1tF2mx-fogact-live.js +11 -0
- package/frontend/user/assets/CardBind-CsCxihhP-fogact-live.js +21 -0
- package/frontend/user/assets/CardContent.vue_vue_type_script_setup_true_lang-D2L-uqSl-fogact-live.js +1 -0
- package/frontend/user/assets/CardDescription.vue_vue_type_script_setup_true_lang-D-v5Pl7F-fogact-live.js +1 -0
- package/frontend/user/assets/CardTitle.vue_vue_type_script_setup_true_lang-a0CCN6D5-fogact-live.js +1 -0
- package/frontend/user/assets/Dashboard-rPsmltm5-fogact-live.js +51 -0
- package/frontend/user/assets/DashboardLayout-DDkxHYFj-fogact-live.js +80 -0
- package/frontend/user/assets/Input.vue_vue_type_script_setup_true_lang-B0SyPmYb-fogact-live.js +6 -0
- package/frontend/user/assets/Label.vue_vue_type_script_setup_true_lang-CxYORSgN-fogact-live.js +1 -0
- package/frontend/user/assets/Progress.vue_vue_type_script_setup_true_lang-2_QbPsEQ-fogact-live.js +1 -0
- package/frontend/user/assets/QuotaPack-B_tJ7Psm-fogact-live.js +6 -0
- package/frontend/user/assets/Renewal-BSDhDmwv-fogact-live.js +6 -0
- package/frontend/user/assets/ScrollArea.vue_vue_type_script_setup_true_lang-DMYwcfpz-fogact-live.js +1 -0
- package/frontend/user/assets/Separator.vue_vue_type_script_setup_true_lang-Ckg8EXj_-fogact-live.js +1 -0
- package/frontend/user/assets/Settings-CBdAa3lw-fogact-live.js +11 -0
- package/frontend/user/assets/TooltipTrigger.vue_vue_type_script_setup_true_lang-DtSBjzGo-fogact-live.js +16 -0
- package/frontend/user/assets/Welcome-Dtfp6oER-fogact-live.js +1 -0
- package/frontend/user/assets/_plugin-vue_export-helper-5cjT4u0R-fogact-live.js +16 -0
- package/frontend/user/assets/activity-wYWtyqTJ-fogact-live.js +6 -0
- package/frontend/user/assets/announcement-35mOnjRL-fogact-live.js +16 -0
- package/frontend/user/assets/calendar-BFNuCata-fogact-live.js +6 -0
- package/frontend/user/assets/chevron-down-kDbuU1Py-fogact-live.js +6 -0
- package/frontend/user/assets/chevron-right-BayASIm0-fogact-live.js +6 -0
- package/frontend/user/assets/eye-CY62vip0-fogact-live.js +6 -0
- package/frontend/user/assets/gauge-C5NQ-mV8-fogact-live.js +6 -0
- package/frontend/user/assets/index-fogact-live.js +91 -0
- package/frontend/user/assets/link-2-DT5R5nGO-fogact-live.js +6 -0
- package/frontend/user/assets/package-rUbExUEn-fogact-live.js +6 -0
- package/frontend/user/assets/plus-CQc6C8wG-fogact-live.js +11 -0
- package/frontend/user/assets/refresh-cw-Y9hCloPL-fogact-live.js +6 -0
- package/frontend/user/assets/useUserPageRefresh-BYZvpNR9-fogact-live.js +1 -0
- package/frontend/user/assets/zap-l5zbZqrM-fogact-live.js +11 -0
- package/frontend/user/index.html +1 -1
- package/lib/index.js +91 -13
- package/lib/services/database.js +47 -0
- package/package.json +1 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as e}from"./index-fogact-live.js";/**
|
|
2
|
+
* @license lucide-vue-next v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const n=e("Link2Icon",[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]]);export{n as L};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as a}from"./index-fogact-live.js";/**
|
|
2
|
+
* @license lucide-vue-next v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const c=a("PackageIcon",[["path",{d:"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",key:"1a0edw"}],["path",{d:"M12 22V12",key:"d0xqtd"}],["path",{d:"m3.3 7 7.703 4.734a2 2 0 0 0 1.994 0L20.7 7",key:"yx3hmr"}],["path",{d:"m7.5 4.27 9 5.15",key:"1c824w"}]]);export{c as P};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{c as a}from"./index-fogact-live.js";/**
|
|
2
|
+
* @license lucide-vue-next v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const s=a("LayersIcon",[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]]);/**
|
|
7
|
+
* @license lucide-vue-next v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const t=a("PlusIcon",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);export{s as L,t as P};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as e}from"./index-fogact-live.js";/**
|
|
2
|
+
* @license lucide-vue-next v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const t=e("RefreshCwIcon",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);export{t as R};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{u as c}from"./index-fogact-live.js";import{w as i,L as d,f as h}from"./chart-vendor-CULJE59K.js";const o=Symbol("user-page-refresh");function v(l,e={}){const n=c(),f=h(o,null);let t=0;async function a(r="custom"){var u;const s=++t;(u=e.resetBeforeLoad)==null||u.call(e,r),await l({reason:r,runId:s,isLatest:()=>s===t})}return e.reloadOnKeyChange!==!1&&i(()=>n.activeKeyId,(r,s)=>{r!==s&&a("active-key-change")}),e.reloadOnManualRefresh!==!1&&f&&i(()=>f.refreshTick.value,()=>{a("manual-refresh")}),e.immediate!==!1&&d(()=>{a("initial")}),{reload:a}}export{v as a,o as u};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{c as a}from"./index-fogact-live.js";/**
|
|
2
|
+
* @license lucide-vue-next v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const e=a("ShieldIcon",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]]);/**
|
|
7
|
+
* @license lucide-vue-next v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const o=a("ZapIcon",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]);export{e as S,o as Z};
|
package/frontend/user/index.html
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
}
|
|
29
29
|
})()
|
|
30
30
|
</script>
|
|
31
|
-
<script type="module" crossorigin src="assets/index-
|
|
31
|
+
<script type="module" crossorigin src="assets/index-fogact-live.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
34
|
<link rel="stylesheet" href="/assets/market-ui.css?v=20260619-fogact-copy2" />
|
package/lib/index.js
CHANGED
|
@@ -170,6 +170,28 @@ function printBanner() {
|
|
|
170
170
|
console.log(renderMenu(0));
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
function shouldUseFixedMenuScreen(env = process.env, stdout = process.stdout) {
|
|
174
|
+
if (!stdout.isTTY) return false;
|
|
175
|
+
if (env.FOGACT_NO_FIXED_MENU === "1" || env.FOGACT_PLAIN_MENU === "1") return false;
|
|
176
|
+
return String(env.TERM || "").toLowerCase() !== "dumb";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function enterFixedMenuScreen(stdout = process.stdout) {
|
|
180
|
+
stdout.write("\x1b[?1049h\x1b[?25l\x1b[?7l");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function leaveFixedMenuScreen(stdout = process.stdout) {
|
|
184
|
+
stdout.write("\x1b[?7h\x1b[?25h\x1b[?1049l");
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function saveMenuCursor(stdout = process.stdout) {
|
|
188
|
+
stdout.write("\x1b7\x1b[s\x1b[?25l");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function restoreMenuCursor(stdout = process.stdout) {
|
|
192
|
+
stdout.write("\x1b8\x1b[u\x1b[J");
|
|
193
|
+
}
|
|
194
|
+
|
|
173
195
|
function moveMenuCursor(cursor, direction, total) {
|
|
174
196
|
return (cursor + direction + total) % total;
|
|
175
197
|
}
|
|
@@ -221,6 +243,41 @@ async function runInteractiveMenu() {
|
|
|
221
243
|
await runToolsMenu();
|
|
222
244
|
}
|
|
223
245
|
|
|
246
|
+
function waitForMenuReturn(message = "按回车返回菜单...") {
|
|
247
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
248
|
+
return Promise.resolve();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return new Promise((resolve) => {
|
|
252
|
+
const stdin = process.stdin;
|
|
253
|
+
const wasRaw = Boolean(stdin.isRaw);
|
|
254
|
+
let closed = false;
|
|
255
|
+
|
|
256
|
+
const cleanup = () => {
|
|
257
|
+
if (closed) return;
|
|
258
|
+
closed = true;
|
|
259
|
+
stdin.off("data", onData);
|
|
260
|
+
if (stdin.isTTY && stdin.isRaw !== wasRaw) stdin.setRawMode(wasRaw);
|
|
261
|
+
stdin.pause();
|
|
262
|
+
process.stdout.write("\n");
|
|
263
|
+
resolve();
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const onData = (data) => {
|
|
267
|
+
const value = String(data);
|
|
268
|
+
if (value.includes("\u0003") || value.includes("\u001b") || value.includes("\r") || value.includes("\n")) {
|
|
269
|
+
cleanup();
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
process.stdout.write(` ${message}`);
|
|
274
|
+
stdin.setEncoding("utf8");
|
|
275
|
+
stdin.setRawMode(true);
|
|
276
|
+
stdin.resume();
|
|
277
|
+
stdin.on("data", onData);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
224
281
|
function selectMenuAction() {
|
|
225
282
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
226
283
|
printBanner();
|
|
@@ -229,24 +286,33 @@ function selectMenuAction() {
|
|
|
229
286
|
|
|
230
287
|
return new Promise((resolve) => {
|
|
231
288
|
let cursor = 0;
|
|
232
|
-
let
|
|
289
|
+
let closed = false;
|
|
233
290
|
const stdin = process.stdin;
|
|
291
|
+
const stdout = process.stdout;
|
|
292
|
+
const useFixedScreen = shouldUseFixedMenuScreen(process.env, stdout);
|
|
293
|
+
const wasRaw = Boolean(stdin.isRaw);
|
|
234
294
|
|
|
235
295
|
const render = () => {
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
|
|
296
|
+
if (useFixedScreen) {
|
|
297
|
+
stdout.write("\x1b[H\x1b[2J");
|
|
298
|
+
} else {
|
|
299
|
+
restoreMenuCursor(stdout);
|
|
239
300
|
}
|
|
240
|
-
|
|
241
|
-
renderedLines = output.split("\n").length;
|
|
242
|
-
process.stdout.write(output);
|
|
301
|
+
stdout.write(renderMenu(cursor));
|
|
243
302
|
};
|
|
244
303
|
|
|
245
304
|
const cleanup = () => {
|
|
305
|
+
if (closed) return;
|
|
306
|
+
closed = true;
|
|
246
307
|
stdin.off("data", onData);
|
|
247
|
-
if (stdin.isRaw) stdin.setRawMode(
|
|
308
|
+
if (stdin.isTTY && stdin.isRaw !== wasRaw) stdin.setRawMode(wasRaw);
|
|
248
309
|
stdin.pause();
|
|
249
|
-
|
|
310
|
+
if (useFixedScreen) {
|
|
311
|
+
leaveFixedMenuScreen(stdout);
|
|
312
|
+
} else {
|
|
313
|
+
restoreMenuCursor(stdout);
|
|
314
|
+
stdout.write("\x1b[?25h");
|
|
315
|
+
}
|
|
250
316
|
};
|
|
251
317
|
|
|
252
318
|
const submit = () => {
|
|
@@ -261,7 +327,7 @@ function selectMenuAction() {
|
|
|
261
327
|
};
|
|
262
328
|
|
|
263
329
|
const onData = (data) => {
|
|
264
|
-
const next = applyMenuInput(data
|
|
330
|
+
const next = applyMenuInput(String(data), cursor, MENU_CHOICES.length);
|
|
265
331
|
const cursorChanged = next.cursor !== cursor;
|
|
266
332
|
cursor = next.cursor;
|
|
267
333
|
|
|
@@ -280,11 +346,16 @@ function selectMenuAction() {
|
|
|
280
346
|
}
|
|
281
347
|
};
|
|
282
348
|
|
|
283
|
-
process.stdout.write("\x1b[?25l");
|
|
284
|
-
render();
|
|
285
|
-
stdin.resume();
|
|
286
349
|
stdin.setEncoding("utf8");
|
|
287
350
|
stdin.setRawMode(true);
|
|
351
|
+
stdin.resume();
|
|
352
|
+
|
|
353
|
+
if (useFixedScreen) {
|
|
354
|
+
enterFixedMenuScreen(stdout);
|
|
355
|
+
} else {
|
|
356
|
+
saveMenuCursor(stdout);
|
|
357
|
+
}
|
|
358
|
+
render();
|
|
288
359
|
stdin.on("data", onData);
|
|
289
360
|
});
|
|
290
361
|
}
|
|
@@ -299,9 +370,11 @@ async function runToolsMenu() {
|
|
|
299
370
|
break;
|
|
300
371
|
case "test":
|
|
301
372
|
await runTestCommand();
|
|
373
|
+
await waitForMenuReturn();
|
|
302
374
|
break;
|
|
303
375
|
case "restore":
|
|
304
376
|
await runRestoreCommand();
|
|
377
|
+
await waitForMenuReturn();
|
|
305
378
|
break;
|
|
306
379
|
default:
|
|
307
380
|
console.log("");
|
|
@@ -403,10 +476,15 @@ async function runCli(argv = process.argv) {
|
|
|
403
476
|
module.exports = {
|
|
404
477
|
applyMenuInput,
|
|
405
478
|
buildProgram,
|
|
479
|
+
enterFixedMenuScreen,
|
|
480
|
+
leaveFixedMenuScreen,
|
|
481
|
+
renderMenu,
|
|
482
|
+
shouldUseFixedMenuScreen,
|
|
406
483
|
ensureLatestVersion,
|
|
407
484
|
isNewerVersion,
|
|
408
485
|
runCli,
|
|
409
486
|
runInteractiveMenu,
|
|
410
487
|
runToolsMenu,
|
|
411
488
|
runWebServer,
|
|
489
|
+
waitForMenuReturn,
|
|
412
490
|
};
|
package/lib/services/database.js
CHANGED
|
@@ -6,6 +6,7 @@ const path = require("path");
|
|
|
6
6
|
const DATA_DIR = path.join(__dirname, "..", "..", "data");
|
|
7
7
|
const USERS_FILE = path.join(DATA_DIR, "users.json");
|
|
8
8
|
const CODES_FILE = path.join(DATA_DIR, "codes.json");
|
|
9
|
+
const USAGE_FILE = path.join(DATA_DIR, "usage.json");
|
|
9
10
|
|
|
10
11
|
// 确保数据目录存在
|
|
11
12
|
function ensureDataDir() {
|
|
@@ -257,6 +258,51 @@ const codeDb = {
|
|
|
257
258
|
},
|
|
258
259
|
};
|
|
259
260
|
|
|
261
|
+
// 用量日志数据库操作
|
|
262
|
+
const usageDb = {
|
|
263
|
+
getAll() {
|
|
264
|
+
return readJsonFile(USAGE_FILE, []);
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
create(usageData) {
|
|
268
|
+
const items = this.getAll();
|
|
269
|
+
const now = new Date().toISOString();
|
|
270
|
+
const newItem = {
|
|
271
|
+
id: usageData.id || `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
272
|
+
codeId: usageData.codeId || null,
|
|
273
|
+
code: usageData.code || null,
|
|
274
|
+
service: usageData.service || "claude",
|
|
275
|
+
model: usageData.model || "unknown",
|
|
276
|
+
inputTokens: Number(usageData.inputTokens || 0),
|
|
277
|
+
outputTokens: Number(usageData.outputTokens || 0),
|
|
278
|
+
totalTokens: Number(usageData.totalTokens || 0),
|
|
279
|
+
requests: Number(usageData.requests || 1),
|
|
280
|
+
statusCode: usageData.statusCode || null,
|
|
281
|
+
success: usageData.success !== false,
|
|
282
|
+
cost: Number(usageData.cost || 0),
|
|
283
|
+
path: usageData.path || null,
|
|
284
|
+
createdAt: usageData.createdAt || now,
|
|
285
|
+
};
|
|
286
|
+
items.push(newItem);
|
|
287
|
+
writeJsonFile(USAGE_FILE, items);
|
|
288
|
+
return newItem;
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
getByCode(code) {
|
|
292
|
+
const value = String(code || "").trim();
|
|
293
|
+
if (!value) return [];
|
|
294
|
+
return this.getAll().filter((item) => item.code === value);
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
getSince(code, since) {
|
|
298
|
+
const sinceTime = since ? new Date(since).getTime() : 0;
|
|
299
|
+
return this.getByCode(code).filter((item) => {
|
|
300
|
+
const createdAt = new Date(item.createdAt || 0).getTime();
|
|
301
|
+
return Number.isFinite(createdAt) && createdAt >= sinceTime;
|
|
302
|
+
});
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
|
|
260
306
|
// 初始化示例数据
|
|
261
307
|
function initializeSampleData() {
|
|
262
308
|
ensureDataDir();
|
|
@@ -457,5 +503,6 @@ function initializeSampleData() {
|
|
|
457
503
|
module.exports = {
|
|
458
504
|
userDb,
|
|
459
505
|
codeDb,
|
|
506
|
+
usageDb,
|
|
460
507
|
initializeSampleData,
|
|
461
508
|
};
|