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