@eddyskywalker/dsh-chatgpt-subscription 0.1.37 → 0.1.38
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/antigravity-login.mjs +36 -0
- package/lib/client.js +1256 -53
- package/lib/client.js.map +1 -1
- package/lib/index.js +1896 -20
- package/lib/types/client/antigravity/AntigravityComposerQuota.d.ts +11 -0
- package/lib/types/client/antigravity/AntigravityComposerQuota.d.ts.map +1 -0
- package/lib/types/client/antigravity/AntigravitySection.d.ts +10 -0
- package/lib/types/client/antigravity/AntigravitySection.d.ts.map +1 -0
- package/lib/types/client/antigravity/locales.d.ts +298 -0
- package/lib/types/client/antigravity/locales.d.ts.map +1 -0
- package/lib/types/client/antigravity/styles.d.ts +3 -0
- package/lib/types/client/antigravity/styles.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +1 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +7 -7
- package/lib/types/client/mermaid/renderer.d.ts +3 -0
- package/lib/types/client/mermaid/renderer.d.ts.map +1 -0
- package/lib/types/client/mermaid/sanitize.d.ts +2 -0
- package/lib/types/client/mermaid/sanitize.d.ts.map +1 -0
- package/lib/types/client/mermaid/styles.d.ts +3 -0
- package/lib/types/client/mermaid/styles.d.ts.map +1 -0
- package/lib/types/host/antigravity/adapter.d.ts +15 -0
- package/lib/types/host/antigravity/adapter.d.ts.map +1 -0
- package/lib/types/host/antigravity/client.d.ts +21 -0
- package/lib/types/host/antigravity/client.d.ts.map +1 -0
- package/lib/types/host/antigravity/mapper.d.ts +28 -0
- package/lib/types/host/antigravity/mapper.d.ts.map +1 -0
- package/lib/types/host/antigravity/oauth.d.ts +38 -0
- package/lib/types/host/antigravity/oauth.d.ts.map +1 -0
- package/lib/types/host/antigravity/routes.d.ts +6 -0
- package/lib/types/host/antigravity/routes.d.ts.map +1 -0
- package/lib/types/host/antigravity/token-store.d.ts +60 -0
- package/lib/types/host/antigravity/token-store.d.ts.map +1 -0
- package/lib/types/host/antigravity/types.d.ts +46 -0
- package/lib/types/host/antigravity/types.d.ts.map +1 -0
- package/lib/types/host/common/idle-watchdog.d.ts +8 -0
- package/lib/types/host/common/idle-watchdog.d.ts.map +1 -0
- package/lib/types/host/responses-client.d.ts.map +1 -1
- package/lib/types/host/routes.d.ts.map +1 -1
- package/lib/types/index.d.ts +4 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/antigravity-contracts.d.ts +72 -0
- package/lib/types/shared/antigravity-contracts.d.ts.map +1 -0
- package/lib/types/shared/model-catalog.d.ts +7 -0
- package/lib/types/shared/model-catalog.d.ts.map +1 -1
- package/package.json +34 -29
package/lib/client.js
CHANGED
|
@@ -4,7 +4,30 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
//#region \0rolldown/runtime.js
|
|
8
|
+
var __create = Object.create;
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
16
|
+
key = keys[i];
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
18
|
+
get: ((k) => from[k]).bind(null, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
25
|
+
value: mod,
|
|
26
|
+
enumerable: true
|
|
27
|
+
}) : target, mod));
|
|
28
|
+
//#endregion
|
|
7
29
|
let react = require("react");
|
|
30
|
+
react = __toESM(react, 1);
|
|
8
31
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
32
|
const ROUTE_PREFIX = "/api/dsh-chatgpt-subscription";
|
|
10
33
|
const CODEX_CHATGPT_PROVIDER_ID = "codex-chatgpt";
|
|
@@ -33,7 +56,7 @@ window.__ModuleLoader__.load({
|
|
|
33
56
|
//#endregion
|
|
34
57
|
//#region src/client/CodexComposerQuota.tsx
|
|
35
58
|
function CodexComposerQuota({ api, directory, loadModelDirectory, t }) {
|
|
36
|
-
const modelState = useStore(directory);
|
|
59
|
+
const modelState = useStore$1(directory);
|
|
37
60
|
const [status, setStatus] = (0, react.useState)(null);
|
|
38
61
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
39
62
|
const mountedRef = (0, react.useRef)(false);
|
|
@@ -80,7 +103,7 @@ window.__ModuleLoader__.load({
|
|
|
80
103
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("quickQuotaLabel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota === null ? loading ? t("quickQuotaLoading") : "—" : formatPercent$1(quota.remainingPercent) })]
|
|
81
104
|
});
|
|
82
105
|
}
|
|
83
|
-
function useStore(store) {
|
|
106
|
+
function useStore$1(store) {
|
|
84
107
|
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
85
108
|
}
|
|
86
109
|
function formatPercent$1(value) {
|
|
@@ -185,7 +208,8 @@ window.__ModuleLoader__.load({
|
|
|
185
208
|
inputModalities: ["text", "image"],
|
|
186
209
|
defaultReasoningEffort: "medium",
|
|
187
210
|
reasoningProfile: "gpt-5.6",
|
|
188
|
-
supportsReasoningSummary: true
|
|
211
|
+
supportsReasoningSummary: true,
|
|
212
|
+
fallbackModelId: "gpt-5.6-terra"
|
|
189
213
|
},
|
|
190
214
|
{
|
|
191
215
|
id: "gpt-5.6-terra",
|
|
@@ -194,7 +218,8 @@ window.__ModuleLoader__.load({
|
|
|
194
218
|
inputModalities: ["text", "image"],
|
|
195
219
|
defaultReasoningEffort: "medium",
|
|
196
220
|
reasoningProfile: "gpt-5.6",
|
|
197
|
-
supportsReasoningSummary: true
|
|
221
|
+
supportsReasoningSummary: true,
|
|
222
|
+
fallbackModelId: "gpt-5.5"
|
|
198
223
|
},
|
|
199
224
|
{
|
|
200
225
|
id: "gpt-5.6-luna",
|
|
@@ -203,7 +228,8 @@ window.__ModuleLoader__.load({
|
|
|
203
228
|
inputModalities: ["text", "image"],
|
|
204
229
|
defaultReasoningEffort: "medium",
|
|
205
230
|
reasoningProfile: "gpt-5.6",
|
|
206
|
-
supportsReasoningSummary: true
|
|
231
|
+
supportsReasoningSummary: true,
|
|
232
|
+
fallbackModelId: "gpt-5.5"
|
|
207
233
|
},
|
|
208
234
|
{
|
|
209
235
|
id: "gpt-5.5",
|
|
@@ -221,7 +247,8 @@ window.__ModuleLoader__.load({
|
|
|
221
247
|
inputModalities: ["text", "image"],
|
|
222
248
|
defaultReasoningEffort: "none",
|
|
223
249
|
reasoningProfile: "standard",
|
|
224
|
-
supportsReasoningSummary: true
|
|
250
|
+
supportsReasoningSummary: true,
|
|
251
|
+
fallbackModelId: "gpt-5.4-mini"
|
|
225
252
|
},
|
|
226
253
|
{
|
|
227
254
|
id: "gpt-5.4-mini",
|
|
@@ -486,7 +513,7 @@ window.__ModuleLoader__.load({
|
|
|
486
513
|
setSubagentContextDraft(null);
|
|
487
514
|
return;
|
|
488
515
|
}
|
|
489
|
-
const parsed = parsePositiveCapacity(draft);
|
|
516
|
+
const parsed = parsePositiveCapacity$1(draft);
|
|
490
517
|
if (parsed === null) {
|
|
491
518
|
setError(t("contextWindowInvalid"));
|
|
492
519
|
return;
|
|
@@ -565,7 +592,7 @@ window.__ModuleLoader__.load({
|
|
|
565
592
|
}),
|
|
566
593
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoRow, {
|
|
567
594
|
label: t("expires"),
|
|
568
|
-
value: formatDate(account?.tokenExpiresAt)
|
|
595
|
+
value: formatDate$1(account?.tokenExpiresAt)
|
|
569
596
|
})
|
|
570
597
|
] }) : null,
|
|
571
598
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoRow, {
|
|
@@ -628,7 +655,7 @@ window.__ModuleLoader__.load({
|
|
|
628
655
|
}),
|
|
629
656
|
connection !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoRow, {
|
|
630
657
|
label: t("latency"),
|
|
631
|
-
value: `${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`
|
|
658
|
+
value: `${connection.latencyMs} ms · ${formatDate$1(connection.checkedAt)}`
|
|
632
659
|
}) : null,
|
|
633
660
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
634
661
|
className: "dsh-codex-muted dsh-codex-models-hint",
|
|
@@ -883,7 +910,7 @@ window.__ModuleLoader__.load({
|
|
|
883
910
|
type: "text",
|
|
884
911
|
inputMode: "numeric",
|
|
885
912
|
placeholder: t("providerDefault"),
|
|
886
|
-
value: subagentContextDraft ?? (preferences?.subagentContextWindow ? formatCapacity(preferences.subagentContextWindow) : ""),
|
|
913
|
+
value: subagentContextDraft ?? (preferences?.subagentContextWindow ? formatCapacity$1(preferences.subagentContextWindow) : ""),
|
|
887
914
|
disabled: busy !== null,
|
|
888
915
|
"aria-label": t("subagentContextWindow"),
|
|
889
916
|
onChange: (event) => {
|
|
@@ -932,7 +959,7 @@ window.__ModuleLoader__.load({
|
|
|
932
959
|
id: inputId,
|
|
933
960
|
type: "text",
|
|
934
961
|
inputMode: "numeric",
|
|
935
|
-
value: draft ?? formatCapacity(fallback),
|
|
962
|
+
value: draft ?? formatCapacity$1(fallback),
|
|
936
963
|
disabled: busy !== null,
|
|
937
964
|
"aria-label": entry.name + " " + t("contextWindow"),
|
|
938
965
|
onChange: (event) => {
|
|
@@ -1046,7 +1073,7 @@ window.__ModuleLoader__.load({
|
|
|
1046
1073
|
children: [
|
|
1047
1074
|
t("updated"),
|
|
1048
1075
|
": ",
|
|
1049
|
-
formatDate(quota.fetchedAt)
|
|
1076
|
+
formatDate$1(quota.fetchedAt)
|
|
1050
1077
|
]
|
|
1051
1078
|
}) : null
|
|
1052
1079
|
]
|
|
@@ -1197,7 +1224,7 @@ window.__ModuleLoader__.load({
|
|
|
1197
1224
|
return `${value} ${t("limitWindow")}`;
|
|
1198
1225
|
}
|
|
1199
1226
|
}
|
|
1200
|
-
function parsePositiveCapacity(value) {
|
|
1227
|
+
function parsePositiveCapacity$1(value) {
|
|
1201
1228
|
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
1202
1229
|
if (matched === null) return null;
|
|
1203
1230
|
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
@@ -1205,10 +1232,10 @@ window.__ModuleLoader__.load({
|
|
|
1205
1232
|
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
1206
1233
|
}
|
|
1207
1234
|
function parseCapacity(value) {
|
|
1208
|
-
const parsed = parsePositiveCapacity(value);
|
|
1235
|
+
const parsed = parsePositiveCapacity$1(value);
|
|
1209
1236
|
return parsed !== null && parsed <= 1e6 ? parsed : null;
|
|
1210
1237
|
}
|
|
1211
|
-
function formatCapacity(value) {
|
|
1238
|
+
function formatCapacity$1(value) {
|
|
1212
1239
|
if (value % 1e3 === 0) return `${value / 1e3}K`;
|
|
1213
1240
|
return String(value);
|
|
1214
1241
|
}
|
|
@@ -1229,7 +1256,7 @@ window.__ModuleLoader__.load({
|
|
|
1229
1256
|
].filter((part) => part !== null);
|
|
1230
1257
|
return parts.length > 0 ? parts.join(" · ") : t("unknown");
|
|
1231
1258
|
}
|
|
1232
|
-
function formatDate(seconds) {
|
|
1259
|
+
function formatDate$1(seconds) {
|
|
1233
1260
|
if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
|
|
1234
1261
|
const ms = seconds > 1e10 ? seconds : seconds * 1e3;
|
|
1235
1262
|
try {
|
|
@@ -1244,7 +1271,7 @@ window.__ModuleLoader__.load({
|
|
|
1244
1271
|
function formatReset(seconds) {
|
|
1245
1272
|
if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
|
|
1246
1273
|
const ms = seconds > 1e10 ? seconds : seconds * 1e3;
|
|
1247
|
-
const absolute = formatDate(seconds);
|
|
1274
|
+
const absolute = formatDate$1(seconds);
|
|
1248
1275
|
const diff = ms - Date.now();
|
|
1249
1276
|
const abs = Math.abs(diff);
|
|
1250
1277
|
const [amount, unit] = abs >= 864e5 ? [Math.round(diff / 864e5), "day"] : abs >= 36e5 ? [Math.round(diff / 36e5), "hour"] : [Math.round(diff / 6e4), "minute"];
|
|
@@ -1260,10 +1287,10 @@ window.__ModuleLoader__.load({
|
|
|
1260
1287
|
//#endregion
|
|
1261
1288
|
//#region src/client/locales.ts
|
|
1262
1289
|
const NS = "dsh-chatgpt-subscription";
|
|
1263
|
-
const dictionaries = {
|
|
1290
|
+
const dictionaries$1 = {
|
|
1264
1291
|
zh: {
|
|
1265
|
-
title: "
|
|
1266
|
-
intro: "使用 ChatGPT 账号登录,在 DSH
|
|
1292
|
+
title: "ChatGPT",
|
|
1293
|
+
intro: "使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的模型。",
|
|
1267
1294
|
account: "账号",
|
|
1268
1295
|
signedOut: "尚未登录",
|
|
1269
1296
|
signedIn: "已登录",
|
|
@@ -1325,7 +1352,7 @@ window.__ModuleLoader__.load({
|
|
|
1325
1352
|
searchProvider: "搜索与抓取来源",
|
|
1326
1353
|
searchProviderHint: "选择 DSH 联网工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。",
|
|
1327
1354
|
searchProviderDsh: "DSH 默认",
|
|
1328
|
-
searchProviderCodex: "
|
|
1355
|
+
searchProviderCodex: "ChatGPT(代理隧道)",
|
|
1329
1356
|
providerDefault: "使用 Provider 默认值",
|
|
1330
1357
|
subagentEnhancements: "子代理设置",
|
|
1331
1358
|
subagentContextWindow: "子代理上下文预算",
|
|
@@ -1387,8 +1414,8 @@ window.__ModuleLoader__.load({
|
|
|
1387
1414
|
unknown: "未知"
|
|
1388
1415
|
},
|
|
1389
1416
|
en: {
|
|
1390
|
-
title: "
|
|
1391
|
-
intro: "Sign in with ChatGPT to use
|
|
1417
|
+
title: "ChatGPT",
|
|
1418
|
+
intro: "Sign in with ChatGPT to use models available to your subscription in DSH.",
|
|
1392
1419
|
account: "Account",
|
|
1393
1420
|
signedOut: "Not signed in",
|
|
1394
1421
|
signedIn: "Signed in",
|
|
@@ -1450,7 +1477,7 @@ window.__ModuleLoader__.load({
|
|
|
1450
1477
|
searchProvider: "Search & Fetch provider",
|
|
1451
1478
|
searchProviderHint: "Choose whether DSH web tools use the default provider or the Codex proxy-backed source from this ChatGPT subscription.",
|
|
1452
1479
|
searchProviderDsh: "DSH default",
|
|
1453
|
-
searchProviderCodex: "
|
|
1480
|
+
searchProviderCodex: "ChatGPT (Proxy tunnel)",
|
|
1454
1481
|
providerDefault: "Use provider default",
|
|
1455
1482
|
subagentEnhancements: "Subagent settings",
|
|
1456
1483
|
subagentContextWindow: "Subagent context window budget",
|
|
@@ -1514,77 +1541,77 @@ window.__ModuleLoader__.load({
|
|
|
1514
1541
|
};
|
|
1515
1542
|
//#endregion
|
|
1516
1543
|
//#region src/client/styles.ts
|
|
1517
|
-
const STYLE_ID = "@eddyskywalker/dsh-chatgpt-subscription/main";
|
|
1544
|
+
const STYLE_ID$1 = "@eddyskywalker/dsh-chatgpt-subscription/main";
|
|
1518
1545
|
const CSS = `
|
|
1519
1546
|
.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}
|
|
1520
1547
|
.dsh-codex-page *{box-sizing:border-box}
|
|
1521
1548
|
.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}
|
|
1522
1549
|
.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}
|
|
1523
|
-
.dsh-codex-group{border-top:
|
|
1550
|
+
.dsh-codex-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}
|
|
1524
1551
|
.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}
|
|
1525
1552
|
.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}
|
|
1526
|
-
.dsh-codex-row{align-items:center;border-bottom:
|
|
1553
|
+
.dsh-codex-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}
|
|
1527
1554
|
.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}
|
|
1528
1555
|
.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}
|
|
1529
1556
|
.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}
|
|
1530
|
-
.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:
|
|
1557
|
+
.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}
|
|
1531
1558
|
.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
|
|
1532
1559
|
.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
|
|
1533
1560
|
.dsh-codex-button:disabled{cursor:default;opacity:.5}
|
|
1534
1561
|
.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}
|
|
1535
|
-
.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:
|
|
1562
|
+
.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}
|
|
1536
1563
|
.dsh-codex-error,.dsh-codex-warning,.dsh-codex-success{font-size:12px;line-height:1.5;margin:8px 0 0}
|
|
1537
1564
|
.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}
|
|
1538
1565
|
.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}
|
|
1539
1566
|
.dsh-codex-success{color:var(--dsw-alias-label-success,#2e9b62)}
|
|
1540
|
-
.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:
|
|
1567
|
+
.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 28%,transparent);border-radius:7px;color:var(--dsw-alias-label-danger,#d94b4b);display:flex;font-size:13px;gap:12px;justify-content:space-between;padding:10px 12px}
|
|
1541
1568
|
.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}
|
|
1542
1569
|
.dsh-codex-models-hint{padding-top:10px}
|
|
1543
1570
|
.dsh-codex-models{display:flex;flex-wrap:wrap;gap:7px;padding-top:8px}
|
|
1544
1571
|
.dsh-codex-models label{cursor:pointer;display:block;position:relative}
|
|
1545
1572
|
.dsh-codex-models input{position:absolute;opacity:0;pointer-events:none}
|
|
1546
|
-
.dsh-codex-models span{background:var(--dsw-alias-bg-layer-2);border:
|
|
1573
|
+
.dsh-codex-models span{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:5px 8px}
|
|
1547
1574
|
.dsh-codex-models input:checked+span{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 14%,var(--dsw-alias-bg-layer-2));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 55%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary)}
|
|
1548
1575
|
.dsh-codex-models input:focus-visible+span{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
|
|
1549
1576
|
.dsh-codex-models input:disabled+span{cursor:default;opacity:.5}
|
|
1550
|
-
.dsh-codex-pref-row{align-items:center;border-bottom:
|
|
1577
|
+
.dsh-codex-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}
|
|
1551
1578
|
.dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}
|
|
1552
|
-
.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:
|
|
1579
|
+
.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:inline-flex;flex-wrap:nowrap;gap:3px;padding:3px}
|
|
1553
1580
|
.dsh-codex-segments label{cursor:pointer;display:block;margin:0}
|
|
1554
1581
|
.dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}
|
|
1555
|
-
.dsh-codex-segments span,.dsh-codex-segments button{border:
|
|
1582
|
+
.dsh-codex-segments span,.dsh-codex-segments button{border:0.5px solid transparent;border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font:inherit;font-size:12px;font-weight:500;line-height:1.2;padding:6px 12px;transition:all .15s ease;user-select:none;white-space:nowrap}
|
|
1556
1583
|
.dsh-codex-segments button{background:transparent;cursor:pointer}
|
|
1557
1584
|
.dsh-codex-segments label:hover span,.dsh-codex-segments button:hover:not(:disabled){color:var(--dsw-alias-label-primary)}
|
|
1558
1585
|
.dsh-codex-segments input:checked+span,.dsh-codex-segments button.active,.dsh-codex-segments button[aria-pressed=true]{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 22%,var(--dsw-alias-bg-layer-2));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 60%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary);font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.15)}
|
|
1559
1586
|
.dsh-codex-segments input:focus-visible+span,.dsh-codex-segments button:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
|
|
1560
1587
|
.dsh-codex-segments input:disabled+span,.dsh-codex-segments button:disabled{cursor:default;opacity:.5}
|
|
1561
|
-
.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:
|
|
1588
|
+
.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}
|
|
1562
1589
|
.dsh-codex-select{max-width:210px;min-width:150px}
|
|
1563
|
-
.dsh-codex-context-settings{border-bottom:
|
|
1590
|
+
.dsh-codex-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}
|
|
1564
1591
|
.dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}
|
|
1565
1592
|
.dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}
|
|
1566
1593
|
.dsh-codex-proxy-control{align-items:center;display:flex;gap:8px;width:100%}
|
|
1567
|
-
.dsh-codex-proxy-control input{background:var(--dsw-alias-bg-layer-2);border:
|
|
1594
|
+
.dsh-codex-proxy-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);flex:1;font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;min-width:220px;padding:7px 10px;text-align:left}
|
|
1568
1595
|
.dsh-codex-proxy-status{align-items:center;color:var(--dsw-alias-label-secondary);display:flex;flex-wrap:wrap;font-size:12px;gap:6px;margin:6px 0 0}
|
|
1569
|
-
.dsh-codex-proxy-tag{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 18%,transparent);border:
|
|
1596
|
+
.dsh-codex-proxy-tag{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 18%,transparent);border:0.5px solid color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 45%,transparent);border-radius:4px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:2px 6px}
|
|
1570
1597
|
.dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}
|
|
1571
1598
|
.dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}
|
|
1572
1599
|
.dsh-codex-capacity-control input[type=number]{width:110px}
|
|
1573
1600
|
.dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}
|
|
1574
|
-
.dsh-codex-context-save{background:var(--dsw-alias-bg-layer-2);border:
|
|
1601
|
+
.dsh-codex-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}
|
|
1575
1602
|
.dsh-codex-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
|
|
1576
1603
|
.dsh-codex-context-save:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
|
|
1577
1604
|
.dsh-codex-context-save:disabled{cursor:default;opacity:.45}
|
|
1578
|
-
.dsh-codex-check{align-items:flex-start;border-bottom:
|
|
1605
|
+
.dsh-codex-check{align-items:flex-start;border-bottom:0.5px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}
|
|
1579
1606
|
.dsh-codex-check input{flex:none;margin-top:2px}
|
|
1580
1607
|
.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}
|
|
1581
|
-
.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:
|
|
1608
|
+
.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}
|
|
1582
1609
|
.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}
|
|
1583
1610
|
.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}
|
|
1584
|
-
.dsh-codex-quota-fact{align-items:flex-start;border-bottom:
|
|
1611
|
+
.dsh-codex-quota-fact{align-items:flex-start;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;font-size:12px;gap:12px;justify-content:space-between;line-height:1.45;padding:10px 0}
|
|
1585
1612
|
.dsh-codex-quota-fact span{color:var(--dsw-alias-label-secondary);flex:none}
|
|
1586
1613
|
.dsh-codex-quota-fact strong{font-weight:600;min-width:0;overflow-wrap:anywhere;text-align:right}
|
|
1587
|
-
.dsh-codex-reset-credits{align-items:center;border-bottom:
|
|
1614
|
+
.dsh-codex-reset-credits{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;padding:10px 0}
|
|
1588
1615
|
.dsh-codex-reset-credits-info{display:grid;font-size:12px;gap:2px;grid-template-columns:auto auto}
|
|
1589
1616
|
.dsh-codex-reset-credits-info>span{color:var(--dsw-alias-label-secondary)}
|
|
1590
1617
|
.dsh-codex-reset-credits-info>strong{font-weight:650;text-align:right}
|
|
@@ -1593,44 +1620,1182 @@ window.__ModuleLoader__.load({
|
|
|
1593
1620
|
.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}
|
|
1594
1621
|
.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}
|
|
1595
1622
|
.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}
|
|
1596
|
-
.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;height:7px;overflow:hidden;width:100%}
|
|
1623
|
+
.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}
|
|
1597
1624
|
.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}
|
|
1598
1625
|
.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}
|
|
1599
1626
|
.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}
|
|
1600
|
-
.dsh-codex-empty{border:
|
|
1627
|
+
.dsh-codex-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}
|
|
1601
1628
|
.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}
|
|
1602
1629
|
.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}
|
|
1603
1630
|
.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}
|
|
1604
1631
|
.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}
|
|
1605
1632
|
.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}
|
|
1606
|
-
.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:
|
|
1633
|
+
.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap}
|
|
1607
1634
|
.dsh-codex-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}
|
|
1608
1635
|
.dsh-codex-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}
|
|
1609
1636
|
.dsh-codex-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}
|
|
1610
|
-
.dsh-codex-image-tool{border:
|
|
1637
|
+
.dsh-codex-image-tool{border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:8px;margin:4px 0 4px 4px;max-width:520px;padding:10px 12px}
|
|
1611
1638
|
.dsh-codex-image-tool-head{align-items:center;display:flex;font-size:13px;gap:8px;min-width:0}
|
|
1612
|
-
.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;display:inline-block;flex:none;height:8px;width:8px}
|
|
1639
|
+
.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;corner-shape:round;display:inline-block;flex:none;height:8px;width:8px}
|
|
1613
1640
|
.dsh-codex-image-tool[data-state=error] .dsh-codex-image-dot{background:var(--dsw-alias-label-danger,#d94b4b)}
|
|
1614
1641
|
.dsh-codex-image-title{font-weight:600}
|
|
1615
1642
|
.dsh-codex-image-summary{color:var(--dsw-alias-label-tertiary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1616
1643
|
.dsh-codex-image-grid{display:flex;flex-wrap:wrap;gap:8px}
|
|
1617
|
-
.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:
|
|
1618
|
-
.dsh-codex-image-loading,.dsh-codex-image-failed{border:
|
|
1644
|
+
.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:block;max-height:260px;max-width:min(100%,360px);object-fit:contain}
|
|
1645
|
+
.dsh-codex-image-loading,.dsh-codex-image-failed{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}
|
|
1619
1646
|
.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}
|
|
1620
1647
|
@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}
|
|
1621
1648
|
@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact,.dsh-codex-reset-credits{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-select{max-width:none;width:100%}.dsh-codex-context-row{align-items:flex-start;flex-direction:column;gap:5px}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}
|
|
1622
1649
|
@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}
|
|
1623
1650
|
`;
|
|
1624
1651
|
function installStyles() {
|
|
1625
|
-
if (document.querySelector(`style[data-plugin-css="${STYLE_ID}"]`) !== null) return () => void 0;
|
|
1652
|
+
if (document.querySelector(`style[data-plugin-css="${STYLE_ID$1}"]`) !== null) return () => void 0;
|
|
1626
1653
|
const element = document.createElement("style");
|
|
1627
1654
|
element.dataset.plugin = "@eddyskywalker/dsh-chatgpt-subscription";
|
|
1628
|
-
element.dataset.pluginCss = STYLE_ID;
|
|
1655
|
+
element.dataset.pluginCss = STYLE_ID$1;
|
|
1629
1656
|
element.textContent = CSS;
|
|
1630
1657
|
document.head.appendChild(element);
|
|
1631
1658
|
return () => element.remove();
|
|
1632
1659
|
}
|
|
1633
1660
|
//#endregion
|
|
1661
|
+
//#region src/client/antigravity/locales.ts
|
|
1662
|
+
const NS_ANTIGRAVITY = "dsh-antigravity";
|
|
1663
|
+
const zh = {
|
|
1664
|
+
title: "Antigravity",
|
|
1665
|
+
pageDesc: "登录 Google Antigravity / Cloud Code Assist,并查看当前账号的共享额度。",
|
|
1666
|
+
account: "已登录",
|
|
1667
|
+
signedIn: "已登录",
|
|
1668
|
+
signedOut: "未登录",
|
|
1669
|
+
plan: "套餐",
|
|
1670
|
+
accountId: "账号 ID",
|
|
1671
|
+
expires: "令牌到期",
|
|
1672
|
+
storage: "凭据存储",
|
|
1673
|
+
storageNotice: "令牌由 Host 保存于本地安全存储 ($DSH_HOME/storages/antigravity-oauth.json),不会进入浏览器。",
|
|
1674
|
+
signInAgain: "重新登录",
|
|
1675
|
+
refreshToken: "刷新凭据",
|
|
1676
|
+
signOut: "注销",
|
|
1677
|
+
signIn: "登录",
|
|
1678
|
+
signingIn: "登录中...",
|
|
1679
|
+
connection: "连接",
|
|
1680
|
+
provider: "Provider",
|
|
1681
|
+
providerValue: "Google Antigravity · antigravity",
|
|
1682
|
+
connectionState: "连接状态",
|
|
1683
|
+
connected: "已连接",
|
|
1684
|
+
untested: "未测试",
|
|
1685
|
+
modelsHint: "勾选后模型才会显示在对话页的模型选择列表中;至少保留一个。",
|
|
1686
|
+
selectAll: "全选",
|
|
1687
|
+
unselectAll: "全不选",
|
|
1688
|
+
enhanced: "增强功能",
|
|
1689
|
+
defaultReasoningEffort: "默认思考深度",
|
|
1690
|
+
defaultReasoningEffortHint: "控制支持推理的模型在未单独指定时的思考强度。",
|
|
1691
|
+
defaultEffortAuto: "使用 Provider 默认值",
|
|
1692
|
+
contextWindowSection: "模型上下文窗口",
|
|
1693
|
+
contextWindowHint: "默认按模型标准;可选应用最高容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。",
|
|
1694
|
+
save: "保存",
|
|
1695
|
+
saved: "已保存",
|
|
1696
|
+
saving: "保存中...",
|
|
1697
|
+
quotaSection: "用量与配额",
|
|
1698
|
+
quotaDesc: "数据来自 Google Cloud Code Assist 配额服务,页面可见时最多每 60 秒刷新一次。",
|
|
1699
|
+
refreshQuota: "刷新用量",
|
|
1700
|
+
refreshingQuota: "刷新中...",
|
|
1701
|
+
resetPrefix: "重置: {time}",
|
|
1702
|
+
resetUnavailable: "重置: n/a",
|
|
1703
|
+
resetNow: "现在",
|
|
1704
|
+
timeDayHour: "{days}天 {hours}时",
|
|
1705
|
+
timeHourMin: "{hours}h {minutes}m",
|
|
1706
|
+
timeMin: "{minutes}m",
|
|
1707
|
+
updatedAt: "更新时间:{time}",
|
|
1708
|
+
loading: "加载中...",
|
|
1709
|
+
loginFailed: "登录失败",
|
|
1710
|
+
tokens: "tokens"
|
|
1711
|
+
};
|
|
1712
|
+
const en = {
|
|
1713
|
+
title: "Antigravity",
|
|
1714
|
+
pageDesc: "Sign in to Google Antigravity / Cloud Code Assist and view shared quotas.",
|
|
1715
|
+
account: "Signed in",
|
|
1716
|
+
signedIn: "Signed in",
|
|
1717
|
+
signedOut: "Not signed in",
|
|
1718
|
+
plan: "Plan",
|
|
1719
|
+
accountId: "Account ID",
|
|
1720
|
+
expires: "Token expires",
|
|
1721
|
+
storage: "Credential storage",
|
|
1722
|
+
storageNotice: "Tokens are stored locally by the Host ($DSH_HOME/storages/antigravity-oauth.json) and never sent to browser.",
|
|
1723
|
+
signInAgain: "Sign in again",
|
|
1724
|
+
refreshToken: "Refresh token",
|
|
1725
|
+
signOut: "Sign out",
|
|
1726
|
+
signIn: "Sign in",
|
|
1727
|
+
signingIn: "Signing in...",
|
|
1728
|
+
connection: "Connection",
|
|
1729
|
+
provider: "Provider",
|
|
1730
|
+
providerValue: "Google Antigravity · antigravity",
|
|
1731
|
+
connectionState: "Connection state",
|
|
1732
|
+
connected: "Connected",
|
|
1733
|
+
untested: "Untested",
|
|
1734
|
+
modelsHint: "Checked models will appear in DSH conversation model list; keep at least one.",
|
|
1735
|
+
selectAll: "Select all",
|
|
1736
|
+
unselectAll: "Deselect all",
|
|
1737
|
+
enhanced: "Enhanced Features",
|
|
1738
|
+
defaultReasoningEffort: "Default reasoning effort",
|
|
1739
|
+
defaultReasoningEffortHint: "Controls reasoning effort for reasoning models when not explicitly specified in conversation.",
|
|
1740
|
+
defaultEffortAuto: "Use Provider default",
|
|
1741
|
+
contextWindowSection: "Model Context Window",
|
|
1742
|
+
contextWindowHint: "Defaults to model specification; configure custom capacity used by DSH for compaction and overflow judgments (e.g., 1M, 512K, 200K).",
|
|
1743
|
+
save: "Save",
|
|
1744
|
+
saved: "Saved",
|
|
1745
|
+
saving: "Saving...",
|
|
1746
|
+
quotaSection: "Usage & Quota",
|
|
1747
|
+
quotaDesc: "Data from Google Cloud Code Assist quota service; refreshes up to once every 60 seconds when visible.",
|
|
1748
|
+
refreshQuota: "Refresh quota",
|
|
1749
|
+
refreshingQuota: "Refreshing...",
|
|
1750
|
+
resetPrefix: "Reset: {time}",
|
|
1751
|
+
resetUnavailable: "Reset: n/a",
|
|
1752
|
+
resetNow: "now",
|
|
1753
|
+
timeDayHour: "{days}d {hours}h",
|
|
1754
|
+
timeHourMin: "{hours}h {minutes}m",
|
|
1755
|
+
timeMin: "{minutes}m",
|
|
1756
|
+
updatedAt: "Updated at: {time}",
|
|
1757
|
+
loading: "Loading...",
|
|
1758
|
+
loginFailed: "Login failed",
|
|
1759
|
+
tokens: "tokens"
|
|
1760
|
+
};
|
|
1761
|
+
const dictionaries = {
|
|
1762
|
+
zh,
|
|
1763
|
+
"zh-CN": zh,
|
|
1764
|
+
en,
|
|
1765
|
+
"en-US": en
|
|
1766
|
+
};
|
|
1767
|
+
//#endregion
|
|
1768
|
+
//#region src/client/antigravity/AntigravitySection.tsx
|
|
1769
|
+
const API$1 = "/antigravity/api";
|
|
1770
|
+
async function fetchApi$1(path, options) {
|
|
1771
|
+
const res = await fetch(`${API$1}${path}`, {
|
|
1772
|
+
...options,
|
|
1773
|
+
headers: {
|
|
1774
|
+
"Content-Type": "application/json",
|
|
1775
|
+
...options?.headers
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
const json = await res.json();
|
|
1779
|
+
if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
|
|
1780
|
+
return json.value;
|
|
1781
|
+
}
|
|
1782
|
+
function parsePositiveCapacity(value) {
|
|
1783
|
+
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
1784
|
+
if (matched === null) return null;
|
|
1785
|
+
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
1786
|
+
const parsed = Number(matched[1]) * multiplier;
|
|
1787
|
+
return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
|
|
1788
|
+
}
|
|
1789
|
+
function formatCapacity(value) {
|
|
1790
|
+
if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
|
|
1791
|
+
if (value % 1e3 === 0) return `${value / 1e3}K`;
|
|
1792
|
+
return String(value);
|
|
1793
|
+
}
|
|
1794
|
+
function formatResetTime(resetTime) {
|
|
1795
|
+
if (!resetTime) return "";
|
|
1796
|
+
const diff = new Date(resetTime).getTime() - Date.now();
|
|
1797
|
+
if (diff <= 0) return "现在";
|
|
1798
|
+
const mins = Math.floor(diff / 6e4);
|
|
1799
|
+
const hours = Math.floor(mins / 60);
|
|
1800
|
+
const days = Math.floor(hours / 24);
|
|
1801
|
+
if (days > 0) return `${days}天 ${hours % 24}时`;
|
|
1802
|
+
if (hours > 0) return `${hours}h ${mins % 60}m`;
|
|
1803
|
+
return `${mins}m`;
|
|
1804
|
+
}
|
|
1805
|
+
function formatDate(ms) {
|
|
1806
|
+
if (!ms || ms <= 0) return "—";
|
|
1807
|
+
try {
|
|
1808
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
1809
|
+
dateStyle: "medium",
|
|
1810
|
+
timeStyle: "short"
|
|
1811
|
+
}).format(ms);
|
|
1812
|
+
} catch {
|
|
1813
|
+
return "—";
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
function AntigravitySection({ onModelChange, loadModelDirectory }) {
|
|
1817
|
+
const [status, setStatus] = (0, react.useState)(null);
|
|
1818
|
+
const [loading, setLoading] = (0, react.useState)(true);
|
|
1819
|
+
const [busy, setBusy] = (0, react.useState)(null);
|
|
1820
|
+
const [error, setError] = (0, react.useState)(null);
|
|
1821
|
+
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
1822
|
+
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
1823
|
+
const t = zh;
|
|
1824
|
+
const notifyChange = (0, react.useCallback)(() => {
|
|
1825
|
+
onModelChange?.();
|
|
1826
|
+
loadModelDirectory?.();
|
|
1827
|
+
}, [onModelChange, loadModelDirectory]);
|
|
1828
|
+
const loadStatus = (0, react.useCallback)(async (quiet = false) => {
|
|
1829
|
+
if (!quiet) setError(null);
|
|
1830
|
+
try {
|
|
1831
|
+
const data = await fetchApi$1("/status");
|
|
1832
|
+
setStatus(data);
|
|
1833
|
+
const drafts = {};
|
|
1834
|
+
for (const m of data.models) {
|
|
1835
|
+
const val = data.contextWindowOverrides[m.id] || m.defaultContextWindow;
|
|
1836
|
+
drafts[m.id] = formatCapacity(val);
|
|
1837
|
+
}
|
|
1838
|
+
setContextDrafts(drafts);
|
|
1839
|
+
} catch (err) {
|
|
1840
|
+
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
1841
|
+
} finally {
|
|
1842
|
+
setLoading(false);
|
|
1843
|
+
}
|
|
1844
|
+
}, []);
|
|
1845
|
+
(0, react.useEffect)(() => {
|
|
1846
|
+
loadStatus();
|
|
1847
|
+
const refreshWhenVisible = () => {
|
|
1848
|
+
if (document.visibilityState === "visible") loadStatus(true);
|
|
1849
|
+
};
|
|
1850
|
+
document.addEventListener("visibilitychange", refreshWhenVisible);
|
|
1851
|
+
const timer = window.setInterval(refreshWhenVisible, 6e4);
|
|
1852
|
+
return () => {
|
|
1853
|
+
window.clearInterval(timer);
|
|
1854
|
+
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
1855
|
+
};
|
|
1856
|
+
}, [loadStatus]);
|
|
1857
|
+
const handleLogin = async () => {
|
|
1858
|
+
try {
|
|
1859
|
+
setBusy("login");
|
|
1860
|
+
setError(null);
|
|
1861
|
+
const flow = await fetchApi$1("/login", { method: "POST" });
|
|
1862
|
+
if (flow.authUrl) window.open(flow.authUrl, "_blank");
|
|
1863
|
+
const pollTimer = setInterval(async () => {
|
|
1864
|
+
try {
|
|
1865
|
+
const pollStatus = await fetchApi$1("/login/status");
|
|
1866
|
+
if (pollStatus.status === "complete") {
|
|
1867
|
+
clearInterval(pollTimer);
|
|
1868
|
+
setBusy(null);
|
|
1869
|
+
await loadStatus();
|
|
1870
|
+
notifyChange();
|
|
1871
|
+
} else if (pollStatus.status === "error") {
|
|
1872
|
+
clearInterval(pollTimer);
|
|
1873
|
+
setBusy(null);
|
|
1874
|
+
setError(t.loginFailed);
|
|
1875
|
+
}
|
|
1876
|
+
} catch {}
|
|
1877
|
+
}, 1500);
|
|
1878
|
+
setTimeout(() => {
|
|
1879
|
+
clearInterval(pollTimer);
|
|
1880
|
+
setBusy(null);
|
|
1881
|
+
}, 300 * 1e3);
|
|
1882
|
+
} catch (err) {
|
|
1883
|
+
setBusy(null);
|
|
1884
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1885
|
+
}
|
|
1886
|
+
};
|
|
1887
|
+
const handleRefreshQuota = async () => {
|
|
1888
|
+
try {
|
|
1889
|
+
setBusy("quota");
|
|
1890
|
+
setError(null);
|
|
1891
|
+
const updated = await fetchApi$1("/quota", { method: "POST" });
|
|
1892
|
+
setStatus(updated);
|
|
1893
|
+
} catch (err) {
|
|
1894
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1895
|
+
} finally {
|
|
1896
|
+
setBusy(null);
|
|
1897
|
+
}
|
|
1898
|
+
};
|
|
1899
|
+
const handleLogout = async () => {
|
|
1900
|
+
try {
|
|
1901
|
+
setBusy("logout");
|
|
1902
|
+
setError(null);
|
|
1903
|
+
const updated = await fetchApi$1("/logout", { method: "POST" });
|
|
1904
|
+
setStatus(updated);
|
|
1905
|
+
notifyChange();
|
|
1906
|
+
} catch (err) {
|
|
1907
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1908
|
+
} finally {
|
|
1909
|
+
setBusy(null);
|
|
1910
|
+
}
|
|
1911
|
+
};
|
|
1912
|
+
const toggleModel = async (modelId, checked) => {
|
|
1913
|
+
if (!status) return;
|
|
1914
|
+
const currentEnabled = status.models.filter((m) => m.enabled).map((m) => m.id);
|
|
1915
|
+
const nextEnabled = checked ? [.../* @__PURE__ */ new Set([...currentEnabled, modelId])] : currentEnabled.filter((id) => id !== modelId);
|
|
1916
|
+
if (nextEnabled.length === 0) return;
|
|
1917
|
+
try {
|
|
1918
|
+
const updated = await fetchApi$1("/models", {
|
|
1919
|
+
method: "POST",
|
|
1920
|
+
body: JSON.stringify({ enabledModelIds: nextEnabled })
|
|
1921
|
+
});
|
|
1922
|
+
setStatus(updated);
|
|
1923
|
+
notifyChange();
|
|
1924
|
+
} catch (err) {
|
|
1925
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
const setAllModels = async (selectAll) => {
|
|
1929
|
+
if (!status) return;
|
|
1930
|
+
const nextEnabled = selectAll ? status.models.map((m) => m.id) : [status.models[0].id];
|
|
1931
|
+
try {
|
|
1932
|
+
const updated = await fetchApi$1("/models", {
|
|
1933
|
+
method: "POST",
|
|
1934
|
+
body: JSON.stringify({ enabledModelIds: nextEnabled })
|
|
1935
|
+
});
|
|
1936
|
+
setStatus(updated);
|
|
1937
|
+
notifyChange();
|
|
1938
|
+
} catch (err) {
|
|
1939
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
const handleUpdateEffort = async (effort) => {
|
|
1943
|
+
try {
|
|
1944
|
+
const updated = await fetchApi$1("/settings", {
|
|
1945
|
+
method: "POST",
|
|
1946
|
+
body: JSON.stringify({ defaultReasoningEffort: effort })
|
|
1947
|
+
});
|
|
1948
|
+
setStatus(updated);
|
|
1949
|
+
notifyChange();
|
|
1950
|
+
} catch (err) {
|
|
1951
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
const handleSaveContextWindow = async (modelId) => {
|
|
1955
|
+
const raw = contextDrafts[modelId] || "";
|
|
1956
|
+
const parsed = parsePositiveCapacity(raw);
|
|
1957
|
+
if (parsed === null) {
|
|
1958
|
+
setError(`无效的上下文容量值: ${raw}`);
|
|
1959
|
+
return;
|
|
1960
|
+
}
|
|
1961
|
+
try {
|
|
1962
|
+
setSavingModel(modelId);
|
|
1963
|
+
setError(null);
|
|
1964
|
+
const updated = await fetchApi$1("/settings", {
|
|
1965
|
+
method: "POST",
|
|
1966
|
+
body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
|
|
1967
|
+
});
|
|
1968
|
+
setStatus(updated);
|
|
1969
|
+
setContextDrafts((prev) => ({
|
|
1970
|
+
...prev,
|
|
1971
|
+
[modelId]: formatCapacity(parsed)
|
|
1972
|
+
}));
|
|
1973
|
+
notifyChange();
|
|
1974
|
+
} catch (err) {
|
|
1975
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1976
|
+
} finally {
|
|
1977
|
+
setSavingModel(null);
|
|
1978
|
+
}
|
|
1979
|
+
};
|
|
1980
|
+
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1981
|
+
className: "dsha-page",
|
|
1982
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1983
|
+
className: "dsha-empty",
|
|
1984
|
+
children: t.loading
|
|
1985
|
+
})
|
|
1986
|
+
});
|
|
1987
|
+
const quota = status?.quota;
|
|
1988
|
+
const groups = quota?.groups || [];
|
|
1989
|
+
const visibleCount = status?.models.filter((m) => m.enabled).length || 0;
|
|
1990
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1991
|
+
className: "dsha-page",
|
|
1992
|
+
children: [
|
|
1993
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1994
|
+
className: "dsha-group",
|
|
1995
|
+
children: [
|
|
1996
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1997
|
+
className: "dsha-grouphead",
|
|
1998
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: status?.authenticated ? t.account : t.signedOut })
|
|
1999
|
+
}),
|
|
2000
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2001
|
+
className: "dsha-row",
|
|
2002
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2003
|
+
className: "dsha-label",
|
|
2004
|
+
children: status?.authenticated ? t.signedIn : t.signedOut
|
|
2005
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2006
|
+
className: "dsha-value",
|
|
2007
|
+
children: status?.email || "—"
|
|
2008
|
+
})]
|
|
2009
|
+
}),
|
|
2010
|
+
status?.authenticated && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2011
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2012
|
+
className: "dsha-row",
|
|
2013
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2014
|
+
className: "dsha-label",
|
|
2015
|
+
children: t.plan
|
|
2016
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2017
|
+
className: "dsha-value",
|
|
2018
|
+
children: quota?.planLabel || "Google AI Ultra"
|
|
2019
|
+
})]
|
|
2020
|
+
}),
|
|
2021
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2022
|
+
className: "dsha-row",
|
|
2023
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2024
|
+
className: "dsha-label",
|
|
2025
|
+
children: t.accountId
|
|
2026
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2027
|
+
className: "dsha-value",
|
|
2028
|
+
children: status.projectId || "antigravity-default"
|
|
2029
|
+
})]
|
|
2030
|
+
}),
|
|
2031
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2032
|
+
className: "dsha-row",
|
|
2033
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2034
|
+
className: "dsha-label",
|
|
2035
|
+
children: t.expires
|
|
2036
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2037
|
+
className: "dsha-value",
|
|
2038
|
+
children: formatDate(Date.now() + 864e5 * 30)
|
|
2039
|
+
})]
|
|
2040
|
+
})
|
|
2041
|
+
] }),
|
|
2042
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2043
|
+
className: "dsha-row",
|
|
2044
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2045
|
+
className: "dsha-label",
|
|
2046
|
+
children: t.storage
|
|
2047
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2048
|
+
className: "dsha-value",
|
|
2049
|
+
children: "本地安全存储 (JSON)"
|
|
2050
|
+
})]
|
|
2051
|
+
}),
|
|
2052
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2053
|
+
className: "dsha-notice",
|
|
2054
|
+
children: t.storageNotice
|
|
2055
|
+
}),
|
|
2056
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2057
|
+
className: "dsha-actions",
|
|
2058
|
+
children: !status?.authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2059
|
+
className: "dsha-btn dsha-btn-primary",
|
|
2060
|
+
disabled: busy !== null,
|
|
2061
|
+
onClick: handleLogin,
|
|
2062
|
+
children: busy === "login" ? t.signingIn : t.signIn
|
|
2063
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2064
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2065
|
+
className: "dsha-btn dsha-btn-primary",
|
|
2066
|
+
disabled: busy !== null,
|
|
2067
|
+
onClick: handleLogin,
|
|
2068
|
+
children: t.signInAgain
|
|
2069
|
+
}),
|
|
2070
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2071
|
+
className: "dsha-btn",
|
|
2072
|
+
disabled: busy !== null,
|
|
2073
|
+
onClick: handleRefreshQuota,
|
|
2074
|
+
children: busy === "quota" ? t.refreshingQuota : t.refreshToken
|
|
2075
|
+
}),
|
|
2076
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2077
|
+
className: "dsha-btn",
|
|
2078
|
+
disabled: busy !== null,
|
|
2079
|
+
onClick: handleLogout,
|
|
2080
|
+
children: t.signOut
|
|
2081
|
+
})
|
|
2082
|
+
] })
|
|
2083
|
+
})
|
|
2084
|
+
]
|
|
2085
|
+
}),
|
|
2086
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2087
|
+
className: "dsha-group",
|
|
2088
|
+
children: [
|
|
2089
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2090
|
+
className: "dsha-grouphead",
|
|
2091
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.connection })
|
|
2092
|
+
}),
|
|
2093
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2094
|
+
className: "dsha-row",
|
|
2095
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2096
|
+
className: "dsha-label",
|
|
2097
|
+
children: t.provider
|
|
2098
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2099
|
+
className: "dsha-value",
|
|
2100
|
+
children: t.providerValue
|
|
2101
|
+
})]
|
|
2102
|
+
}),
|
|
2103
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2104
|
+
className: "dsha-row",
|
|
2105
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2106
|
+
className: "dsha-label",
|
|
2107
|
+
children: t.connectionState
|
|
2108
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2109
|
+
className: "dsha-value",
|
|
2110
|
+
children: status?.authenticated ? t.connected : t.untested
|
|
2111
|
+
})]
|
|
2112
|
+
}),
|
|
2113
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2114
|
+
className: "dsha-muted dsha-models-hint",
|
|
2115
|
+
children: t.modelsHint
|
|
2116
|
+
}),
|
|
2117
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2118
|
+
className: "dsha-models",
|
|
2119
|
+
"aria-label": "Antigravity Models",
|
|
2120
|
+
children: status?.models.map((model) => {
|
|
2121
|
+
const checked = model.enabled;
|
|
2122
|
+
const lastVisible = checked && visibleCount === 1;
|
|
2123
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2124
|
+
title: model.id,
|
|
2125
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2126
|
+
type: "checkbox",
|
|
2127
|
+
checked,
|
|
2128
|
+
disabled: busy !== null || lastVisible,
|
|
2129
|
+
onChange: (e) => void toggleModel(model.id, e.currentTarget.checked)
|
|
2130
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name })]
|
|
2131
|
+
}, model.id);
|
|
2132
|
+
})
|
|
2133
|
+
}),
|
|
2134
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2135
|
+
className: "dsha-actions",
|
|
2136
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2137
|
+
className: "dsha-btn",
|
|
2138
|
+
disabled: busy !== null,
|
|
2139
|
+
onClick: () => setAllModels(true),
|
|
2140
|
+
children: t.selectAll
|
|
2141
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2142
|
+
className: "dsha-btn",
|
|
2143
|
+
disabled: busy !== null,
|
|
2144
|
+
onClick: () => setAllModels(false),
|
|
2145
|
+
children: t.unselectAll
|
|
2146
|
+
})]
|
|
2147
|
+
})
|
|
2148
|
+
]
|
|
2149
|
+
}),
|
|
2150
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2151
|
+
className: "dsha-group",
|
|
2152
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2153
|
+
className: "dsha-grouphead",
|
|
2154
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.enhanced })
|
|
2155
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2156
|
+
className: "dsha-pref-row",
|
|
2157
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t.defaultReasoningEffort }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2158
|
+
className: "dsha-muted",
|
|
2159
|
+
children: t.defaultReasoningEffortHint
|
|
2160
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2161
|
+
className: "dsha-select",
|
|
2162
|
+
"aria-label": t.defaultReasoningEffort,
|
|
2163
|
+
value: status?.defaultReasoningEffort ?? "",
|
|
2164
|
+
disabled: busy !== null,
|
|
2165
|
+
onChange: (e) => {
|
|
2166
|
+
const val = e.currentTarget.value;
|
|
2167
|
+
handleUpdateEffort(val === "" ? null : val);
|
|
2168
|
+
},
|
|
2169
|
+
children: [
|
|
2170
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2171
|
+
value: "",
|
|
2172
|
+
children: t.defaultEffortAuto
|
|
2173
|
+
}),
|
|
2174
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2175
|
+
value: "low",
|
|
2176
|
+
children: "Low"
|
|
2177
|
+
}),
|
|
2178
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2179
|
+
value: "medium",
|
|
2180
|
+
children: "Medium"
|
|
2181
|
+
}),
|
|
2182
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2183
|
+
value: "high",
|
|
2184
|
+
children: "High"
|
|
2185
|
+
})
|
|
2186
|
+
]
|
|
2187
|
+
})]
|
|
2188
|
+
})]
|
|
2189
|
+
}),
|
|
2190
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2191
|
+
className: "dsha-group",
|
|
2192
|
+
children: [
|
|
2193
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2194
|
+
className: "dsha-grouphead",
|
|
2195
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.contextWindowSection })
|
|
2196
|
+
}),
|
|
2197
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2198
|
+
className: "dsha-muted",
|
|
2199
|
+
children: t.contextWindowHint
|
|
2200
|
+
}),
|
|
2201
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2202
|
+
className: "dsha-context-settings",
|
|
2203
|
+
children: status?.models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2204
|
+
className: "dsha-context-row",
|
|
2205
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2206
|
+
className: "dsha-capacity-control",
|
|
2207
|
+
children: [
|
|
2208
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2209
|
+
type: "text",
|
|
2210
|
+
value: contextDrafts[model.id] ?? "",
|
|
2211
|
+
onChange: (e) => setContextDrafts({
|
|
2212
|
+
...contextDrafts,
|
|
2213
|
+
[model.id]: e.target.value
|
|
2214
|
+
}),
|
|
2215
|
+
onKeyDown: (e) => {
|
|
2216
|
+
if (e.key === "Enter") handleSaveContextWindow(model.id);
|
|
2217
|
+
}
|
|
2218
|
+
}),
|
|
2219
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t.tokens }),
|
|
2220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2221
|
+
type: "button",
|
|
2222
|
+
className: "dsha-context-save",
|
|
2223
|
+
disabled: savingModel === model.id,
|
|
2224
|
+
onClick: () => void handleSaveContextWindow(model.id),
|
|
2225
|
+
children: savingModel === model.id ? t.saving : t.save
|
|
2226
|
+
})
|
|
2227
|
+
]
|
|
2228
|
+
})]
|
|
2229
|
+
}, model.id))
|
|
2230
|
+
})
|
|
2231
|
+
]
|
|
2232
|
+
}),
|
|
2233
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2234
|
+
className: "dsha-group",
|
|
2235
|
+
children: [
|
|
2236
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2237
|
+
className: "dsha-grouphead",
|
|
2238
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2239
|
+
className: "dsha-btn",
|
|
2240
|
+
disabled: busy !== null || !status?.authenticated,
|
|
2241
|
+
onClick: handleRefreshQuota,
|
|
2242
|
+
children: busy === "quota" ? t.refreshingQuota : t.refreshQuota
|
|
2243
|
+
})]
|
|
2244
|
+
}),
|
|
2245
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2246
|
+
className: "dsha-muted",
|
|
2247
|
+
children: t.quotaDesc
|
|
2248
|
+
}),
|
|
2249
|
+
!status?.authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2250
|
+
className: "dsha-empty",
|
|
2251
|
+
children: t.signedOut
|
|
2252
|
+
}) : groups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2253
|
+
className: "dsha-empty",
|
|
2254
|
+
children: "暂无配额数据,点击右上角刷新用量。"
|
|
2255
|
+
}) : groups.map((group, gIdx) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2256
|
+
className: "dsha-quota-card",
|
|
2257
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2258
|
+
className: "dsha-quota-title",
|
|
2259
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: group.displayName }), group.description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: group.description })]
|
|
2260
|
+
}), group.buckets.map((bucket, bIdx) => {
|
|
2261
|
+
const isCyan = /claude|gpt|3p/i.test(group.displayName);
|
|
2262
|
+
const pct = Math.round(bucket.remainingFraction * 100);
|
|
2263
|
+
const resetText = formatResetTime(bucket.resetTime);
|
|
2264
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2265
|
+
className: "dsha-meter-wrap",
|
|
2266
|
+
children: [
|
|
2267
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2268
|
+
className: "dsha-meter-label",
|
|
2269
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: bucket.displayName }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [pct, "% 剩余"] })]
|
|
2270
|
+
}),
|
|
2271
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2272
|
+
className: `dsha-meter ${isCyan ? "dsha-meter-cyan" : "dsha-meter-green"}`,
|
|
2273
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${pct}%` } })
|
|
2274
|
+
}),
|
|
2275
|
+
resetText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2276
|
+
className: "dsha-meter-meta",
|
|
2277
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["重置: ", resetText] })
|
|
2278
|
+
})
|
|
2279
|
+
]
|
|
2280
|
+
}, bIdx);
|
|
2281
|
+
})]
|
|
2282
|
+
}, gIdx)),
|
|
2283
|
+
quota?.fetchedAt && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2284
|
+
className: "dsha-timestamp",
|
|
2285
|
+
children: ["更新时间: ", new Date(quota.fetchedAt).toLocaleString()]
|
|
2286
|
+
})
|
|
2287
|
+
]
|
|
2288
|
+
}),
|
|
2289
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2290
|
+
className: "dsha-error",
|
|
2291
|
+
children: error
|
|
2292
|
+
})
|
|
2293
|
+
]
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
//#endregion
|
|
2297
|
+
//#region src/client/antigravity/styles.ts
|
|
2298
|
+
const STYLE_ID = "dsh-antigravity-settings-style";
|
|
2299
|
+
function installAntigravityStyles() {
|
|
2300
|
+
if (typeof document === "undefined" || document.getElementById("dsh-antigravity-settings-style")) return;
|
|
2301
|
+
const style = document.createElement("style");
|
|
2302
|
+
style.id = STYLE_ID;
|
|
2303
|
+
style.textContent = `
|
|
2304
|
+
.dsha-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}
|
|
2305
|
+
.dsha-page *{box-sizing:border-box}
|
|
2306
|
+
.dsha-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}
|
|
2307
|
+
.dsha-group:first-of-type{border-top:0}
|
|
2308
|
+
.dsha-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}
|
|
2309
|
+
.dsha-grouphead h3{font-size:14px;font-weight:650;margin:0;color:var(--dsw-alias-label-primary)}
|
|
2310
|
+
.dsha-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}
|
|
2311
|
+
.dsha-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}
|
|
2312
|
+
.dsha-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right;color:var(--dsw-alias-label-primary)}
|
|
2313
|
+
.dsha-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}
|
|
2314
|
+
.dsha-btn{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}
|
|
2315
|
+
.dsha-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
|
|
2316
|
+
.dsha-btn:disabled{cursor:default;opacity:.5}
|
|
2317
|
+
.dsha-btn-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}
|
|
2318
|
+
.dsha-btn-primary:hover:not(:disabled){opacity:.9}
|
|
2319
|
+
.dsha-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}
|
|
2320
|
+
.dsha-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}
|
|
2321
|
+
.dsha-models-hint{padding-top:10px}
|
|
2322
|
+
.dsha-models{display:flex;flex-wrap:wrap;gap:7px;padding-top:8px}
|
|
2323
|
+
.dsha-models label{cursor:pointer;display:block;position:relative}
|
|
2324
|
+
.dsha-models input{position:absolute;opacity:0;pointer-events:none}
|
|
2325
|
+
.dsha-models span{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:5px 8px;transition:all .15s ease}
|
|
2326
|
+
.dsha-models input:checked+span{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 14%,var(--dsw-alias-bg-layer-2));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 55%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary);font-weight:600}
|
|
2327
|
+
.dsha-models input:disabled+span{cursor:default;opacity:.5}
|
|
2328
|
+
.dsha-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}
|
|
2329
|
+
.dsha-pref-row strong{display:block;font-size:13px;font-weight:600;line-height:1.35;color:var(--dsw-alias-label-primary)}
|
|
2330
|
+
.dsha-select{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px;max-width:220px;min-width:160px}
|
|
2331
|
+
.dsha-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}
|
|
2332
|
+
.dsha-context-settings>div>strong{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}
|
|
2333
|
+
.dsha-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}
|
|
2334
|
+
.dsha-capacity-control{align-items:center;display:flex;gap:7px}
|
|
2335
|
+
.dsha-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;padding:7px 9px;text-align:right;width:90px}
|
|
2336
|
+
.dsha-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}
|
|
2337
|
+
.dsha-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}
|
|
2338
|
+
.dsha-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
|
|
2339
|
+
.dsha-context-save:disabled{cursor:default;opacity:.45}
|
|
2340
|
+
.dsha-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}
|
|
2341
|
+
.dsha-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between;color:var(--dsw-alias-label-primary);font-weight:650}
|
|
2342
|
+
.dsha-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}
|
|
2343
|
+
.dsha-meter-wrap{margin-top:13px}
|
|
2344
|
+
.dsha-meter-label,.dsha-meter-meta{display:flex;gap:10px;justify-content:space-between}
|
|
2345
|
+
.dsha-meter-label{font-size:12px;margin-bottom:6px;color:var(--dsw-alias-label-primary)}
|
|
2346
|
+
.dsha-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}
|
|
2347
|
+
.dsha-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}
|
|
2348
|
+
.dsha-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}
|
|
2349
|
+
.dsha-meter-green>span{background:var(--dsw-alias-label-success,#10b981)}
|
|
2350
|
+
.dsha-meter-cyan>span{background:#06b6d4}
|
|
2351
|
+
.dsha-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}
|
|
2352
|
+
.dsha-mini-btn{border:0;background:transparent;color:var(--dsw-alias-label-link,#397ee8);font-size:12px;line-height:18px;cursor:pointer;padding:0;margin-left:8px}
|
|
2353
|
+
.dsha-mini-btn:hover{text-decoration:underline}
|
|
2354
|
+
.dsha-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}
|
|
2355
|
+
.dsha-error{color:var(--dsw-alias-label-danger,#d94b4b);font-size:12px;margin:8px 0 0}
|
|
2356
|
+
.dsha-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);cursor:pointer;display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap;user-select:none;transition:all .15s ease}
|
|
2357
|
+
.dsha-composer-quota:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l1,var(--dsw-alias-border-l2))}
|
|
2358
|
+
.dsha-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}
|
|
2359
|
+
.dsha-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}
|
|
2360
|
+
.dsha-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}
|
|
2361
|
+
`;
|
|
2362
|
+
document.head.append(style);
|
|
2363
|
+
}
|
|
2364
|
+
//#endregion
|
|
2365
|
+
//#region src/client/antigravity/AntigravityComposerQuota.tsx
|
|
2366
|
+
const API = "/antigravity/api";
|
|
2367
|
+
async function fetchApi(path, options) {
|
|
2368
|
+
const res = await fetch(`${API}${path}`, {
|
|
2369
|
+
...options,
|
|
2370
|
+
headers: {
|
|
2371
|
+
"Content-Type": "application/json",
|
|
2372
|
+
...options?.headers
|
|
2373
|
+
}
|
|
2374
|
+
});
|
|
2375
|
+
const json = await res.json();
|
|
2376
|
+
if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
|
|
2377
|
+
return json.value;
|
|
2378
|
+
}
|
|
2379
|
+
function selectQuotaBucketForModel(groups, modelId) {
|
|
2380
|
+
if (!groups || groups.length === 0) return null;
|
|
2381
|
+
const isClaudeOrGpt = modelId ? /claude|gpt/i.test(modelId) : false;
|
|
2382
|
+
const targetGroup = groups.find((g) => {
|
|
2383
|
+
const match = /claude|gpt|3p/i.test(g.displayName);
|
|
2384
|
+
return isClaudeOrGpt ? match : !match;
|
|
2385
|
+
}) || groups[0];
|
|
2386
|
+
if (!targetGroup || !targetGroup.buckets || targetGroup.buckets.length === 0) return null;
|
|
2387
|
+
const shortBucket = targetGroup.buckets.find((b) => /5\s*小时|hour|5h/i.test(b.displayName)) || targetGroup.buckets[0];
|
|
2388
|
+
return {
|
|
2389
|
+
groupName: targetGroup.displayName,
|
|
2390
|
+
bucketName: shortBucket.displayName,
|
|
2391
|
+
remainingPercent: Math.round(shortBucket.remainingFraction * 100),
|
|
2392
|
+
resetTime: shortBucket.resetTime
|
|
2393
|
+
};
|
|
2394
|
+
}
|
|
2395
|
+
function formatResetCountdown(resetTime) {
|
|
2396
|
+
if (!resetTime) return "";
|
|
2397
|
+
try {
|
|
2398
|
+
const diff = new Date(resetTime).getTime() - Date.now();
|
|
2399
|
+
if (diff <= 0) return "即将重置";
|
|
2400
|
+
const h = Math.floor(diff / 36e5);
|
|
2401
|
+
const m = Math.floor(diff % 36e5 / 6e4);
|
|
2402
|
+
if (h > 0) return `${h}小时${m}分后重置`;
|
|
2403
|
+
return `${m}分钟后重置`;
|
|
2404
|
+
} catch {
|
|
2405
|
+
return "";
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
function AntigravityComposerQuota({ directory, loadModelDirectory }) {
|
|
2409
|
+
const modelState = useStore(directory);
|
|
2410
|
+
const [status, setStatus] = (0, react.useState)(null);
|
|
2411
|
+
const [loading, setLoading] = (0, react.useState)(false);
|
|
2412
|
+
const mountedRef = (0, react.useRef)(false);
|
|
2413
|
+
const selected = modelState.current;
|
|
2414
|
+
const isAntigravity = selected?.provider === "antigravity";
|
|
2415
|
+
(0, react.useEffect)(() => {
|
|
2416
|
+
loadModelDirectory();
|
|
2417
|
+
}, [loadModelDirectory]);
|
|
2418
|
+
(0, react.useEffect)(() => {
|
|
2419
|
+
mountedRef.current = true;
|
|
2420
|
+
return () => {
|
|
2421
|
+
mountedRef.current = false;
|
|
2422
|
+
};
|
|
2423
|
+
}, []);
|
|
2424
|
+
const fetchStatus = (0, react.useCallback)(async (refresh = false) => {
|
|
2425
|
+
if (!mountedRef.current) return;
|
|
2426
|
+
setLoading(true);
|
|
2427
|
+
try {
|
|
2428
|
+
const data = refresh ? await fetchApi("/quota", { method: "POST" }) : await fetchApi("/status");
|
|
2429
|
+
if (mountedRef.current) setStatus(data);
|
|
2430
|
+
} catch {} finally {
|
|
2431
|
+
if (mountedRef.current) setLoading(false);
|
|
2432
|
+
}
|
|
2433
|
+
}, []);
|
|
2434
|
+
(0, react.useEffect)(() => {
|
|
2435
|
+
if (!isAntigravity) return;
|
|
2436
|
+
fetchStatus(false);
|
|
2437
|
+
const timer = window.setInterval(() => {
|
|
2438
|
+
if (document.visibilityState === "visible") fetchStatus(false);
|
|
2439
|
+
}, 6e4);
|
|
2440
|
+
return () => {
|
|
2441
|
+
window.clearInterval(timer);
|
|
2442
|
+
};
|
|
2443
|
+
}, [fetchStatus, isAntigravity]);
|
|
2444
|
+
const quotaInfo = (0, react.useMemo)(() => {
|
|
2445
|
+
return selectQuotaBucketForModel(status?.quota?.groups || [], selected?.model);
|
|
2446
|
+
}, [status?.quota?.groups, selected?.model]);
|
|
2447
|
+
if (!isAntigravity || !status?.authenticated) return null;
|
|
2448
|
+
const level = quotaInfo === null ? "normal" : quotaInfo.remainingPercent <= 5 ? "danger" : quotaInfo.remainingPercent <= 20 ? "warning" : "normal";
|
|
2449
|
+
const countdown = quotaInfo?.resetTime ? formatResetCountdown(quotaInfo.resetTime) : "";
|
|
2450
|
+
const tooltip = quotaInfo ? `[Antigravity] ${quotaInfo.groupName} - ${quotaInfo.bucketName}: 剩余 ${quotaInfo.remainingPercent}%${countdown ? " (" + countdown + ")" : ""},点击刷新` : "点击刷新 Antigravity 配额";
|
|
2451
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2452
|
+
className: "dsha-composer-quota",
|
|
2453
|
+
"data-level": level,
|
|
2454
|
+
title: tooltip,
|
|
2455
|
+
"aria-label": tooltip,
|
|
2456
|
+
onClick: () => void fetchStatus(true),
|
|
2457
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2458
|
+
className: "dsha-composer-quota-label",
|
|
2459
|
+
children: "额度"
|
|
2460
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
2461
|
+
className: "dsha-composer-quota-val",
|
|
2462
|
+
children: loading ? "…" : quotaInfo === null ? "—" : `${quotaInfo.remainingPercent}%`
|
|
2463
|
+
})]
|
|
2464
|
+
});
|
|
2465
|
+
}
|
|
2466
|
+
function useStore(store) {
|
|
2467
|
+
return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
|
|
2468
|
+
}
|
|
2469
|
+
//#endregion
|
|
2470
|
+
//#region src/client/mermaid/sanitize.ts
|
|
2471
|
+
const STRIP_ELEMENTS = /* @__PURE__ */ new Set([
|
|
2472
|
+
"foreignobject",
|
|
2473
|
+
"script",
|
|
2474
|
+
"img",
|
|
2475
|
+
"iframe",
|
|
2476
|
+
"object",
|
|
2477
|
+
"embed",
|
|
2478
|
+
"video",
|
|
2479
|
+
"audio",
|
|
2480
|
+
"input",
|
|
2481
|
+
"button",
|
|
2482
|
+
"form",
|
|
2483
|
+
"link",
|
|
2484
|
+
"meta",
|
|
2485
|
+
"base"
|
|
2486
|
+
]);
|
|
2487
|
+
function sanitizeSvg(svg) {
|
|
2488
|
+
if (typeof DOMParser === "undefined" || typeof XMLSerializer === "undefined") return "";
|
|
2489
|
+
let doc;
|
|
2490
|
+
try {
|
|
2491
|
+
doc = new DOMParser().parseFromString(svg, "image/svg+xml");
|
|
2492
|
+
} catch {
|
|
2493
|
+
return "";
|
|
2494
|
+
}
|
|
2495
|
+
if (doc.querySelector("parsererror") !== null) return "";
|
|
2496
|
+
if (doc.documentElement === null || doc.documentElement.localName !== "svg") return "";
|
|
2497
|
+
doc.querySelectorAll("*").forEach((node) => {
|
|
2498
|
+
if (STRIP_ELEMENTS.has(node.localName.toLowerCase())) {
|
|
2499
|
+
node.remove();
|
|
2500
|
+
return;
|
|
2501
|
+
}
|
|
2502
|
+
for (const attribute of [...node.attributes]) {
|
|
2503
|
+
const name = attribute.name;
|
|
2504
|
+
const normalized = name.toLowerCase();
|
|
2505
|
+
if (normalized.startsWith("@") || normalized.startsWith("on")) {
|
|
2506
|
+
node.removeAttribute(name);
|
|
2507
|
+
continue;
|
|
2508
|
+
}
|
|
2509
|
+
if (normalized === "href" || normalized === "xlink:href") node.removeAttribute(name);
|
|
2510
|
+
}
|
|
2511
|
+
});
|
|
2512
|
+
return new XMLSerializer().serializeToString(doc.documentElement);
|
|
2513
|
+
}
|
|
2514
|
+
//#endregion
|
|
2515
|
+
//#region src/client/mermaid/styles.ts
|
|
2516
|
+
const MERMAID_STYLE_ID = "dsh-mermaid-renderer-style";
|
|
2517
|
+
function installMermaidStyles() {
|
|
2518
|
+
if (typeof document === "undefined" || document.getElementById("dsh-mermaid-renderer-style")) return;
|
|
2519
|
+
const style = document.createElement("style");
|
|
2520
|
+
style.id = MERMAID_STYLE_ID;
|
|
2521
|
+
style.textContent = `
|
|
2522
|
+
.dsh-mermaid-wrapper{margin:12px 0;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.12));border-radius:8px;overflow:hidden;background:var(--dsw-alias-bg-layer-2,#1a1a1a);box-shadow:0 2px 8px rgba(0,0,0,0.15)}
|
|
2523
|
+
.dsh-mermaid-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;background:var(--dsw-alias-bg-layer-1,rgba(0,0,0,0.25));border-bottom:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.08));font-size:12px;color:var(--dsw-alias-label-secondary,#888)}
|
|
2524
|
+
.dsh-mermaid-title{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.5px;color:var(--dsw-alias-label-tertiary,#aaa);font-weight:600}
|
|
2525
|
+
.dsh-mermaid-controls{display:flex;gap:8px;align-items:center}
|
|
2526
|
+
.dsh-mermaid-btn{background:transparent;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.15));border-radius:4px;color:var(--dsw-alias-label-secondary,#ccc);padding:2px 8px;font-size:11px;cursor:pointer;line-height:18px;transition:all .15s}
|
|
2527
|
+
.dsh-mermaid-btn:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,0.08));color:var(--dsw-alias-label-primary,#fff);border-color:var(--dsw-alias-border-l1,rgba(255,255,255,0.3))}
|
|
2528
|
+
.dsh-mermaid-chart{padding:18px;overflow-x:auto;display:flex;justify-content:center;align-items:center;min-height:100px;background:var(--dsw-alias-bg-layer-2,#181818);cursor:zoom-in}
|
|
2529
|
+
.dsh-mermaid-chart svg{max-width:100%;height:auto;display:block;margin:0 auto}
|
|
2530
|
+
.dsh-mermaid-source{display:none;margin:0;padding:12px;background:var(--dsw-alias-bg-layer-1,#121212);border-top:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.08));font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:1.5;overflow-x:auto;white-space:pre-wrap;word-break:break-all}
|
|
2531
|
+
.dsh-mermaid-source.is-visible{display:block}
|
|
2532
|
+
|
|
2533
|
+
/* 全屏缩放预览模态框 */
|
|
2534
|
+
.dsh-mermaid-modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.8);backdrop-filter:blur(4px);z-index:99999;display:flex;flex-direction:column;justify-content:center;align-items:center}
|
|
2535
|
+
.dsh-mermaid-modal-toolbar{position:absolute;top:20px;right:24px;display:flex;gap:8px;background:rgba(20,20,20,0.85);border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:4px;box-shadow:0 8px 24px rgba(0,0,0,0.5)}
|
|
2536
|
+
.dsh-mermaid-modal-btn{background:transparent;border:0;color:#fff;font-size:14px;padding:6px 12px;cursor:pointer;border-radius:4px}
|
|
2537
|
+
.dsh-mermaid-modal-btn:hover{background:rgba(255,255,255,0.15)}
|
|
2538
|
+
.dsh-mermaid-modal-stage{flex:1;width:100%;height:100%;overflow:auto;display:flex;justify-content:center;align-items:center;padding:40px}
|
|
2539
|
+
.dsh-mermaid-modal-stage svg{max-width:90vw;max-height:85vh;height:auto}
|
|
2540
|
+
`;
|
|
2541
|
+
document.head.append(style);
|
|
2542
|
+
}
|
|
2543
|
+
//#endregion
|
|
2544
|
+
//#region src/client/mermaid/renderer.ts
|
|
2545
|
+
let mermaidSeq = 0;
|
|
2546
|
+
let mermaidPromise = null;
|
|
2547
|
+
const processedHosts = /* @__PURE__ */ new WeakSet();
|
|
2548
|
+
function loadMermaid() {
|
|
2549
|
+
if (typeof window === "undefined") return Promise.resolve(null);
|
|
2550
|
+
const existing = window.mermaid;
|
|
2551
|
+
if (existing) return Promise.resolve(existing);
|
|
2552
|
+
if (mermaidPromise) return mermaidPromise;
|
|
2553
|
+
mermaidPromise = new Promise((resolve) => {
|
|
2554
|
+
const current = window.mermaid;
|
|
2555
|
+
if (current) {
|
|
2556
|
+
resolve(current);
|
|
2557
|
+
return;
|
|
2558
|
+
}
|
|
2559
|
+
const script = document.createElement("script");
|
|
2560
|
+
script.src = "/api/dsh-chatgpt-subscription/mermaid.min.js";
|
|
2561
|
+
script.async = true;
|
|
2562
|
+
script.onload = () => {
|
|
2563
|
+
resolve(window.mermaid || null);
|
|
2564
|
+
};
|
|
2565
|
+
script.onerror = () => {
|
|
2566
|
+
const cdn = document.createElement("script");
|
|
2567
|
+
cdn.src = "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js";
|
|
2568
|
+
cdn.async = true;
|
|
2569
|
+
cdn.onload = () => resolve(window.mermaid || null);
|
|
2570
|
+
cdn.onerror = () => resolve(null);
|
|
2571
|
+
document.head.appendChild(cdn);
|
|
2572
|
+
};
|
|
2573
|
+
document.head.appendChild(script);
|
|
2574
|
+
});
|
|
2575
|
+
return mermaidPromise;
|
|
2576
|
+
}
|
|
2577
|
+
function isDarkTheme() {
|
|
2578
|
+
if (typeof document === "undefined") return false;
|
|
2579
|
+
const root = document.documentElement;
|
|
2580
|
+
return root.classList.contains("dark") || root.getAttribute("data-theme") === "dark" || root.getAttribute("data-color-mode") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
2581
|
+
}
|
|
2582
|
+
async function initMermaidConfig() {
|
|
2583
|
+
const m = await loadMermaid();
|
|
2584
|
+
if (!m) return null;
|
|
2585
|
+
try {
|
|
2586
|
+
m.initialize({
|
|
2587
|
+
startOnLoad: false,
|
|
2588
|
+
securityLevel: "strict",
|
|
2589
|
+
htmlLabels: false,
|
|
2590
|
+
theme: isDarkTheme() ? "dark" : "default",
|
|
2591
|
+
fontFamily: "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
|
|
2592
|
+
});
|
|
2593
|
+
} catch {}
|
|
2594
|
+
return m;
|
|
2595
|
+
}
|
|
2596
|
+
function openZoomModal(svgHtml) {
|
|
2597
|
+
const overlay = document.createElement("div");
|
|
2598
|
+
overlay.className = "dsh-mermaid-modal-overlay";
|
|
2599
|
+
let scale = 1;
|
|
2600
|
+
overlay.innerHTML = `
|
|
2601
|
+
<div class="dsh-mermaid-modal-toolbar">
|
|
2602
|
+
<button type="button" class="dsh-mermaid-modal-btn" data-action="zoom-out" title="缩小">− 缩小</button>
|
|
2603
|
+
<button type="button" class="dsh-mermaid-modal-btn" data-action="zoom-in" title="放大">+ 放大</button>
|
|
2604
|
+
<button type="button" class="dsh-mermaid-modal-btn" data-action="reset" title="重置">⟳ 重置</button>
|
|
2605
|
+
<button type="button" class="dsh-mermaid-modal-btn" data-action="close" title="关闭">✕ 关闭</button>
|
|
2606
|
+
</div>
|
|
2607
|
+
<div class="dsh-mermaid-modal-stage">
|
|
2608
|
+
<div class="dsh-mermaid-zoom-container">${svgHtml}</div>
|
|
2609
|
+
</div>
|
|
2610
|
+
`;
|
|
2611
|
+
const stage = overlay.querySelector(".dsh-mermaid-zoom-container");
|
|
2612
|
+
const updateTransform = () => {
|
|
2613
|
+
if (stage) stage.style.transform = `scale(${scale})`;
|
|
2614
|
+
};
|
|
2615
|
+
overlay.addEventListener("click", (e) => {
|
|
2616
|
+
const target = e.target;
|
|
2617
|
+
const action = target?.getAttribute("data-action");
|
|
2618
|
+
if (action === "close" || target === overlay) {
|
|
2619
|
+
overlay.remove();
|
|
2620
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
2621
|
+
} else if (action === "zoom-in") {
|
|
2622
|
+
scale = Math.min(5, scale * 1.25);
|
|
2623
|
+
updateTransform();
|
|
2624
|
+
} else if (action === "zoom-out") {
|
|
2625
|
+
scale = Math.max(.2, scale / 1.25);
|
|
2626
|
+
updateTransform();
|
|
2627
|
+
} else if (action === "reset") {
|
|
2628
|
+
scale = 1;
|
|
2629
|
+
updateTransform();
|
|
2630
|
+
}
|
|
2631
|
+
});
|
|
2632
|
+
const onKeyDown = (e) => {
|
|
2633
|
+
if (e.key === "Escape") {
|
|
2634
|
+
overlay.remove();
|
|
2635
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
2636
|
+
}
|
|
2637
|
+
};
|
|
2638
|
+
document.addEventListener("keydown", onKeyDown);
|
|
2639
|
+
document.body.appendChild(overlay);
|
|
2640
|
+
}
|
|
2641
|
+
function findMermaidCandidate(codeEl) {
|
|
2642
|
+
if (codeEl.closest(".dsh-mermaid-wrapper")) return null;
|
|
2643
|
+
const host = codeEl.closest(".md-code-block") || codeEl.closest("pre") || codeEl;
|
|
2644
|
+
if (processedHosts.has(host) || host.getAttribute("data-dsh-mermaid-status")) return null;
|
|
2645
|
+
if (host.previousElementSibling?.classList.contains("dsh-mermaid-wrapper")) return null;
|
|
2646
|
+
const codeText = (codeEl.textContent || "").trim();
|
|
2647
|
+
if (!codeText || codeText.length < 5) return null;
|
|
2648
|
+
const hasMermaidClass = [...codeEl.classList].some((c) => c.toLowerCase().includes("mermaid"));
|
|
2649
|
+
const topText = host.firstElementChild?.textContent?.trim().toLowerCase();
|
|
2650
|
+
const isHeaderMermaid = topText === "mermaid" || topText?.startsWith("mermaid ");
|
|
2651
|
+
const isGrammarStart = /^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|gitGraph|mindmap|timeline)\b/i.test(codeText);
|
|
2652
|
+
if (hasMermaidClass || isHeaderMermaid || isGrammarStart) return {
|
|
2653
|
+
host,
|
|
2654
|
+
code: codeText
|
|
2655
|
+
};
|
|
2656
|
+
return null;
|
|
2657
|
+
}
|
|
2658
|
+
async function renderMermaidHost(host, code) {
|
|
2659
|
+
processedHosts.add(host);
|
|
2660
|
+
host.setAttribute("data-dsh-mermaid-status", "processing");
|
|
2661
|
+
const m = await initMermaidConfig();
|
|
2662
|
+
if (!m) {
|
|
2663
|
+
processedHosts.delete(host);
|
|
2664
|
+
host.removeAttribute("data-dsh-mermaid-status");
|
|
2665
|
+
return;
|
|
2666
|
+
}
|
|
2667
|
+
const renderId = `dsh-mermaid-${++mermaidSeq}`;
|
|
2668
|
+
try {
|
|
2669
|
+
const { svg } = await m.render(renderId, code);
|
|
2670
|
+
const cleanSvg = sanitizeSvg(svg);
|
|
2671
|
+
if (!cleanSvg) {
|
|
2672
|
+
processedHosts.delete(host);
|
|
2673
|
+
host.removeAttribute("data-dsh-mermaid-status");
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
if (host.previousElementSibling?.classList.contains("dsh-mermaid-wrapper")) {
|
|
2677
|
+
host.setAttribute("data-dsh-mermaid-status", "done");
|
|
2678
|
+
host.style.display = "none";
|
|
2679
|
+
return;
|
|
2680
|
+
}
|
|
2681
|
+
const wrapper = document.createElement("div");
|
|
2682
|
+
wrapper.className = "dsh-mermaid-wrapper";
|
|
2683
|
+
let showSource = false;
|
|
2684
|
+
wrapper.innerHTML = `
|
|
2685
|
+
<div class="dsh-mermaid-header">
|
|
2686
|
+
<span class="dsh-mermaid-title">Mermaid 图表</span>
|
|
2687
|
+
<div class="dsh-mermaid-controls">
|
|
2688
|
+
<button type="button" class="dsh-mermaid-btn" data-btn="toggle-source">源码</button>
|
|
2689
|
+
<button type="button" class="dsh-mermaid-btn" data-btn="copy">复制</button>
|
|
2690
|
+
<button type="button" class="dsh-mermaid-btn" data-btn="zoom" title="放大查看">放大 ↗</button>
|
|
2691
|
+
</div>
|
|
2692
|
+
</div>
|
|
2693
|
+
<div class="dsh-mermaid-chart" title="点击放大">${cleanSvg}</div>
|
|
2694
|
+
<div class="dsh-mermaid-source"><code>${code.replace(/</g, "<").replace(/>/g, ">")}</code></div>
|
|
2695
|
+
`;
|
|
2696
|
+
const sourceEl = wrapper.querySelector(".dsh-mermaid-source");
|
|
2697
|
+
const toggleBtn = wrapper.querySelector("[data-btn=\"toggle-source\"]");
|
|
2698
|
+
const copyBtn = wrapper.querySelector("[data-btn=\"copy\"]");
|
|
2699
|
+
const chartEl = wrapper.querySelector(".dsh-mermaid-chart");
|
|
2700
|
+
toggleBtn?.addEventListener("click", (e) => {
|
|
2701
|
+
e.stopPropagation();
|
|
2702
|
+
showSource = !showSource;
|
|
2703
|
+
if (showSource) {
|
|
2704
|
+
sourceEl.classList.add("is-visible");
|
|
2705
|
+
toggleBtn.textContent = "图表";
|
|
2706
|
+
} else {
|
|
2707
|
+
sourceEl.classList.remove("is-visible");
|
|
2708
|
+
toggleBtn.textContent = "源码";
|
|
2709
|
+
}
|
|
2710
|
+
});
|
|
2711
|
+
copyBtn?.addEventListener("click", async (e) => {
|
|
2712
|
+
e.stopPropagation();
|
|
2713
|
+
try {
|
|
2714
|
+
await navigator.clipboard.writeText(code);
|
|
2715
|
+
copyBtn.textContent = "已复制";
|
|
2716
|
+
setTimeout(() => {
|
|
2717
|
+
copyBtn.textContent = "复制";
|
|
2718
|
+
}, 1500);
|
|
2719
|
+
} catch {}
|
|
2720
|
+
});
|
|
2721
|
+
const handleZoom = (e) => {
|
|
2722
|
+
e.stopPropagation();
|
|
2723
|
+
openZoomModal(cleanSvg);
|
|
2724
|
+
};
|
|
2725
|
+
wrapper.querySelector("[data-btn=\"zoom\"]")?.addEventListener("click", handleZoom);
|
|
2726
|
+
chartEl?.addEventListener("click", handleZoom);
|
|
2727
|
+
host.style.display = "none";
|
|
2728
|
+
host.parentNode?.insertBefore(wrapper, host);
|
|
2729
|
+
host.setAttribute("data-dsh-mermaid-status", "done");
|
|
2730
|
+
} catch {
|
|
2731
|
+
processedHosts.delete(host);
|
|
2732
|
+
host.removeAttribute("data-dsh-mermaid-status");
|
|
2733
|
+
const errContainer = document.getElementById(renderId);
|
|
2734
|
+
if (errContainer) errContainer.remove();
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
function scanAndRenderMermaid() {
|
|
2738
|
+
if (typeof document === "undefined") return;
|
|
2739
|
+
const codeElements = document.querySelectorAll("pre code, .md-code-block code");
|
|
2740
|
+
for (const codeEl of codeElements) {
|
|
2741
|
+
const candidate = findMermaidCandidate(codeEl);
|
|
2742
|
+
if (candidate) renderMermaidHost(candidate.host, candidate.code);
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
function setupMermaidObserver() {
|
|
2746
|
+
if (typeof document === "undefined") return () => {};
|
|
2747
|
+
installMermaidStyles();
|
|
2748
|
+
let timer;
|
|
2749
|
+
const debouncedScan = () => {
|
|
2750
|
+
window.clearTimeout(timer);
|
|
2751
|
+
timer = window.setTimeout(() => {
|
|
2752
|
+
scanAndRenderMermaid();
|
|
2753
|
+
}, 250);
|
|
2754
|
+
};
|
|
2755
|
+
debouncedScan();
|
|
2756
|
+
const observer = new MutationObserver((mutations) => {
|
|
2757
|
+
let shouldScan = false;
|
|
2758
|
+
for (const m of mutations) {
|
|
2759
|
+
for (const node of m.addedNodes) if (node.nodeType === 1) {
|
|
2760
|
+
const el = node;
|
|
2761
|
+
if (el.classList?.contains("dsh-mermaid-wrapper") || el.closest?.(".dsh-mermaid-wrapper")) continue;
|
|
2762
|
+
shouldScan = true;
|
|
2763
|
+
break;
|
|
2764
|
+
}
|
|
2765
|
+
if (shouldScan) break;
|
|
2766
|
+
}
|
|
2767
|
+
if (shouldScan) debouncedScan();
|
|
2768
|
+
});
|
|
2769
|
+
observer.observe(document.body, {
|
|
2770
|
+
childList: true,
|
|
2771
|
+
subtree: true
|
|
2772
|
+
});
|
|
2773
|
+
const themeObserver = new MutationObserver(() => {
|
|
2774
|
+
initMermaidConfig();
|
|
2775
|
+
for (const el of document.querySelectorAll("[data-dsh-mermaid-status=\"done\"]")) {
|
|
2776
|
+
processedHosts.delete(el);
|
|
2777
|
+
el.removeAttribute("data-dsh-mermaid-status");
|
|
2778
|
+
const prevWrapper = el.previousElementSibling;
|
|
2779
|
+
if (prevWrapper && prevWrapper.classList.contains("dsh-mermaid-wrapper")) prevWrapper.remove();
|
|
2780
|
+
el.style.display = "";
|
|
2781
|
+
}
|
|
2782
|
+
debouncedScan();
|
|
2783
|
+
});
|
|
2784
|
+
themeObserver.observe(document.documentElement, {
|
|
2785
|
+
attributes: true,
|
|
2786
|
+
attributeFilter: [
|
|
2787
|
+
"class",
|
|
2788
|
+
"data-theme",
|
|
2789
|
+
"data-color-mode"
|
|
2790
|
+
]
|
|
2791
|
+
});
|
|
2792
|
+
return () => {
|
|
2793
|
+
observer.disconnect();
|
|
2794
|
+
themeObserver.disconnect();
|
|
2795
|
+
window.clearTimeout(timer);
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
//#endregion
|
|
1634
2799
|
//#region src/client/index.tsx
|
|
1635
2800
|
const inject = [
|
|
1636
2801
|
"slots",
|
|
@@ -1639,8 +2804,14 @@ window.__ModuleLoader__.load({
|
|
|
1639
2804
|
"conversation"
|
|
1640
2805
|
];
|
|
1641
2806
|
function apply(ctx) {
|
|
1642
|
-
ctx.effect(() => ctx.locale.register(NS, dictionaries), "dsh-chatgpt-subscription: dictionaries");
|
|
2807
|
+
ctx.effect(() => ctx.locale.register(NS, dictionaries$1), "dsh-chatgpt-subscription: dictionaries");
|
|
1643
2808
|
ctx.effect(() => installStyles(), "dsh-chatgpt-subscription: styles");
|
|
2809
|
+
ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries), "dsh-antigravity: dictionaries");
|
|
2810
|
+
ctx.effect(() => {
|
|
2811
|
+
installAntigravityStyles();
|
|
2812
|
+
return () => {};
|
|
2813
|
+
}, "dsh-antigravity: styles");
|
|
2814
|
+
ctx.effect(() => setupMermaidObserver(), "dsh-mermaid: observer");
|
|
1644
2815
|
const t = ctx.locale.bind(NS);
|
|
1645
2816
|
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
1646
2817
|
name: "settings.section",
|
|
@@ -1649,6 +2820,23 @@ window.__ModuleLoader__.load({
|
|
|
1649
2820
|
label: () => t("title"),
|
|
1650
2821
|
locale: NS
|
|
1651
2822
|
}, CodexSubscriptionSection));
|
|
2823
|
+
const AntigravitySectionWrapper = () => {
|
|
2824
|
+
const handleModelChange = () => {
|
|
2825
|
+
try {
|
|
2826
|
+
const conv = ctx.conversation;
|
|
2827
|
+
const activeSessionId = conv?.activeSessionId || conv?.currentSessionId || conv?.activeId;
|
|
2828
|
+
if (activeSessionId && ctx.modelDirectories) ctx.modelDirectories.directoryFor(activeSessionId)?.load?.().catch?.(() => void 0);
|
|
2829
|
+
} catch {}
|
|
2830
|
+
};
|
|
2831
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AntigravitySection, { onModelChange: handleModelChange });
|
|
2832
|
+
};
|
|
2833
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
2834
|
+
name: "settings.section",
|
|
2835
|
+
id: "antigravity",
|
|
2836
|
+
order: 46,
|
|
2837
|
+
label: () => "Antigravity",
|
|
2838
|
+
locale: NS_ANTIGRAVITY
|
|
2839
|
+
}, AntigravitySectionWrapper));
|
|
1652
2840
|
ctx.slots.inject("conversation.input.right", () => ctx.slots.register({
|
|
1653
2841
|
name: "conversation.input.right",
|
|
1654
2842
|
id: "codex-subscription-quota",
|
|
@@ -1665,6 +2853,21 @@ window.__ModuleLoader__.load({
|
|
|
1665
2853
|
};
|
|
1666
2854
|
}
|
|
1667
2855
|
}, CodexComposerQuota));
|
|
2856
|
+
ctx.slots.inject("conversation.input.right", () => ctx.slots.register({
|
|
2857
|
+
name: "conversation.input.right",
|
|
2858
|
+
id: "antigravity-quota",
|
|
2859
|
+
order: 36,
|
|
2860
|
+
locale: NS_ANTIGRAVITY,
|
|
2861
|
+
inject: (sessionId) => {
|
|
2862
|
+
const directory = ctx.modelDirectories.directoryFor(sessionId);
|
|
2863
|
+
return {
|
|
2864
|
+
directory: directory.store,
|
|
2865
|
+
loadModelDirectory: () => {
|
|
2866
|
+
directory.load().catch(() => void 0);
|
|
2867
|
+
}
|
|
2868
|
+
};
|
|
2869
|
+
}
|
|
2870
|
+
}, AntigravityComposerQuota));
|
|
1668
2871
|
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
1669
2872
|
name: "tool.call.toolview",
|
|
1670
2873
|
key: CODEX_IMAGE_TOOL_NAME,
|