dsh-agy-link 0.4.46 → 0.4.49
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/CHANGELOG.md +118 -0
- package/dist/assets/mermaid.min.js +3636 -0
- package/dist/client.js +1492 -139
- package/dist/index.js +7218 -6288
- package/docs/KNOWN-GAPS.md +15 -13
- package/docs/merge-2026-10-13-review.md +102 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -8,12 +8,16 @@ window.__ModuleLoader__.load({
|
|
|
8
8
|
const BRAND_PATHS = {
|
|
9
9
|
gemini: "M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81",
|
|
10
10
|
claude: "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z",
|
|
11
|
-
openai: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z"
|
|
11
|
+
openai: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z",
|
|
12
|
+
chrome: "M12 0C8.21 0 4.831 1.757 2.632 4.501l3.953 6.848A5.454 5.454 0 0 1 12 6.545h10.73c-.911-3.794-4.321-6.545-8.384-6.545zM1.986 6.368A11.95 11.95 0 0 0 0 12c0 6.096 4.542 11.134 10.428 11.89l3.953-6.848a5.454 5.454 0 0 1-5.836-2.585L1.986 6.368zm14.569 5.632a5.454 5.454 0 0 1-1.127 3.327l-5.365 9.293C10.784 24.873 11.385 25 12 25c6.627 0 12-5.373 12-12 0-.341-.014-.679-.042-1.013H12v.013h4.555z",
|
|
13
|
+
edge: "M23.95 13.91c-.13-1.68-.78-3.23-1.83-4.47-.98-1.16-2.29-1.99-3.76-2.4-.64-.18-1.3-.28-1.97-.29-2.09-.03-4.08.74-5.63 2.16-1.57 1.44-2.48 3.44-2.55 5.56.08 1.47.66 2.87 1.66 3.96.99 1.09 2.37 1.76 3.86 1.88 1.34.1 2.69-.26 3.82-1.02.44-.3.84-.66 1.18-1.07l2.87 2.87c-1.35 1.44-3.04 2.51-4.92 3.12-1.89.6-3.9.7-5.84.28-2.67-.58-5.06-2.06-6.75-4.17-1.68-2.12-2.59-4.78-2.57-7.51.02-2.85 1.04-5.6 2.89-7.77C6.88 4.31 9.53 2.85 12.44 2.38c2.19-.35 4.43-.2 6.55.45 2.13.65 4.04 1.83 5.58 3.44l-2.9 2.9c-1.12-1.19-2.52-2.06-4.07-2.54-1.55-.47-3.19-.57-4.78-.3-2.14.36-4.08 1.45-5.46 3.06-1.38 1.62-2.13 3.69-2.13 5.84 0 2.05.69 4.04 1.98 5.62 1.28 1.58 3.1 2.64 5.12 3.01 1.47.27 2.99.17 4.42-.31 1.43-.48 2.7-1.33 3.69-2.46l-4.13-4.13c-.37.28-.8.48-1.26.58-.46.1-.94.09-1.4-.02-.57-.14-1.08-.47-1.46-.93-.38-.46-.59-1.04-.59-1.64.03-.84.4-1.63 1.03-2.2.63-.57 1.45-.88 2.3-.87.87.01 1.7.35 2.32.95.62.61.98 1.43 1 2.3h4.67z"
|
|
12
14
|
};
|
|
13
15
|
const BRAND_COLORS = {
|
|
14
16
|
gemini: "#8E75B2",
|
|
15
17
|
claude: "#D97757",
|
|
16
|
-
openai: "#10a37f"
|
|
18
|
+
openai: "#10a37f",
|
|
19
|
+
chrome: "#4285F4",
|
|
20
|
+
edge: "#0078D7"
|
|
17
21
|
};
|
|
18
22
|
const UI_PATHS = {
|
|
19
23
|
trash: "M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M10 11v6M14 11v6",
|
|
@@ -28,7 +32,10 @@ window.__ModuleLoader__.load({
|
|
|
28
32
|
check: "M20 6L9 17l-5-5",
|
|
29
33
|
x: "M18 6L6 18M6 6l12 12",
|
|
30
34
|
externalLink: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3",
|
|
31
|
-
alert: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0zM12 9v4M12 17h.01"
|
|
35
|
+
alert: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0zM12 9v4M12 17h.01",
|
|
36
|
+
move: "M9 5h.01M9 12h.01M9 19h.01M15 5h.01M15 12h.01M15 19h.01",
|
|
37
|
+
arrowUp: "M12 19V5M5 12l7-7 7 7",
|
|
38
|
+
arrowDown: "M12 5v14M19 12l-7 7-7-7"
|
|
32
39
|
};
|
|
33
40
|
//#endregion
|
|
34
41
|
//#region src/client/locales.ts
|
|
@@ -71,6 +78,7 @@ window.__ModuleLoader__.load({
|
|
|
71
78
|
"account.add": "添加 Google 账号",
|
|
72
79
|
"account.aliasDefault": "备用 Google 账号 {number}",
|
|
73
80
|
"account.defaultAlias": "主账号(系统登录)",
|
|
81
|
+
"account.proxyPlaceholder": "专属代理 URL(如 http://127.0.0.1:7890,留空则继承全局)",
|
|
74
82
|
"account.aliasPlaceholder": "账号别名(例如:备用账号 2)",
|
|
75
83
|
"account.removeTitle": "移除此账号",
|
|
76
84
|
"aria.aliasInput": "账号别名",
|
|
@@ -81,6 +89,9 @@ window.__ModuleLoader__.load({
|
|
|
81
89
|
"account.settingPrimary": "设置中",
|
|
82
90
|
"account.details": "明细",
|
|
83
91
|
"account.collapse": "收起",
|
|
92
|
+
"account.expandOthers": "展开查看 Claude & GPT-OSS 模型额度",
|
|
93
|
+
"account.collapseOthers": "收起 Claude & GPT-OSS 模型额度",
|
|
94
|
+
"account.otherModels": "Claude / GPT 额度",
|
|
84
95
|
"account.sync": "同步",
|
|
85
96
|
"account.syncing": "同步中",
|
|
86
97
|
"account.syncTitle": "刷新此账号(换号后立即同步 email / 额度 / 模型)",
|
|
@@ -93,7 +104,6 @@ window.__ModuleLoader__.load({
|
|
|
93
104
|
"quota.weekly": "周额度",
|
|
94
105
|
"quota.refreshed": "额度已刷新",
|
|
95
106
|
"proxy.button": "代理",
|
|
96
|
-
"pool.winIsolationWarn": "Windows 提示:agy 的登录凭据存在系统级 Credential Manager(单槽位),多账号池无法隔离凭据——轮巡只切换工作目录,实际仍消耗系统登录账号(issue #45)。",
|
|
97
107
|
"proxy.placeholder": "专属代理 URL(如:http://127.0.0.1:7890;留空则使用全局)",
|
|
98
108
|
"proxy.save": "保存",
|
|
99
109
|
"proxy.saved": "代理已保存",
|
|
@@ -147,7 +157,21 @@ window.__ModuleLoader__.load({
|
|
|
147
157
|
"header.refreshQuota": "刷新额度",
|
|
148
158
|
"header.refreshing": "刷新中",
|
|
149
159
|
"console.close": "关闭(Esc)",
|
|
150
|
-
"header.badgeTitle": "Antigravity:{count} 个账号已就绪 · 点击打开控制台"
|
|
160
|
+
"header.badgeTitle": "Antigravity:{count} 个账号已就绪 · 点击打开控制台",
|
|
161
|
+
"header.badgeLoading": "Antigravity · 点击打开控制台",
|
|
162
|
+
"account.type.agy": "Google Antigravity (CLI / OAuth)",
|
|
163
|
+
"account.loginType": "登录方式:",
|
|
164
|
+
"account.dragHandle": "拖拽调整优先级",
|
|
165
|
+
"account.moveUp": "上移优先级",
|
|
166
|
+
"account.moveDown": "下移优先级",
|
|
167
|
+
"account.reordered": "账号优先级顺序已更新",
|
|
168
|
+
"account.collapseAll": "全部折叠",
|
|
169
|
+
"account.expandAll": "全部展开",
|
|
170
|
+
"account.cardCollapse": "收起详情",
|
|
171
|
+
"account.cardExpand": "展开详情",
|
|
172
|
+
"account.draggingTarget": "放置至此成为优先级 #{num}",
|
|
173
|
+
"account.dragBanner": "正在调整优先级:将【{alias}】移动至 #{num}",
|
|
174
|
+
"account.dragHint": "拖拽卡片可实时调整调度优先级"
|
|
151
175
|
};
|
|
152
176
|
const en = {
|
|
153
177
|
"section.label": "Antigravity",
|
|
@@ -185,6 +209,7 @@ window.__ModuleLoader__.load({
|
|
|
185
209
|
"account.add": "Add Google account",
|
|
186
210
|
"account.aliasDefault": "Backup Google account {number}",
|
|
187
211
|
"account.defaultAlias": "Primary account (system sign-in)",
|
|
212
|
+
"account.proxyPlaceholder": "Dedicated proxy URL (e.g. http://127.0.0.1:7890; leave blank to inherit global)",
|
|
188
213
|
"account.aliasPlaceholder": "Account alias (for example: Backup account 2)",
|
|
189
214
|
"account.removeTitle": "Remove this account",
|
|
190
215
|
"aria.aliasInput": "Account alias",
|
|
@@ -195,6 +220,9 @@ window.__ModuleLoader__.load({
|
|
|
195
220
|
"account.settingPrimary": "Setting...",
|
|
196
221
|
"account.details": "Details",
|
|
197
222
|
"account.collapse": "Collapse",
|
|
223
|
+
"account.expandOthers": "Expand Claude & GPT-OSS quotas",
|
|
224
|
+
"account.collapseOthers": "Collapse Claude & GPT-OSS quotas",
|
|
225
|
+
"account.otherModels": "Claude / GPT quotas",
|
|
198
226
|
"account.sync": "Sync",
|
|
199
227
|
"account.syncing": "Syncing...",
|
|
200
228
|
"account.syncTitle": "Refresh this account (sync email, quota, and models after switching accounts)",
|
|
@@ -207,7 +235,6 @@ window.__ModuleLoader__.load({
|
|
|
207
235
|
"quota.weekly": "Weekly quota",
|
|
208
236
|
"quota.refreshed": "Quota refreshed",
|
|
209
237
|
"proxy.button": "Proxy",
|
|
210
|
-
"pool.winIsolationWarn": "Windows: agy keeps its login in the system-wide Credential Manager (single slot), so the account pool cannot isolate credentials — rotation switches workspaces only, and generation still bills the system login (issue #45).",
|
|
211
238
|
"proxy.placeholder": "Dedicated proxy URL (for example: http://127.0.0.1:7890; leave blank to use the global proxy)",
|
|
212
239
|
"proxy.save": "Save",
|
|
213
240
|
"proxy.saved": "Proxy saved",
|
|
@@ -261,7 +288,21 @@ window.__ModuleLoader__.load({
|
|
|
261
288
|
"header.refreshQuota": "Refresh quota",
|
|
262
289
|
"header.refreshing": "Refreshing...",
|
|
263
290
|
"console.close": "Close (Esc)",
|
|
264
|
-
"header.badgeTitle": "Antigravity: {count} accounts ready · click to open the console"
|
|
291
|
+
"header.badgeTitle": "Antigravity: {count} accounts ready · click to open the console",
|
|
292
|
+
"header.badgeLoading": "Antigravity · click to open the console",
|
|
293
|
+
"account.type.agy": "Google Antigravity (CLI / OAuth)",
|
|
294
|
+
"account.loginType": "Login Method:",
|
|
295
|
+
"account.dragHandle": "Drag to reorder priority",
|
|
296
|
+
"account.moveUp": "Move up priority",
|
|
297
|
+
"account.moveDown": "Move down priority",
|
|
298
|
+
"account.reordered": "Account priorities reordered successfully",
|
|
299
|
+
"account.collapseAll": "Collapse all",
|
|
300
|
+
"account.expandAll": "Expand all",
|
|
301
|
+
"account.cardCollapse": "Collapse",
|
|
302
|
+
"account.cardExpand": "Expand details",
|
|
303
|
+
"account.draggingTarget": "Drop here to set priority #{num}",
|
|
304
|
+
"account.dragBanner": "Reordering: moving [{alias}] to priority #{num}",
|
|
305
|
+
"account.dragHint": "Drag cards to reorder scheduling priority in real time"
|
|
265
306
|
};
|
|
266
307
|
const ptBR = {
|
|
267
308
|
"section.label": "Antigravity",
|
|
@@ -299,6 +340,7 @@ window.__ModuleLoader__.load({
|
|
|
299
340
|
"account.add": "Adicionar conta Google",
|
|
300
341
|
"account.aliasDefault": "Conta Google reserva {number}",
|
|
301
342
|
"account.defaultAlias": "Conta principal (login do sistema)",
|
|
343
|
+
"account.proxyPlaceholder": "URL de proxy dedicada (ex.: http://127.0.0.1:7890; deixe vazio para herdar a global)",
|
|
302
344
|
"account.aliasPlaceholder": "Apelido da conta (por exemplo: Conta reserva 2)",
|
|
303
345
|
"account.removeTitle": "Remover esta conta",
|
|
304
346
|
"aria.aliasInput": "Apelido da conta",
|
|
@@ -309,6 +351,9 @@ window.__ModuleLoader__.load({
|
|
|
309
351
|
"account.settingPrimary": "Definindo...",
|
|
310
352
|
"account.details": "Detalhes",
|
|
311
353
|
"account.collapse": "Recolher",
|
|
354
|
+
"account.expandOthers": "Expandir cotas Claude e GPT-OSS",
|
|
355
|
+
"account.collapseOthers": "Recolher cotas Claude e GPT-OSS",
|
|
356
|
+
"account.otherModels": "Cotas Claude / GPT",
|
|
312
357
|
"account.sync": "Sincronizar",
|
|
313
358
|
"account.syncing": "Sincronizando...",
|
|
314
359
|
"account.syncTitle": "Atualizar esta conta (sincroniza e-mail, cota e modelos depois de trocar de conta)",
|
|
@@ -321,7 +366,6 @@ window.__ModuleLoader__.load({
|
|
|
321
366
|
"quota.weekly": "Cota semanal",
|
|
322
367
|
"quota.refreshed": "Cota atualizada",
|
|
323
368
|
"proxy.button": "Proxy",
|
|
324
|
-
"pool.winIsolationWarn": "Windows: o agy guarda o login no Credential Manager do sistema (um único slot), então o pool de contas não isola credenciais — a rotação troca apenas os diretórios e o consumo continua na conta do sistema (issue #45).",
|
|
325
369
|
"proxy.placeholder": "URL do proxy exclusivo (por exemplo: http://127.0.0.1:7890; deixe vazio para usar o proxy global)",
|
|
326
370
|
"proxy.save": "Salvar",
|
|
327
371
|
"proxy.saved": "Proxy salvo",
|
|
@@ -375,7 +419,21 @@ window.__ModuleLoader__.load({
|
|
|
375
419
|
"header.refreshQuota": "Atualizar cota",
|
|
376
420
|
"header.refreshing": "Atualizando...",
|
|
377
421
|
"console.close": "Fechar (Esc)",
|
|
378
|
-
"header.badgeTitle": "Antigravity: {count} contas prontas · clique para abrir o console"
|
|
422
|
+
"header.badgeTitle": "Antigravity: {count} contas prontas · clique para abrir o console",
|
|
423
|
+
"header.badgeLoading": "Antigravity · clique para abrir o console",
|
|
424
|
+
"account.type.agy": "Google Antigravity (CLI / OAuth)",
|
|
425
|
+
"account.loginType": "Tipo de login:",
|
|
426
|
+
"account.dragHandle": "Arrastar para reordenar prioridade",
|
|
427
|
+
"account.moveUp": "Subir prioridade",
|
|
428
|
+
"account.moveDown": "Descer prioridade",
|
|
429
|
+
"account.reordered": "Prioridade das contas reordenada com sucesso",
|
|
430
|
+
"account.collapseAll": "Recolher todos",
|
|
431
|
+
"account.expandAll": "Expandir todos",
|
|
432
|
+
"account.cardCollapse": "Recolher",
|
|
433
|
+
"account.cardExpand": "Expandir detalhes",
|
|
434
|
+
"account.draggingTarget": "Soltar aqui para prioridade #{num}",
|
|
435
|
+
"account.dragBanner": "Reordenando: movendo [{alias}] para #{num}",
|
|
436
|
+
"account.dragHint": "Arraste os cartões para reordenar a prioridade em tempo real"
|
|
379
437
|
};
|
|
380
438
|
const es = {
|
|
381
439
|
"section.label": "Antigravity",
|
|
@@ -413,6 +471,7 @@ window.__ModuleLoader__.load({
|
|
|
413
471
|
"account.add": "Añadir cuenta de Google",
|
|
414
472
|
"account.aliasDefault": "Cuenta de Google de respaldo {number}",
|
|
415
473
|
"account.defaultAlias": "Cuenta principal (inicio de sesión del sistema)",
|
|
474
|
+
"account.proxyPlaceholder": "URL de proxy dedicada (p. ej., http://127.0.0.1:7890; déjalo vacío para heredar la global)",
|
|
416
475
|
"account.aliasPlaceholder": "Alias de la cuenta (por ejemplo: Cuenta de respaldo 2)",
|
|
417
476
|
"account.removeTitle": "Eliminar esta cuenta",
|
|
418
477
|
"aria.aliasInput": "Alias de la cuenta",
|
|
@@ -423,6 +482,9 @@ window.__ModuleLoader__.load({
|
|
|
423
482
|
"account.settingPrimary": "Configurando...",
|
|
424
483
|
"account.details": "Detalles",
|
|
425
484
|
"account.collapse": "Contraer",
|
|
485
|
+
"account.expandOthers": "Expandir cuotas Claude y GPT-OSS",
|
|
486
|
+
"account.collapseOthers": "Contraer cuotas Claude y GPT-OSS",
|
|
487
|
+
"account.otherModels": "Cuotas Claude / GPT",
|
|
426
488
|
"account.sync": "Sincronizar",
|
|
427
489
|
"account.syncing": "Sincronizando...",
|
|
428
490
|
"account.syncTitle": "Actualizar esta cuenta (sincroniza correo, cuota y modelos tras cambiar de cuenta)",
|
|
@@ -435,7 +497,6 @@ window.__ModuleLoader__.load({
|
|
|
435
497
|
"quota.weekly": "Cuota semanal",
|
|
436
498
|
"quota.refreshed": "Cuota actualizada",
|
|
437
499
|
"proxy.button": "Proxy",
|
|
438
|
-
"pool.winIsolationWarn": "Windows: agy guarda el inicio de sesión en el Credential Manager del sistema (un único espacio), por lo que el pool de cuentas no puede aislar credenciales — la rotación solo cambia de directorio y el consumo sigue en la cuenta del sistema (issue #45).",
|
|
439
500
|
"proxy.placeholder": "URL de proxy exclusivo (por ejemplo: http://127.0.0.1:7890; déjelo vacío para usar el proxy global)",
|
|
440
501
|
"proxy.save": "Guardar",
|
|
441
502
|
"proxy.saved": "Proxy guardado",
|
|
@@ -489,9 +550,729 @@ window.__ModuleLoader__.load({
|
|
|
489
550
|
"header.refreshQuota": "Actualizar cuota",
|
|
490
551
|
"header.refreshing": "Actualizando...",
|
|
491
552
|
"console.close": "Cerrar (Esc)",
|
|
492
|
-
"header.badgeTitle": "Antigravity: {count} cuentas listas · haga clic para abrir la consola"
|
|
553
|
+
"header.badgeTitle": "Antigravity: {count} cuentas listas · haga clic para abrir la consola",
|
|
554
|
+
"header.badgeLoading": "Antigravity · haga clic para abrir la consola",
|
|
555
|
+
"account.type.agy": "Google Antigravity (CLI / OAuth)",
|
|
556
|
+
"account.loginType": "Tipo de inicio de sesión:",
|
|
557
|
+
"account.dragHandle": "Arrastrar para reordenar prioridad",
|
|
558
|
+
"account.moveUp": "Subir prioridad",
|
|
559
|
+
"account.moveDown": "Bajar prioridad",
|
|
560
|
+
"account.reordered": "Prioridad de cuentas reordenada con éxito",
|
|
561
|
+
"account.collapseAll": "Contraer todo",
|
|
562
|
+
"account.expandAll": "Expandir todo",
|
|
563
|
+
"account.cardCollapse": "Contraer",
|
|
564
|
+
"account.cardExpand": "Expandir detalles",
|
|
565
|
+
"account.draggingTarget": "Soltar aquí para prioridad #{num}",
|
|
566
|
+
"account.dragBanner": "Reordenando: moviendo [{alias}] a #{num}",
|
|
567
|
+
"account.dragHint": "Arrastre las tarjetas para reordenar la prioridad en tiempo real"
|
|
493
568
|
};
|
|
494
569
|
//#endregion
|
|
570
|
+
//#region src/client/decisions.ts
|
|
571
|
+
const DECISION_CSS = `
|
|
572
|
+
.agy-decision-container {
|
|
573
|
+
margin: 10px 0 6px 0;
|
|
574
|
+
padding: 10px 12px;
|
|
575
|
+
border-radius: 8px;
|
|
576
|
+
background: var(--dsw-alias-bg-l2, rgba(127, 127, 127, 0.07));
|
|
577
|
+
border: 1px dashed var(--dsw-alias-border-l3, rgba(127, 127, 127, 0.3));
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
.agy-decision-header {
|
|
581
|
+
font-size: 12px;
|
|
582
|
+
font-weight: 600;
|
|
583
|
+
color: var(--dsw-alias-label-secondary, #aaa);
|
|
584
|
+
margin-bottom: 8px;
|
|
585
|
+
display: flex;
|
|
586
|
+
align-items: center;
|
|
587
|
+
gap: 6px;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.agy-decision-chips {
|
|
591
|
+
display: flex;
|
|
592
|
+
flex-wrap: wrap;
|
|
593
|
+
gap: 8px;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
.agy-decision-chip {
|
|
597
|
+
background: var(--dsw-alias-bg-l1, rgba(255, 255, 255, 0.05));
|
|
598
|
+
border: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.25));
|
|
599
|
+
color: var(--dsw-alias-label-primary, #eee);
|
|
600
|
+
padding: 5px 12px;
|
|
601
|
+
border-radius: 999px;
|
|
602
|
+
cursor: pointer;
|
|
603
|
+
font-size: 12px;
|
|
604
|
+
font-weight: 500;
|
|
605
|
+
display: inline-flex;
|
|
606
|
+
align-items: center;
|
|
607
|
+
gap: 6px;
|
|
608
|
+
transition: all 0.15s ease;
|
|
609
|
+
user-select: none;
|
|
610
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
611
|
+
text-align: left;
|
|
612
|
+
max-width: 100%;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.agy-decision-chip:hover {
|
|
616
|
+
background: var(--dsw-alias-bg-hover, rgba(127, 127, 127, 0.18));
|
|
617
|
+
border-color: var(--dsw-alias-border-l4, rgba(127, 127, 127, 0.5));
|
|
618
|
+
transform: translateY(-1px);
|
|
619
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
.agy-decision-chip:active {
|
|
623
|
+
transform: translateY(0);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.agy-decision-chip.selected {
|
|
627
|
+
background: rgba(16, 185, 129, 0.15);
|
|
628
|
+
border-color: #10b981;
|
|
629
|
+
color: #10b981;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.agy-decision-chip-num {
|
|
633
|
+
font-weight: 700;
|
|
634
|
+
opacity: 0.8;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
.agy-decision-chip-text {
|
|
638
|
+
overflow: hidden;
|
|
639
|
+
text-overflow: ellipsis;
|
|
640
|
+
white-space: nowrap;
|
|
641
|
+
}
|
|
642
|
+
`;
|
|
643
|
+
function injectStyles$3() {
|
|
644
|
+
if (typeof document === "undefined") return;
|
|
645
|
+
const styleId = "dsh-agy-link-decisions-css";
|
|
646
|
+
if (document.getElementById(styleId) === null) {
|
|
647
|
+
const st = document.createElement("style");
|
|
648
|
+
st.id = styleId;
|
|
649
|
+
st.textContent = DECISION_CSS;
|
|
650
|
+
const host = document.head ?? document.documentElement;
|
|
651
|
+
if (host) host.appendChild(st);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Insert text directly into DSH's chat composer
|
|
656
|
+
*/
|
|
657
|
+
function insertTextIntoChatComposer(text) {
|
|
658
|
+
if (typeof document === "undefined" || !text) return false;
|
|
659
|
+
const inputEl = document.querySelector("[data-composer-input]") ?? document.querySelector("[role=\"textbox\"][contenteditable=\"true\"]") ?? document.querySelector("textarea");
|
|
660
|
+
if (!inputEl) return false;
|
|
661
|
+
inputEl.focus();
|
|
662
|
+
if (inputEl instanceof HTMLTextAreaElement || inputEl instanceof HTMLInputElement) {
|
|
663
|
+
const start = inputEl.selectionStart ?? inputEl.value.length;
|
|
664
|
+
const end = inputEl.selectionEnd ?? inputEl.value.length;
|
|
665
|
+
inputEl.setRangeText(text, start, end, "end");
|
|
666
|
+
inputEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
667
|
+
inputEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
try {
|
|
671
|
+
if (document.execCommand("insertText", false, text)) return true;
|
|
672
|
+
} catch {}
|
|
673
|
+
const existing = inputEl.textContent?.trim() ?? "";
|
|
674
|
+
inputEl.textContent = existing ? `${existing} ${text}` : text;
|
|
675
|
+
inputEl.dispatchEvent(new InputEvent("input", {
|
|
676
|
+
bubbles: true,
|
|
677
|
+
inputType: "insertText",
|
|
678
|
+
data: text
|
|
679
|
+
}));
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
/** Check if text header suggests an actionable decision or choice prompt */
|
|
683
|
+
const DECISION_HEADER_REGEX = /(?:请(?:您)?(?:拍板|指示|决定|选择|决策)|decision|next\s+step|choose|拍板|选择方案)/i;
|
|
684
|
+
/** Extract numbered options or choice items from a decision list */
|
|
685
|
+
function extractOptionsFromList(container) {
|
|
686
|
+
const options = [];
|
|
687
|
+
const listItems = container.querySelectorAll("li");
|
|
688
|
+
if (listItems.length > 0) for (let i = 0; i < listItems.length; i++) {
|
|
689
|
+
const li = listItems[i];
|
|
690
|
+
if (!li) continue;
|
|
691
|
+
const text = (li.textContent ?? "").trim();
|
|
692
|
+
if (!text) continue;
|
|
693
|
+
const m = text.match(/^([0-9]+[、..:]\s*)?(.*?)(?:[::—\-·]|\n|$)/);
|
|
694
|
+
const num = m?.[1]?.trim() ?? `${i + 1}.`;
|
|
695
|
+
let title = m?.[2]?.trim() || text.slice(0, 50);
|
|
696
|
+
if (title.length > 40) title = title.slice(0, 40) + "…";
|
|
697
|
+
options.push({
|
|
698
|
+
num,
|
|
699
|
+
title,
|
|
700
|
+
fullText: text
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
return options;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Scan DOM for decision prompts and mount interactive choice chips
|
|
707
|
+
*/
|
|
708
|
+
function scanAndEnhanceDecisions() {
|
|
709
|
+
if (typeof document === "undefined") return;
|
|
710
|
+
const markdownContainers = document.querySelectorAll("div[class*=\"_markdown_\"], [data-markdown-variant]");
|
|
711
|
+
for (let i = 0; i < markdownContainers.length; i++) {
|
|
712
|
+
const container = markdownContainers[i];
|
|
713
|
+
if (!container || container.dataset.agyDecisionsScanned === "true") continue;
|
|
714
|
+
const headings = container.querySelectorAll("h2, h3, h4, p > strong");
|
|
715
|
+
for (let j = 0; j < headings.length; j++) {
|
|
716
|
+
const heading = headings[j];
|
|
717
|
+
if (!heading || heading.dataset.agyDecisionAttached === "true") continue;
|
|
718
|
+
const headingText = (heading.textContent ?? "").trim();
|
|
719
|
+
if (!DECISION_HEADER_REGEX.test(headingText)) continue;
|
|
720
|
+
let sibling = heading.nextElementSibling;
|
|
721
|
+
let targetList = null;
|
|
722
|
+
while (sibling) {
|
|
723
|
+
if (sibling.tagName === "OL" || sibling.tagName === "UL") {
|
|
724
|
+
targetList = sibling;
|
|
725
|
+
break;
|
|
726
|
+
}
|
|
727
|
+
if (/^H[1-4]$/.test(sibling.tagName)) break;
|
|
728
|
+
sibling = sibling.nextElementSibling;
|
|
729
|
+
}
|
|
730
|
+
if (!targetList) continue;
|
|
731
|
+
const options = extractOptionsFromList(targetList);
|
|
732
|
+
if (options.length === 0) continue;
|
|
733
|
+
heading.dataset.agyDecisionAttached = "true";
|
|
734
|
+
const box = document.createElement("div");
|
|
735
|
+
box.className = "agy-decision-container";
|
|
736
|
+
const header = document.createElement("div");
|
|
737
|
+
header.className = "agy-decision-header";
|
|
738
|
+
header.innerHTML = "<span>💬 点击选项快速填入:</span>";
|
|
739
|
+
box.appendChild(header);
|
|
740
|
+
const chips = document.createElement("div");
|
|
741
|
+
chips.className = "agy-decision-chips";
|
|
742
|
+
for (const opt of options) {
|
|
743
|
+
const chip = document.createElement("button");
|
|
744
|
+
chip.type = "button";
|
|
745
|
+
chip.className = "agy-decision-chip";
|
|
746
|
+
chip.title = `点击填入: ${opt.fullText}`;
|
|
747
|
+
const numSpan = document.createElement("span");
|
|
748
|
+
numSpan.className = "agy-decision-chip-num";
|
|
749
|
+
numSpan.textContent = opt.num ?? "👉";
|
|
750
|
+
const textSpan = document.createElement("span");
|
|
751
|
+
textSpan.className = "agy-decision-chip-text";
|
|
752
|
+
textSpan.textContent = opt.title;
|
|
753
|
+
chip.appendChild(numSpan);
|
|
754
|
+
chip.appendChild(textSpan);
|
|
755
|
+
chip.onclick = (e) => {
|
|
756
|
+
e.stopPropagation();
|
|
757
|
+
const cleanText = opt.fullText.replace(/^[0-9]+[、..:]\s*/, "").trim();
|
|
758
|
+
insertTextIntoChatComposer(`我选择 ${opt.num ? opt.num + " " : ""}${cleanText}`);
|
|
759
|
+
chip.classList.add("selected");
|
|
760
|
+
setTimeout(() => chip.classList.remove("selected"), 1200);
|
|
761
|
+
};
|
|
762
|
+
chips.appendChild(chip);
|
|
763
|
+
}
|
|
764
|
+
box.appendChild(chips);
|
|
765
|
+
targetList.parentNode?.insertBefore(box, targetList.nextSibling);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
let decisionChipsDispose = null;
|
|
770
|
+
function installDecisionChips() {
|
|
771
|
+
if (typeof window === "undefined" || typeof document === "undefined") return () => {};
|
|
772
|
+
decisionChipsDispose?.();
|
|
773
|
+
injectStyles$3();
|
|
774
|
+
const observer = new MutationObserver(() => {
|
|
775
|
+
scanAndEnhanceDecisions();
|
|
776
|
+
});
|
|
777
|
+
const setup = () => {
|
|
778
|
+
if (document.body) {
|
|
779
|
+
observer.observe(document.body, {
|
|
780
|
+
childList: true,
|
|
781
|
+
subtree: true
|
|
782
|
+
});
|
|
783
|
+
scanAndEnhanceDecisions();
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
if (document.readyState === "loading") window.addEventListener("DOMContentLoaded", setup, { once: true });
|
|
787
|
+
else setup();
|
|
788
|
+
const dispose = () => {
|
|
789
|
+
observer.disconnect();
|
|
790
|
+
window.removeEventListener("DOMContentLoaded", setup);
|
|
791
|
+
if (decisionChipsDispose === dispose) decisionChipsDispose = null;
|
|
792
|
+
};
|
|
793
|
+
decisionChipsDispose = dispose;
|
|
794
|
+
return dispose;
|
|
795
|
+
}
|
|
796
|
+
//#endregion
|
|
797
|
+
//#region src/client/images.ts
|
|
798
|
+
let lightboxOverlay = null;
|
|
799
|
+
let lightboxScale = 1;
|
|
800
|
+
let lightboxTranslateX = 0;
|
|
801
|
+
let lightboxTranslateY = 0;
|
|
802
|
+
let isDraggingLightbox = false;
|
|
803
|
+
let dragStartX = 0;
|
|
804
|
+
let dragStartY = 0;
|
|
805
|
+
const IMAGE_CSS = `
|
|
806
|
+
.agy-image-card {
|
|
807
|
+
display: inline-flex;
|
|
808
|
+
flex-direction: column;
|
|
809
|
+
margin: 6px 0;
|
|
810
|
+
max-width: 100%;
|
|
811
|
+
border-radius: 8px;
|
|
812
|
+
overflow: hidden;
|
|
813
|
+
border: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.25));
|
|
814
|
+
background: var(--dsw-alias-bg-l1, rgba(255, 255, 255, 0.03));
|
|
815
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
816
|
+
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
|
817
|
+
vertical-align: middle;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.agy-image-card:hover {
|
|
821
|
+
border-color: var(--dsw-alias-border-l3, rgba(127, 127, 127, 0.45));
|
|
822
|
+
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
.agy-image-thumb-wrap {
|
|
826
|
+
position: relative;
|
|
827
|
+
overflow: hidden;
|
|
828
|
+
max-height: 480px;
|
|
829
|
+
cursor: zoom-in;
|
|
830
|
+
display: flex;
|
|
831
|
+
align-items: center;
|
|
832
|
+
justify-content: center;
|
|
833
|
+
background: repeating-conic-gradient(rgba(127,127,127,0.08) 0% 25%, transparent 0% 50%) 50% / 16px 16px;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
.agy-image-thumb {
|
|
837
|
+
display: block;
|
|
838
|
+
max-width: 100%;
|
|
839
|
+
max-height: 480px;
|
|
840
|
+
height: auto;
|
|
841
|
+
object-fit: contain;
|
|
842
|
+
transition: transform 0.2s ease;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
.agy-image-card:hover .agy-image-thumb {
|
|
846
|
+
transform: scale(1.015);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
.agy-image-caption {
|
|
850
|
+
padding: 6px 10px;
|
|
851
|
+
font-size: 11.5px;
|
|
852
|
+
color: var(--dsw-alias-label-secondary, #aaa);
|
|
853
|
+
background: var(--dsw-alias-bg-l2, rgba(127, 127, 127, 0.08));
|
|
854
|
+
border-top: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.15));
|
|
855
|
+
display: flex;
|
|
856
|
+
align-items: center;
|
|
857
|
+
justify-content: space-between;
|
|
858
|
+
gap: 8px;
|
|
859
|
+
overflow: hidden;
|
|
860
|
+
text-overflow: ellipsis;
|
|
861
|
+
white-space: nowrap;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.agy-image-link-chip {
|
|
865
|
+
display: inline-flex;
|
|
866
|
+
align-items: center;
|
|
867
|
+
gap: 4px;
|
|
868
|
+
padding: 2px 6px;
|
|
869
|
+
margin: 0 2px;
|
|
870
|
+
border-radius: 4px;
|
|
871
|
+
font-size: 12px;
|
|
872
|
+
background: var(--dsw-alias-bg-l2, rgba(127, 127, 127, 0.1));
|
|
873
|
+
border: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.2));
|
|
874
|
+
color: var(--dsw-alias-label-primary, #ddd);
|
|
875
|
+
cursor: pointer;
|
|
876
|
+
text-decoration: none;
|
|
877
|
+
transition: all 0.15s ease;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
.agy-image-link-chip:hover {
|
|
881
|
+
background: var(--dsw-alias-bg-hover, rgba(127, 127, 127, 0.2));
|
|
882
|
+
border-color: var(--dsw-alias-border-l3, rgba(127, 127, 127, 0.35));
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/* Lightbox Modal */
|
|
886
|
+
.agy-lightbox-backdrop {
|
|
887
|
+
position: fixed;
|
|
888
|
+
inset: 0;
|
|
889
|
+
z-index: 999999;
|
|
890
|
+
background: rgba(0, 0, 0, 0.85);
|
|
891
|
+
backdrop-filter: blur(8px);
|
|
892
|
+
display: flex;
|
|
893
|
+
flex-direction: column;
|
|
894
|
+
user-select: none;
|
|
895
|
+
opacity: 0;
|
|
896
|
+
transition: opacity 0.2s ease;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
.agy-lightbox-backdrop.open {
|
|
900
|
+
opacity: 1;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
.agy-lightbox-header {
|
|
904
|
+
height: 48px;
|
|
905
|
+
display: flex;
|
|
906
|
+
align-items: center;
|
|
907
|
+
justify-content: space-between;
|
|
908
|
+
padding: 0 16px;
|
|
909
|
+
background: rgba(20, 20, 20, 0.65);
|
|
910
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
911
|
+
color: #fff;
|
|
912
|
+
font-size: 13px;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
.agy-lightbox-title {
|
|
916
|
+
font-weight: 500;
|
|
917
|
+
overflow: hidden;
|
|
918
|
+
text-overflow: ellipsis;
|
|
919
|
+
white-space: nowrap;
|
|
920
|
+
max-width: 60%;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
.agy-lightbox-actions {
|
|
924
|
+
display: flex;
|
|
925
|
+
align-items: center;
|
|
926
|
+
gap: 8px;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
.agy-lightbox-btn {
|
|
930
|
+
background: rgba(255, 255, 255, 0.1);
|
|
931
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
932
|
+
color: #fff;
|
|
933
|
+
border-radius: 6px;
|
|
934
|
+
padding: 4px 10px;
|
|
935
|
+
cursor: pointer;
|
|
936
|
+
font-size: 12px;
|
|
937
|
+
display: inline-flex;
|
|
938
|
+
align-items: center;
|
|
939
|
+
gap: 4px;
|
|
940
|
+
transition: all 0.15s ease;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
.agy-lightbox-btn:hover {
|
|
944
|
+
background: rgba(255, 255, 255, 0.2);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
.agy-lightbox-btn-close {
|
|
948
|
+
background: rgba(239, 68, 68, 0.25);
|
|
949
|
+
border-color: rgba(239, 68, 68, 0.4);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
.agy-lightbox-btn-close:hover {
|
|
953
|
+
background: rgba(239, 68, 68, 0.45);
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
.agy-lightbox-body {
|
|
957
|
+
flex: 1;
|
|
958
|
+
position: relative;
|
|
959
|
+
overflow: hidden;
|
|
960
|
+
display: flex;
|
|
961
|
+
align-items: center;
|
|
962
|
+
justify-content: center;
|
|
963
|
+
cursor: grab;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
.agy-lightbox-body.grabbing {
|
|
967
|
+
cursor: grabbing;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
.agy-lightbox-img-wrap {
|
|
971
|
+
transform-origin: center center;
|
|
972
|
+
transition: transform 0.05s ease-out;
|
|
973
|
+
display: inline-block;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
.agy-lightbox-img {
|
|
977
|
+
max-width: 90vw;
|
|
978
|
+
max-height: 85vh;
|
|
979
|
+
object-fit: contain;
|
|
980
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
|
981
|
+
border-radius: 4px;
|
|
982
|
+
pointer-events: none;
|
|
983
|
+
}
|
|
984
|
+
`;
|
|
985
|
+
function injectStyles$2() {
|
|
986
|
+
if (typeof document === "undefined") return;
|
|
987
|
+
const styleId = "dsh-agy-link-images-css";
|
|
988
|
+
if (document.getElementById(styleId) === null) {
|
|
989
|
+
const st = document.createElement("style");
|
|
990
|
+
st.id = styleId;
|
|
991
|
+
st.textContent = IMAGE_CSS;
|
|
992
|
+
const host = document.head ?? document.documentElement;
|
|
993
|
+
if (host) host.appendChild(st);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
function getOrigin() {
|
|
997
|
+
if (typeof window !== "undefined" && window.location?.origin) return window.location.origin;
|
|
998
|
+
return "";
|
|
999
|
+
}
|
|
1000
|
+
/** Build media URL from path */
|
|
1001
|
+
function buildMediaUrl(rawPath) {
|
|
1002
|
+
return `${getOrigin()}/plugins/agy-link/media?path=${encodeURIComponent(rawPath.trim())}`;
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Open fullscreen Lightbox modal
|
|
1006
|
+
*/
|
|
1007
|
+
function openLightbox(src, title = "Image Preview", rawPath) {
|
|
1008
|
+
if (typeof document === "undefined") return;
|
|
1009
|
+
injectStyles$2();
|
|
1010
|
+
if (lightboxOverlay) {
|
|
1011
|
+
lightboxOverlay.remove();
|
|
1012
|
+
lightboxOverlay = null;
|
|
1013
|
+
}
|
|
1014
|
+
lightboxScale = 1;
|
|
1015
|
+
lightboxTranslateX = 0;
|
|
1016
|
+
lightboxTranslateY = 0;
|
|
1017
|
+
const overlay = document.createElement("div");
|
|
1018
|
+
overlay.className = "agy-lightbox-backdrop";
|
|
1019
|
+
const header = document.createElement("div");
|
|
1020
|
+
header.className = "agy-lightbox-header";
|
|
1021
|
+
const titleEl = document.createElement("div");
|
|
1022
|
+
titleEl.className = "agy-lightbox-title";
|
|
1023
|
+
titleEl.textContent = title;
|
|
1024
|
+
header.appendChild(titleEl);
|
|
1025
|
+
const actions = document.createElement("div");
|
|
1026
|
+
actions.className = "agy-lightbox-actions";
|
|
1027
|
+
const btnZoomIn = document.createElement("button");
|
|
1028
|
+
btnZoomIn.className = "agy-lightbox-btn";
|
|
1029
|
+
btnZoomIn.textContent = "🔍+";
|
|
1030
|
+
btnZoomIn.title = "放大 / Zoom In";
|
|
1031
|
+
const btnZoomOut = document.createElement("button");
|
|
1032
|
+
btnZoomOut.className = "agy-lightbox-btn";
|
|
1033
|
+
btnZoomOut.textContent = "🔍-";
|
|
1034
|
+
btnZoomOut.title = "缩小 / Zoom Out";
|
|
1035
|
+
const btnReset = document.createElement("button");
|
|
1036
|
+
btnReset.className = "agy-lightbox-btn";
|
|
1037
|
+
btnReset.textContent = "1:1";
|
|
1038
|
+
btnReset.title = "实际大小 / Reset";
|
|
1039
|
+
actions.appendChild(btnZoomIn);
|
|
1040
|
+
actions.appendChild(btnZoomOut);
|
|
1041
|
+
actions.appendChild(btnReset);
|
|
1042
|
+
if (rawPath) {
|
|
1043
|
+
const btnCopyPath = document.createElement("button");
|
|
1044
|
+
btnCopyPath.className = "agy-lightbox-btn";
|
|
1045
|
+
btnCopyPath.textContent = "📋 复制路径";
|
|
1046
|
+
btnCopyPath.onclick = (e) => {
|
|
1047
|
+
e.stopPropagation();
|
|
1048
|
+
if (navigator.clipboard) navigator.clipboard.writeText(rawPath).then(() => {
|
|
1049
|
+
btnCopyPath.textContent = "✓ 已复制";
|
|
1050
|
+
setTimeout(() => {
|
|
1051
|
+
btnCopyPath.textContent = "📋 复制路径";
|
|
1052
|
+
}, 1500);
|
|
1053
|
+
}).catch(() => {});
|
|
1054
|
+
};
|
|
1055
|
+
actions.appendChild(btnCopyPath);
|
|
1056
|
+
}
|
|
1057
|
+
const btnClose = document.createElement("button");
|
|
1058
|
+
btnClose.className = "agy-lightbox-btn agy-lightbox-btn-close";
|
|
1059
|
+
btnClose.textContent = "✕ 关闭";
|
|
1060
|
+
actions.appendChild(btnClose);
|
|
1061
|
+
header.appendChild(actions);
|
|
1062
|
+
overlay.appendChild(header);
|
|
1063
|
+
const body = document.createElement("div");
|
|
1064
|
+
body.className = "agy-lightbox-body";
|
|
1065
|
+
const imgWrap = document.createElement("div");
|
|
1066
|
+
imgWrap.className = "agy-lightbox-img-wrap";
|
|
1067
|
+
const img = document.createElement("img");
|
|
1068
|
+
img.className = "agy-lightbox-img";
|
|
1069
|
+
img.src = src;
|
|
1070
|
+
img.alt = title;
|
|
1071
|
+
imgWrap.appendChild(img);
|
|
1072
|
+
body.appendChild(imgWrap);
|
|
1073
|
+
overlay.appendChild(body);
|
|
1074
|
+
const updateTransform = () => {
|
|
1075
|
+
imgWrap.style.transform = `translate(${lightboxTranslateX}px, ${lightboxTranslateY}px) scale(${lightboxScale})`;
|
|
1076
|
+
};
|
|
1077
|
+
btnZoomIn.onclick = (e) => {
|
|
1078
|
+
e.stopPropagation();
|
|
1079
|
+
lightboxScale = Math.min(lightboxScale * 1.3, 5);
|
|
1080
|
+
updateTransform();
|
|
1081
|
+
};
|
|
1082
|
+
btnZoomOut.onclick = (e) => {
|
|
1083
|
+
e.stopPropagation();
|
|
1084
|
+
lightboxScale = Math.max(lightboxScale / 1.3, .2);
|
|
1085
|
+
updateTransform();
|
|
1086
|
+
};
|
|
1087
|
+
btnReset.onclick = (e) => {
|
|
1088
|
+
e.stopPropagation();
|
|
1089
|
+
lightboxScale = 1;
|
|
1090
|
+
lightboxTranslateX = 0;
|
|
1091
|
+
lightboxTranslateY = 0;
|
|
1092
|
+
updateTransform();
|
|
1093
|
+
};
|
|
1094
|
+
const closeLightbox = () => {
|
|
1095
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
1096
|
+
overlay.classList.remove("open");
|
|
1097
|
+
setTimeout(() => {
|
|
1098
|
+
overlay.remove();
|
|
1099
|
+
if (lightboxOverlay === overlay) lightboxOverlay = null;
|
|
1100
|
+
}, 200);
|
|
1101
|
+
};
|
|
1102
|
+
btnClose.onclick = (e) => {
|
|
1103
|
+
e.stopPropagation();
|
|
1104
|
+
closeLightbox();
|
|
1105
|
+
};
|
|
1106
|
+
overlay.onclick = (e) => {
|
|
1107
|
+
if (e.target === overlay || e.target === body) closeLightbox();
|
|
1108
|
+
};
|
|
1109
|
+
const onKeyDown = (e) => {
|
|
1110
|
+
if (e.key === "Escape") closeLightbox();
|
|
1111
|
+
};
|
|
1112
|
+
window.addEventListener("keydown", onKeyDown);
|
|
1113
|
+
body.onmousedown = (e) => {
|
|
1114
|
+
isDraggingLightbox = true;
|
|
1115
|
+
dragStartX = e.clientX - lightboxTranslateX;
|
|
1116
|
+
dragStartY = e.clientY - lightboxTranslateY;
|
|
1117
|
+
body.classList.add("grabbing");
|
|
1118
|
+
};
|
|
1119
|
+
const onMouseMove = (e) => {
|
|
1120
|
+
if (!isDraggingLightbox) return;
|
|
1121
|
+
lightboxTranslateX = e.clientX - dragStartX;
|
|
1122
|
+
lightboxTranslateY = e.clientY - dragStartY;
|
|
1123
|
+
updateTransform();
|
|
1124
|
+
};
|
|
1125
|
+
const onMouseUp = () => {
|
|
1126
|
+
if (isDraggingLightbox) {
|
|
1127
|
+
isDraggingLightbox = false;
|
|
1128
|
+
body.classList.remove("grabbing");
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
window.addEventListener("mousemove", onMouseMove);
|
|
1132
|
+
window.addEventListener("mouseup", onMouseUp);
|
|
1133
|
+
body.onwheel = (e) => {
|
|
1134
|
+
e.preventDefault();
|
|
1135
|
+
const factor = e.deltaY < 0 ? 1.15 : .87;
|
|
1136
|
+
lightboxScale = Math.max(.2, Math.min(lightboxScale * factor, 5));
|
|
1137
|
+
updateTransform();
|
|
1138
|
+
};
|
|
1139
|
+
document.body.appendChild(overlay);
|
|
1140
|
+
lightboxOverlay = overlay;
|
|
1141
|
+
requestAnimationFrame(() => overlay.classList.add("open"));
|
|
1142
|
+
}
|
|
1143
|
+
/** Check if a URL or path is an image */
|
|
1144
|
+
function isImageFile(pathOrUrl) {
|
|
1145
|
+
if (!pathOrUrl || typeof pathOrUrl !== "string") return false;
|
|
1146
|
+
const clean = pathOrUrl.split(/[?#]/)[0] ?? "";
|
|
1147
|
+
return /\.(png|jpe?g|webp|gif|svg|bmp|ico|avif)$/i.test(clean);
|
|
1148
|
+
}
|
|
1149
|
+
/** Get React props of a DOM element */
|
|
1150
|
+
function getReactProps(el) {
|
|
1151
|
+
const key = Object.keys(el).find((k) => k.startsWith("__reactProps"));
|
|
1152
|
+
if (!key) return null;
|
|
1153
|
+
return el[key];
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Scan DOM for imageAlt spans and enhance them with live rendered images
|
|
1157
|
+
*/
|
|
1158
|
+
function scanAndEnhanceImages() {
|
|
1159
|
+
if (typeof document === "undefined") return;
|
|
1160
|
+
const origin = getOrigin();
|
|
1161
|
+
if (origin && !origin.includes("127.0.0.1") && !origin.includes("localhost")) {
|
|
1162
|
+
const images = document.querySelectorAll("img[src*=\"/plugins/agy-link/media\"]");
|
|
1163
|
+
for (let i = 0; i < images.length; i++) {
|
|
1164
|
+
const img = images[i];
|
|
1165
|
+
if (img && img.src.includes("127.0.0.1")) {
|
|
1166
|
+
const u = new URL(img.src);
|
|
1167
|
+
img.src = `${origin}${u.pathname}${u.search}`;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
const markdownContainers = document.querySelectorAll("div[class*=\"_markdown_\"], [data-markdown-variant]");
|
|
1172
|
+
for (let i = 0; i < markdownContainers.length; i++) {
|
|
1173
|
+
const container = markdownContainers[i];
|
|
1174
|
+
if (!container) continue;
|
|
1175
|
+
const altSpans = container.querySelectorAll("span[class*=\"imageAlt\"], span[class*=\"_imageAlt_\"]");
|
|
1176
|
+
if (altSpans.length === 0) continue;
|
|
1177
|
+
const props = getReactProps(container);
|
|
1178
|
+
const mdText = typeof props?.text === "string" ? props.text : "";
|
|
1179
|
+
if (!mdText) continue;
|
|
1180
|
+
const imgMatches = [];
|
|
1181
|
+
const re = /!\[(.*?)\]\((file:\/\/\/[^\s)]+|file:\/\/[^\s)]+|[A-Za-z]:[\\/][^\s)]+|\/home\/[^\s)]+|\/mnt\/[a-zA-Z]\/[^\s)]+|\\\\wsl\.localhost\\[^\s)]+)\)/g;
|
|
1182
|
+
let m;
|
|
1183
|
+
while ((m = re.exec(mdText)) !== null) imgMatches.push({
|
|
1184
|
+
alt: m[1] ?? "",
|
|
1185
|
+
target: m[2] ?? ""
|
|
1186
|
+
});
|
|
1187
|
+
if (imgMatches.length === 0) continue;
|
|
1188
|
+
for (let j = 0; j < altSpans.length; j++) {
|
|
1189
|
+
const span = altSpans[j];
|
|
1190
|
+
if (!span || span.dataset.agyEnhanced === "true") continue;
|
|
1191
|
+
const altText = (span.textContent ?? "").trim();
|
|
1192
|
+
const match = imgMatches.find((im) => im.alt.trim() === altText) ?? imgMatches[j];
|
|
1193
|
+
if (!match) continue;
|
|
1194
|
+
span.dataset.agyEnhanced = "true";
|
|
1195
|
+
const mediaUrl = buildMediaUrl(match.target);
|
|
1196
|
+
const card = document.createElement("div");
|
|
1197
|
+
card.className = "agy-image-card";
|
|
1198
|
+
const thumbWrap = document.createElement("div");
|
|
1199
|
+
thumbWrap.className = "agy-image-thumb-wrap";
|
|
1200
|
+
thumbWrap.title = `${altText || "Image"} (点击全屏放大)`;
|
|
1201
|
+
const img = document.createElement("img");
|
|
1202
|
+
img.className = "agy-image-thumb";
|
|
1203
|
+
img.src = mediaUrl;
|
|
1204
|
+
img.alt = altText || "Preview";
|
|
1205
|
+
img.loading = "lazy";
|
|
1206
|
+
img.onerror = () => {
|
|
1207
|
+
card.style.display = "none";
|
|
1208
|
+
span.style.display = "";
|
|
1209
|
+
};
|
|
1210
|
+
thumbWrap.appendChild(img);
|
|
1211
|
+
card.appendChild(thumbWrap);
|
|
1212
|
+
if (altText) {
|
|
1213
|
+
const caption = document.createElement("div");
|
|
1214
|
+
caption.className = "agy-image-caption";
|
|
1215
|
+
caption.textContent = altText;
|
|
1216
|
+
card.appendChild(caption);
|
|
1217
|
+
}
|
|
1218
|
+
thumbWrap.onclick = (e) => {
|
|
1219
|
+
e.stopPropagation();
|
|
1220
|
+
openLightbox(mediaUrl, altText || "Image Preview", match.target);
|
|
1221
|
+
};
|
|
1222
|
+
span.style.display = "none";
|
|
1223
|
+
span.parentNode?.insertBefore(card, span);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
const links = document.querySelectorAll("a[href^=\"file://\"]");
|
|
1227
|
+
for (let i = 0; i < links.length; i++) {
|
|
1228
|
+
const link = links[i];
|
|
1229
|
+
if (!link || link.dataset.agyLinkEnhanced === "true") continue;
|
|
1230
|
+
const href = link.href ?? "";
|
|
1231
|
+
if (!isImageFile(href)) continue;
|
|
1232
|
+
link.dataset.agyLinkEnhanced = "true";
|
|
1233
|
+
const mediaUrl = buildMediaUrl(href);
|
|
1234
|
+
const linkText = link.textContent ?? "Image";
|
|
1235
|
+
link.onclick = (e) => {
|
|
1236
|
+
e.preventDefault();
|
|
1237
|
+
e.stopPropagation();
|
|
1238
|
+
openLightbox(mediaUrl, linkText, href);
|
|
1239
|
+
};
|
|
1240
|
+
if (!link.querySelector(".agy-image-link-icon")) {
|
|
1241
|
+
const badge = document.createElement("span");
|
|
1242
|
+
badge.className = "agy-image-link-chip agy-image-link-icon";
|
|
1243
|
+
badge.textContent = "🖼️ 预览";
|
|
1244
|
+
link.appendChild(badge);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
let imageEnhancerDispose = null;
|
|
1249
|
+
function installImageEnhancer() {
|
|
1250
|
+
if (typeof window === "undefined" || typeof document === "undefined") return () => {};
|
|
1251
|
+
imageEnhancerDispose?.();
|
|
1252
|
+
injectStyles$2();
|
|
1253
|
+
const observer = new MutationObserver(() => {
|
|
1254
|
+
scanAndEnhanceImages();
|
|
1255
|
+
});
|
|
1256
|
+
const setup = () => {
|
|
1257
|
+
if (document.body) {
|
|
1258
|
+
observer.observe(document.body, {
|
|
1259
|
+
childList: true,
|
|
1260
|
+
subtree: true
|
|
1261
|
+
});
|
|
1262
|
+
scanAndEnhanceImages();
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
if (document.readyState === "loading") window.addEventListener("DOMContentLoaded", setup, { once: true });
|
|
1266
|
+
else setup();
|
|
1267
|
+
const dispose = () => {
|
|
1268
|
+
observer.disconnect();
|
|
1269
|
+
window.removeEventListener("DOMContentLoaded", setup);
|
|
1270
|
+
if (imageEnhancerDispose === dispose) imageEnhancerDispose = null;
|
|
1271
|
+
};
|
|
1272
|
+
imageEnhancerDispose = dispose;
|
|
1273
|
+
return dispose;
|
|
1274
|
+
}
|
|
1275
|
+
//#endregion
|
|
495
1276
|
//#region src/client/toolview.ts
|
|
496
1277
|
function react() {
|
|
497
1278
|
const mod = require("react");
|
|
@@ -684,6 +1465,40 @@ window.__ModuleLoader__.load({
|
|
|
684
1465
|
fill: "currentColor"
|
|
685
1466
|
}));
|
|
686
1467
|
}
|
|
1468
|
+
function IconQuestionOutline16(size = 14, className = "") {
|
|
1469
|
+
return hx("svg", {
|
|
1470
|
+
width: size,
|
|
1471
|
+
height: size,
|
|
1472
|
+
className: className || void 0,
|
|
1473
|
+
viewBox: "0 0 16 16",
|
|
1474
|
+
fill: "none",
|
|
1475
|
+
style: {
|
|
1476
|
+
display: "block",
|
|
1477
|
+
flexShrink: 0
|
|
1478
|
+
},
|
|
1479
|
+
"aria-hidden": true
|
|
1480
|
+
}, hx("path", {
|
|
1481
|
+
d: "M8 1C4.134 1 1 3.91 1 7.5c0 1.547.575 2.973 1.559 4.093L1.13 14.54a.5.5 0 00.627.63l3.238-1.079C5.875 14.316 6.91 14.5 8 14.5c3.866 0 7-2.91 7-6.5S11.866 1 8 1zm0 10.5a.75.75 0 110-1.5.75.75 0 010 1.5zm1.09-3.41c-.42.34-.59.54-.59.91H7.5v-.5c0-.66.36-1.12.82-1.48.44-.35.68-.61.68-1.02 0-.55-.45-1-1-1s-1 .45-1 1H6c0-1.1.9-2 2-2s2 .9 2 2c0 .73-.39 1.25-.91 1.67z",
|
|
1482
|
+
fill: "currentColor"
|
|
1483
|
+
}));
|
|
1484
|
+
}
|
|
1485
|
+
function IconImageOutline16(size = 14, className = "") {
|
|
1486
|
+
return hx("svg", {
|
|
1487
|
+
width: size,
|
|
1488
|
+
height: size,
|
|
1489
|
+
className: className || void 0,
|
|
1490
|
+
viewBox: "0 0 16 16",
|
|
1491
|
+
fill: "none",
|
|
1492
|
+
style: {
|
|
1493
|
+
display: "block",
|
|
1494
|
+
flexShrink: 0
|
|
1495
|
+
},
|
|
1496
|
+
"aria-hidden": true
|
|
1497
|
+
}, hx("path", {
|
|
1498
|
+
d: "M14 3H2a1 1 0 00-1 1v8a1 1 0 001 1h12a1 1 0 001-1V4a1 1 0 00-1-1zm-1 8H3l2.5-3.2 1.8 2.3 2.7-3.5L13 11zM5.5 6a1.5 1.5 0 110-3 1.5 1.5 0 010 3z",
|
|
1499
|
+
fill: "currentColor"
|
|
1500
|
+
}));
|
|
1501
|
+
}
|
|
687
1502
|
function toolIconFor(kind, size = 14) {
|
|
688
1503
|
switch (kind) {
|
|
689
1504
|
case "terminal": return IconApiOutline14(size);
|
|
@@ -692,6 +1507,8 @@ window.__ModuleLoader__.load({
|
|
|
692
1507
|
case "read": return IconBrowseOutline16(size);
|
|
693
1508
|
case "search":
|
|
694
1509
|
case "list": return IconSearchOutline16(size);
|
|
1510
|
+
case "question": return IconQuestionOutline16(size);
|
|
1511
|
+
case "image": return IconImageOutline16(size);
|
|
695
1512
|
default: return IconCodeOutline16(size);
|
|
696
1513
|
}
|
|
697
1514
|
}
|
|
@@ -795,6 +1612,16 @@ window.__ModuleLoader__.load({
|
|
|
795
1612
|
"remove_file",
|
|
796
1613
|
"rm"
|
|
797
1614
|
]);
|
|
1615
|
+
const QUESTION_TOOLS = /* @__PURE__ */ new Set([
|
|
1616
|
+
"ask_question",
|
|
1617
|
+
"ask",
|
|
1618
|
+
"question"
|
|
1619
|
+
]);
|
|
1620
|
+
const IMAGE_TOOLS = /* @__PURE__ */ new Set([
|
|
1621
|
+
"generate_image",
|
|
1622
|
+
"create_image",
|
|
1623
|
+
"render_image"
|
|
1624
|
+
]);
|
|
798
1625
|
function mirrorCardModel(block, cwd, home) {
|
|
799
1626
|
const info = mirrorInfo(block);
|
|
800
1627
|
const out = resultText(block);
|
|
@@ -806,6 +1633,33 @@ window.__ModuleLoader__.load({
|
|
|
806
1633
|
};
|
|
807
1634
|
const { tool, input } = info;
|
|
808
1635
|
const desc = pick(input, "Description", "description", "toolAction", "toolSummary", "Instruction", "instruction");
|
|
1636
|
+
if (QUESTION_TOOLS.has(tool)) {
|
|
1637
|
+
const questionsRaw = input.questions ?? input.Questions;
|
|
1638
|
+
const questions = Array.isArray(questionsRaw) ? questionsRaw : [];
|
|
1639
|
+
return {
|
|
1640
|
+
kind: "question",
|
|
1641
|
+
tool,
|
|
1642
|
+
title: questions[0]?.question ?? desc ?? "Ask Question",
|
|
1643
|
+
output: out,
|
|
1644
|
+
questions,
|
|
1645
|
+
raw: parsedArgsRaw(block)
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
if (IMAGE_TOOLS.has(tool)) {
|
|
1649
|
+
const prompt = pick(input, "Prompt", "prompt") ?? "";
|
|
1650
|
+
const name = pick(input, "ImageName", "image_name", "name") ?? "image";
|
|
1651
|
+
const ratio = pick(input, "AspectRatio", "aspect_ratio") ?? "1:1";
|
|
1652
|
+
return {
|
|
1653
|
+
kind: "image",
|
|
1654
|
+
tool,
|
|
1655
|
+
title: desc ?? `Generate Image · ${name}`,
|
|
1656
|
+
prompt,
|
|
1657
|
+
imageName: name,
|
|
1658
|
+
aspectRatio: ratio,
|
|
1659
|
+
output: out,
|
|
1660
|
+
raw: parsedArgsRaw(block)
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
809
1663
|
if (TERMINAL_TOOLS.has(tool)) {
|
|
810
1664
|
const command = pick(input, "CommandLine", "command_line", "command", "cmd", "Cmd") ?? JSON.stringify(input);
|
|
811
1665
|
const cwdVal = pick(input, "Cwd", "cwd", "WorkingDirectory", "working_directory") ?? cwd;
|
|
@@ -839,12 +1693,17 @@ window.__ModuleLoader__.load({
|
|
|
839
1693
|
const path = pick(input, "AbsolutePath", "absolute_path", "TargetFile", "target_file", "path", "file_path", "filename", "Path", "FilePath", "FileName", "targetFile") ?? "";
|
|
840
1694
|
const offset = num(input, "offset", "Offset") ?? num(input, "StartLine", "start_line");
|
|
841
1695
|
const line = offset !== void 0 ? offset > 0 && (tool === "view_file" || tool === "read_file") ? offset : offset + 1 : void 0;
|
|
1696
|
+
const isImg = isImageFile(path);
|
|
842
1697
|
return {
|
|
843
|
-
kind: "read",
|
|
1698
|
+
kind: isImg ? "image" : "read",
|
|
844
1699
|
tool,
|
|
845
1700
|
title: desc ? `${desc} · ${path}` : path !== "" ? "Read " + path : "Read",
|
|
846
1701
|
path,
|
|
847
1702
|
output: out,
|
|
1703
|
+
isImage: isImg,
|
|
1704
|
+
imagePath: isImg ? path : void 0,
|
|
1705
|
+
prompt: desc,
|
|
1706
|
+
imageName: path.split(/[/\\]/).pop() || "image",
|
|
848
1707
|
...path !== "" ? { location: {
|
|
849
1708
|
path,
|
|
850
1709
|
...line !== void 0 ? { line } : {}
|
|
@@ -938,6 +1797,8 @@ window.__ModuleLoader__.load({
|
|
|
938
1797
|
case "search": return model.tool === "search_web" || model.tool === "web_search" ? tr(t, "tv.webSearch", "Web Search") : tr(t, "tv.search", "Search");
|
|
939
1798
|
case "list": return tr(t, "tv.list", "List");
|
|
940
1799
|
case "delete": return tr(t, "tv.delete", "Delete");
|
|
1800
|
+
case "question": return tr(t, "tv.question", "Question");
|
|
1801
|
+
case "image": return tr(t, "tv.image", "Image");
|
|
941
1802
|
default: return model.tool ? model.tool.replace(/_/g, " ") : tr(t, "tv.tool", "Tool");
|
|
942
1803
|
}
|
|
943
1804
|
}
|
|
@@ -950,6 +1811,8 @@ window.__ModuleLoader__.load({
|
|
|
950
1811
|
}
|
|
951
1812
|
if (model.kind === "search") return model.title.replace(/^(Web search|Search)\s*/i, "") || model.title;
|
|
952
1813
|
if (model.kind === "list") return model.title.replace(/^List\s*(directory\s*)?/i, "") || model.title;
|
|
1814
|
+
if (model.kind === "question") return model.title;
|
|
1815
|
+
if (model.kind === "image") return model.prompt || model.title;
|
|
953
1816
|
return model.title;
|
|
954
1817
|
}
|
|
955
1818
|
function diffStat(model) {
|
|
@@ -1026,6 +1889,101 @@ window.__ModuleLoader__.load({
|
|
|
1026
1889
|
}, tr(t, "tv.noChanges", "(no textual changes)")));
|
|
1027
1890
|
return h("div", { className: "agy-tv-diff-list" }, ...rows);
|
|
1028
1891
|
}
|
|
1892
|
+
function QuestionCardBody({ model }) {
|
|
1893
|
+
const h = hx;
|
|
1894
|
+
const questions = model.questions ?? [];
|
|
1895
|
+
const [selectedMap, setSelectedMap] = react().useState({});
|
|
1896
|
+
const [inserted, setInserted] = react().useState(false);
|
|
1897
|
+
const toggleOption = (qIdx, opt, isMulti) => {
|
|
1898
|
+
setSelectedMap((prev) => {
|
|
1899
|
+
const next = { ...prev };
|
|
1900
|
+
const current = new Set(next[qIdx] ?? []);
|
|
1901
|
+
if (isMulti) {
|
|
1902
|
+
if (current.has(opt)) current.delete(opt);
|
|
1903
|
+
else current.add(opt);
|
|
1904
|
+
} else {
|
|
1905
|
+
current.clear();
|
|
1906
|
+
current.add(opt);
|
|
1907
|
+
}
|
|
1908
|
+
next[qIdx] = current;
|
|
1909
|
+
return next;
|
|
1910
|
+
});
|
|
1911
|
+
};
|
|
1912
|
+
const onInsert = () => {
|
|
1913
|
+
const parts = [];
|
|
1914
|
+
for (let i = 0; i < questions.length; i++) {
|
|
1915
|
+
const sel = Array.from(selectedMap[i] ?? []);
|
|
1916
|
+
if (sel.length > 0) parts.push(sel.join("; "));
|
|
1917
|
+
}
|
|
1918
|
+
if (parts.length > 0) {
|
|
1919
|
+
insertTextIntoChatComposer(parts.join("\n"));
|
|
1920
|
+
setInserted(true);
|
|
1921
|
+
setTimeout(() => setInserted(false), 1500);
|
|
1922
|
+
}
|
|
1923
|
+
};
|
|
1924
|
+
const qNodes = [];
|
|
1925
|
+
for (let i = 0; i < questions.length; i++) {
|
|
1926
|
+
const q = questions[i];
|
|
1927
|
+
if (!q) continue;
|
|
1928
|
+
const options = q.options ?? [];
|
|
1929
|
+
const isMulti = q.is_multi_select === true;
|
|
1930
|
+
const sel = selectedMap[i] ?? /* @__PURE__ */ new Set();
|
|
1931
|
+
const optNodes = options.map((opt, oIdx) => {
|
|
1932
|
+
const isChecked = sel.has(opt);
|
|
1933
|
+
return h("button", {
|
|
1934
|
+
key: "opt-" + oIdx,
|
|
1935
|
+
type: "button",
|
|
1936
|
+
className: cls("agy-tv-q-opt", isChecked && "selected"),
|
|
1937
|
+
onClick: (e) => {
|
|
1938
|
+
e.stopPropagation();
|
|
1939
|
+
toggleOption(i, opt, isMulti);
|
|
1940
|
+
}
|
|
1941
|
+
}, h("span", { className: cls("agy-tv-q-check", isMulti ? "checkbox" : "radio", isChecked && "checked") }), h("span", { className: "agy-tv-q-opt-text" }, opt));
|
|
1942
|
+
});
|
|
1943
|
+
qNodes.push(h("div", {
|
|
1944
|
+
key: "q-" + i,
|
|
1945
|
+
className: "agy-tv-q-item"
|
|
1946
|
+
}, h("div", { className: "agy-tv-q-prompt" }, q.question || "Please select:"), h("div", { className: "agy-tv-q-opts" }, ...optNodes)));
|
|
1947
|
+
}
|
|
1948
|
+
const hasSelection = Object.values(selectedMap).some((s) => s.size > 0);
|
|
1949
|
+
return h("div", { className: "agy-tv-question-wrap" }, ...qNodes, h("div", { className: "agy-tv-q-footer" }, h("button", {
|
|
1950
|
+
type: "button",
|
|
1951
|
+
className: cls("agy-tv-q-insert-btn", hasSelection && "active"),
|
|
1952
|
+
disabled: !hasSelection,
|
|
1953
|
+
onClick: (e) => {
|
|
1954
|
+
e.stopPropagation();
|
|
1955
|
+
onInsert();
|
|
1956
|
+
}
|
|
1957
|
+
}, inserted ? "✓ 已填入对话框" : "💬 填入对话框 / Insert into Chat"), model.output ? h("div", { className: "agy-tv-q-answered" }, `已记录: ${model.output}`) : null));
|
|
1958
|
+
}
|
|
1959
|
+
function ImageCardBody({ model }) {
|
|
1960
|
+
const h = hx;
|
|
1961
|
+
const prompt = model.prompt || "";
|
|
1962
|
+
const name = model.imageName || "image";
|
|
1963
|
+
const ratio = model.aspectRatio || "1:1";
|
|
1964
|
+
const path = model.imagePath || model.path || "";
|
|
1965
|
+
const mediaUrl = path ? buildMediaUrl(path) : null;
|
|
1966
|
+
return h("div", { className: "agy-tv-img-wrap" }, h("div", { className: "agy-tv-img-meta" }, h("div", {
|
|
1967
|
+
className: "agy-tv-img-prompt",
|
|
1968
|
+
title: prompt || name
|
|
1969
|
+
}, prompt ? `"${prompt}"` : name), h("div", { className: "agy-tv-img-badges" }, h("span", { className: "agy-tv-img-badge" }, ratio), ...path ? [h("span", {
|
|
1970
|
+
key: "path",
|
|
1971
|
+
className: "agy-tv-img-badge",
|
|
1972
|
+
title: path
|
|
1973
|
+
}, path.split(/[/\\]/).pop())] : [])), mediaUrl ? h("div", {
|
|
1974
|
+
className: "agy-tv-img-preview-box",
|
|
1975
|
+
onClick: (e) => {
|
|
1976
|
+
e.stopPropagation();
|
|
1977
|
+
openLightbox(mediaUrl, prompt || name, path);
|
|
1978
|
+
},
|
|
1979
|
+
title: "点击放大预览 / Click to open lightbox"
|
|
1980
|
+
}, h("img", {
|
|
1981
|
+
className: "agy-tv-img-thumb",
|
|
1982
|
+
src: mediaUrl,
|
|
1983
|
+
alt: prompt || name,
|
|
1984
|
+
loading: "lazy"
|
|
1985
|
+
})) : null);
|
|
1986
|
+
}
|
|
1029
1987
|
function CardBody({ model, openFile, cwd, home, inspect, t }) {
|
|
1030
1988
|
const h = hx;
|
|
1031
1989
|
const inspectNode = inspect !== void 0 ? h("div", {
|
|
@@ -1088,6 +2046,8 @@ window.__ModuleLoader__.load({
|
|
|
1088
2046
|
t
|
|
1089
2047
|
})), h("pre", { className: "agy-tv-card-content" }, clip(rawBody, 16e3)), inspectNode);
|
|
1090
2048
|
}
|
|
2049
|
+
case "question": return h("div", { className: "agy-tv-card" }, h("div", { className: "agy-tv-card-header" }, h("div", { className: "agy-tv-card-header-left" }, IconQuestionOutline16(13), h("span", { className: "agy-tv-card-path" }, model.title)), h(CopyButton, { text: model.output ?? model.raw ?? "" })), h(QuestionCardBody, { model }), inspectNode);
|
|
2050
|
+
case "image": return h("div", { className: "agy-tv-card" }, h("div", { className: "agy-tv-card-header" }, h("div", { className: "agy-tv-card-header-left" }, IconImageOutline16(13), h("span", { className: "agy-tv-card-path" }, model.imageName || "Image")), h(CopyButton, { text: model.prompt || (model.raw ?? "") })), h(ImageCardBody, { model }), inspectNode);
|
|
1091
2051
|
default: {
|
|
1092
2052
|
const copyText = model.output !== void 0 && model.output !== "" ? model.output : model.raw ?? "";
|
|
1093
2053
|
const rawBody = model.output !== void 0 && model.output !== "" ? trimTrailingBlankLines(model.output) : model.raw !== void 0 && model.raw !== "" ? clip(model.raw, 4e3) : tr(t, "tv.noDetail", "(no detail)");
|
|
@@ -1695,6 +2655,156 @@ window.__ModuleLoader__.load({
|
|
|
1695
2655
|
background: var(--dsw-alias-interactive-bg-hover-solid, #f1f5f9);
|
|
1696
2656
|
color: var(--dsw-alias-label-primary, #0f172a);
|
|
1697
2657
|
}
|
|
2658
|
+
|
|
2659
|
+
/* Question Card Styles */
|
|
2660
|
+
.agy-tv-question-wrap {
|
|
2661
|
+
padding: 10px 14px;
|
|
2662
|
+
display: flex;
|
|
2663
|
+
flex-direction: column;
|
|
2664
|
+
gap: 10px;
|
|
2665
|
+
font-family: inherit;
|
|
2666
|
+
}
|
|
2667
|
+
.agy-tv-q-item {
|
|
2668
|
+
display: flex;
|
|
2669
|
+
flex-direction: column;
|
|
2670
|
+
gap: 6px;
|
|
2671
|
+
}
|
|
2672
|
+
.agy-tv-q-prompt {
|
|
2673
|
+
font-size: 13px;
|
|
2674
|
+
font-weight: 600;
|
|
2675
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
2676
|
+
}
|
|
2677
|
+
.agy-tv-q-opts {
|
|
2678
|
+
display: flex;
|
|
2679
|
+
flex-direction: column;
|
|
2680
|
+
gap: 6px;
|
|
2681
|
+
}
|
|
2682
|
+
.agy-tv-q-opt {
|
|
2683
|
+
display: flex;
|
|
2684
|
+
align-items: center;
|
|
2685
|
+
gap: 8px;
|
|
2686
|
+
padding: 6px 10px;
|
|
2687
|
+
border-radius: 6px;
|
|
2688
|
+
background: var(--dsw-alias-bg-l2, rgba(127, 127, 127, 0.08));
|
|
2689
|
+
border: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.2));
|
|
2690
|
+
color: var(--dsw-alias-label-primary, #334155);
|
|
2691
|
+
cursor: pointer;
|
|
2692
|
+
text-align: left;
|
|
2693
|
+
font-size: 12.5px;
|
|
2694
|
+
transition: all 0.15s ease;
|
|
2695
|
+
}
|
|
2696
|
+
.agy-tv-q-opt:hover {
|
|
2697
|
+
background: var(--dsw-alias-bg-hover, rgba(127, 127, 127, 0.15));
|
|
2698
|
+
border-color: var(--dsw-alias-border-l3, rgba(127, 127, 127, 0.35));
|
|
2699
|
+
}
|
|
2700
|
+
.agy-tv-q-opt.selected {
|
|
2701
|
+
background: rgba(16, 185, 129, 0.12);
|
|
2702
|
+
border-color: #10b981;
|
|
2703
|
+
color: #10b981;
|
|
2704
|
+
}
|
|
2705
|
+
.agy-tv-q-check {
|
|
2706
|
+
width: 14px;
|
|
2707
|
+
height: 14px;
|
|
2708
|
+
border: 1.5px solid currentColor;
|
|
2709
|
+
display: inline-flex;
|
|
2710
|
+
align-items: center;
|
|
2711
|
+
justify-content: center;
|
|
2712
|
+
flex-shrink: 0;
|
|
2713
|
+
}
|
|
2714
|
+
.agy-tv-q-check.radio {
|
|
2715
|
+
border-radius: 50%;
|
|
2716
|
+
}
|
|
2717
|
+
.agy-tv-q-check.checkbox {
|
|
2718
|
+
border-radius: 3px;
|
|
2719
|
+
}
|
|
2720
|
+
.agy-tv-q-check.checked:after {
|
|
2721
|
+
content: "";
|
|
2722
|
+
width: 6px;
|
|
2723
|
+
height: 6px;
|
|
2724
|
+
background: currentColor;
|
|
2725
|
+
border-radius: inherit;
|
|
2726
|
+
}
|
|
2727
|
+
.agy-tv-q-footer {
|
|
2728
|
+
display: flex;
|
|
2729
|
+
align-items: center;
|
|
2730
|
+
justify-content: space-between;
|
|
2731
|
+
padding-top: 6px;
|
|
2732
|
+
border-top: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.15));
|
|
2733
|
+
}
|
|
2734
|
+
.agy-tv-q-insert-btn {
|
|
2735
|
+
padding: 5px 12px;
|
|
2736
|
+
border-radius: 6px;
|
|
2737
|
+
font-size: 12px;
|
|
2738
|
+
font-weight: 600;
|
|
2739
|
+
background: rgba(16, 185, 129, 0.15);
|
|
2740
|
+
border: 1px solid #10b981;
|
|
2741
|
+
color: #10b981;
|
|
2742
|
+
cursor: pointer;
|
|
2743
|
+
transition: all 0.15s ease;
|
|
2744
|
+
}
|
|
2745
|
+
.agy-tv-q-insert-btn:disabled {
|
|
2746
|
+
opacity: 0.4;
|
|
2747
|
+
cursor: not-allowed;
|
|
2748
|
+
}
|
|
2749
|
+
.agy-tv-q-insert-btn:not(:disabled):hover {
|
|
2750
|
+
background: #10b981;
|
|
2751
|
+
color: #fff;
|
|
2752
|
+
}
|
|
2753
|
+
.agy-tv-q-answered {
|
|
2754
|
+
font-size: 11px;
|
|
2755
|
+
color: var(--dsw-alias-label-tertiary, #888);
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
/* Image Card Styles */
|
|
2759
|
+
.agy-tv-img-wrap {
|
|
2760
|
+
padding: 10px 14px;
|
|
2761
|
+
display: flex;
|
|
2762
|
+
flex-direction: column;
|
|
2763
|
+
gap: 8px;
|
|
2764
|
+
}
|
|
2765
|
+
.agy-tv-img-meta {
|
|
2766
|
+
display: flex;
|
|
2767
|
+
align-items: center;
|
|
2768
|
+
justify-content: space-between;
|
|
2769
|
+
gap: 8px;
|
|
2770
|
+
}
|
|
2771
|
+
.agy-tv-img-prompt {
|
|
2772
|
+
font-size: 12.5px;
|
|
2773
|
+
color: var(--dsw-alias-label-primary, #334155);
|
|
2774
|
+
font-style: italic;
|
|
2775
|
+
overflow: hidden;
|
|
2776
|
+
text-overflow: ellipsis;
|
|
2777
|
+
white-space: nowrap;
|
|
2778
|
+
}
|
|
2779
|
+
.agy-tv-img-badges {
|
|
2780
|
+
display: flex;
|
|
2781
|
+
gap: 4px;
|
|
2782
|
+
flex-shrink: 0;
|
|
2783
|
+
}
|
|
2784
|
+
.agy-tv-img-badge {
|
|
2785
|
+
font-size: 11px;
|
|
2786
|
+
padding: 1px 6px;
|
|
2787
|
+
border-radius: 4px;
|
|
2788
|
+
background: var(--dsw-alias-bg-l2, rgba(127, 127, 127, 0.1));
|
|
2789
|
+
border: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.2));
|
|
2790
|
+
color: var(--dsw-alias-label-secondary, #888);
|
|
2791
|
+
}
|
|
2792
|
+
.agy-tv-img-preview-box {
|
|
2793
|
+
max-height: 320px;
|
|
2794
|
+
overflow: hidden;
|
|
2795
|
+
border-radius: 6px;
|
|
2796
|
+
border: 1px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.2));
|
|
2797
|
+
display: flex;
|
|
2798
|
+
align-items: center;
|
|
2799
|
+
justify-content: center;
|
|
2800
|
+
background: repeating-conic-gradient(rgba(127,127,127,0.08) 0% 25%, transparent 0% 50%) 50% / 16px 16px;
|
|
2801
|
+
cursor: zoom-in;
|
|
2802
|
+
}
|
|
2803
|
+
.agy-tv-img-thumb {
|
|
2804
|
+
max-width: 100%;
|
|
2805
|
+
max-height: 320px;
|
|
2806
|
+
object-fit: contain;
|
|
2807
|
+
}
|
|
1698
2808
|
`;
|
|
1699
2809
|
const gDoc = globalThis.document;
|
|
1700
2810
|
if (gDoc !== void 0 && gDoc !== null) {
|
|
@@ -2147,15 +3257,26 @@ div[data-variant="think"] [class*="thinkBody"] {
|
|
|
2147
3257
|
const { createElement: h, useState, useEffect, useRef } = require("react");
|
|
2148
3258
|
const reactDom = require("react-dom");
|
|
2149
3259
|
const win = globalThis;
|
|
2150
|
-
const bodyEl = win.document?.body ?? null;
|
|
2151
3260
|
const portalToBody = (node) => {
|
|
2152
|
-
|
|
3261
|
+
const body = win.document?.body ?? (typeof document !== "undefined" ? document.body : null);
|
|
3262
|
+
if (body && reactDom && typeof reactDom.createPortal === "function") return reactDom.createPortal(node, body);
|
|
2153
3263
|
return node;
|
|
2154
3264
|
};
|
|
2155
3265
|
const name = "dsh-agy-link-client";
|
|
2156
3266
|
const inject = ["slots", "locale"];
|
|
2157
3267
|
const base = win.location?.origin ?? "";
|
|
2158
|
-
|
|
3268
|
+
const STATUS_CACHE_KEY = "dsh_agy_status_cache";
|
|
3269
|
+
function loadInitialStatusCache() {
|
|
3270
|
+
try {
|
|
3271
|
+
const raw = win.localStorage?.getItem(STATUS_CACHE_KEY);
|
|
3272
|
+
if (raw) {
|
|
3273
|
+
const parsed = JSON.parse(raw);
|
|
3274
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
3275
|
+
}
|
|
3276
|
+
} catch {}
|
|
3277
|
+
return null;
|
|
3278
|
+
}
|
|
3279
|
+
let statusCache = loadInitialStatusCache();
|
|
2159
3280
|
async function getStatus() {
|
|
2160
3281
|
try {
|
|
2161
3282
|
const init = {};
|
|
@@ -2194,8 +3315,20 @@ div[data-variant="think"] [class*="thinkBody"] {
|
|
|
2194
3315
|
const statusListeners = /* @__PURE__ */ new Set();
|
|
2195
3316
|
let statusPollTimer = null;
|
|
2196
3317
|
let statusFetchSeq = 0;
|
|
3318
|
+
function isStatusEqual(a, b) {
|
|
3319
|
+
if (a === b) return true;
|
|
3320
|
+
if (a === null || b === null) return false;
|
|
3321
|
+
try {
|
|
3322
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
3323
|
+
} catch {
|
|
3324
|
+
return false;
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
2197
3327
|
function notifyStatus(st) {
|
|
2198
3328
|
statusCache = st;
|
|
3329
|
+
try {
|
|
3330
|
+
win.localStorage?.setItem(STATUS_CACHE_KEY, JSON.stringify(st));
|
|
3331
|
+
} catch {}
|
|
2199
3332
|
for (const fn of [...statusListeners]) try {
|
|
2200
3333
|
fn(st);
|
|
2201
3334
|
} catch {}
|
|
@@ -2203,7 +3336,9 @@ div[data-variant="think"] [class*="thinkBody"] {
|
|
|
2203
3336
|
async function statusPollTick() {
|
|
2204
3337
|
const seq = ++statusFetchSeq;
|
|
2205
3338
|
const st = await getStatus();
|
|
2206
|
-
if (st !== null && seq === statusFetchSeq)
|
|
3339
|
+
if (st !== null && seq === statusFetchSeq) {
|
|
3340
|
+
if (!isStatusEqual(statusCache, st)) notifyStatus(st);
|
|
3341
|
+
}
|
|
2207
3342
|
}
|
|
2208
3343
|
function ensureStatusPolling() {
|
|
2209
3344
|
if (statusPollTimer !== null) return;
|
|
@@ -2259,6 +3394,21 @@ div[data-variant="think"] [class*="thinkBody"] {
|
|
|
2259
3394
|
}
|
|
2260
3395
|
};
|
|
2261
3396
|
/**
|
|
3397
|
+
* Singleton modal instance manager: ensures at most one modal dialog is
|
|
3398
|
+
* rendered into document.body at any time even when multiple session headers mount.
|
|
3399
|
+
*/
|
|
3400
|
+
let primaryModalInstanceId = null;
|
|
3401
|
+
const modalInstanceIds = /* @__PURE__ */ new Set();
|
|
3402
|
+
function registerModalInstance(id) {
|
|
3403
|
+
modalInstanceIds.add(id);
|
|
3404
|
+
if (primaryModalInstanceId === null || !modalInstanceIds.has(primaryModalInstanceId)) primaryModalInstanceId = id;
|
|
3405
|
+
return primaryModalInstanceId === id;
|
|
3406
|
+
}
|
|
3407
|
+
function unregisterModalInstance(id) {
|
|
3408
|
+
modalInstanceIds.delete(id);
|
|
3409
|
+
if (primaryModalInstanceId === id) primaryModalInstanceId = modalInstanceIds.values().next().value ?? null;
|
|
3410
|
+
}
|
|
3411
|
+
/**
|
|
2262
3412
|
* Format reset timestamp into readable date/time + relative countdown.
|
|
2263
3413
|
*/
|
|
2264
3414
|
function formatQuotaWindow(t, resetTimeStr) {
|
|
@@ -2632,12 +3782,13 @@ body.dark,
|
|
|
2632
3782
|
border-radius: 50%;
|
|
2633
3783
|
}
|
|
2634
3784
|
.agy-card-hover {
|
|
2635
|
-
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.
|
|
3785
|
+
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s ease;
|
|
2636
3786
|
}
|
|
2637
3787
|
.agy-card-hover:hover {
|
|
2638
3788
|
border-color: var(--agy-border-card-primary, #3b82f6) !important;
|
|
2639
3789
|
box-shadow: var(--agy-shadow-card-hover) !important;
|
|
2640
3790
|
}
|
|
3791
|
+
|
|
2641
3792
|
.agy-btn {
|
|
2642
3793
|
transition: all 0.15s ease;
|
|
2643
3794
|
user-select: none;
|
|
@@ -2692,6 +3843,17 @@ body.dark,
|
|
|
2692
3843
|
color: var(--agy-text-primary);
|
|
2693
3844
|
}
|
|
2694
3845
|
`;
|
|
3846
|
+
function injectGlobalStyles() {
|
|
3847
|
+
if (typeof document === "undefined") return;
|
|
3848
|
+
const styleId = "dsh-agy-link-global-css";
|
|
3849
|
+
if (document.getElementById(styleId) === null) {
|
|
3850
|
+
const st = document.createElement("style");
|
|
3851
|
+
st.id = styleId;
|
|
3852
|
+
st.textContent = GLOBAL_CSS;
|
|
3853
|
+
const host = document.head ?? document.documentElement;
|
|
3854
|
+
if (host) host.appendChild(st);
|
|
3855
|
+
}
|
|
3856
|
+
}
|
|
2695
3857
|
const S = {
|
|
2696
3858
|
container: {
|
|
2697
3859
|
lineHeight: 1.5,
|
|
@@ -2762,27 +3924,29 @@ body.dark,
|
|
|
2762
3924
|
card: {
|
|
2763
3925
|
background: "var(--agy-bg-card)",
|
|
2764
3926
|
border: "1px solid var(--agy-border-card)",
|
|
2765
|
-
borderRadius: "
|
|
2766
|
-
padding: "14px
|
|
2767
|
-
marginBottom: "
|
|
3927
|
+
borderRadius: "8px",
|
|
3928
|
+
padding: "10px 14px",
|
|
3929
|
+
marginBottom: "8px",
|
|
2768
3930
|
color: "var(--agy-text-primary)",
|
|
2769
|
-
boxShadow: "var(--agy-shadow-card)"
|
|
3931
|
+
boxShadow: "var(--agy-shadow-card)",
|
|
3932
|
+
transition: "all 0.18s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
2770
3933
|
},
|
|
2771
3934
|
cardPrimary: {
|
|
2772
|
-
background: "var(--agy-bg-card
|
|
2773
|
-
border: "
|
|
2774
|
-
borderRadius: "
|
|
2775
|
-
padding: "14px
|
|
2776
|
-
marginBottom: "
|
|
2777
|
-
|
|
2778
|
-
|
|
3935
|
+
background: "var(--agy-bg-card)",
|
|
3936
|
+
border: "1px solid var(--agy-border-card)",
|
|
3937
|
+
borderRadius: "8px",
|
|
3938
|
+
padding: "10px 14px",
|
|
3939
|
+
marginBottom: "8px",
|
|
3940
|
+
color: "var(--agy-text-primary)",
|
|
3941
|
+
boxShadow: "var(--agy-shadow-card)",
|
|
3942
|
+
transition: "all 0.18s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
2779
3943
|
},
|
|
2780
3944
|
quotaBox: {
|
|
2781
3945
|
background: "var(--agy-bg-box)",
|
|
2782
3946
|
border: "1px solid var(--agy-border-box)",
|
|
2783
3947
|
borderRadius: "8px",
|
|
2784
3948
|
padding: "8px 10px",
|
|
2785
|
-
marginTop: "
|
|
3949
|
+
marginTop: "8px"
|
|
2786
3950
|
},
|
|
2787
3951
|
progressBarBg: {
|
|
2788
3952
|
flex: "1",
|
|
@@ -2952,6 +4116,7 @@ body.dark,
|
|
|
2952
4116
|
return locale.bind(NS);
|
|
2953
4117
|
};
|
|
2954
4118
|
const AgySettingsSection = (props) => {
|
|
4119
|
+
injectGlobalStyles();
|
|
2955
4120
|
const t = useAgyTranslation();
|
|
2956
4121
|
const { status, refresh } = useAgyStatus();
|
|
2957
4122
|
const [aliasInput, setAliasInput] = useState("");
|
|
@@ -2962,6 +4127,7 @@ body.dark,
|
|
|
2962
4127
|
const [loadingAction, setLoadingAction] = useState(null);
|
|
2963
4128
|
const [toast, setToast] = useState(null);
|
|
2964
4129
|
const [expandedModels, setExpandedModels] = useState({});
|
|
4130
|
+
const [addProxyInput, setAddProxyInput] = useState("");
|
|
2965
4131
|
const [, setTimeTick] = useState(0);
|
|
2966
4132
|
useEffect(() => {
|
|
2967
4133
|
const timer = setInterval(() => setTimeTick((n) => n + 1), 3e4);
|
|
@@ -2981,6 +4147,7 @@ body.dark,
|
|
|
2981
4147
|
setAddingAccount(false);
|
|
2982
4148
|
setAuthCodeInput("");
|
|
2983
4149
|
setAliasInput("");
|
|
4150
|
+
setAddProxyInput("");
|
|
2984
4151
|
showToast(safeMessage(pa.code), "success");
|
|
2985
4152
|
} else if (pa.phase === "failed") {
|
|
2986
4153
|
flowStartedRef.current = false;
|
|
@@ -3013,7 +4180,11 @@ body.dark,
|
|
|
3013
4180
|
const handleBeginAddAccount = async () => {
|
|
3014
4181
|
setLoadingAction("pool:beginAdd");
|
|
3015
4182
|
const alias = aliasInput.trim();
|
|
3016
|
-
const
|
|
4183
|
+
const proxyUrl = addProxyInput.trim();
|
|
4184
|
+
const res = await postJson("/plugins/agy-link/pool/begin-add", {
|
|
4185
|
+
...alias ? { alias } : {},
|
|
4186
|
+
...proxyUrl ? { proxyUrl } : {}
|
|
4187
|
+
});
|
|
3017
4188
|
setLoadingAction(null);
|
|
3018
4189
|
if (res && res.ok) {
|
|
3019
4190
|
flowStartedRef.current = true;
|
|
@@ -3031,6 +4202,7 @@ body.dark,
|
|
|
3031
4202
|
flowStartedRef.current = false;
|
|
3032
4203
|
setAuthCodeInput("");
|
|
3033
4204
|
setAliasInput("");
|
|
4205
|
+
setAddProxyInput("");
|
|
3034
4206
|
setAddingAccount(false);
|
|
3035
4207
|
await refresh();
|
|
3036
4208
|
showToast(safeMessage(res.code), "success");
|
|
@@ -3041,9 +4213,29 @@ body.dark,
|
|
|
3041
4213
|
await postJson("/plugins/agy-link/pool/cancel-add", {});
|
|
3042
4214
|
setAuthCodeInput("");
|
|
3043
4215
|
setAliasInput("");
|
|
4216
|
+
setAddProxyInput("");
|
|
3044
4217
|
setAddingAccount(false);
|
|
3045
4218
|
await refresh();
|
|
3046
4219
|
};
|
|
4220
|
+
const reorderAccounts = async (newIds) => {
|
|
4221
|
+
setLoadingAction("pool:reorder");
|
|
4222
|
+
const res = await postJson("/plugins/agy-link/pool/reorder", { ids: newIds });
|
|
4223
|
+
setLoadingAction(null);
|
|
4224
|
+
if (res && res.ok) {
|
|
4225
|
+
await refresh();
|
|
4226
|
+
showToast(t("account.reordered"), "success");
|
|
4227
|
+
} else actionFailed();
|
|
4228
|
+
};
|
|
4229
|
+
const moveAccount = async (accId, delta) => {
|
|
4230
|
+
const ids = (status?.pool?.accounts ?? []).map((a) => a.id);
|
|
4231
|
+
const idx = ids.indexOf(accId);
|
|
4232
|
+
if (idx === -1) return;
|
|
4233
|
+
const newIdx = idx + delta;
|
|
4234
|
+
if (newIdx < 0 || newIdx >= ids.length) return;
|
|
4235
|
+
const [moved] = ids.splice(idx, 1);
|
|
4236
|
+
if (moved) ids.splice(newIdx, 0, moved);
|
|
4237
|
+
await reorderAccounts(ids);
|
|
4238
|
+
};
|
|
3047
4239
|
const setCfg = async (key, value) => {
|
|
3048
4240
|
setLoadingAction(`config:${key}`);
|
|
3049
4241
|
const res = await postJson("/plugins/agy-link/config", {
|
|
@@ -3312,9 +4504,15 @@ body.dark,
|
|
|
3312
4504
|
const dotColor = !acc.enabled ? "#64748b" : isAuthRequired ? "#ef4444" : hasCooldown ? "#f59e0b" : "#10b981";
|
|
3313
4505
|
const isEditingProxy = editingProxyId === acc.id;
|
|
3314
4506
|
const isExpanded = expandedModels[acc.id] ?? false;
|
|
3315
|
-
const
|
|
4507
|
+
const accIndex = accounts.indexOf(acc);
|
|
4508
|
+
const cardStyle = {
|
|
4509
|
+
...S.card,
|
|
4510
|
+
cursor: "default",
|
|
4511
|
+
padding: "10px 14px",
|
|
4512
|
+
marginBottom: "8px"
|
|
4513
|
+
};
|
|
3316
4514
|
const legacyDefault = acc.defaultAlias === void 0 && acc.systemHome && acc.alias === "主账号 (系统登录)";
|
|
3317
|
-
const displayAlias = acc.defaultAlias || legacyDefault ? acc.systemHome ? t("account.defaultAlias") : t("account.aliasDefault", { number:
|
|
4515
|
+
const displayAlias = acc.defaultAlias || legacyDefault ? acc.systemHome ? t("account.defaultAlias") : t("account.aliasDefault", { number: accIndex + 1 }) : acc.alias;
|
|
3318
4516
|
const googleModels = acc.quotas.google?.models ?? [];
|
|
3319
4517
|
const anthropicModels = acc.quotas.anthropic?.models ?? [];
|
|
3320
4518
|
const openaiModels = acc.quotas.openai?.models ?? [];
|
|
@@ -3340,155 +4538,278 @@ body.dark,
|
|
|
3340
4538
|
display: "flex",
|
|
3341
4539
|
alignItems: "center",
|
|
3342
4540
|
justifyContent: "space-between",
|
|
4541
|
+
userSelect: "none",
|
|
4542
|
+
gap: "8px",
|
|
3343
4543
|
marginBottom: "8px"
|
|
3344
4544
|
} }, h("div", { style: {
|
|
3345
4545
|
display: "flex",
|
|
3346
4546
|
alignItems: "center",
|
|
3347
|
-
gap: "
|
|
3348
|
-
flexWrap: "wrap"
|
|
4547
|
+
gap: "6px",
|
|
4548
|
+
flexWrap: "wrap",
|
|
4549
|
+
flex: "1",
|
|
4550
|
+
minWidth: 0
|
|
3349
4551
|
} }, h("span", {
|
|
4552
|
+
style: {
|
|
4553
|
+
...S.badgeTag,
|
|
4554
|
+
fontWeight: 700,
|
|
4555
|
+
fontSize: "10.5px",
|
|
4556
|
+
padding: "1px 5px",
|
|
4557
|
+
background: isPrimary ? "var(--agy-badge-primary-bg)" : "var(--agy-badge-tag-bg)",
|
|
4558
|
+
color: isPrimary ? "var(--agy-badge-primary-text)" : "var(--agy-badge-tag-text)",
|
|
4559
|
+
borderColor: isPrimary ? "var(--agy-badge-primary-border)" : "var(--agy-badge-tag-border)"
|
|
4560
|
+
},
|
|
4561
|
+
title: `优先级 #${accIndex + 1}`
|
|
4562
|
+
}, `#${accIndex + 1}`), accounts.length > 1 ? h("div", { style: {
|
|
4563
|
+
display: "inline-flex",
|
|
4564
|
+
gap: "2px",
|
|
4565
|
+
alignItems: "center"
|
|
4566
|
+
} }, accIndex > 0 ? h("button", {
|
|
4567
|
+
type: "button",
|
|
4568
|
+
className: "agy-btn",
|
|
4569
|
+
style: {
|
|
4570
|
+
...S.btnSm,
|
|
4571
|
+
padding: "1px 4px",
|
|
4572
|
+
fontSize: "10px",
|
|
4573
|
+
lineHeight: 1,
|
|
4574
|
+
height: "18px"
|
|
4575
|
+
},
|
|
4576
|
+
title: t("account.moveUp"),
|
|
4577
|
+
onClick: () => void moveAccount(acc.id, -1)
|
|
4578
|
+
}, uiIcon("arrowUp", 10)) : null, accIndex < accounts.length - 1 ? h("button", {
|
|
4579
|
+
type: "button",
|
|
4580
|
+
className: "agy-btn",
|
|
4581
|
+
style: {
|
|
4582
|
+
...S.btnSm,
|
|
4583
|
+
padding: "1px 4px",
|
|
4584
|
+
fontSize: "10px",
|
|
4585
|
+
lineHeight: 1,
|
|
4586
|
+
height: "18px"
|
|
4587
|
+
},
|
|
4588
|
+
title: t("account.moveDown"),
|
|
4589
|
+
onClick: () => void moveAccount(acc.id, 1)
|
|
4590
|
+
}, uiIcon("arrowDown", 10)) : null) : null, h("span", {
|
|
3350
4591
|
className: "agy-pulse-dot",
|
|
3351
4592
|
style: {
|
|
3352
4593
|
background: dotColor,
|
|
3353
|
-
boxShadow: `0 0
|
|
4594
|
+
boxShadow: `0 0 6px ${dotColor}aa`,
|
|
4595
|
+
marginLeft: "1px"
|
|
3354
4596
|
}
|
|
3355
|
-
}), h("span", {
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
4597
|
+
}), h("span", {
|
|
4598
|
+
style: {
|
|
4599
|
+
fontWeight: 700,
|
|
4600
|
+
fontSize: "13px",
|
|
4601
|
+
color: "var(--agy-text-primary)",
|
|
4602
|
+
whiteSpace: "nowrap"
|
|
4603
|
+
},
|
|
4604
|
+
title: displayAlias
|
|
4605
|
+
}, displayAlias), h("span", { style: {
|
|
4606
|
+
...S.badgeTag,
|
|
4607
|
+
background: "rgba(59, 130, 246, 0.12)",
|
|
4608
|
+
color: "#3b82f6",
|
|
4609
|
+
borderColor: "rgba(59, 130, 246, 0.35)",
|
|
4610
|
+
fontSize: "10px",
|
|
4611
|
+
padding: "1px 5px",
|
|
4612
|
+
fontWeight: 700
|
|
4613
|
+
} }, "AGY"), isAuthRequired ? h("span", { style: {
|
|
3360
4614
|
...S.badgeTag,
|
|
3361
4615
|
background: "var(--agy-badge-email-bg)",
|
|
3362
4616
|
color: "#ef4444",
|
|
3363
4617
|
borderColor: "#fca5a5",
|
|
3364
|
-
gap: "
|
|
4618
|
+
gap: "3px",
|
|
4619
|
+
fontSize: "10px",
|
|
4620
|
+
padding: "1px 5px",
|
|
3365
4621
|
fontWeight: 700
|
|
3366
|
-
} }, uiIcon("alert",
|
|
4622
|
+
} }, uiIcon("alert", 10, "#ef4444"), t("status.authRequired")) : null, hasCooldown ? h("span", { style: {
|
|
3367
4623
|
...S.badgeTag,
|
|
3368
|
-
background: "
|
|
3369
|
-
color: "
|
|
3370
|
-
borderColor: "
|
|
3371
|
-
gap: "
|
|
3372
|
-
|
|
4624
|
+
background: "rgba(245, 158, 11, 0.15)",
|
|
4625
|
+
color: "#f59e0b",
|
|
4626
|
+
borderColor: "rgba(245, 158, 11, 0.4)",
|
|
4627
|
+
gap: "3px",
|
|
4628
|
+
fontSize: "10px",
|
|
4629
|
+
padding: "1px 5px",
|
|
4630
|
+
fontWeight: 700
|
|
4631
|
+
} }, uiIcon("alert", 10, "#f59e0b"), "冷却中") : null, acc.email ? h("span", {
|
|
4632
|
+
style: {
|
|
4633
|
+
...S.badgeTag,
|
|
4634
|
+
background: "var(--agy-badge-email-bg)",
|
|
4635
|
+
color: "var(--agy-badge-email-text)",
|
|
4636
|
+
borderColor: "var(--agy-badge-email-border)",
|
|
4637
|
+
gap: "4px",
|
|
4638
|
+
fontSize: "11px",
|
|
4639
|
+
padding: "1px 6px",
|
|
4640
|
+
whiteSpace: "nowrap"
|
|
4641
|
+
},
|
|
4642
|
+
title: acc.email
|
|
4643
|
+
}, uiIcon("mail", 10, "var(--agy-badge-email-text)"), acc.email) : null, isPrimary ? h("span", { style: {
|
|
3373
4644
|
...S.badgePrimary,
|
|
3374
|
-
gap: "
|
|
4645
|
+
gap: "3px",
|
|
4646
|
+
fontSize: "10.5px",
|
|
4647
|
+
padding: "1px 5px"
|
|
3375
4648
|
} }, uiIcon("star", 10, "var(--agy-badge-primary-text)"), t("status.primary")) : null, isInUse ? h("span", {
|
|
3376
4649
|
style: {
|
|
3377
4650
|
...S.badgeTag,
|
|
3378
4651
|
background: "rgba(16, 185, 129, 0.12)",
|
|
3379
4652
|
color: "#10b981",
|
|
3380
4653
|
borderColor: "rgba(16, 185, 129, 0.45)",
|
|
3381
|
-
gap: "
|
|
4654
|
+
gap: "3px",
|
|
4655
|
+
fontSize: "10px",
|
|
4656
|
+
padding: "1px 5px",
|
|
3382
4657
|
fontWeight: 700
|
|
3383
4658
|
},
|
|
3384
4659
|
title: t("status.inUse")
|
|
3385
|
-
}, uiIcon("zap",
|
|
4660
|
+
}, uiIcon("zap", 10, "#10b981"), t("status.inUse")) : null, acc.proxyUrl ? h("span", { style: {
|
|
3386
4661
|
...S.badgeTag,
|
|
3387
4662
|
background: "var(--agy-badge-proxy-bg)",
|
|
3388
4663
|
color: "var(--agy-badge-proxy-text)",
|
|
3389
4664
|
borderColor: "var(--agy-badge-proxy-border)",
|
|
3390
|
-
gap: "
|
|
3391
|
-
|
|
4665
|
+
gap: "4px",
|
|
4666
|
+
fontSize: "10px",
|
|
4667
|
+
padding: "1px 5px"
|
|
4668
|
+
} }, uiIcon("globe", 10, "var(--agy-badge-proxy-text)"), t("status.proxy")) : null), h("div", { style: {
|
|
3392
4669
|
display: "flex",
|
|
3393
|
-
gap: "
|
|
3394
|
-
alignItems: "center"
|
|
3395
|
-
|
|
4670
|
+
gap: "4px",
|
|
4671
|
+
alignItems: "center",
|
|
4672
|
+
flexShrink: 0
|
|
4673
|
+
} }, h("button", {
|
|
3396
4674
|
type: "button",
|
|
3397
4675
|
className: "agy-btn",
|
|
3398
4676
|
style: isExpanded ? {
|
|
3399
4677
|
...S.btnSmPrimary,
|
|
3400
|
-
gap: "3px"
|
|
4678
|
+
gap: "3px",
|
|
4679
|
+
fontSize: "11px",
|
|
4680
|
+
padding: "2px 6px"
|
|
3401
4681
|
} : {
|
|
3402
4682
|
...S.btnSm,
|
|
3403
|
-
gap: "3px"
|
|
4683
|
+
gap: "3px",
|
|
4684
|
+
fontSize: "11px",
|
|
4685
|
+
padding: "2px 6px"
|
|
3404
4686
|
},
|
|
3405
4687
|
onClick: () => toggleExpand(acc.id)
|
|
3406
|
-
}, isExpanded ? [uiIcon("chevronUp",
|
|
4688
|
+
}, isExpanded ? [uiIcon("chevronUp", 10), ` ${t("account.collapse")}`] : [uiIcon("chevronDown", 10), ` ${t("account.otherModels")}`]), h("button", {
|
|
3407
4689
|
type: "button",
|
|
3408
4690
|
className: "agy-btn",
|
|
3409
4691
|
style: {
|
|
3410
4692
|
...S.btnSm,
|
|
3411
|
-
gap: "
|
|
4693
|
+
gap: "3px",
|
|
4694
|
+
fontSize: "11px",
|
|
4695
|
+
padding: "2px 6px"
|
|
3412
4696
|
},
|
|
3413
4697
|
title: t("account.syncTitle"),
|
|
3414
4698
|
disabled: isBusy,
|
|
3415
4699
|
onClick: () => void refreshQuota(acc.id)
|
|
3416
|
-
}, loadingAction === `refresh:${acc.id}` ? [renderSpinner(), t("account.syncing")] : [uiIcon("refresh",
|
|
4700
|
+
}, loadingAction === `refresh:${acc.id}` ? [renderSpinner(), t("account.syncing")] : [uiIcon("refresh", 10), ` ${t("account.sync")}`]), !isPrimary ? h("button", {
|
|
3417
4701
|
type: "button",
|
|
3418
4702
|
className: "agy-btn",
|
|
3419
4703
|
style: {
|
|
3420
4704
|
...S.btnSm,
|
|
3421
|
-
gap: "
|
|
4705
|
+
gap: "3px",
|
|
4706
|
+
fontSize: "11px",
|
|
4707
|
+
padding: "2px 6px"
|
|
3422
4708
|
},
|
|
3423
4709
|
disabled: isBusy,
|
|
3424
4710
|
onClick: () => void setPrimary(acc.id)
|
|
3425
|
-
}, loadingAction === `primary:${acc.id}` ? [renderSpinner(), t("account.settingPrimary")] : [uiIcon("star",
|
|
4711
|
+
}, loadingAction === `primary:${acc.id}` ? [renderSpinner(), t("account.settingPrimary")] : [uiIcon("star", 10), ` ${t("account.setPrimary")}`]) : null, h("button", {
|
|
3426
4712
|
type: "button",
|
|
3427
4713
|
className: "agy-btn",
|
|
3428
4714
|
style: isEditingProxy ? {
|
|
3429
4715
|
...S.btnSmPrimary,
|
|
3430
|
-
gap: "
|
|
4716
|
+
gap: "3px",
|
|
4717
|
+
fontSize: "11px",
|
|
4718
|
+
padding: "2px 6px"
|
|
3431
4719
|
} : {
|
|
3432
4720
|
...S.btnSm,
|
|
3433
|
-
gap: "
|
|
4721
|
+
gap: "3px",
|
|
4722
|
+
fontSize: "11px",
|
|
4723
|
+
padding: "2px 6px"
|
|
3434
4724
|
},
|
|
3435
4725
|
disabled: isBusy,
|
|
3436
4726
|
onClick: () => setEditingProxyId(isEditingProxy ? null : acc.id)
|
|
3437
|
-
}, [uiIcon("globe",
|
|
4727
|
+
}, [uiIcon("globe", 10), ` ${t("proxy.button")}`]), accounts.length > 1 ? h("button", {
|
|
3438
4728
|
type: "button",
|
|
3439
4729
|
className: "agy-btn",
|
|
3440
4730
|
style: {
|
|
3441
4731
|
...S.btnDanger,
|
|
3442
|
-
padding: "
|
|
4732
|
+
padding: "2px 6px",
|
|
4733
|
+
fontSize: "11px"
|
|
3443
4734
|
},
|
|
3444
4735
|
title: t("account.removeTitle"),
|
|
3445
4736
|
"aria-label": t("account.removeTitle"),
|
|
3446
4737
|
disabled: isBusy,
|
|
3447
4738
|
onClick: () => void removeAccount(acc.id, displayAlias)
|
|
3448
|
-
}, loadingAction === `remove:${acc.id}` ? renderSpinner() : uiIcon("trash",
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
fontSize: "11px"
|
|
3457
|
-
} }, t("account.models")), allChildModels.map(({ family, model }) => {
|
|
3458
|
-
const frac = model.remainingFraction ?? 1;
|
|
3459
|
-
const pct = Math.round(frac * 100);
|
|
3460
|
-
const w = formatQuotaWindow(t, model.resetTime);
|
|
3461
|
-
const pColor = pct <= 20 ? "var(--agy-quota-low-text)" : pct <= 50 ? "var(--agy-quota-med-text)" : "var(--agy-quota-high-text)";
|
|
3462
|
-
return h("div", {
|
|
3463
|
-
key: model.modelId,
|
|
3464
|
-
className: "agy-submodel-row"
|
|
3465
|
-
}, h("span", { style: {
|
|
3466
|
-
fontWeight: 500,
|
|
3467
|
-
color: "var(--agy-text-primary)"
|
|
3468
|
-
} }, `[${family}] ${model.displayName || model.modelId}`), h("div", { style: {
|
|
4739
|
+
}, loadingAction === `remove:${acc.id}` ? renderSpinner() : uiIcon("trash", 11, "var(--agy-danger-text)")) : null)), h("div", {
|
|
4740
|
+
key: "agy-body",
|
|
4741
|
+
style: S.quotaBox
|
|
4742
|
+
}, renderQuotaBar("Gemini", "google", acc), h("button", {
|
|
4743
|
+
type: "button",
|
|
4744
|
+
className: "agy-btn",
|
|
4745
|
+
style: {
|
|
4746
|
+
width: "100%",
|
|
3469
4747
|
display: "flex",
|
|
3470
4748
|
alignItems: "center",
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
4749
|
+
justifyContent: "center",
|
|
4750
|
+
gap: "5px",
|
|
4751
|
+
marginTop: "6px",
|
|
4752
|
+
padding: "5px 10px",
|
|
4753
|
+
fontSize: "11px",
|
|
4754
|
+
fontWeight: 600,
|
|
4755
|
+
cursor: "pointer",
|
|
4756
|
+
color: isExpanded ? "var(--dsw-alias-state-business-primary, #3b82f6)" : "var(--agy-text-secondary)",
|
|
4757
|
+
background: "var(--agy-bg-subbox)",
|
|
4758
|
+
border: "1px dashed var(--agy-border-box)",
|
|
4759
|
+
borderRadius: "6px"
|
|
4760
|
+
},
|
|
4761
|
+
onClick: () => toggleExpand(acc.id)
|
|
4762
|
+
}, uiIcon(isExpanded ? "chevronUp" : "chevronDown", 10), h("span", null, isExpanded ? t("account.collapseOthers") : t("account.expandOthers"))), isExpanded ? [
|
|
4763
|
+
renderQuotaBar("Claude", "anthropic", acc),
|
|
4764
|
+
renderQuotaBar("GPT-OSS", "openai", acc),
|
|
4765
|
+
allChildModels.length > 0 ? h("div", { style: {
|
|
4766
|
+
marginTop: "8px",
|
|
4767
|
+
paddingTop: "8px",
|
|
4768
|
+
borderTop: "1px solid var(--agy-border-box)"
|
|
4769
|
+
} }, h("div", { style: {
|
|
4770
|
+
color: "var(--agy-text-secondary)",
|
|
4771
|
+
marginBottom: "6px",
|
|
4772
|
+
fontWeight: 600,
|
|
4773
|
+
fontSize: "11px"
|
|
4774
|
+
} }, t("account.models")), allChildModels.map(({ family, model }) => {
|
|
4775
|
+
const frac = model.remainingFraction ?? 1;
|
|
4776
|
+
const pct = Math.round(frac * 100);
|
|
4777
|
+
const w = formatQuotaWindow(t, model.resetTime);
|
|
4778
|
+
const pColor = pct <= 20 ? "var(--agy-quota-low-text)" : pct <= 50 ? "var(--agy-quota-med-text)" : "var(--agy-quota-high-text)";
|
|
4779
|
+
return h("div", {
|
|
4780
|
+
key: `${family}-${model.modelId}`,
|
|
4781
|
+
className: "agy-submodel-row"
|
|
4782
|
+
}, h("span", { style: {
|
|
4783
|
+
fontWeight: 500,
|
|
4784
|
+
color: "var(--agy-text-primary)"
|
|
4785
|
+
} }, `[${family}] ${model.displayName || model.modelId}`), h("div", { style: {
|
|
4786
|
+
display: "flex",
|
|
4787
|
+
alignItems: "center",
|
|
4788
|
+
gap: "8px"
|
|
4789
|
+
} }, h("span", { style: {
|
|
4790
|
+
color: pColor,
|
|
4791
|
+
fontWeight: 700
|
|
4792
|
+
} }, `${pct}%`), w.resetText ? h("span", { style: {
|
|
4793
|
+
color: "var(--agy-text-tertiary)",
|
|
4794
|
+
fontSize: "10.5px"
|
|
4795
|
+
} }, `↻ ${w.resetText}`) : null));
|
|
4796
|
+
})) : null
|
|
4797
|
+
] : null), hasCooldown ? h("div", {
|
|
4798
|
+
key: "cd-body",
|
|
4799
|
+
style: {
|
|
4800
|
+
background: "var(--agy-warn-bg)",
|
|
4801
|
+
border: "1px solid var(--agy-warn-border)",
|
|
4802
|
+
borderRadius: "7px",
|
|
4803
|
+
padding: "6px 10px",
|
|
4804
|
+
color: "var(--agy-warn-text)",
|
|
4805
|
+
fontSize: "11.5px",
|
|
4806
|
+
fontWeight: 600,
|
|
4807
|
+
marginTop: "8px",
|
|
4808
|
+
display: "flex",
|
|
4809
|
+
alignItems: "center",
|
|
4810
|
+
justifyContent: "space-between"
|
|
4811
|
+
}
|
|
4812
|
+
}, h("div", { style: {
|
|
3492
4813
|
display: "flex",
|
|
3493
4814
|
alignItems: "center",
|
|
3494
4815
|
gap: "6px"
|
|
@@ -3504,13 +4825,16 @@ body.dark,
|
|
|
3504
4825
|
},
|
|
3505
4826
|
disabled: isBusy,
|
|
3506
4827
|
onClick: () => void clearCooldown(acc.id)
|
|
3507
|
-
}, loadingAction === `clearCooldown:${acc.id}` ? [renderSpinner(), ""] : [uiIcon("zap", 11, "var(--agy-warn-btn-text)"), ` ${t("account.clearCooldown")}`])) : null, isEditingProxy ? h("div", {
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
4828
|
+
}, loadingAction === `clearCooldown:${acc.id}` ? [renderSpinner(), ""] : [uiIcon("zap", 11, "var(--agy-warn-btn-text)"), ` ${t("account.clearCooldown")}`])) : null, isEditingProxy ? h("div", {
|
|
4829
|
+
key: "proxy-body",
|
|
4830
|
+
style: {
|
|
4831
|
+
marginTop: "8px",
|
|
4832
|
+
padding: "10px 12px",
|
|
4833
|
+
background: "var(--agy-bg-subbox)",
|
|
4834
|
+
borderRadius: "7px",
|
|
4835
|
+
border: "1px solid var(--agy-border-subbox)"
|
|
4836
|
+
}
|
|
4837
|
+
}, h("div", { style: {
|
|
3514
4838
|
display: "flex",
|
|
3515
4839
|
gap: "8px"
|
|
3516
4840
|
} }, h("input", {
|
|
@@ -3543,23 +4867,40 @@ body.dark,
|
|
|
3543
4867
|
role: "group",
|
|
3544
4868
|
"aria-label": t("account.add")
|
|
3545
4869
|
}, h("div", { style: {
|
|
4870
|
+
display: "flex",
|
|
4871
|
+
alignItems: "center",
|
|
4872
|
+
justifyContent: "space-between",
|
|
4873
|
+
marginBottom: "12px",
|
|
4874
|
+
flexWrap: "wrap",
|
|
4875
|
+
gap: "8px"
|
|
4876
|
+
} }, h("div", { style: {
|
|
3546
4877
|
fontWeight: 700,
|
|
3547
4878
|
fontSize: "13.5px",
|
|
3548
|
-
marginBottom: "10px",
|
|
3549
4879
|
display: "flex",
|
|
3550
4880
|
alignItems: "center",
|
|
3551
4881
|
gap: "6px",
|
|
3552
4882
|
color: "var(--agy-text-primary)"
|
|
3553
|
-
} }, uiIcon("plus", 13, "var(--agy-btn-primary-bg)"), t("account.add")), !flowActive ? h("div", null, h("div", { style: {
|
|
4883
|
+
} }, uiIcon("plus", 13, "var(--agy-btn-primary-bg)"), t("account.add"))), !flowActive ? h("div", null, h("div", { style: {
|
|
3554
4884
|
display: "flex",
|
|
3555
|
-
|
|
4885
|
+
flexDirection: "column",
|
|
4886
|
+
gap: "8px",
|
|
4887
|
+
marginBottom: "12px"
|
|
3556
4888
|
} }, h("input", {
|
|
3557
4889
|
style: S.input,
|
|
3558
4890
|
value: aliasInput,
|
|
3559
4891
|
placeholder: t("account.aliasPlaceholder"),
|
|
3560
4892
|
"aria-label": t("aria.aliasInput"),
|
|
3561
4893
|
onChange: (e) => setAliasInput(e.target.value)
|
|
3562
|
-
}), h("
|
|
4894
|
+
}), h("input", {
|
|
4895
|
+
style: S.input,
|
|
4896
|
+
value: addProxyInput,
|
|
4897
|
+
placeholder: t("account.proxyPlaceholder"),
|
|
4898
|
+
"aria-label": t("aria.proxyInput"),
|
|
4899
|
+
onChange: (e) => setAddProxyInput(e.target.value)
|
|
4900
|
+
})), h("div", { style: {
|
|
4901
|
+
display: "flex",
|
|
4902
|
+
gap: "8px"
|
|
4903
|
+
} }, h("button", {
|
|
3563
4904
|
type: "button",
|
|
3564
4905
|
className: "agy-btn",
|
|
3565
4906
|
style: {
|
|
@@ -3635,8 +4976,8 @@ body.dark,
|
|
|
3635
4976
|
display: "flex",
|
|
3636
4977
|
alignItems: "center",
|
|
3637
4978
|
justifyContent: "center"
|
|
3638
|
-
} }, h("
|
|
3639
|
-
return h("div", { style: S.container }, h("
|
|
4979
|
+
} }, h("span", { style: S.muted }, [renderSpinner(), t("status.loading")]));
|
|
4980
|
+
return h("div", { style: S.container }, h("div", { style: S.headerCard }, h("div", { style: {
|
|
3640
4981
|
display: "flex",
|
|
3641
4982
|
alignItems: "center",
|
|
3642
4983
|
gap: "8px"
|
|
@@ -3665,21 +5006,21 @@ body.dark,
|
|
|
3665
5006
|
},
|
|
3666
5007
|
disabled: isBusy,
|
|
3667
5008
|
onClick: () => void refreshQuota()
|
|
3668
|
-
}, loadingAction === "refresh:all" ? [renderSpinner(), t("header.refreshing")] : [uiIcon("refresh", 12, "var(--agy-text-btn)"), ` ${t("header.refreshQuota")}`]))), renderToastBanner(),
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
}
|
|
5009
|
+
}, loadingAction === "refresh:all" ? [renderSpinner(), t("header.refreshing")] : [uiIcon("refresh", 12, "var(--agy-text-btn)"), ` ${t("header.refreshQuota")}`]))), renderToastBanner(), addAccountSection, h("div", { style: {
|
|
5010
|
+
display: "flex",
|
|
5011
|
+
alignItems: "center",
|
|
5012
|
+
justifyContent: "space-between",
|
|
5013
|
+
marginBottom: "8px",
|
|
5014
|
+
padding: "0 2px"
|
|
5015
|
+
} }, h("div", { style: {
|
|
5016
|
+
display: "flex",
|
|
5017
|
+
alignItems: "center",
|
|
5018
|
+
gap: "6px"
|
|
5019
|
+
} }, h("span", { style: {
|
|
5020
|
+
fontWeight: 700,
|
|
5021
|
+
fontSize: "12.5px",
|
|
5022
|
+
color: "var(--agy-text-primary)"
|
|
5023
|
+
} }, `账号池 (${accounts.length})`))), renderedAccountCards, h("div", { style: {
|
|
3683
5024
|
marginTop: "16px",
|
|
3684
5025
|
paddingTop: "12px",
|
|
3685
5026
|
borderTop: "1px solid var(--agy-border-divider)"
|
|
@@ -3782,9 +5123,19 @@ body.dark,
|
|
|
3782
5123
|
};
|
|
3783
5124
|
/** Modal dialog container rendered into document.body */
|
|
3784
5125
|
const AgyModalDialog = () => {
|
|
5126
|
+
const instanceIdRef = useRef(null);
|
|
5127
|
+
if (instanceIdRef.current === null) instanceIdRef.current = "modal_" + Math.random().toString(36).slice(2);
|
|
5128
|
+
const isPrimary = registerModalInstance(instanceIdRef.current);
|
|
5129
|
+
useEffect(() => {
|
|
5130
|
+
const id = instanceIdRef.current;
|
|
5131
|
+
return () => {
|
|
5132
|
+
unregisterModalInstance(id);
|
|
5133
|
+
};
|
|
5134
|
+
}, []);
|
|
3785
5135
|
const t = useAgyTranslation();
|
|
3786
5136
|
const [isOpen, setIsOpen] = useState(agyModalStore.open);
|
|
3787
5137
|
useEffect(() => {
|
|
5138
|
+
injectGlobalStyles();
|
|
3788
5139
|
return agyModalStore.subscribe(() => {
|
|
3789
5140
|
setIsOpen(agyModalStore.open);
|
|
3790
5141
|
});
|
|
@@ -3800,7 +5151,7 @@ body.dark,
|
|
|
3800
5151
|
win.addEventListener?.("keydown", onKey, true);
|
|
3801
5152
|
return () => win.removeEventListener?.("keydown", onKey, true);
|
|
3802
5153
|
}, [isOpen]);
|
|
3803
|
-
if (!isOpen) return null;
|
|
5154
|
+
if (!isOpen || !isPrimary) return null;
|
|
3804
5155
|
return h("div", {
|
|
3805
5156
|
className: "agy-modal-backdrop",
|
|
3806
5157
|
onClick: (e) => {
|
|
@@ -3876,8 +5227,8 @@ body.dark,
|
|
|
3876
5227
|
const displayAlias = activeAcc ? activeAcc.defaultAlias || legacyDefault ? activeAcc.systemHome ? t("account.defaultAlias") : t("account.aliasDefault", { number: accounts.indexOf(activeAcc) + 1 }) : activeAcc.alias : "";
|
|
3877
5228
|
const activeEligible = activeAcc !== void 0 && activeAcc.enabled && !activeAcc.authRequired;
|
|
3878
5229
|
const activeDetail = activeAcc !== void 0 && activeEligible ? ` · ${t("status.inUse")}: ${displayAlias}${activeAcc.email ? ` (${activeAcc.email})` : ""}` : "";
|
|
3879
|
-
const badgeTitle = `${t("header.badgeTitle", { count: accounts.length })}${activeDetail}`;
|
|
3880
|
-
const buttonLabel = displayAlias ? `AGY · ${displayAlias}` : `AGY (${accounts.length})`;
|
|
5230
|
+
const badgeTitle = status === null ? t("header.badgeLoading") : `${t("header.badgeTitle", { count: accounts.length })}${activeDetail}`;
|
|
5231
|
+
const buttonLabel = status === null ? "AGY" : displayAlias ? `AGY · ${displayAlias}` : `AGY (${accounts.length})`;
|
|
3881
5232
|
const badge = h("button", {
|
|
3882
5233
|
type: "button",
|
|
3883
5234
|
title: badgeTitle,
|
|
@@ -3928,6 +5279,8 @@ body.dark,
|
|
|
3928
5279
|
installAgyToolView(ctx);
|
|
3929
5280
|
ctx.effect(() => installAutoExpandReasoning());
|
|
3930
5281
|
ctx.effect(() => installMermaidRendering());
|
|
5282
|
+
ctx.effect(() => installImageEnhancer());
|
|
5283
|
+
ctx.effect(() => installDecisionChips());
|
|
3931
5284
|
}
|
|
3932
5285
|
//#endregion
|
|
3933
5286
|
exports.apply = apply;
|