dsh-agy-link 0.4.50 → 0.4.57

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/dist/client.js CHANGED
@@ -35,7 +35,8 @@ window.__ModuleLoader__.load({
35
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
36
  move: "M9 5h.01M9 12h.01M9 19h.01M15 5h.01M15 12h.01M15 19h.01",
37
37
  arrowUp: "M12 19V5M5 12l7-7 7 7",
38
- arrowDown: "M12 5v14M19 12l-7 7-7-7"
38
+ arrowDown: "M12 5v14M19 12l-7 7-7-7",
39
+ power: "M18.36 6.64a9 9 0 1 1-12.73 0M12 2v10"
39
40
  };
40
41
  //#endregion
41
42
  //#region src/client/locales.ts
@@ -72,7 +73,10 @@ window.__ModuleLoader__.load({
72
73
  "status.needsAuth": "待认证",
73
74
  "status.loading": "正在加载 Antigravity 状态...",
74
75
  "status.authRequired": "需重新登录",
75
- "status.primary": "主用",
76
+ "account.setActive": "设为当前使用",
77
+ "account.settingActive": "切换中",
78
+ "account.activeSet": "已切换当前使用账号",
79
+ "account.activeSetFailed": "该账号当前不可用(冷却或需重新登录)",
76
80
  "status.proxy": "代理",
77
81
  "status.inUse": "当前使用",
78
82
  "account.add": "添加 Google 账号",
@@ -85,8 +89,6 @@ window.__ModuleLoader__.load({
85
89
  "aria.proxyInput": "专属代理 URL",
86
90
  "aria.authCodeInput": "授权码或回调 URL",
87
91
  "aria.closeToast": "关闭提示",
88
- "account.setPrimary": "设为主用",
89
- "account.settingPrimary": "设置中",
90
92
  "account.details": "明细",
91
93
  "account.collapse": "收起",
92
94
  "account.expandOthers": "展开查看 Claude & GPT-OSS 模型额度",
@@ -171,7 +173,14 @@ window.__ModuleLoader__.load({
171
173
  "account.cardExpand": "展开详情",
172
174
  "account.draggingTarget": "放置至此成为优先级 #{num}",
173
175
  "account.dragBanner": "正在调整优先级:将【{alias}】移动至 #{num}",
174
- "account.dragHint": "拖拽卡片可实时调整调度优先级"
176
+ "account.dragHint": "拖拽卡片可实时调整调度优先级",
177
+ "account.enable": "启用",
178
+ "account.disable": "停用",
179
+ "account.enableTitle": "启用此账号(加入自动切号与调度)",
180
+ "account.disableTitle": "停用此账号(切号与调度时跳过)",
181
+ "account.enabledToast": "已启用账号:{alias}",
182
+ "account.disabledToast": "已停用账号:{alias}",
183
+ "status.disabled": "已停用"
175
184
  };
176
185
  const en = {
177
186
  "section.label": "Antigravity",
@@ -203,7 +212,10 @@ window.__ModuleLoader__.load({
203
212
  "status.needsAuth": "Authentication required",
204
213
  "status.loading": "Loading Antigravity status...",
205
214
  "status.authRequired": "Sign in again required",
206
- "status.primary": "Primary",
215
+ "account.setActive": "Set as in use",
216
+ "account.settingActive": "Switching...",
217
+ "account.activeSet": "Active account switched",
218
+ "account.activeSetFailed": "Account not currently eligible (cooldown or auth required)",
207
219
  "status.proxy": "Proxy",
208
220
  "status.inUse": "In use",
209
221
  "account.add": "Add Google account",
@@ -216,8 +228,6 @@ window.__ModuleLoader__.load({
216
228
  "aria.proxyInput": "Dedicated proxy URL",
217
229
  "aria.authCodeInput": "Authorization code or callback URL",
218
230
  "aria.closeToast": "Dismiss notification",
219
- "account.setPrimary": "Set as primary",
220
- "account.settingPrimary": "Setting...",
221
231
  "account.details": "Details",
222
232
  "account.collapse": "Collapse",
223
233
  "account.expandOthers": "Expand Claude & GPT-OSS quotas",
@@ -302,7 +312,14 @@ window.__ModuleLoader__.load({
302
312
  "account.cardExpand": "Expand details",
303
313
  "account.draggingTarget": "Drop here to set priority #{num}",
304
314
  "account.dragBanner": "Reordering: moving [{alias}] to priority #{num}",
305
- "account.dragHint": "Drag cards to reorder scheduling priority in real time"
315
+ "account.dragHint": "Drag cards to reorder scheduling priority in real time",
316
+ "account.enable": "Enable",
317
+ "account.disable": "Disable",
318
+ "account.enableTitle": "Enable this account (include in rotation)",
319
+ "account.disableTitle": "Disable this account (skip in rotation)",
320
+ "account.enabledToast": "Account enabled: {alias}",
321
+ "account.disabledToast": "Account disabled: {alias}",
322
+ "status.disabled": "Disabled"
306
323
  };
307
324
  const ptBR = {
308
325
  "section.label": "Antigravity",
@@ -334,7 +351,10 @@ window.__ModuleLoader__.load({
334
351
  "status.needsAuth": "Autenticação necessária",
335
352
  "status.loading": "Carregando o status do Antigravity...",
336
353
  "status.authRequired": "É necessário entrar novamente",
337
- "status.primary": "Principal",
354
+ "account.setActive": "Definir como em uso",
355
+ "account.settingActive": "Alternando...",
356
+ "account.activeSet": "Conta em uso alterada",
357
+ "account.activeSetFailed": "Conta não elegível no momento (cooldown ou login necessário)",
338
358
  "status.proxy": "Proxy",
339
359
  "status.inUse": "Em uso",
340
360
  "account.add": "Adicionar conta Google",
@@ -347,8 +367,6 @@ window.__ModuleLoader__.load({
347
367
  "aria.proxyInput": "URL do proxy exclusivo",
348
368
  "aria.authCodeInput": "Código de autorização ou URL de retorno",
349
369
  "aria.closeToast": "Fechar notificação",
350
- "account.setPrimary": "Definir como principal",
351
- "account.settingPrimary": "Definindo...",
352
370
  "account.details": "Detalhes",
353
371
  "account.collapse": "Recolher",
354
372
  "account.expandOthers": "Expandir cotas Claude e GPT-OSS",
@@ -433,7 +451,14 @@ window.__ModuleLoader__.load({
433
451
  "account.cardExpand": "Expandir detalhes",
434
452
  "account.draggingTarget": "Soltar aqui para prioridade #{num}",
435
453
  "account.dragBanner": "Reordenando: movendo [{alias}] para #{num}",
436
- "account.dragHint": "Arraste os cartões para reordenar a prioridade em tempo real"
454
+ "account.dragHint": "Arraste os cartões para reordenar a prioridade em tempo real",
455
+ "account.enable": "Ativar",
456
+ "account.disable": "Desativar",
457
+ "account.enableTitle": "Ativar esta conta (incluir na rotação)",
458
+ "account.disableTitle": "Desativar esta conta (ignorar na rotação)",
459
+ "account.enabledToast": "Conta ativada: {alias}",
460
+ "account.disabledToast": "Conta desativada: {alias}",
461
+ "status.disabled": "Desativado"
437
462
  };
438
463
  const es = {
439
464
  "section.label": "Antigravity",
@@ -465,7 +490,10 @@ window.__ModuleLoader__.load({
465
490
  "status.needsAuth": "Se requiere autenticación",
466
491
  "status.loading": "Cargando el estado de Antigravity...",
467
492
  "status.authRequired": "Debe iniciar sesión de nuevo",
468
- "status.primary": "Principal",
493
+ "account.setActive": "Establecer como en uso",
494
+ "account.settingActive": "Cambiando...",
495
+ "account.activeSet": "Cuenta en uso cambiada",
496
+ "account.activeSetFailed": "Cuenta no elegible ahora (enfriamiento o requiere login)",
469
497
  "status.proxy": "Proxy",
470
498
  "status.inUse": "En uso",
471
499
  "account.add": "Añadir cuenta de Google",
@@ -478,8 +506,6 @@ window.__ModuleLoader__.load({
478
506
  "aria.proxyInput": "URL de proxy exclusivo",
479
507
  "aria.authCodeInput": "Código de autorización o URL de devolución",
480
508
  "aria.closeToast": "Cerrar notificación",
481
- "account.setPrimary": "Establecer como principal",
482
- "account.settingPrimary": "Configurando...",
483
509
  "account.details": "Detalles",
484
510
  "account.collapse": "Contraer",
485
511
  "account.expandOthers": "Expandir cuotas Claude y GPT-OSS",
@@ -564,7 +590,14 @@ window.__ModuleLoader__.load({
564
590
  "account.cardExpand": "Expandir detalles",
565
591
  "account.draggingTarget": "Soltar aquí para prioridad #{num}",
566
592
  "account.dragBanner": "Reordenando: moviendo [{alias}] a #{num}",
567
- "account.dragHint": "Arrastre las tarjetas para reordenar la prioridad en tiempo real"
593
+ "account.dragHint": "Arrastre las tarjetas para reordenar la prioridad en tiempo real",
594
+ "account.enable": "Habilitar",
595
+ "account.disable": "Deshabilitar",
596
+ "account.enableTitle": "Habilitar esta cuenta (incluir en rotación)",
597
+ "account.disableTitle": "Deshabilitar esta cuenta (ignorar en rotación)",
598
+ "account.enabledToast": "Cuenta habilitada: {alias}",
599
+ "account.disabledToast": "Cuenta deshabilitada: {alias}",
600
+ "status.disabled": "Deshabilitado"
568
601
  };
569
602
  //#endregion
570
603
  //#region src/client/decisions.ts
@@ -2820,22 +2853,58 @@ window.__ModuleLoader__.load({
2820
2853
  //#endregion
2821
2854
  //#region src/client/mermaid.ts
2822
2855
  const MERMAID_CSS = `
2823
- div.md-code-block[data-agy-mermaid="done"] [data-code-block-content] {
2856
+ div.md-code-block[data-agy-mermaid="done"]:not([data-agy-mermaid-view="source"]) [data-code-block-content] {
2857
+ display: none !important;
2858
+ }
2859
+ div.md-code-block[data-agy-mermaid="done"][data-agy-mermaid-view="source"] [data-agy-mermaid-svg] > .agy-mermaid-body {
2824
2860
  display: none !important;
2825
2861
  }
2826
2862
  div.md-code-block[data-agy-mermaid="render"] {
2827
2863
  border-color: var(--dsw-alias-border-l2, #e2e8f0);
2828
2864
  }
2829
2865
  div[data-agy-mermaid-svg] {
2830
- padding: 12px 8px;
2866
+ position: relative;
2867
+ padding: 8px 8px 12px 8px;
2831
2868
  overflow-x: auto;
2832
2869
  text-align: center;
2833
2870
  background: var(--dsw-alias-bg-base, #ffffff);
2834
2871
  }
2835
2872
  div[data-agy-mermaid-svg] svg {
2836
2873
  max-width: 100%;
2874
+ min-width: 280px;
2837
2875
  height: auto;
2838
2876
  }
2877
+ .agy-mermaid-toolbar {
2878
+ display: flex;
2879
+ justify-content: flex-end;
2880
+ padding: 2px 4px 6px 4px;
2881
+ background: transparent;
2882
+ }
2883
+ .agy-mermaid-toggle {
2884
+ font-size: 11px;
2885
+ line-height: 1.4;
2886
+ padding: 2px 8px;
2887
+ border-radius: 4px;
2888
+ border: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
2889
+ background: var(--dsw-alias-bg-surface, #f8fafc);
2890
+ color: var(--dsw-alias-label-secondary, #475569);
2891
+ cursor: pointer;
2892
+ user-select: none;
2893
+ transition: all 0.15s ease;
2894
+ }
2895
+ .agy-mermaid-toggle:hover {
2896
+ background: var(--dsw-alias-bg-hover, #f1f5f9);
2897
+ color: var(--dsw-alias-label-primary, #0f172a);
2898
+ }
2899
+ .agy-mermaid-warn {
2900
+ padding: 6px 10px;
2901
+ margin-bottom: 6px;
2902
+ font-size: 12px;
2903
+ color: #92400e;
2904
+ background: #fef3c7;
2905
+ border-radius: 4px;
2906
+ text-align: left;
2907
+ }
2839
2908
  div[data-agy-mermaid-svg][data-agy-mermaid-error] {
2840
2909
  text-align: left;
2841
2910
  color: var(--dsw-alias-label-tertiary, #64748b);
@@ -2904,12 +2973,17 @@ body > [id^="iagy-mmd"] .error-icon {
2904
2973
  loadPromise = (async () => {
2905
2974
  for (const url of CDN_URLS) if (await loadScript(url) && window.mermaid !== void 0) {
2906
2975
  try {
2976
+ const isDark = typeof document !== "undefined" && (document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || window.matchMedia?.("(prefers-color-scheme: dark)").matches === true);
2907
2977
  window.mermaid.initialize({
2908
2978
  startOnLoad: false,
2909
2979
  securityLevel: "strict",
2910
- theme: "neutral",
2980
+ theme: isDark ? "dark" : "neutral",
2911
2981
  fontFamily: "inherit",
2912
- suppressErrorRendering: true
2982
+ suppressErrorRendering: true,
2983
+ flowchart: {
2984
+ useMaxWidth: true,
2985
+ htmlLabels: false
2986
+ }
2913
2987
  });
2914
2988
  } catch {}
2915
2989
  return window.mermaid;
@@ -2922,12 +2996,16 @@ body > [id^="iagy-mmd"] .error-icon {
2922
2996
  }
2923
2997
  /** Banner infostring text ("mermaid") identifies the fence language. */
2924
2998
  function fenceLang(block) {
2925
- const text = ((block.querySelector("[data-code-block-banner] [class*=\"infostring\"]") ?? block.querySelector("[data-code-block-banner] [class*=\"language\"]") ?? block.querySelector("[data-code-block-banner]"))?.textContent ?? "").trim().toLowerCase();
2926
- if (text !== "") return text.split(/\s+/)[0] ?? "";
2927
- const code = block.querySelector("[data-code-block-content] code");
2999
+ const code = block.querySelector("[data-code-block-content] code") ?? block.querySelector("[data-code-block-content] pre");
2928
3000
  const m = (code?.getAttribute("class") ?? "").match(/language-([\w-]+)/);
2929
3001
  if (m?.[1]) return m[1].toLowerCase();
2930
- return (code?.getAttribute("data-language") ?? block.getAttribute("data-language") ?? "").toLowerCase();
3002
+ const dataLang = (code?.getAttribute("data-language") ?? block.getAttribute("data-language") ?? "").trim().toLowerCase();
3003
+ if (dataLang !== "") return dataLang;
3004
+ const text = ((block.querySelector("[data-code-block-banner] [class*=\"infostring\"]") ?? block.querySelector("[data-code-block-banner] [class*=\"language\"]"))?.textContent ?? "").trim().toLowerCase();
3005
+ if (text !== "") return text.split(/\s+/)[0] ?? "";
3006
+ const bannerText = (block.querySelector("[data-code-block-banner]")?.textContent ?? "").trim().toLowerCase();
3007
+ if (bannerText !== "" && bannerText !== "代码块" && bannerText !== "code" && bannerText !== "code block") return bannerText.split(/\s+/)[0] ?? "";
3008
+ return "";
2931
3009
  }
2932
3010
  const MERMAID_FIRST_LINE = /^(?:flowchart(?:\s+\w+)?|graph\s+(?:TB|TD|LR|RL|BT)|sequenceDiagram|classDiagram(?:-v2)?|stateDiagram(?:-v2)?|erDiagram|journey|gantt|pie|mindmap|timeline|gitGraph|sankey-beta|xychart-beta|block-beta|quadrantChart|requirementDiagram|radar-beta|C4(?:Context|Container|Component|Dynamic))\b/;
2933
3011
  /** Content sniff: unknown-language fences are the whole reason this module exists. */
@@ -3001,7 +3079,51 @@ body > [id^="iagy-mmd"] .error-icon {
3001
3079
  const stray = document.querySelectorAll("body > [id^=\"dagy-mmd\"], body > [id^=\"iagy-mmd\"], body > [id^=\"d_agy-mmd\"], body > [id^=\"i_agy-mmd\"], body > [id^=\"agy-mmd-\"]");
3002
3080
  for (let i = 0; i < stray.length; i++) stray[i]?.remove();
3003
3081
  }
3004
- async function renderInto(block, source) {
3082
+ function repairMermaidSource(source) {
3083
+ if (!/^\s*(?:flowchart|graph)\b/i.test(source)) return source;
3084
+ return source.split(/\r?\n/).map((line) => {
3085
+ let l = line;
3086
+ const subMatch = l.match(/^(\s*subgraph\s+)([^"[\]\n]+)$/i);
3087
+ if (subMatch && (subMatch[2].includes(":") || subMatch[2].includes(" ") || subMatch[2].includes(":"))) {
3088
+ const title = subMatch[2].trim();
3089
+ l = `${subMatch[1]}"${title}"`;
3090
+ }
3091
+ l = l.replace(/(\b[a-zA-Z0-9_\u4e00-\u9fa5]+)\[([^"\]\n]+)\]/g, (m, id, text) => {
3092
+ if (text.includes(">") || text.includes("<") || text.includes(":") || text.includes(":") || text.includes("(") || text.includes(")")) return `${id}["${text.trim()}"]`;
3093
+ return m;
3094
+ });
3095
+ l = l.replace(/(\b[a-zA-Z0-9_\u4e00-\u9fa5]+)\(([^")\n]+)\)/g, (m, id, text) => {
3096
+ if (text.includes(">") || text.includes("<") || text.includes(":") || text.includes(":") || text.includes("[") || text.includes("]")) return `${id}("${text.trim()}")`;
3097
+ return m;
3098
+ });
3099
+ if (l.includes("-->") || l.includes("---") || l.includes("-.->") || l.includes("==>") || l.includes("<--")) {
3100
+ let inQuote = false;
3101
+ let inBracket = 0;
3102
+ let inPipe = false;
3103
+ let out = "";
3104
+ for (let i = 0; i < l.length; i++) {
3105
+ const ch = l[i];
3106
+ if (ch === "\"" && (i === 0 || l[i - 1] !== "\\")) {
3107
+ inQuote = !inQuote;
3108
+ out += ch;
3109
+ } else if (!inQuote && ch === "|") {
3110
+ inPipe = !inPipe;
3111
+ out += ch;
3112
+ } else if (!inQuote && !inPipe && (ch === "[" || ch === "(" || ch === "{")) {
3113
+ inBracket++;
3114
+ out += ch;
3115
+ } else if (!inQuote && !inPipe && (ch === "]" || ch === ")" || ch === "}")) {
3116
+ if (inBracket > 0) inBracket--;
3117
+ out += ch;
3118
+ } else if (!inQuote && !inPipe && inBracket === 0 && ch === "+") out += "&";
3119
+ else out += ch;
3120
+ }
3121
+ l = out;
3122
+ }
3123
+ return l;
3124
+ }).join("\n");
3125
+ }
3126
+ async function renderInto(block, source, lang = "") {
3005
3127
  block.querySelector("[data-agy-mermaid-svg]")?.remove();
3006
3128
  const mount = document.createElement("div");
3007
3129
  mount.setAttribute("data-agy-mermaid-svg", "1");
@@ -3015,15 +3137,60 @@ body > [id^="iagy-mmd"] .error-icon {
3015
3137
  }
3016
3138
  renderSeq += 1;
3017
3139
  const id = "agy-mmd-" + renderSeq;
3140
+ let targetSource = source;
3018
3141
  try {
3019
- if (typeof api.parse === "function") await api.parse(source);
3020
- const { svg } = await api.render(id, source, mount);
3021
- mount.innerHTML = svg;
3142
+ let parseValidated = false;
3143
+ if (typeof api.parse === "function") try {
3144
+ await api.parse(targetSource);
3145
+ parseValidated = true;
3146
+ } catch (parseErr) {
3147
+ const repaired = repairMermaidSource(targetSource);
3148
+ if (repaired !== targetSource) try {
3149
+ await api.parse(repaired);
3150
+ targetSource = repaired;
3151
+ parseValidated = true;
3152
+ } catch {
3153
+ throw parseErr;
3154
+ }
3155
+ else throw parseErr;
3156
+ }
3157
+ if (!parseValidated && typeof api.parse !== "function") targetSource = repairMermaidSource(targetSource);
3158
+ const { svg } = await api.render(id, targetSource, mount);
3159
+ if (!svg || svg.trim() === "" || svg.includes("class=\"error-icon\"") || svg.includes("class=\"error-text\"") || svg.includes("aria-roledescription=\"error\"")) throw new Error("Mermaid returned an empty or error diagram");
3160
+ mount.innerHTML = "";
3161
+ const toolbar = document.createElement("div");
3162
+ toolbar.className = "agy-mermaid-toolbar";
3163
+ const toggleBtn = document.createElement("button");
3164
+ toggleBtn.type = "button";
3165
+ toggleBtn.className = "agy-mermaid-toggle";
3166
+ toggleBtn.textContent = "查看源码";
3167
+ toggleBtn.title = "切换图表与原始代码";
3168
+ toggleBtn.addEventListener("click", (ev) => {
3169
+ ev.preventDefault();
3170
+ ev.stopPropagation();
3171
+ if (block.getAttribute("data-agy-mermaid-view") === "source") {
3172
+ block.removeAttribute("data-agy-mermaid-view");
3173
+ toggleBtn.textContent = "查看源码";
3174
+ } else {
3175
+ block.setAttribute("data-agy-mermaid-view", "source");
3176
+ toggleBtn.textContent = "查看图表";
3177
+ }
3178
+ });
3179
+ toolbar.appendChild(toggleBtn);
3180
+ mount.appendChild(toolbar);
3181
+ const bodyDiv = document.createElement("div");
3182
+ bodyDiv.className = "agy-mermaid-body";
3183
+ bodyDiv.innerHTML = svg;
3184
+ mount.appendChild(bodyDiv);
3022
3185
  block.setAttribute("data-agy-mermaid", "done");
3023
3186
  } catch (e) {
3024
- block.setAttribute("data-agy-mermaid", "error");
3025
- mount.setAttribute("data-agy-mermaid-error", "1");
3026
- mount.textContent = "Mermaid render failed: " + (e instanceof Error ? e.message : String(e));
3187
+ if (!isMermaidLang(lang)) {
3188
+ mount.remove();
3189
+ block.setAttribute("data-agy-mermaid", "fallback");
3190
+ } else {
3191
+ block.setAttribute("data-agy-mermaid", "error");
3192
+ mount.innerHTML = "<div class=\"agy-mermaid-warn\">⚠️ Mermaid 图表解析失败,已保留原始代码呈现</div>";
3193
+ }
3027
3194
  } finally {
3028
3195
  cleanupTempElements(id);
3029
3196
  }
@@ -3044,13 +3211,13 @@ body > [id^="iagy-mmd"] .error-icon {
3044
3211
  const block = blocks[i];
3045
3212
  if (!block) continue;
3046
3213
  const state = block.getAttribute("data-agy-mermaid");
3047
- if (state === "done" || state === "busy" || state === "error") continue;
3214
+ if (state === "done" || state === "busy" || state === "error" || state === "fallback") continue;
3048
3215
  const lang = fenceLang(block);
3049
3216
  const source = readSource(block);
3050
3217
  if (source === "") continue;
3051
3218
  if (!isMermaidBlock(lang, source)) continue;
3052
3219
  block.setAttribute("data-agy-mermaid", "busy");
3053
- renderInto(block, source);
3220
+ renderInto(block, source, lang);
3054
3221
  }
3055
3222
  }
3056
3223
  let activeObserver$1 = null;
@@ -3174,7 +3341,7 @@ div[data-variant="think"] [class*="thinkBody"] {
3174
3341
  if (!body) return;
3175
3342
  const text = (body.textContent ?? "").trim();
3176
3343
  if (text === "") return;
3177
- if (/^\[agy thinking turn(?: · \d+ thinking tokens)?\]\s*$/.test(text)) return;
3344
+ if (/^\[agy(?: thinking turn)?(?: · \d+ (?:thinking )?tokens)?\]\s*$/.test(text)) return;
3178
3345
  const style = typeof getComputedStyle === "function" ? getComputedStyle(body) : null;
3179
3346
  if (style && style.display !== "none" && body.clientHeight > 8) {
3180
3347
  root.dataset.agyExpanded = "true";
@@ -3283,9 +3450,7 @@ div[data-variant="think"] [class*="thinkBody"] {
3283
3450
  if (typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function") init.signal = AbortSignal.timeout(5e3);
3284
3451
  const res = await win.fetch?.(base + "/plugins/agy-link/status", init);
3285
3452
  if (!res || !res.ok) return null;
3286
- const payload = await res.json();
3287
- statusCache = payload;
3288
- return payload;
3453
+ return await res.json();
3289
3454
  } catch {
3290
3455
  return null;
3291
3456
  }
@@ -3394,20 +3559,35 @@ div[data-variant="think"] [class*="thinkBody"] {
3394
3559
  }
3395
3560
  };
3396
3561
  /**
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.
3562
+ * Global modal host manager: ensures exactly one mounted session header
3563
+ * hosts the modal dialog portal reactively. If the primary header unmounts,
3564
+ * the next available header is immediately notified and seamlessly takes over.
3399
3565
  */
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
- }
3566
+ const modalHostManager = {
3567
+ listeners: /* @__PURE__ */ new Map(),
3568
+ activeId: null,
3569
+ register(id, onChange) {
3570
+ modalHostManager.listeners.set(id, onChange);
3571
+ if (modalHostManager.activeId === null) modalHostManager.activeId = id;
3572
+ onChange(modalHostManager.activeId === id);
3573
+ return () => {
3574
+ modalHostManager.listeners.delete(id);
3575
+ if (modalHostManager.activeId === id) {
3576
+ const next = modalHostManager.listeners.keys().next().value ?? null;
3577
+ modalHostManager.activeId = next;
3578
+ if (next) modalHostManager.listeners.get(next)?.(true);
3579
+ }
3580
+ };
3581
+ },
3582
+ claim(id) {
3583
+ if (modalHostManager.activeId !== id) {
3584
+ const prev = modalHostManager.activeId;
3585
+ modalHostManager.activeId = id;
3586
+ if (prev) modalHostManager.listeners.get(prev)?.(false);
3587
+ modalHostManager.listeners.get(id)?.(true);
3588
+ }
3589
+ }
3590
+ };
3411
3591
  /**
3412
3592
  * Format reset timestamp into readable date/time + relative countdown.
3413
3593
  */
@@ -3472,13 +3652,13 @@ div[data-variant="think"] [class*="thinkBody"] {
3472
3652
  }
3473
3653
  const FAMILY_BRAND = {
3474
3654
  google: "gemini",
3655
+ argon: "gemini",
3475
3656
  anthropic: "claude",
3476
3657
  openai: "openai"
3477
3658
  };
3478
- let agyIconSeq = 0;
3479
3659
  /** Antigravity mark: gradient orb with an orbit ring (product has no public simple-icon). */
3480
3660
  function agyIcon(size = 14) {
3481
- const gid = `agy-g${++agyIconSeq}`;
3661
+ const gid = "agy-icon-linear-gradient";
3482
3662
  return h("svg", {
3483
3663
  viewBox: "0 0 24 24",
3484
3664
  width: size,
@@ -3929,7 +4109,7 @@ body.dark,
3929
4109
  marginBottom: "8px",
3930
4110
  color: "var(--agy-text-primary)",
3931
4111
  boxShadow: "var(--agy-shadow-card)",
3932
- transition: "all 0.18s cubic-bezier(0.16, 1, 0.3, 1)"
4112
+ transition: "border-color 0.18s ease, box-shadow 0.18s ease, opacity 0.18s ease"
3933
4113
  },
3934
4114
  cardPrimary: {
3935
4115
  background: "var(--agy-bg-card)",
@@ -3939,7 +4119,7 @@ body.dark,
3939
4119
  marginBottom: "8px",
3940
4120
  color: "var(--agy-text-primary)",
3941
4121
  boxShadow: "var(--agy-shadow-card)",
3942
- transition: "all 0.18s cubic-bezier(0.16, 1, 0.3, 1)"
4122
+ transition: "border-color 0.18s ease, box-shadow 0.18s ease, opacity 0.18s ease"
3943
4123
  },
3944
4124
  quotaBox: {
3945
4125
  background: "var(--agy-bg-box)",
@@ -4085,6 +4265,7 @@ body.dark,
4085
4265
  }
4086
4266
  };
4087
4267
  function apply(ctx) {
4268
+ injectGlobalStyles();
4088
4269
  const locale = ctx.locale;
4089
4270
  ctx.effect(() => {
4090
4271
  const disposePtBR = locale.addLanguage({
@@ -4116,7 +4297,6 @@ body.dark,
4116
4297
  return locale.bind(NS);
4117
4298
  };
4118
4299
  const AgySettingsSection = (props) => {
4119
- injectGlobalStyles();
4120
4300
  const t = useAgyTranslation();
4121
4301
  const { status, refresh } = useAgyStatus();
4122
4302
  const [aliasInput, setAliasInput] = useState("");
@@ -4262,9 +4442,18 @@ body.dark,
4262
4442
  if (hiddenPendingRef.current === next) hiddenPendingRef.current = null;
4263
4443
  }
4264
4444
  };
4265
- const setPrimary = async (id) => {
4266
- setLoadingAction(`primary:${id}`);
4267
- const res = await postJson("/plugins/agy-link/pool/primary", { id });
4445
+ const setActiveAccount = async (id) => {
4446
+ setLoadingAction(`active:${id}`);
4447
+ const res = await postJson("/plugins/agy-link/pool/set-active", { id });
4448
+ setLoadingAction(null);
4449
+ if (res && res.ok) {
4450
+ await refresh();
4451
+ showToast(t("account.activeSet"), "success");
4452
+ } else showToast(res?.error || t("account.activeSetFailed"), "error");
4453
+ };
4454
+ const removeAccount = async (id, alias) => {
4455
+ setLoadingAction(`remove:${id}`);
4456
+ const res = await postJson("/plugins/agy-link/pool/remove", { id });
4268
4457
  if (res === null || res?.ok === false) {
4269
4458
  setLoadingAction(null);
4270
4459
  actionFailed();
@@ -4272,11 +4461,15 @@ body.dark,
4272
4461
  }
4273
4462
  await refresh();
4274
4463
  setLoadingAction(null);
4275
- showToast(t("account.setPrimary"), "success");
4464
+ showToast(t("account.removed", { alias }), "info");
4276
4465
  };
4277
- const removeAccount = async (id, alias) => {
4278
- setLoadingAction(`remove:${id}`);
4279
- const res = await postJson("/plugins/agy-link/pool/remove", { id });
4466
+ const toggleAccountEnabled = async (acc) => {
4467
+ const nextState = !acc.enabled;
4468
+ setLoadingAction(`enable:${acc.id}`);
4469
+ const res = await postJson("/plugins/agy-link/pool/enable", {
4470
+ id: acc.id,
4471
+ enabled: nextState
4472
+ });
4280
4473
  if (res === null || res?.ok === false) {
4281
4474
  setLoadingAction(null);
4282
4475
  actionFailed();
@@ -4284,7 +4477,9 @@ body.dark,
4284
4477
  }
4285
4478
  await refresh();
4286
4479
  setLoadingAction(null);
4287
- showToast(t("account.removed", { alias }), "info");
4480
+ const legacyDefault = acc.defaultAlias === void 0 && acc.systemHome && acc.alias === "主账号 (系统登录)";
4481
+ const displayAlias = acc.defaultAlias || legacyDefault ? acc.systemHome ? t("account.defaultAlias") : acc.alias : acc.alias;
4482
+ showToast(t(nextState ? "account.enabledToast" : "account.disabledToast", { alias: displayAlias }), "success");
4288
4483
  };
4289
4484
  const refreshQuota = async (id) => {
4290
4485
  setLoadingAction(id ? `refresh:${id}` : "refresh:all");
@@ -4404,7 +4599,8 @@ body.dark,
4404
4599
  const info = acc.quotas[familyKey];
4405
4600
  const cd = acc.cooldowns[familyKey];
4406
4601
  const inCooldown = cd && cd.cooldownUntil > Date.now();
4407
- const pct5h = typeof info?.remainingFraction === "number" && Number.isFinite(info.remainingFraction) ? Math.max(0, Math.min(100, Math.round(info.remainingFraction * 100))) : -1;
4602
+ const has5h = typeof info?.remainingFraction === "number" && Number.isFinite(info.remainingFraction);
4603
+ const pct5h = has5h ? Math.max(0, Math.min(100, Math.round(info.remainingFraction * 100))) : -1;
4408
4604
  const cdNote = inCooldown ? t("account.localCooldown") : "";
4409
4605
  const w5h = formatQuotaWindow(t, info?.resetTime);
4410
4606
  const pctWeekly = typeof info?.weeklyFraction === "number" && Number.isFinite(info.weeklyFraction) ? Math.max(0, Math.min(100, Math.round(info.weeklyFraction * 100))) : -1;
@@ -4493,7 +4689,7 @@ body.dark,
4493
4689
  fontSize: "12.5px",
4494
4690
  marginBottom: "5px",
4495
4691
  color: "var(--agy-text-primary)"
4496
- } }, brandIcon(FAMILY_BRAND[familyKey], 14), h("span", null, label)), renderLine(t("quota.fiveHour"), pct5h, c5h, w5h.resetText ? w5h.resetText + cdNote : cdNote.replace(/^ · /, "")), renderLine(t("quota.weekly"), pctWeekly, cWeekly, wWeekly.resetText));
4692
+ } }, brandIcon(FAMILY_BRAND[familyKey], 14), h("span", null, label)), familyKey !== "argon" || has5h ? renderLine(t("quota.fiveHour"), pct5h, c5h, w5h.resetText ? w5h.resetText + cdNote : cdNote.replace(/^ · /, "")) : null, renderLine(t("quota.weekly"), pctWeekly, cWeekly, wWeekly.resetText));
4497
4693
  };
4498
4694
  const activeAccountId = pool?.activeAccountId ?? pool?.lastActiveAccountId ?? pool?.activeAccountIds?.google ?? pool?.primaryAccountId;
4499
4695
  const renderedAccountCards = accounts.map((acc) => {
@@ -4509,11 +4705,13 @@ body.dark,
4509
4705
  ...S.card,
4510
4706
  cursor: "default",
4511
4707
  padding: "10px 14px",
4512
- marginBottom: "8px"
4708
+ marginBottom: "8px",
4709
+ ...!acc.enabled ? { opacity: .72 } : {}
4513
4710
  };
4514
4711
  const legacyDefault = acc.defaultAlias === void 0 && acc.systemHome && acc.alias === "主账号 (系统登录)";
4515
4712
  const displayAlias = acc.defaultAlias || legacyDefault ? acc.systemHome ? t("account.defaultAlias") : t("account.aliasDefault", { number: accIndex + 1 }) : acc.alias;
4516
4713
  const googleModels = acc.quotas.google?.models ?? [];
4714
+ const argonModels = acc.quotas.argon?.models ?? [];
4517
4715
  const anthropicModels = acc.quotas.anthropic?.models ?? [];
4518
4716
  const openaiModels = acc.quotas.openai?.models ?? [];
4519
4717
  const allChildModels = [
@@ -4521,6 +4719,10 @@ body.dark,
4521
4719
  family: "Google",
4522
4720
  model: m
4523
4721
  })),
4722
+ ...argonModels.map((m) => ({
4723
+ family: "Argon",
4724
+ model: m
4725
+ })),
4524
4726
  ...anthropicModels.map((m) => ({
4525
4727
  family: "Anthropic",
4526
4728
  model: m
@@ -4640,12 +4842,7 @@ body.dark,
4640
4842
  whiteSpace: "nowrap"
4641
4843
  },
4642
4844
  title: acc.email
4643
- }, uiIcon("mail", 10, "var(--agy-badge-email-text)"), acc.email) : null, isPrimary ? h("span", { style: {
4644
- ...S.badgePrimary,
4645
- gap: "3px",
4646
- fontSize: "10.5px",
4647
- padding: "1px 5px"
4648
- } }, uiIcon("star", 10, "var(--agy-badge-primary-text)"), t("status.primary")) : null, isInUse ? h("span", {
4845
+ }, uiIcon("mail", 10, "var(--agy-badge-email-text)"), acc.email) : null, isInUse ? h("span", {
4649
4846
  style: {
4650
4847
  ...S.badgeTag,
4651
4848
  background: "rgba(16, 185, 129, 0.12)",
@@ -4665,7 +4862,19 @@ body.dark,
4665
4862
  gap: "4px",
4666
4863
  fontSize: "10px",
4667
4864
  padding: "1px 5px"
4668
- } }, uiIcon("globe", 10, "var(--agy-badge-proxy-text)"), t("status.proxy")) : null), h("div", { style: {
4865
+ } }, uiIcon("globe", 10, "var(--agy-badge-proxy-text)"), t("status.proxy")) : null, !acc.enabled ? h("span", {
4866
+ style: {
4867
+ ...S.badgeTag,
4868
+ background: "var(--agy-bg-subbox)",
4869
+ color: "var(--agy-text-secondary)",
4870
+ borderColor: "var(--agy-border-subbox)",
4871
+ gap: "3px",
4872
+ fontSize: "10px",
4873
+ padding: "1px 5px",
4874
+ fontWeight: 700
4875
+ },
4876
+ title: t("status.disabled")
4877
+ }, uiIcon("power", 10, "#64748b"), t("status.disabled")) : null), h("div", { style: {
4669
4878
  display: "flex",
4670
4879
  gap: "4px",
4671
4880
  alignItems: "center",
@@ -4673,19 +4882,21 @@ body.dark,
4673
4882
  } }, h("button", {
4674
4883
  type: "button",
4675
4884
  className: "agy-btn",
4676
- style: isExpanded ? {
4677
- ...S.btnSmPrimary,
4885
+ style: acc.enabled ? {
4886
+ ...S.btnSm,
4678
4887
  gap: "3px",
4679
4888
  fontSize: "11px",
4680
4889
  padding: "2px 6px"
4681
4890
  } : {
4682
- ...S.btnSm,
4891
+ ...S.btnSmPrimary,
4683
4892
  gap: "3px",
4684
4893
  fontSize: "11px",
4685
4894
  padding: "2px 6px"
4686
4895
  },
4687
- onClick: () => toggleExpand(acc.id)
4688
- }, isExpanded ? [uiIcon("chevronUp", 10), ` ${t("account.collapse")}`] : [uiIcon("chevronDown", 10), ` ${t("account.otherModels")}`]), h("button", {
4896
+ title: acc.enabled ? t("account.disableTitle") : t("account.enableTitle"),
4897
+ disabled: isBusy,
4898
+ onClick: () => void toggleAccountEnabled(acc)
4899
+ }, loadingAction === `enable:${acc.id}` ? [renderSpinner(), acc.enabled ? t("account.disable") : t("account.enable")] : [uiIcon("power", 10, acc.enabled ? "var(--agy-text-secondary)" : "#ffffff"), ` ${acc.enabled ? t("account.disable") : t("account.enable")}`]), h("button", {
4689
4900
  type: "button",
4690
4901
  className: "agy-btn",
4691
4902
  style: {
@@ -4697,7 +4908,7 @@ body.dark,
4697
4908
  title: t("account.syncTitle"),
4698
4909
  disabled: isBusy,
4699
4910
  onClick: () => void refreshQuota(acc.id)
4700
- }, loadingAction === `refresh:${acc.id}` ? [renderSpinner(), t("account.syncing")] : [uiIcon("refresh", 10), ` ${t("account.sync")}`]), !isPrimary ? h("button", {
4911
+ }, loadingAction === `refresh:${acc.id}` ? [renderSpinner(), t("account.syncing")] : [uiIcon("refresh", 10), ` ${t("account.sync")}`]), acc.enabled && !isInUse ? h("button", {
4701
4912
  type: "button",
4702
4913
  className: "agy-btn",
4703
4914
  style: {
@@ -4706,9 +4917,10 @@ body.dark,
4706
4917
  fontSize: "11px",
4707
4918
  padding: "2px 6px"
4708
4919
  },
4920
+ title: t("account.setActive"),
4709
4921
  disabled: isBusy,
4710
- onClick: () => void setPrimary(acc.id)
4711
- }, loadingAction === `primary:${acc.id}` ? [renderSpinner(), t("account.settingPrimary")] : [uiIcon("star", 10), ` ${t("account.setPrimary")}`]) : null, h("button", {
4922
+ onClick: () => void setActiveAccount(acc.id)
4923
+ }, loadingAction === `active:${acc.id}` ? [renderSpinner(), t("account.settingActive")] : [uiIcon("zap", 10), ` ${t("account.setActive")}`]) : null, h("button", {
4712
4924
  type: "button",
4713
4925
  className: "agy-btn",
4714
4926
  style: isEditingProxy ? {
@@ -4739,7 +4951,7 @@ body.dark,
4739
4951
  }, loadingAction === `remove:${acc.id}` ? renderSpinner() : uiIcon("trash", 11, "var(--agy-danger-text)")) : null)), h("div", {
4740
4952
  key: "agy-body",
4741
4953
  style: S.quotaBox
4742
- }, renderQuotaBar("Gemini", "google", acc), h("button", {
4954
+ }, renderQuotaBar("Gemini", "google", acc), acc.quotas.argon ? renderQuotaBar("Argon", "argon", acc) : null, h("button", {
4743
4955
  type: "button",
4744
4956
  className: "agy-btn",
4745
4957
  style: {
@@ -5123,25 +5335,8 @@ body.dark,
5123
5335
  };
5124
5336
  /** Modal dialog container rendered into document.body */
5125
5337
  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
- }, []);
5135
5338
  const t = useAgyTranslation();
5136
- const [isOpen, setIsOpen] = useState(agyModalStore.open);
5137
5339
  useEffect(() => {
5138
- injectGlobalStyles();
5139
- return agyModalStore.subscribe(() => {
5140
- setIsOpen(agyModalStore.open);
5141
- });
5142
- }, []);
5143
- useEffect(() => {
5144
- if (!isOpen) return;
5145
5340
  const onKey = (e) => {
5146
5341
  if (e.key === "Escape") {
5147
5342
  e.stopPropagation();
@@ -5150,8 +5345,7 @@ body.dark,
5150
5345
  };
5151
5346
  win.addEventListener?.("keydown", onKey, true);
5152
5347
  return () => win.removeEventListener?.("keydown", onKey, true);
5153
- }, [isOpen]);
5154
- if (!isOpen || !isPrimary) return null;
5348
+ }, []);
5155
5349
  return h("div", {
5156
5350
  className: "agy-modal-backdrop",
5157
5351
  onClick: (e) => {
@@ -5208,6 +5402,19 @@ body.dark,
5208
5402
  };
5209
5403
  /** Session Header badge in chat toolbar */
5210
5404
  const AgySessionStatus = () => {
5405
+ const hostIdRef = useRef(null);
5406
+ if (hostIdRef.current === null) hostIdRef.current = "host_" + Math.random().toString(36).slice(2);
5407
+ const hostId = hostIdRef.current;
5408
+ const [isPrimaryHost, setIsPrimaryHost] = useState(false);
5409
+ useEffect(() => {
5410
+ return modalHostManager.register(hostId, setIsPrimaryHost);
5411
+ }, [hostId]);
5412
+ const [isModalOpen, setIsModalOpen] = useState(agyModalStore.open);
5413
+ useEffect(() => {
5414
+ return agyModalStore.subscribe(() => {
5415
+ setIsModalOpen(agyModalStore.open);
5416
+ });
5417
+ }, []);
5211
5418
  const t = useAgyTranslation();
5212
5419
  const { status } = useAgyStatus();
5213
5420
  const [, setTimeTick] = useState(0);
@@ -5234,7 +5441,10 @@ body.dark,
5234
5441
  type: "button",
5235
5442
  title: badgeTitle,
5236
5443
  className: "agy-btn",
5237
- onClick: () => agyModalStore.setOpen(true),
5444
+ onClick: () => {
5445
+ modalHostManager.claim(hostId);
5446
+ agyModalStore.setOpen(true);
5447
+ },
5238
5448
  style: {
5239
5449
  background: "var(--agy-bg-header)",
5240
5450
  border: "1px solid var(--agy-border-card)",
@@ -5257,7 +5467,7 @@ body.dark,
5257
5467
  borderRadius: "50%",
5258
5468
  background: color
5259
5469
  } }), buttonLabel);
5260
- return h("div", { style: { display: "inline-block" } }, badge, portalToBody(h(AgyModalDialog, null)));
5470
+ return h("div", { style: { display: "inline-block" } }, badge, isPrimaryHost && isModalOpen ? portalToBody(h(AgyModalDialog, null)) : null);
5261
5471
  };
5262
5472
  ctx.slots.inject("conversation.session.header.actions", () => {
5263
5473
  return ctx.slots.register({