dsh-provider-qoder 0.4.3 → 0.5.1

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/lib/client.js CHANGED
@@ -5,6 +5,7 @@ window.__ModuleLoader__.load({
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  let react = require("react");
8
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
8
9
  let react_jsx_runtime = require("react/jsx-runtime");
9
10
  //#region src/dsh/credential-contract.ts
10
11
  /** Shared DSH host/browser contract for the one managed Qoder credential. */
@@ -14,6 +15,172 @@ window.__ModuleLoader__.load({
14
15
  return source === "env" || source?.endsWith("-env") === true;
15
16
  }
16
17
  //#endregion
18
+ //#region src/client/queue-status.ts
19
+ /** Match DSH's running status clock: whole hours, minutes and seconds. */
20
+ function formatQueueDuration(ms, t) {
21
+ const total = Math.max(0, Math.floor(ms / 1e3));
22
+ const hours = Math.floor(total / 3600);
23
+ const minutes = Math.floor(total / 60) % 60;
24
+ const seconds = total % 60;
25
+ return (hours > 0 ? `${hours}${t("queueHourUnit")}` : "") + (total >= 60 ? `${minutes}${t("queueMinuteUnit")}` : "") + `${seconds}${t("queueSecondUnit")}`;
26
+ }
27
+ function parseQueueSnapshots(value, sessionId) {
28
+ if (!Array.isArray(value) || value.length > 256) throw new Error("Invalid queue snapshots");
29
+ return value.map((item) => {
30
+ if (!item || typeof item !== "object" || item.sessionId !== sessionId || typeof item.callId !== "string" || !item.callId || typeof item.model !== "string" || item.modelName !== void 0 && (typeof item.modelName !== "string" || !item.modelName.trim()) || ![
31
+ "waitElapsedMs",
32
+ "maxWaitMs",
33
+ "updatedAt"
34
+ ].every((key) => typeof item[key] === "number" && Number.isFinite(item[key]) && item[key] >= 0) || !["queueCount", "waitTimeMs"].every((key) => item[key] === void 0 || typeof item[key] === "number" && Number.isFinite(item[key]) && item[key] >= 0)) throw new Error("Invalid queue snapshot");
35
+ return item;
36
+ });
37
+ }
38
+ function watchQueueStatus(rpc, sessionId, visibility, changed) {
39
+ let disposed = false;
40
+ let generation = 0;
41
+ let timer;
42
+ let active;
43
+ let items = [];
44
+ const poll = async () => {
45
+ if (disposed || visibility.hidden || active) return;
46
+ const revision = generation;
47
+ const controller = new AbortController();
48
+ active = controller;
49
+ const timeout = setTimeout(() => controller.abort(), 5e3);
50
+ try {
51
+ const result = await rpc.call("queue", { sessionId }, controller.signal);
52
+ if (disposed || revision !== generation) return;
53
+ if (!result.ok) throw new Error("Queue status unavailable");
54
+ items = parseQueueSnapshots(result.value, sessionId);
55
+ changed({
56
+ items,
57
+ unavailable: false
58
+ });
59
+ } catch {
60
+ if (!disposed && revision === generation) changed({
61
+ items,
62
+ unavailable: true
63
+ });
64
+ } finally {
65
+ clearTimeout(timeout);
66
+ if (active === controller) active = void 0;
67
+ if (!disposed && revision === generation && !visibility.hidden) timer = setTimeout(() => {
68
+ poll();
69
+ }, 1e3);
70
+ }
71
+ };
72
+ const stop = () => {
73
+ generation++;
74
+ clearTimeout(timer);
75
+ active?.abort();
76
+ active = void 0;
77
+ };
78
+ const onVisibility = () => {
79
+ stop();
80
+ if (!visibility.hidden) poll();
81
+ };
82
+ visibility.addEventListener("visibilitychange", onVisibility);
83
+ poll();
84
+ return () => {
85
+ disposed = true;
86
+ stop();
87
+ visibility.removeEventListener("visibilitychange", onVisibility);
88
+ };
89
+ }
90
+ //#endregion
91
+ //#region \0dsh-css:/home/runner/work/dsh-provider-qoder/dsh-provider-qoder/src/client/QoderQueueStatus.module.css.mjs
92
+ const css$2 = "._8MdOdG_queues{box-sizing:border-box;width:calc(100% - 2 * var(--dsh-composer-side-clearance,16px) - 2 * var(--dsh-composer-dock-inset,8px));max-width:calc(var(--dsh-composer-card-max-width,952px) - 2 * var(--dsh-composer-dock-inset,8px));padding:0 var(--dsh-composer-dock-inset,8px);--dsw-alias-label-shimmer:var(--dsw-alias-label-deep-diving-shimmer);color:var(--dsw-alias-label-deep-diving,#4d6bfe);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(22px + var(--dsh-content-font-delta,0px));flex:none;margin:0 auto}._8MdOdG_panel{isolation:isolate;border-radius:var(--dsw-radius-lg,16px);width:100%;padding:2px 0;position:relative;overflow:hidden}._8MdOdG_panel:before{z-index:-1;border-radius:inherit;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-1,#242629));backdrop-filter:var(--dsw-menu-backdrop-filter,none);content:\"\";pointer-events:none;position:absolute;inset:0}._8MdOdG_panel:after{border:.5px solid var(--dsw-alias-border-l1,#42454a);border-radius:inherit;content:\"\";pointer-events:none;position:absolute;inset:0}._8MdOdG_row{min-width:0}._8MdOdG_row+._8MdOdG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1,#42454a)}._8MdOdG_row[data-unavailable]{color:var(--dsw-alias-label-secondary)}._8MdOdG_summary{box-sizing:border-box;cursor:pointer;align-items:center;gap:10px;width:100%;min-width:0;min-height:36px;padding:7px 12px;list-style:none;display:flex}._8MdOdG_summary::-webkit-details-marker{display:none}._8MdOdG_summary:focus-visible{outline-offset:-2px;border-radius:var(--dsw-radius-md,8px);outline:2px solid}._8MdOdG_icon{flex:none;width:14px;height:14px}._8MdOdG_text{font-variant-numeric:tabular-nums;overflow-wrap:anywhere;flex:1;min-width:0}._8MdOdG_chevron{width:6px;height:6px;color:var(--dsw-alias-label-tertiary);border-bottom:1.5px solid;border-right:1.5px solid;flex:none;margin:0 3px 3px;transform:rotate(45deg)}._8MdOdG_row>details[open] ._8MdOdG_chevron{margin-bottom:-3px;transform:rotate(225deg)}._8MdOdG_details{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:2px 16px;padding:0 12px 10px 36px;display:flex}._8MdOdG_visuallyHidden{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;padding:0;position:absolute;overflow:hidden}";
93
+ const tagId$2 = "dsh-provider-qoder/QoderQueueStatus.module.css";
94
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
95
+ const tag = document.createElement("style");
96
+ tag.dataset.plugin = "dsh-provider-qoder";
97
+ tag.dataset.pluginCss = tagId$2;
98
+ tag.textContent = css$2;
99
+ document.head.appendChild(tag);
100
+ }
101
+ var QoderQueueStatus_module_css_default = {
102
+ "chevron": "_8MdOdG_chevron",
103
+ "details": "_8MdOdG_details",
104
+ "icon": "_8MdOdG_icon",
105
+ "panel": "_8MdOdG_panel",
106
+ "queues": "_8MdOdG_queues",
107
+ "row": "_8MdOdG_row",
108
+ "summary": "_8MdOdG_summary",
109
+ "text": "_8MdOdG_text",
110
+ "visuallyHidden": "_8MdOdG_visuallyHidden"
111
+ };
112
+ //#endregion
113
+ //#region src/client/QoderQueueStatus.tsx
114
+ function QueueRow({ item, unavailable, t }) {
115
+ const elapsed = Math.min(item.maxWaitMs, item.waitElapsedMs + Math.max(0, Date.now() - item.updatedAt));
116
+ const name = item.modelName ?? item.model;
117
+ const status = unavailable ? t("queueUnavailable") : t("queueWaiting", { model: name });
118
+ const label = unavailable ? status : t("queueRunningFor", {
119
+ model: name,
120
+ duration: formatQueueDuration(elapsed, t)
121
+ });
122
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
123
+ className: QoderQueueStatus_module_css_default.row,
124
+ "data-unavailable": unavailable || void 0,
125
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
126
+ className: QoderQueueStatus_module_css_default.visuallyHidden,
127
+ role: "status",
128
+ "aria-live": "polite",
129
+ "aria-atomic": "true",
130
+ children: status
131
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
132
+ className: QoderQueueStatus_module_css_default.summary,
133
+ "aria-label": status,
134
+ children: [
135
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutlineRegular, {
136
+ className: QoderQueueStatus_module_css_default.icon,
137
+ "aria-hidden": "true"
138
+ }),
139
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
140
+ active: !unavailable,
141
+ className: QoderQueueStatus_module_css_default.text,
142
+ "aria-hidden": "true",
143
+ children: label
144
+ }),
145
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
146
+ className: QoderQueueStatus_module_css_default.chevron,
147
+ "aria-hidden": "true"
148
+ })
149
+ ]
150
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
151
+ className: QoderQueueStatus_module_css_default.details,
152
+ children: [
153
+ item.queueCount !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueCount", { count: item.queueCount }) }),
154
+ item.waitTimeMs !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueEstimate", { seconds: Math.ceil(item.waitTimeMs / 1e3) }) }),
155
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueBudget", { seconds: Math.ceil(item.maxWaitMs / 1e3) }) }),
156
+ item.serviceAvailable === false && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueServiceUnavailable") })
157
+ ]
158
+ })] })]
159
+ });
160
+ }
161
+ /** A provider contribution in DSH's input dock, using its shared process-row primitives. */
162
+ function QoderQueueStatus({ sessionId, rpc, t }) {
163
+ const [view, setView] = (0, react.useState)();
164
+ (0, react.useEffect)(() => watchQueueStatus(rpc, sessionId, document, (state) => setView({
165
+ sessionId,
166
+ state
167
+ })), [rpc, sessionId]);
168
+ const state = view?.sessionId === sessionId ? view.state : void 0;
169
+ if (!state?.items.length) return null;
170
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
171
+ className: QoderQueueStatus_module_css_default.queues,
172
+ "aria-label": t("queueTitle"),
173
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
174
+ className: QoderQueueStatus_module_css_default.panel,
175
+ children: state.items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QueueRow, {
176
+ item,
177
+ unavailable: state.unavailable,
178
+ t
179
+ }, item.callId))
180
+ })
181
+ });
182
+ }
183
+ //#endregion
17
184
  //#region src/qoder/catalog.ts
18
185
  function positiveNumber(value) {
19
186
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
@@ -170,6 +337,61 @@ window.__ModuleLoader__.load({
170
337
  //#endregion
171
338
  //#region src/client/locales.ts
172
339
  const zh = {
340
+ accountConnectionTitle: "Qoder 账号",
341
+ signInDescription: "登录 Qoder,使用当前区域的订阅和模型。",
342
+ manageAccount: "管理账号",
343
+ manageCredential: "管理凭据",
344
+ changeAccount: "更换账号",
345
+ editPat: "编辑 PAT",
346
+ patActive: "正在使用 PAT",
347
+ saveAndUsePat: "保存并使用 PAT",
348
+ useSavedPat: "使用已保存的 PAT",
349
+ signInAgain: "重新登录",
350
+ reopenLogin: "重新打开官网",
351
+ loginLinkCopied: "链接已复制",
352
+ loginTimeRemaining: "链接剩余有效时间:{seconds} 秒",
353
+ regionChanged: "已切换服务区域;原区域如有未完成的登录,已取消。",
354
+ regionChangeFailed: "服务区域切换失败,请重试。",
355
+ browserRejected: "Qoder 未完成授权,请重新登录。",
356
+ browserStorageFailed: "官网授权已完成,但凭据保存失败。请检查存储后重新登录。",
357
+ authorizationConnectionFailed: "暂时无法连接或读取登录状态,请稍后重试。",
358
+ patSaveFailed: "PAT 保存或启用失败,请重试。",
359
+ browserRemoveFailed: "浏览器授权移除失败,请检查凭据存储是否可写后重试。",
360
+ browserLoginTitle: "Qoder 官网登录",
361
+ browserMethod: "浏览器授权",
362
+ savedBrowserAccount: "已保存的浏览器账号",
363
+ patMethod: "PAT 鉴权",
364
+ signedOut: "未连接",
365
+ sharedAuthorization: "当前区域的账号由所有连接此 DSH 实例的客户端共享。",
366
+ signInQoder: "通过 Qoder 登录",
367
+ signOutQoder: "移除浏览器授权",
368
+ usePat: "使用 PAT",
369
+ useBrowser: "使用已保存的浏览器授权",
370
+ cancelLogin: "取消登录",
371
+ openLogin: "打开登录页面",
372
+ copyLogin: "复制登录链接",
373
+ copyLoginFailed: "无法复制,请使用“打开登录页面”。",
374
+ browserWaiting: "等待在 Qoder 官网完成验证与授权…",
375
+ browserSaving: "正在保存授权…",
376
+ browserComplete: "已登录。",
377
+ browserCancelled: "登录已取消。",
378
+ browserTimeout: "登录链接已过期,请重新发起登录。",
379
+ browserFailed: "登录未完成,或授权保存失败。请检查账号状态后重试。",
380
+ browserExpired: "浏览器授权已失效,请重新登录。",
381
+ browserUnsaved: "续期凭据尚未保存,重启后可能需要重新登录;下次使用时将重试保存。",
382
+ browserOperationFailed: "无法更新登录状态,请重试。",
383
+ queueTitle: "Qoder 模型排队",
384
+ queueWaiting: "{model} 正在排队",
385
+ queueRunningFor: "{model} 正在排队,用时 {duration} ···",
386
+ queueHourUnit: "小时",
387
+ queueMinuteUnit: "分",
388
+ queueSecondUnit: "秒",
389
+ queueCount: "排队数量:{count}",
390
+ queueEstimate: "预计等待 {seconds} 秒",
391
+ queueElapsed: "已等待 {seconds} 秒",
392
+ queueUnavailable: "Qoder 排队状态暂不可用",
393
+ queueServiceUnavailable: "服务暂不可用,继续等待",
394
+ queueBudget: "等待上限 {seconds} 秒",
173
395
  nav: "Qoder",
174
396
  title: "Qoder 凭据",
175
397
  configured: "已配置",
@@ -183,7 +405,7 @@ window.__ModuleLoader__.load({
183
405
  regionGlobal: "国际版 (Global)",
184
406
  regionChina: "中国区 (CN)",
185
407
  regionHint: "请确保 PAT 与所选服务区域匹配。",
186
- tokenLabel: "API 密钥",
408
+ tokenLabel: "Personal Access Token (PAT)",
187
409
  tokenPlaceholder: "输入新的 Personal Access Token",
188
410
  configuredHint: "已配置——输入新值可替换",
189
411
  readOnly: "当前凭据存储不可写。",
@@ -218,7 +440,7 @@ window.__ModuleLoader__.load({
218
440
  accountTitle: "Qoder",
219
441
  accountLoading: "正在读取账号与额度…",
220
442
  accountFailed: "无法读取账号信息与额度。",
221
- accountCredentialHint: "请先在“模型”设置中配置 Qoder Personal Access Token。",
443
+ accountCredentialHint: "请先在“模型”设置中登录 Qoder 或选择已配置的 PAT。",
222
444
  refresh: "刷新",
223
445
  refreshing: "正在刷新…",
224
446
  userQuotaTitle: "个人额度",
@@ -242,6 +464,61 @@ window.__ModuleLoader__.load({
242
464
  searchModeHint: "智能路由模式下,使用 Qoder 模型时走 Qoder 搜索,使用其他模型时自动回退给备用搜索。"
243
465
  };
244
466
  const en = {
467
+ accountConnectionTitle: "Qoder account",
468
+ signInDescription: "Sign in to use your subscription and models for this region.",
469
+ manageAccount: "Manage account",
470
+ manageCredential: "Manage credentials",
471
+ changeAccount: "Change account",
472
+ editPat: "Edit PAT",
473
+ patActive: "Using PAT",
474
+ saveAndUsePat: "Save and use PAT",
475
+ useSavedPat: "Use saved PAT",
476
+ signInAgain: "Sign in again",
477
+ reopenLogin: "Reopen Qoder website",
478
+ loginLinkCopied: "Link copied",
479
+ loginTimeRemaining: "Link expires in {seconds} seconds",
480
+ regionChanged: "Region changed; any unfinished sign-in for the previous region was cancelled.",
481
+ regionChangeFailed: "Could not change region. Please retry.",
482
+ browserRejected: "Qoder authorization was not completed. Sign in again.",
483
+ browserStorageFailed: "Website authorization completed, but credentials could not be saved. Check storage and sign in again.",
484
+ authorizationConnectionFailed: "Could not connect or read sign-in status. Please retry shortly.",
485
+ patSaveFailed: "Could not save or activate the PAT. Please retry.",
486
+ browserRemoveFailed: "Could not remove browser authorization. Check that credential storage is writable and retry.",
487
+ browserLoginTitle: "Qoder website sign-in",
488
+ browserMethod: "Browser authorization",
489
+ savedBrowserAccount: "Saved browser account",
490
+ patMethod: "PAT authentication",
491
+ signedOut: "Disconnected",
492
+ sharedAuthorization: "The account for this region is shared by all clients connected to this DSH instance.",
493
+ signInQoder: "Sign in with Qoder",
494
+ signOutQoder: "Remove browser authorization",
495
+ usePat: "Use PAT",
496
+ useBrowser: "Use saved browser authorization",
497
+ cancelLogin: "Cancel sign-in",
498
+ openLogin: "Open sign-in page",
499
+ copyLogin: "Copy sign-in link",
500
+ copyLoginFailed: "Could not copy. Use Open sign-in page.",
501
+ browserWaiting: "Complete verification and authorization on the Qoder website…",
502
+ browserSaving: "Saving authorization…",
503
+ browserComplete: "Signed in.",
504
+ browserCancelled: "Sign-in cancelled.",
505
+ browserTimeout: "Sign-in link expired. Start a new sign-in.",
506
+ browserFailed: "Sign-in or saving authorization failed. Check account status and retry.",
507
+ browserExpired: "Browser authorization expired. Sign in again.",
508
+ browserUnsaved: "Renewed credentials have not been saved. Restarting may require sign-in; saving will be retried on next use.",
509
+ browserOperationFailed: "Could not update sign-in status. Please retry.",
510
+ queueTitle: "Qoder model queue",
511
+ queueWaiting: "{model} is queued",
512
+ queueRunningFor: "{model} queued for {duration} ···",
513
+ queueHourUnit: "h",
514
+ queueMinuteUnit: "m",
515
+ queueSecondUnit: "s",
516
+ queueCount: "Queue count: {count}",
517
+ queueEstimate: "Estimated wait: {seconds}s",
518
+ queueElapsed: "Waited {seconds}s",
519
+ queueUnavailable: "Qoder queue status is temporarily unavailable",
520
+ queueServiceUnavailable: "Service unavailable; waiting",
521
+ queueBudget: "Wait limit: {seconds}s",
245
522
  nav: "Qoder",
246
523
  title: "Qoder credential",
247
524
  configured: "Configured",
@@ -255,7 +532,7 @@ window.__ModuleLoader__.load({
255
532
  regionGlobal: "Global",
256
533
  regionChina: "China (CN)",
257
534
  regionHint: "Ensure your PAT matches the selected service region.",
258
- tokenLabel: "API Key",
535
+ tokenLabel: "Personal Access Token (PAT)",
259
536
  tokenPlaceholder: "Enter a new Personal Access Token",
260
537
  configuredHint: "Configured — enter a new value to replace",
261
538
  readOnly: "The current credential store is read-only.",
@@ -290,7 +567,7 @@ window.__ModuleLoader__.load({
290
567
  accountTitle: "Qoder",
291
568
  accountLoading: "Reading account and quota…",
292
569
  accountFailed: "Could not read account details or quota.",
293
- accountCredentialHint: "Configure the Qoder Personal Access Token in Models settings first.",
570
+ accountCredentialHint: "Sign in to Qoder or select a configured PAT in Models settings first.",
294
571
  refresh: "Refresh",
295
572
  refreshing: "Refreshing…",
296
573
  userQuotaTitle: "Personal Quota",
@@ -395,10 +672,13 @@ window.__ModuleLoader__.load({
395
672
  const followsConfig = this.snapshot.catalog === this.confirmed;
396
673
  this.confirmed = models.map(cloneCatalogModel);
397
674
  const selected = new Map(this.confirmed.map((model) => [model.id, model]));
675
+ const catalog = new Map(this.snapshot.catalog.map((model) => [model.id, selected.get(model.id) ?? model]));
676
+ for (const model of this.confirmed) catalog.set(model.id, model);
398
677
  this.publish({
399
678
  ...this.snapshot,
400
679
  models: this.confirmed,
401
- catalog: followsConfig ? this.confirmed : this.snapshot.catalog.map((model) => selected.get(model.id) ?? model)
680
+ catalog: followsConfig ? this.confirmed : [...catalog.values()],
681
+ unavailableIds: new Set([...this.snapshot.unavailableIds].filter((id) => !selected.has(id)))
402
682
  });
403
683
  }
404
684
  activate() {
@@ -505,7 +785,7 @@ window.__ModuleLoader__.load({
505
785
  };
506
786
  //#endregion
507
787
  //#region \0dsh-css:/home/runner/work/dsh-provider-qoder/dsh-provider-qoder/src/client/QoderCredentialCard.module.css.mjs
508
- const css$1 = ".SRqrhW_credential{color:var(--dsw-alias-label-primary);border-radius:10px;margin-top:12px}.SRqrhW_credential p{margin:8px 0 0}.SRqrhW_credentialEditor{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);flex-direction:column;gap:12px;padding:12px 14px;display:flex}.SRqrhW_credentialRowHead{align-items:center;gap:10px;display:flex}.SRqrhW_credentialIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.SRqrhW_credentialName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.SRqrhW_credentialDot{box-sizing:border-box;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.SRqrhW_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.SRqrhW_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.SRqrhW_regionBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:500;line-height:16px;display:inline-flex}.SRqrhW_regionSelector{flex-direction:column;gap:8px;margin-bottom:14px;display:flex}.SRqrhW_regionGroup{gap:8px;display:flex}.SRqrhW_regionOption{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);user-select:none;border-radius:8px;align-items:center;gap:6px;padding:6px 12px;font-size:12px;line-height:18px;transition:all .12s;display:inline-flex}.SRqrhW_regionOption:hover:not(.SRqrhW_regionOptionDisabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.SRqrhW_credential button.SRqrhW_regionOptionActive{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-selected);color:var(--dsw-alias-brand-primary);font-weight:500}.SRqrhW_regionOptionDisabled{cursor:not-allowed;opacity:.5}.SRqrhW_editButton{box-sizing:border-box;font:inherit;background:0 0;margin-left:auto;font-size:12px;line-height:18px;border:1px solid var(--dsw-alias-border-l2)!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_editButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.SRqrhW_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;padding:14px 16px}.SRqrhW_customized{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);margin-top:12px;transition:all .12s;overflow:hidden}.SRqrhW_customizedSummary{box-sizing:border-box;border-radius:var(--dsw-radius-xl,12px);cursor:pointer;width:100%;color:var(--dsw-alias-label-primary);user-select:none;align-items:center;gap:8px;margin:0;padding:12px 14px;font-size:13px;font-weight:600;line-height:18px;list-style:none;transition:background .12s;display:flex}.SRqrhW_customizedSummary:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelSummaryBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-tertiary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:400;line-height:16px;display:inline-flex}.SRqrhW_customizedSummary::-webkit-details-marker{display:none}.SRqrhW_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary{border-bottom:.5px solid var(--dsw-alias-border-l2);border-bottom-right-radius:0;border-bottom-left-radius:0}.SRqrhW_customizedBody{padding:12px 14px 14px}.SRqrhW_modelCatalog{flex-direction:column;gap:10px;display:flex}.SRqrhW_modelList{flex-direction:column;gap:10px;max-height:360px;padding-right:4px;display:flex;overflow-y:auto}.SRqrhW_modelList::-webkit-scrollbar{width:4px}.SRqrhW_modelList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);border-radius:2px}.SRqrhW_modelCatalogHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.SRqrhW_modelCatalogHeadCompact{justify-content:flex-end;align-items:center;gap:12px;display:flex}.SRqrhW_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.SRqrhW_modelCatalogMeta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:2px 0 0!important}.SRqrhW_linkButton{box-sizing:border-box;font:inherit;background:0 0;font-size:12px;line-height:18px;border:none!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoice{border-radius:6px;flex-direction:column;gap:4px;padding:6px 8px;font-size:13px;display:flex}.SRqrhW_modelChoice:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoiceHead{cursor:pointer;grid-template-columns:auto minmax(0,1fr) auto auto auto;align-items:center;gap:8px;display:grid}.SRqrhW_modelTier{align-items:center;gap:8px;padding-left:24px;display:flex}.SRqrhW_modelTierLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px}.SRqrhW_modelTierSelect{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);height:24px;color:inherit;font:inherit;cursor:pointer;border:0;border-radius:6px;padding:0 6px;font-size:12px}.SRqrhW_modelTierHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px;margin:0!important}.SRqrhW_modelChoiceName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.SRqrhW_modelChoice code{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_modelRate{min-width:34px;color:var(--dsw-alias-brand-primary);text-align:right;font-size:12px;font-weight:600}.SRqrhW_modelUnavailable{cursor:not-allowed;opacity:.55}.SRqrhW_modelBadge{color:var(--dsw-alias-state-error-primary);font-size:11px}@media (prefers-reduced-motion:reduce){.SRqrhW_customizedSummary:before{transition:none}}.SRqrhW_head{justify-content:space-between;align-items:center;gap:12px;margin-bottom:20px;display:flex}.SRqrhW_heading{margin:0;font-size:18px;font-weight:600}.SRqrhW_status{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_configured,.SRqrhW_success{color:var(--dsw-alias-state-success-primary)}.SRqrhW_label{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;display:block}.SRqrhW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;height:32px;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;margin-top:6px;padding:0 10px}.SRqrhW_input:focus{border-color:var(--dsw-alias-brand-primary)}.SRqrhW_input::placeholder{color:var(--dsw-alias-label-dimmed)}.SRqrhW_input:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_hint{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_actions{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.SRqrhW_credential button{cursor:pointer;height:32px;color:var(--dsw-alias-label-primary);border:1px solid #0000;border-radius:16px;padding:0 12px}.SRqrhW_credential button:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_primary{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)!important}.SRqrhW_primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.SRqrhW_secondary{background:0 0;border-color:var(--dsw-alias-border-l2)!important}.SRqrhW_secondary:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_danger{background:0 0;border-color:var(--dsw-alias-state-error-primary)!important;color:var(--dsw-alias-state-error-primary)!important}.SRqrhW_danger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.SRqrhW_error{color:var(--dsw-alias-state-error-primary);font-size:12px}.SRqrhW_success{font-size:12px}.SRqrhW_accountSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_accountHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_userInfo{align-items:center;gap:10px;min-width:0;display:flex}.SRqrhW_avatar{background:var(--dsw-alias-brand-primary);width:32px;height:32px;color:var(--dsw-alias-label-primary-foreground);text-transform:uppercase;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:flex}.SRqrhW_userDetails{flex-direction:column;gap:2px;min-width:0;display:flex}.SRqrhW_userName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;overflow:hidden}.SRqrhW_userEmail{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.SRqrhW_refreshBtn{border:1px solid var(--dsw-alias-border-l2)!important;height:26px!important;color:var(--dsw-alias-label-secondary)!important;background:0 0!important;border-radius:13px!important;padding:0 8px!important;font-size:12px!important}.SRqrhW_refreshBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)!important}.SRqrhW_quotaBlock{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding-top:8px;display:flex}.SRqrhW_quotaHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_quotaLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.SRqrhW_quotaTop{justify-content:space-between;align-items:baseline;gap:8px;font-size:12px;display:flex}.SRqrhW_quotaTop strong{color:var(--dsw-alias-brand-primary);font-size:13px}.SRqrhW_quotaDescription{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;margin:0!important}.SRqrhW_quotaProgress{background:var(--dsw-alias-border-l3);width:100%;height:6px;accent-color:var(--dsw-alias-brand-primary);-webkit-appearance:none;appearance:none;border:0;border-radius:999px;overflow:hidden}.SRqrhW_quotaProgress::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.SRqrhW_quotaProgress::-webkit-progress-value{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaProgress::-moz-progress-bar{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaMeta{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;gap:8px;font-size:11px;display:flex}.SRqrhW_accountLoadingText,.SRqrhW_accountEmptyText{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}.SRqrhW_userNameRow{align-items:center;gap:8px;display:flex}.SRqrhW_planBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-brand-primary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.SRqrhW_orgTag{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_suspendedBanner{background:var(--dsw-alias-state-error-subtle,#ff4d4f1a);color:var(--dsw-alias-state-error-primary);border-radius:6px;align-items:center;gap:6px;margin-bottom:8px;padding:6px 10px;font-size:12px;display:flex}.SRqrhW_searchModeSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_searchModeHintText{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:12px;line-height:18px}";
788
+ const css$1 = ".SRqrhW_credential{color:var(--dsw-alias-label-primary);border-radius:10px;margin-top:12px}.SRqrhW_connectionBody{flex-direction:column;gap:10px;display:flex}.SRqrhW_connectionHead,.SRqrhW_subscriberRow{justify-content:space-between;align-items:center;gap:16px;display:flex}.SRqrhW_connectionHead{flex-wrap:wrap}.SRqrhW_subscriberRow{padding:10px 0}.SRqrhW_subscriberAvatar{width:42px;height:42px;color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-selected);border-radius:50%;flex:none;place-items:center;font-size:18px;font-weight:600;display:grid}.SRqrhW_subscriberIdentity{overflow-wrap:anywhere;flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.SRqrhW_subscriberIdentity>span{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_connectionActions{flex-wrap:wrap;align-items:center;gap:10px;margin-top:12px;display:flex}.SRqrhW_loginProgress{background:var(--dsw-alias-interactive-bg-hover);border-radius:10px;flex-direction:column;gap:8px;padding:14px;display:flex}.SRqrhW_managementPanel{background:var(--dsw-alias-bg-module-platform);border-radius:10px;flex-wrap:wrap;align-items:center;gap:10px;padding:12px;display:flex}.SRqrhW_credential .SRqrhW_textButton{color:var(--dsw-alias-brand-primary);background:0 0;border:0!important;padding:4px 2px!important}.SRqrhW_primaryLink{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-radius:18px;padding:8px 14px;font-size:12px;text-decoration:none;display:inline-flex}.SRqrhW_credential p.SRqrhW_sharedNote{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin-top:6px;padding-top:12px;font-size:12px}@media (width<=480px){.SRqrhW_subscriberRow{flex-wrap:wrap}.SRqrhW_subscriberIdentity{flex-basis:calc(100% - 60px)}}.SRqrhW_credential p{margin:8px 0 0}.SRqrhW_credentialEditor{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);flex-direction:column;gap:12px;padding:12px 14px;display:flex}.SRqrhW_credentialRowHead{align-items:center;gap:10px;display:flex}.SRqrhW_credentialIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.SRqrhW_credentialName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.SRqrhW_credentialDot{box-sizing:border-box;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.SRqrhW_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.SRqrhW_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.SRqrhW_regionBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:500;line-height:16px;display:inline-flex}.SRqrhW_regionSelector{flex-direction:column;gap:8px;margin-bottom:14px;display:flex}.SRqrhW_regionGroup{gap:8px;display:flex}.SRqrhW_regionOption{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);user-select:none;border-radius:8px;align-items:center;gap:6px;padding:6px 12px;font-size:12px;line-height:18px;transition:all .12s;display:inline-flex}.SRqrhW_regionOption:hover:not(.SRqrhW_regionOptionDisabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.SRqrhW_credential button.SRqrhW_regionOptionActive{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-selected);color:var(--dsw-alias-brand-primary);font-weight:500}.SRqrhW_regionOptionDisabled{cursor:not-allowed;opacity:.5}.SRqrhW_editButton{box-sizing:border-box;font:inherit;background:0 0;margin-left:auto;font-size:12px;line-height:18px;border:1px solid var(--dsw-alias-border-l2)!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_editButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.SRqrhW_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;padding:14px 16px}.SRqrhW_customized{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);margin-top:12px;transition:all .12s;overflow:hidden}.SRqrhW_customizedSummary{box-sizing:border-box;border-radius:var(--dsw-radius-xl,12px);cursor:pointer;width:100%;color:var(--dsw-alias-label-primary);user-select:none;align-items:center;gap:8px;margin:0;padding:12px 14px;font-size:13px;font-weight:600;line-height:18px;list-style:none;transition:background .12s;display:flex}.SRqrhW_customizedSummary:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelSummaryBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-tertiary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:400;line-height:16px;display:inline-flex}.SRqrhW_customizedSummary::-webkit-details-marker{display:none}.SRqrhW_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary{border-bottom:.5px solid var(--dsw-alias-border-l2);border-bottom-right-radius:0;border-bottom-left-radius:0}.SRqrhW_customizedBody{padding:12px 14px 14px}.SRqrhW_modelCatalog{flex-direction:column;gap:10px;display:flex}.SRqrhW_modelList{flex-direction:column;gap:10px;max-height:360px;padding-right:4px;display:flex;overflow-y:auto}.SRqrhW_modelList::-webkit-scrollbar{width:4px}.SRqrhW_modelList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);border-radius:2px}.SRqrhW_modelCatalogHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.SRqrhW_modelCatalogHeadCompact{justify-content:flex-end;align-items:center;gap:12px;display:flex}.SRqrhW_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.SRqrhW_modelCatalogMeta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:2px 0 0!important}.SRqrhW_linkButton{box-sizing:border-box;font:inherit;background:0 0;font-size:12px;line-height:18px;border:none!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoice{border-radius:6px;flex-direction:column;gap:4px;padding:6px 8px;font-size:13px;display:flex}.SRqrhW_modelChoice:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoiceHead{cursor:pointer;grid-template-columns:auto minmax(0,1fr) auto auto auto;align-items:center;gap:8px;display:grid}.SRqrhW_modelTier{align-items:center;gap:8px;padding-left:24px;display:flex}.SRqrhW_modelTierLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px}.SRqrhW_modelTierSelect{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);height:24px;color:inherit;font:inherit;cursor:pointer;border:0;border-radius:6px;padding:0 6px;font-size:12px}.SRqrhW_modelTierHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px;margin:0!important}.SRqrhW_modelChoiceName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.SRqrhW_modelChoice code{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_modelRate{min-width:34px;color:var(--dsw-alias-brand-primary);text-align:right;font-size:12px;font-weight:600}.SRqrhW_modelUnavailable{cursor:not-allowed;opacity:.55}.SRqrhW_modelBadge{color:var(--dsw-alias-state-error-primary);font-size:11px}@media (prefers-reduced-motion:reduce){.SRqrhW_customizedSummary:before{transition:none}}.SRqrhW_head{justify-content:space-between;align-items:center;gap:12px;margin-bottom:20px;display:flex}.SRqrhW_heading{margin:0;font-size:18px;font-weight:600}.SRqrhW_status{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_configured,.SRqrhW_success{color:var(--dsw-alias-state-success-primary)}.SRqrhW_label{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;display:block}.SRqrhW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;height:32px;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;margin-top:6px;padding:0 10px}.SRqrhW_input:focus{border-color:var(--dsw-alias-brand-primary)}.SRqrhW_input::placeholder{color:var(--dsw-alias-label-dimmed)}.SRqrhW_input:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_hint{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_actions{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.SRqrhW_credential button{cursor:pointer;height:32px;color:var(--dsw-alias-label-primary);border:1px solid #0000;border-radius:16px;padding:0 12px}.SRqrhW_credential button:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_primary{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)!important}.SRqrhW_primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.SRqrhW_secondary{background:0 0;border-color:var(--dsw-alias-border-l2)!important}.SRqrhW_secondary:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_danger{background:0 0;border-color:var(--dsw-alias-state-error-primary)!important;color:var(--dsw-alias-state-error-primary)!important}.SRqrhW_danger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.SRqrhW_error{color:var(--dsw-alias-state-error-primary);font-size:12px}.SRqrhW_success{font-size:12px}.SRqrhW_accountSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_accountHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_userInfo{align-items:center;gap:10px;min-width:0;display:flex}.SRqrhW_avatar{background:var(--dsw-alias-brand-primary);width:32px;height:32px;color:var(--dsw-alias-label-primary-foreground);text-transform:uppercase;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:flex}.SRqrhW_userDetails{flex-direction:column;gap:2px;min-width:0;display:flex}.SRqrhW_userName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;overflow:hidden}.SRqrhW_userEmail{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.SRqrhW_refreshBtn{border:1px solid var(--dsw-alias-border-l2)!important;height:26px!important;color:var(--dsw-alias-label-secondary)!important;background:0 0!important;border-radius:13px!important;padding:0 8px!important;font-size:12px!important}.SRqrhW_refreshBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)!important}.SRqrhW_quotaBlock{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding-top:8px;display:flex}.SRqrhW_quotaHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_quotaLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.SRqrhW_quotaTop{justify-content:space-between;align-items:baseline;gap:8px;font-size:12px;display:flex}.SRqrhW_quotaTop strong{color:var(--dsw-alias-brand-primary);font-size:13px}.SRqrhW_quotaDescription{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;margin:0!important}.SRqrhW_quotaProgress{background:var(--dsw-alias-border-l3);width:100%;height:6px;accent-color:var(--dsw-alias-brand-primary);-webkit-appearance:none;appearance:none;border:0;border-radius:999px;overflow:hidden}.SRqrhW_quotaProgress::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.SRqrhW_quotaProgress::-webkit-progress-value{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaProgress::-moz-progress-bar{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaMeta{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;gap:8px;font-size:11px;display:flex}.SRqrhW_accountLoadingText,.SRqrhW_accountEmptyText{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}.SRqrhW_userNameRow{align-items:center;gap:8px;display:flex}.SRqrhW_planBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-brand-primary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.SRqrhW_orgTag{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_suspendedBanner{background:var(--dsw-alias-state-error-subtle,#ff4d4f1a);color:var(--dsw-alias-state-error-primary);border-radius:6px;align-items:center;gap:6px;margin-bottom:8px;padding:6px 10px;font-size:12px;display:flex}.SRqrhW_searchModeSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_searchModeHintText{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:12px;line-height:18px}";
509
789
  const tagId$1 = "dsh-provider-qoder/QoderCredentialCard.module.css";
510
790
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
511
791
  const tag = document.createElement("style");
@@ -522,6 +802,9 @@ window.__ModuleLoader__.load({
522
802
  "actions": "SRqrhW_actions",
523
803
  "avatar": "SRqrhW_avatar",
524
804
  "configured": "SRqrhW_configured",
805
+ "connectionActions": "SRqrhW_connectionActions",
806
+ "connectionBody": "SRqrhW_connectionBody",
807
+ "connectionHead": "SRqrhW_connectionHead",
525
808
  "credential": "SRqrhW_credential",
526
809
  "credentialDot": "SRqrhW_credentialDot",
527
810
  "credentialDotConfigured": "SRqrhW_credentialDotConfigured",
@@ -543,6 +826,8 @@ window.__ModuleLoader__.load({
543
826
  "input": "SRqrhW_input",
544
827
  "label": "SRqrhW_label",
545
828
  "linkButton": "SRqrhW_linkButton",
829
+ "loginProgress": "SRqrhW_loginProgress",
830
+ "managementPanel": "SRqrhW_managementPanel",
546
831
  "modelBadge": "SRqrhW_modelBadge",
547
832
  "modelCatalog": "SRqrhW_modelCatalog",
548
833
  "modelCatalogHead": "SRqrhW_modelCatalogHead",
@@ -563,6 +848,7 @@ window.__ModuleLoader__.load({
563
848
  "orgTag": "SRqrhW_orgTag",
564
849
  "planBadge": "SRqrhW_planBadge",
565
850
  "primary": "SRqrhW_primary",
851
+ "primaryLink": "SRqrhW_primaryLink",
566
852
  "quotaBlock": "SRqrhW_quotaBlock",
567
853
  "quotaDescription": "SRqrhW_quotaDescription",
568
854
  "quotaHeader": "SRqrhW_quotaHeader",
@@ -580,9 +866,14 @@ window.__ModuleLoader__.load({
580
866
  "searchModeHintText": "SRqrhW_searchModeHintText",
581
867
  "searchModeSection": "SRqrhW_searchModeSection",
582
868
  "secondary": "SRqrhW_secondary",
869
+ "sharedNote": "SRqrhW_sharedNote",
583
870
  "status": "SRqrhW_status",
871
+ "subscriberAvatar": "SRqrhW_subscriberAvatar",
872
+ "subscriberIdentity": "SRqrhW_subscriberIdentity",
873
+ "subscriberRow": "SRqrhW_subscriberRow",
584
874
  "success": "SRqrhW_success",
585
875
  "suspendedBanner": "SRqrhW_suspendedBanner",
876
+ "textButton": "SRqrhW_textButton",
586
877
  "userDetails": "SRqrhW_userDetails",
587
878
  "userEmail": "SRqrhW_userEmail",
588
879
  "userInfo": "SRqrhW_userInfo",
@@ -612,7 +903,7 @@ window.__ModuleLoader__.load({
612
903
  const fetching = snapshot.pending === "discovering";
613
904
  const failure = snapshot.failureMessage || (snapshot.failure ? t(snapshot.failure) : void 0);
614
905
  const renderRate = (model) => {
615
- if (model.isFree || model.priceFactor === 0) return t("modelRateFree");
906
+ if (model.priceFactor === 0 || model.priceFactor === void 0 && model.isFree) return t("modelRateFree");
616
907
  if (model.priceFactor === void 0) return t("modelRateUnknown");
617
908
  const current = formatRateFactor(model.priceFactor);
618
909
  if (model.originalPriceFactor !== void 0 && model.originalPriceFactor > model.priceFactor) return t("modelRateDiscount", {
@@ -869,7 +1160,7 @@ window.__ModuleLoader__.load({
869
1160
  const renderAccount = () => {
870
1161
  if (!configured) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
871
1162
  className: QoderCredentialCard_module_css_default.accountSection,
872
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1163
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
873
1164
  className: QoderCredentialCard_module_css_default.accountEmptyText,
874
1165
  children: t("accountCredentialHint")
875
1166
  })
@@ -1098,228 +1389,539 @@ window.__ModuleLoader__.load({
1098
1389
  });
1099
1390
  }
1100
1391
  //#endregion
1101
- //#region src/client/QoderCredentialCard.tsx
1102
- function QoderCredentialCard({ operations, t }) {
1103
- const [state, setState] = (0, react.useState)({ status: "loading" });
1392
+ //#region src/client/QoderBrowserLogin.tsx
1393
+ /** A single current identity, with browser and PAT management revealed only when needed. */
1394
+ function QoderBrowserLogin({ region, operations, credentials, onBusyChange, t }) {
1395
+ const [view, setView] = (0, react.useState)();
1396
+ const [pat, setPat] = (0, react.useState)();
1397
+ const [profile, setProfile] = (0, react.useState)();
1398
+ const [busy, setBusy] = (0, react.useState)(false);
1399
+ const [error, setError] = (0, react.useState)();
1400
+ const [readFailed, setReadFailed] = (0, react.useState)(false);
1104
1401
  const [editing, setEditing] = (0, react.useState)(false);
1402
+ const [menu, setMenu] = (0, react.useState)(false);
1105
1403
  const [draft, setDraft] = (0, react.useState)("");
1106
- const [regionDraft, setRegionDraft] = (0, react.useState)("global");
1107
- const [regionDirty, setRegionDirty] = (0, react.useState)(false);
1108
- const [mutation, setMutation] = (0, react.useState)();
1109
- const [notice, setNotice] = (0, react.useState)();
1110
- const modelSnapshot = (0, react.useSyncExternalStore)(operations.subscribeModels, operations.getModelSnapshot, operations.getModelSnapshot);
1404
+ const [copyFailed, setCopyFailed] = (0, react.useState)(false);
1405
+ const [copied, setCopied] = (0, react.useState)(false);
1406
+ const [now, setNow] = (0, react.useState)(Date.now());
1407
+ const [accountRevision, setAccountRevision] = (0, react.useState)(0);
1408
+ const mounted = (0, react.useRef)(false);
1409
+ const revision = (0, react.useRef)(0);
1410
+ const mutating = (0, react.useRef)(false);
1411
+ const waitingRef = (0, react.useRef)(false);
1412
+ const wakeRef = (0, react.useRef)(void 0);
1413
+ const attempt = view?.attempt;
1414
+ const pending = attempt !== void 0 && [
1415
+ "waiting",
1416
+ "verifying",
1417
+ "saving"
1418
+ ].includes(attempt.phase);
1419
+ const connected = view?.configured === true && !view.expired;
1420
+ const identity = view?.method === "browser" ? view.profile : profile;
1421
+ const patConfigured = pat?.configured === true && !isEnvironmentCredentialSource(pat.source);
1422
+ const remaining = Math.max(0, Math.ceil(((attempt?.expiresAt ?? now) - now) / 1e3));
1423
+ const read = async () => {
1424
+ const info = await (credentials.describePat ?? credentials.describe)();
1425
+ const result = operations ? await operations.read(region) : void 0;
1426
+ if (result && !result.ok) throw new Error("Authorization status unavailable");
1427
+ if (!result && !info) throw new Error("Credential status unavailable");
1428
+ return {
1429
+ info,
1430
+ value: result?.value ?? {
1431
+ region,
1432
+ method: "pat",
1433
+ configured: info?.configured === true && !isEnvironmentCredentialSource(info.source),
1434
+ writable: false
1435
+ }
1436
+ };
1437
+ };
1111
1438
  (0, react.useEffect)(() => {
1112
- if (modelSnapshot.status === "ready" && !regionDirty) setRegionDraft(regionOf(modelSnapshot.value));
1113
- }, [modelSnapshot, regionDirty]);
1114
- const load = (0, react.useCallback)(async () => {
1115
- const info = await operations.describe();
1116
- setState(info === void 0 ? { status: "failed" } : {
1117
- status: "ready",
1118
- info
1439
+ mounted.current = true;
1440
+ let active = true;
1441
+ let timer;
1442
+ const poll = async (identityChanged = false) => {
1443
+ const version = revision.current;
1444
+ try {
1445
+ const result = await read();
1446
+ if (active && mounted.current && version === revision.current && !mutating.current) {
1447
+ waitingRef.current = result.value.attempt !== void 0 && [
1448
+ "waiting",
1449
+ "verifying",
1450
+ "saving"
1451
+ ].includes(result.value.attempt.phase);
1452
+ setView(result.value);
1453
+ setPat(result.info);
1454
+ setReadFailed(false);
1455
+ setNow(Date.now());
1456
+ if (identityChanged) setAccountRevision((value) => value + 1);
1457
+ }
1458
+ } catch {
1459
+ if (mounted.current && version === revision.current) setReadFailed(true);
1460
+ }
1461
+ if (active && mounted.current) {
1462
+ clearTimeout(timer);
1463
+ timer = setTimeout(() => {
1464
+ poll();
1465
+ }, waitingRef.current ? 1e3 : 1e4);
1466
+ }
1467
+ };
1468
+ poll();
1469
+ wakeRef.current = () => {
1470
+ clearTimeout(timer);
1471
+ timer = setTimeout(() => {
1472
+ poll();
1473
+ }, 1e3);
1474
+ };
1475
+ const unsubscribe = credentials.subscribe?.(() => {
1476
+ if (mutating.current || !active) return;
1477
+ revision.current++;
1478
+ setProfile(void 0);
1479
+ poll(true);
1119
1480
  });
1120
- }, [operations]);
1481
+ return () => {
1482
+ active = false;
1483
+ mounted.current = false;
1484
+ wakeRef.current = void 0;
1485
+ clearTimeout(timer);
1486
+ unsubscribe?.();
1487
+ revision.current++;
1488
+ };
1489
+ }, [
1490
+ operations,
1491
+ credentials,
1492
+ region
1493
+ ]);
1121
1494
  (0, react.useEffect)(() => {
1122
- load();
1123
- return operations.subscribe(() => {
1124
- load();
1125
- });
1126
- }, [load, operations]);
1127
- if (state.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
1128
- className: QoderCredentialCard_module_css_default.credential,
1129
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("loading") })
1130
- });
1131
- if (state.status === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1132
- className: QoderCredentialCard_module_css_default.credential,
1133
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1134
- className: QoderCredentialCard_module_css_default.error,
1135
- role: "alert",
1136
- children: t("loadFailed")
1137
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1138
- type: "button",
1139
- className: QoderCredentialCard_module_css_default.secondary,
1140
- onClick: () => {
1141
- load();
1142
- },
1143
- children: t("retry")
1144
- })]
1145
- });
1146
- const configured = state.info.configured && !isEnvironmentCredentialSource(state.info.source);
1147
- const writable = state.info.writable;
1148
- const busy = mutation !== void 0;
1149
- const normalized = draft.trim();
1150
- const canModifyRegion = modelSnapshot.status === "ready" && modelSnapshot.writable;
1151
- const currentRegion = regionOf(modelSnapshot.value);
1152
- const closeEditor = () => {
1153
- setDraft("");
1154
- setRegionDraft(regionOf(modelSnapshot.value));
1155
- setRegionDirty(false);
1156
- setNotice(void 0);
1157
- setEditing(false);
1158
- };
1159
- const save = async () => {
1160
- if (busy || !regionDirty && normalized.length === 0 || regionDirty && !canModifyRegion) return;
1161
- setMutation("saving");
1162
- setNotice(void 0);
1163
- if (regionDirty) {
1164
- if (!await operations.storeRegion(regionDraft)) {
1165
- setNotice("saveFailed");
1166
- setMutation(void 0);
1495
+ let active = true;
1496
+ setProfile(void 0);
1497
+ if (view?.method === "pat" && view.configured) {
1498
+ const version = revision.current;
1499
+ credentials.getAccount().then((result) => {
1500
+ if (active && version === revision.current && result?.ok) setProfile(result.value.profile);
1501
+ }).catch(() => {});
1502
+ }
1503
+ return () => {
1504
+ active = false;
1505
+ };
1506
+ }, [
1507
+ credentials,
1508
+ view?.method,
1509
+ view?.configured,
1510
+ accountRevision
1511
+ ]);
1512
+ const mutate = async (action) => {
1513
+ if (mutating.current) return;
1514
+ const popup = action === "begin" ? window.open("about:blank", "_blank") : null;
1515
+ if (popup) popup.opener = null;
1516
+ const version = ++revision.current;
1517
+ mutating.current = true;
1518
+ onBusyChange?.(true);
1519
+ setBusy(true);
1520
+ setError(void 0);
1521
+ setMenu(false);
1522
+ try {
1523
+ let result;
1524
+ if (action === "savePat") if (draft.trim()) {
1525
+ if (!await credentials.store(draft.trim())) throw new Error("PAT save failed");
1526
+ } else if (patConfigured) {
1527
+ if (operations) result = await operations.select(region, "pat");
1528
+ } else throw new Error("A PAT is required");
1529
+ else if (action === "removePat") {
1530
+ if (!await credentials.remove()) throw new Error("PAT removal failed");
1531
+ } else if (operations) result = action === "begin" ? await operations.begin(region) : action === "cancel" ? await operations.cancel(region) : await operations.select(region, action);
1532
+ if (result && !result.ok) {
1533
+ if (mounted.current && version === revision.current) {
1534
+ const code = result.error.code;
1535
+ setError(action === "none" ? "browserRemoveFailed" : code === "TIMEOUT" ? "browserTimeout" : code === "UNAUTHENTICATED" ? "browserRejected" : "authorizationConnectionFailed");
1536
+ }
1537
+ popup?.close();
1538
+ return;
1539
+ }
1540
+ const current = result?.value;
1541
+ if (!mounted.current || version !== revision.current) {
1542
+ popup?.close();
1167
1543
  return;
1168
1544
  }
1169
- setRegionDirty(false);
1545
+ if (popup && current?.attempt?.url) popup.location.replace(current.attempt.url);
1546
+ else popup?.close();
1547
+ const refreshed = current ? {
1548
+ value: current,
1549
+ info: pat
1550
+ } : await read();
1551
+ if (!mounted.current || version !== revision.current) {
1552
+ popup?.close();
1553
+ return;
1554
+ }
1555
+ setView(refreshed.value);
1556
+ setPat(refreshed.info);
1557
+ setReadFailed(false);
1558
+ setNow(Date.now());
1559
+ waitingRef.current = refreshed.value.attempt !== void 0 && [
1560
+ "waiting",
1561
+ "verifying",
1562
+ "saving"
1563
+ ].includes(refreshed.value.attempt.phase);
1564
+ if (action === "savePat" || action === "removePat") {
1565
+ setDraft("");
1566
+ setEditing(false);
1567
+ setProfile(void 0);
1568
+ setAccountRevision((value) => value + 1);
1569
+ }
1570
+ } catch {
1571
+ popup?.close();
1572
+ if (mounted.current && version === revision.current) setError(action === "savePat" ? "patSaveFailed" : action === "removePat" ? "removeFailed" : action === "none" ? "browserRemoveFailed" : "authorizationConnectionFailed");
1573
+ } finally {
1574
+ mutating.current = false;
1575
+ onBusyChange?.(false);
1576
+ if (mounted.current && version === revision.current) {
1577
+ revision.current++;
1578
+ setBusy(false);
1579
+ }
1580
+ if (mounted.current) wakeRef.current?.();
1170
1581
  }
1171
- if (normalized.length === 0 || await operations.store(normalized)) {
1172
- setDraft("");
1173
- setNotice("saved");
1174
- if (normalized.length > 0) await load();
1175
- setEditing(false);
1176
- } else setNotice("saveFailed");
1177
- setMutation(void 0);
1178
1582
  };
1179
- const remove = async () => {
1180
- if (!configured || !writable || busy || !window.confirm(t("confirmRemove"))) return;
1181
- setMutation("removing");
1182
- setNotice(void 0);
1183
- if (await operations.remove()) {
1184
- setDraft("");
1185
- await load();
1186
- } else setNotice("removeFailed");
1187
- setMutation(void 0);
1583
+ const openPat = () => {
1584
+ setMenu(false);
1585
+ setDraft("");
1586
+ setError(void 0);
1587
+ setEditing(true);
1188
1588
  };
1189
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1190
- className: `${QoderCredentialCard_module_css_default.credential} ${QoderCredentialCard_module_css_default.credentialEditor}`,
1191
- "aria-label": t("title"),
1589
+ const initial = (identity?.name || identity?.email || "Q").slice(0, 1).toUpperCase();
1590
+ const failure = attempt?.phase === "failed" ? attempt.failure === "storage" ? "browserStorageFailed" : attempt.failure === "connection" ? "authorizationConnectionFailed" : "browserRejected" : void 0;
1591
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1592
+ className: QoderCredentialCard_module_css_default.connectionBody,
1593
+ "aria-label": t("accountConnectionTitle"),
1192
1594
  children: [
1193
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1194
- className: QoderCredentialCard_module_css_default.credentialRowHead,
1195
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1196
- className: QoderCredentialCard_module_css_default.credentialIdentity,
1595
+ !view ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1596
+ role: "status",
1597
+ children: t(readFailed ? "authorizationConnectionFailed" : "loading")
1598
+ }) : null,
1599
+ readFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1600
+ type: "button",
1601
+ className: QoderCredentialCard_module_css_default.secondary,
1602
+ onClick: () => wakeRef.current?.(),
1603
+ children: t("retry")
1604
+ }) : null,
1605
+ view ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
1606
+ connected || view.expired ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1607
+ className: QoderCredentialCard_module_css_default.subscriberRow,
1197
1608
  children: [
1198
1609
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1199
- className: QoderCredentialCard_module_css_default.credentialName,
1200
- children: t("nav")
1610
+ className: QoderCredentialCard_module_css_default.subscriberAvatar,
1611
+ "aria-hidden": "true",
1612
+ children: initial
1201
1613
  }),
1202
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1203
- className: QoderCredentialCard_module_css_default.regionBadge,
1204
- children: currentRegion === "china" ? t("regionChina") : t("regionGlobal")
1614
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1615
+ className: QoderCredentialCard_module_css_default.subscriberIdentity,
1616
+ children: [
1617
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: identity?.name || t(view.method === "pat" ? "patActive" : "browserMethod") }),
1618
+ identity?.email ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: identity.email }) : null,
1619
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1620
+ className: QoderCredentialCard_module_css_default.label,
1621
+ children: t(view.method === "browser" ? "browserMethod" : "patMethod")
1622
+ })
1623
+ ]
1205
1624
  }),
1625
+ !pending && !editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1626
+ type: "button",
1627
+ className: QoderCredentialCard_module_css_default.secondary,
1628
+ "aria-expanded": menu,
1629
+ "aria-controls": "qoder-account-management",
1630
+ disabled: busy,
1631
+ onClick: () => setMenu(!menu),
1632
+ children: t(view.method === "pat" ? "manageCredential" : "manageAccount")
1633
+ }) : null
1634
+ ]
1635
+ }) : !pending && !editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1636
+ className: QoderCredentialCard_module_css_default.label,
1637
+ children: t("signInDescription")
1638
+ }) : null,
1639
+ pending ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1640
+ className: QoderCredentialCard_module_css_default.loginProgress,
1641
+ role: "status",
1642
+ children: [
1643
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t(attempt.phase === "saving" ? "browserSaving" : "browserWaiting") }),
1206
1644
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1207
- className: `${QoderCredentialCard_module_css_default.credentialDot} ${configured ? QoderCredentialCard_module_css_default.credentialDotConfigured : QoderCredentialCard_module_css_default.credentialDotMissing}`,
1208
- role: "img",
1209
- "aria-label": configured ? t("configured") : t("missing"),
1210
- title: configured ? t("configured") : t("missing")
1645
+ className: QoderCredentialCard_module_css_default.label,
1646
+ children: t("loginTimeRemaining", { seconds: remaining })
1647
+ }),
1648
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1649
+ className: QoderCredentialCard_module_css_default.connectionActions,
1650
+ children: [
1651
+ attempt.url ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1652
+ className: QoderCredentialCard_module_css_default.primaryLink,
1653
+ href: attempt.url,
1654
+ target: "_blank",
1655
+ rel: "noopener noreferrer",
1656
+ referrerPolicy: "no-referrer",
1657
+ children: t("reopenLogin")
1658
+ }) : null,
1659
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1660
+ type: "button",
1661
+ className: QoderCredentialCard_module_css_default.secondary,
1662
+ disabled: busy || !view.writable,
1663
+ onClick: () => {
1664
+ mutate("cancel");
1665
+ },
1666
+ children: t("cancelLogin")
1667
+ }),
1668
+ attempt.url ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1669
+ type: "button",
1670
+ className: QoderCredentialCard_module_css_default.textButton,
1671
+ onClick: () => {
1672
+ if (!navigator.clipboard) {
1673
+ setCopyFailed(true);
1674
+ return;
1675
+ }
1676
+ navigator.clipboard.writeText(attempt.url).then(() => {
1677
+ if (mounted.current) {
1678
+ setCopied(true);
1679
+ setCopyFailed(false);
1680
+ }
1681
+ }, () => {
1682
+ if (mounted.current) setCopyFailed(true);
1683
+ });
1684
+ },
1685
+ children: t(copied ? "loginLinkCopied" : "copyLogin")
1686
+ }) : null
1687
+ ]
1211
1688
  })
1212
1689
  ]
1213
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1214
- type: "button",
1215
- className: QoderCredentialCard_module_css_default.editButton,
1216
- "aria-expanded": editing,
1217
- "aria-controls": "qoder-credential-editor",
1218
- onClick: () => {
1219
- if (editing) closeEditor();
1220
- else {
1221
- setNotice(void 0);
1222
- setEditing(true);
1223
- }
1224
- },
1225
- children: t("edit")
1690
+ }) : null,
1691
+ view.expired ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1692
+ role: "status",
1693
+ className: QoderCredentialCard_module_css_default.error,
1694
+ children: t("browserExpired")
1695
+ }) : null,
1696
+ view.unsaved ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1697
+ role: "alert",
1698
+ className: QoderCredentialCard_module_css_default.error,
1699
+ children: t("browserUnsaved")
1700
+ }) : null,
1701
+ !pending && attempt?.phase === "timeout" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1702
+ role: "status",
1703
+ className: QoderCredentialCard_module_css_default.error,
1704
+ children: t("browserTimeout")
1705
+ }) : null,
1706
+ !pending && failure ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1707
+ role: "alert",
1708
+ className: QoderCredentialCard_module_css_default.error,
1709
+ children: t(failure)
1710
+ }) : null,
1711
+ menu && !pending && !editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1712
+ id: "qoder-account-management",
1713
+ className: QoderCredentialCard_module_css_default.managementPanel,
1714
+ children: [
1715
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1716
+ type: "button",
1717
+ className: QoderCredentialCard_module_css_default.textButton,
1718
+ disabled: busy || !view.writable,
1719
+ onClick: () => {
1720
+ mutate("begin");
1721
+ },
1722
+ children: t("changeAccount")
1723
+ }),
1724
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1725
+ type: "button",
1726
+ className: QoderCredentialCard_module_css_default.textButton,
1727
+ disabled: busy || !pat?.writable,
1728
+ onClick: openPat,
1729
+ children: t(view.method === "pat" ? "editPat" : "usePat")
1730
+ }),
1731
+ view.method !== "browser" && view.profile ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1732
+ type: "button",
1733
+ className: QoderCredentialCard_module_css_default.textButton,
1734
+ disabled: busy || !view.writable,
1735
+ onClick: () => {
1736
+ mutate("browser");
1737
+ },
1738
+ children: t("useBrowser")
1739
+ }) : null,
1740
+ view.profile ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1741
+ type: "button",
1742
+ className: QoderCredentialCard_module_css_default.danger,
1743
+ disabled: busy || !view.writable,
1744
+ onClick: () => {
1745
+ mutate("none");
1746
+ },
1747
+ children: t("signOutQoder")
1748
+ }) : null
1749
+ ]
1750
+ }) : null,
1751
+ !pending && !editing && (!connected || view.expired) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1752
+ className: QoderCredentialCard_module_css_default.connectionActions,
1753
+ children: [
1754
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1755
+ type: "button",
1756
+ className: QoderCredentialCard_module_css_default.primary,
1757
+ disabled: busy || !view.writable,
1758
+ onClick: () => {
1759
+ mutate("begin");
1760
+ },
1761
+ children: t(view.expired ? "signInAgain" : "signInQoder")
1762
+ }),
1763
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1764
+ type: "button",
1765
+ className: QoderCredentialCard_module_css_default.textButton,
1766
+ disabled: busy || !pat?.writable,
1767
+ onClick: openPat,
1768
+ children: t("usePat")
1769
+ }),
1770
+ view.profile && view.method !== "browser" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1771
+ type: "button",
1772
+ className: QoderCredentialCard_module_css_default.textButton,
1773
+ disabled: busy || !view.writable,
1774
+ onClick: () => {
1775
+ mutate("browser");
1776
+ },
1777
+ children: t("useBrowser")
1778
+ }) : null
1779
+ ]
1780
+ }) : null,
1781
+ editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1782
+ className: QoderCredentialCard_module_css_default.editor,
1783
+ children: [
1784
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1785
+ className: QoderCredentialCard_module_css_default.label,
1786
+ htmlFor: "qoder-managed-credential",
1787
+ children: t("tokenLabel")
1788
+ }),
1789
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1790
+ id: "qoder-managed-credential",
1791
+ className: QoderCredentialCard_module_css_default.input,
1792
+ type: "password",
1793
+ autoComplete: "new-password",
1794
+ value: draft,
1795
+ disabled: busy || !pat?.writable,
1796
+ placeholder: patConfigured ? t("configuredHint") : t("tokenPlaceholder"),
1797
+ onChange: (event) => setDraft(event.currentTarget.value)
1798
+ }),
1799
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1800
+ className: QoderCredentialCard_module_css_default.connectionActions,
1801
+ children: [
1802
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1803
+ type: "button",
1804
+ className: QoderCredentialCard_module_css_default.primary,
1805
+ disabled: busy || !pat?.writable || !draft.trim() && !patConfigured,
1806
+ onClick: () => {
1807
+ mutate("savePat");
1808
+ },
1809
+ children: t(busy ? "saving" : draft.trim() || !patConfigured ? "saveAndUsePat" : "useSavedPat")
1810
+ }),
1811
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1812
+ type: "button",
1813
+ className: QoderCredentialCard_module_css_default.secondary,
1814
+ disabled: busy,
1815
+ onClick: () => {
1816
+ setDraft("");
1817
+ setEditing(false);
1818
+ setError(void 0);
1819
+ },
1820
+ children: t("cancel")
1821
+ }),
1822
+ patConfigured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1823
+ type: "button",
1824
+ className: QoderCredentialCard_module_css_default.danger,
1825
+ disabled: busy || !pat?.writable,
1826
+ onClick: () => {
1827
+ if (window.confirm(t("confirmRemove"))) mutate("removePat");
1828
+ },
1829
+ children: t("remove")
1830
+ }) : null
1831
+ ]
1832
+ })
1833
+ ]
1834
+ }) : null
1835
+ ] }) : null,
1836
+ view && !view.writable && !pat?.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1837
+ className: QoderCredentialCard_module_css_default.label,
1838
+ children: t("readOnly")
1839
+ }) : null,
1840
+ copyFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1841
+ role: "alert",
1842
+ className: QoderCredentialCard_module_css_default.error,
1843
+ children: t("copyLoginFailed")
1844
+ }) : null,
1845
+ error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1846
+ role: "alert",
1847
+ className: QoderCredentialCard_module_css_default.error,
1848
+ children: t(error)
1849
+ }) : null,
1850
+ readFailed && view ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1851
+ role: "alert",
1852
+ className: QoderCredentialCard_module_css_default.error,
1853
+ children: t("authorizationConnectionFailed")
1854
+ }) : null
1855
+ ]
1856
+ });
1857
+ }
1858
+ //#endregion
1859
+ //#region src/client/QoderCredentialCard.tsx
1860
+ /** Region selection stays outside the keyed account state, so old identities never flash. */
1861
+ function QoderCredentialCard({ operations, t }) {
1862
+ const snapshot = (0, react.useSyncExternalStore)(operations.subscribeModels, operations.getModelSnapshot, operations.getModelSnapshot);
1863
+ const region = regionOf(snapshot.value);
1864
+ const [changing, setChanging] = (0, react.useState)(false);
1865
+ const [accountBusy, setAccountBusy] = (0, react.useState)(false);
1866
+ const [notice, setNotice] = (0, react.useState)();
1867
+ const mutating = (0, react.useRef)(false);
1868
+ const canChange = snapshot.status === "ready" && snapshot.writable && !changing && !accountBusy;
1869
+ const changeRegion = async (next) => {
1870
+ if (!canChange || next === region || mutating.current) return;
1871
+ mutating.current = true;
1872
+ setChanging(true);
1873
+ setNotice(void 0);
1874
+ try {
1875
+ setNotice(await operations.storeRegion(next) ? "regionChanged" : "regionChangeFailed");
1876
+ } catch {
1877
+ setNotice("regionChangeFailed");
1878
+ } finally {
1879
+ mutating.current = false;
1880
+ setChanging(false);
1881
+ }
1882
+ };
1883
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1884
+ className: `${QoderCredentialCard_module_css_default.credential} ${QoderCredentialCard_module_css_default.credentialEditor}`,
1885
+ "aria-label": t("accountConnectionTitle"),
1886
+ children: [
1887
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1888
+ className: QoderCredentialCard_module_css_default.connectionHead,
1889
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
1890
+ className: QoderCredentialCard_module_css_default.credentialName,
1891
+ children: t("accountConnectionTitle")
1892
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1893
+ className: QoderCredentialCard_module_css_default.regionGroup,
1894
+ role: "radiogroup",
1895
+ "aria-label": t("regionLabel"),
1896
+ children: ["global", "china"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1897
+ type: "button",
1898
+ role: "radio",
1899
+ "aria-checked": region === value,
1900
+ disabled: !canChange,
1901
+ className: `${QoderCredentialCard_module_css_default.regionOption} ${region === value ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
1902
+ onClick: () => {
1903
+ changeRegion(value);
1904
+ },
1905
+ children: t(value === "china" ? "regionChina" : "regionGlobal")
1906
+ }, value))
1226
1907
  })]
1227
1908
  }),
1228
- notice === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1229
- className: notice === "saved" ? QoderCredentialCard_module_css_default.success : QoderCredentialCard_module_css_default.error,
1909
+ notice ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1230
1910
  role: "status",
1911
+ className: notice === "regionChangeFailed" ? QoderCredentialCard_module_css_default.error : QoderCredentialCard_module_css_default.label,
1231
1912
  children: t(notice)
1232
- }),
1233
- editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1234
- id: "qoder-credential-editor",
1235
- className: QoderCredentialCard_module_css_default.editor,
1236
- children: [
1237
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1238
- className: QoderCredentialCard_module_css_default.regionSelector,
1239
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1240
- className: QoderCredentialCard_module_css_default.label,
1241
- children: t("regionLabel")
1242
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1243
- className: QoderCredentialCard_module_css_default.regionGroup,
1244
- role: "radiogroup",
1245
- "aria-label": t("regionLabel"),
1246
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1247
- type: "button",
1248
- role: "radio",
1249
- "aria-checked": regionDraft === "global",
1250
- className: `${QoderCredentialCard_module_css_default.regionOption} ${regionDraft === "global" ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
1251
- disabled: !canModifyRegion || busy,
1252
- onClick: () => {
1253
- setRegionDraft("global");
1254
- setRegionDirty(true);
1255
- },
1256
- children: t("regionGlobal")
1257
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1258
- type: "button",
1259
- role: "radio",
1260
- "aria-checked": regionDraft === "china",
1261
- className: `${QoderCredentialCard_module_css_default.regionOption} ${regionDraft === "china" ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
1262
- disabled: !canModifyRegion || busy,
1263
- onClick: () => {
1264
- setRegionDraft("china");
1265
- setRegionDirty(true);
1266
- },
1267
- children: t("regionChina")
1268
- })]
1269
- })]
1270
- }),
1271
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1272
- className: QoderCredentialCard_module_css_default.label,
1273
- htmlFor: "qoder-managed-credential",
1274
- children: t("tokenLabel")
1275
- }),
1276
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1277
- id: "qoder-managed-credential",
1278
- className: QoderCredentialCard_module_css_default.input,
1279
- type: "password",
1280
- autoComplete: "new-password",
1281
- value: draft,
1282
- disabled: !writable || busy,
1283
- placeholder: configured ? t("configuredHint") : t("tokenPlaceholder"),
1284
- onChange: (event) => setDraft(event.currentTarget.value)
1285
- }),
1286
- !writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1287
- className: QoderCredentialCard_module_css_default.error,
1288
- role: "alert",
1289
- children: t("readOnly")
1290
- }) : null,
1291
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1292
- className: QoderCredentialCard_module_css_default.actions,
1293
- children: [
1294
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1295
- type: "button",
1296
- className: QoderCredentialCard_module_css_default.secondary,
1297
- disabled: busy,
1298
- onClick: closeEditor,
1299
- children: t("cancel")
1300
- }),
1301
- configured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1302
- type: "button",
1303
- className: QoderCredentialCard_module_css_default.danger,
1304
- disabled: !writable || busy,
1305
- onClick: () => {
1306
- remove();
1307
- },
1308
- children: mutation === "removing" ? t("removing") : t("remove")
1309
- }) : null,
1310
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1311
- type: "button",
1312
- className: QoderCredentialCard_module_css_default.primary,
1313
- disabled: busy || !regionDirty && normalized.length === 0 || regionDirty && !canModifyRegion || normalized.length > 0 && !writable,
1314
- onClick: () => {
1315
- save();
1316
- },
1317
- children: mutation === "saving" ? t("saving") : t("save")
1318
- })
1319
- ]
1320
- })
1321
- ]
1322
- }) : null
1913
+ }) : null,
1914
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QoderBrowserLogin, {
1915
+ region,
1916
+ operations: operations.authorization,
1917
+ credentials: operations,
1918
+ onBusyChange: setAccountBusy,
1919
+ t
1920
+ }, region),
1921
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1922
+ className: QoderCredentialCard_module_css_default.sharedNote,
1923
+ children: t("sharedAuthorization")
1924
+ })
1323
1925
  ]
1324
1926
  });
1325
1927
  }
@@ -1868,8 +2470,26 @@ window.__ModuleLoader__.load({
1868
2470
  const tierEvents = createSessionTierEvents();
1869
2471
  ctx.effect(() => () => tierEvents.dispose(), "provider-qoder: session context tier events");
1870
2472
  const readModelSnapshot = () => modelScope.getSnapshot();
2473
+ const authorizationOperations = {
2474
+ read: (region) => rpc.call("authorization", { region }),
2475
+ begin: (region) => rpc.call("beginLogin", { region }),
2476
+ cancel: (region) => rpc.call("cancelLogin", { region }),
2477
+ select: (region, method) => rpc.call("selectAuthorization", {
2478
+ region,
2479
+ method
2480
+ })
2481
+ };
1871
2482
  const operations = {
2483
+ authorization: authorizationOperations,
1872
2484
  describe: async () => {
2485
+ const result = await authorizationOperations.read(regionOf(readModelSnapshot().value));
2486
+ return result.ok ? {
2487
+ configured: result.value.configured && !result.value.expired,
2488
+ source: result.value.method,
2489
+ writable: result.value.writable
2490
+ } : void 0;
2491
+ },
2492
+ describePat: async () => {
1873
2493
  try {
1874
2494
  const response = await credentials.describe([qoderCredentialRef]);
1875
2495
  return response.ok ? response.value[qoderCredentialRef] : void 0;
@@ -1879,7 +2499,14 @@ window.__ModuleLoader__.load({
1879
2499
  },
1880
2500
  store: async (value) => {
1881
2501
  try {
1882
- return (await credentials.set(qoderCredentialRef, value.trim())).ok;
2502
+ const response = await credentials.set(qoderCredentialRef, value.trim());
2503
+ if (response.ok) {
2504
+ const region = regionOf(readModelSnapshot().value);
2505
+ const current = await authorizationOperations.read(region);
2506
+ if (!current.ok) return false;
2507
+ if (current.value.method !== "pat") return (await authorizationOperations.select(region, "pat")).ok;
2508
+ }
2509
+ return response.ok;
1883
2510
  } catch {
1884
2511
  return false;
1885
2512
  }
@@ -1922,26 +2549,56 @@ window.__ModuleLoader__.load({
1922
2549
  },
1923
2550
  discoverModels: async () => await rpc.call("models", {}),
1924
2551
  setSessionTier: async (sessionId, modelId, tierKey, region) => {
2552
+ const scope = {
2553
+ sessionId,
2554
+ modelId,
2555
+ tierKey,
2556
+ region
2557
+ };
1925
2558
  try {
1926
- const res = await rpc.call("sessionTier", {
1927
- sessionId,
1928
- modelId,
1929
- tierKey,
1930
- region
2559
+ const res = await rpc.call("sessionTier", scope);
2560
+ if (!res.ok) console.error("[Qoder context tier] Failed to save selection", {
2561
+ ...scope,
2562
+ error: res.error
1931
2563
  });
1932
2564
  return res.ok ? res.value : void 0;
1933
- } catch {
2565
+ } catch (error) {
2566
+ console.error("[Qoder context tier] Failed to save selection", {
2567
+ ...scope,
2568
+ error
2569
+ });
1934
2570
  return;
1935
2571
  }
1936
2572
  },
1937
2573
  readSessionTier: async (scope) => {
1938
- const result = await rpc.call("readSessionTier", scope);
1939
- return result.ok ? result.value : void 0;
2574
+ try {
2575
+ const result = await rpc.call("readSessionTier", scope);
2576
+ if (!result.ok) console.error("[Qoder context tier] Failed to read selection", {
2577
+ ...scope,
2578
+ error: result.error
2579
+ });
2580
+ return result.ok ? result.value : void 0;
2581
+ } catch (error) {
2582
+ console.error("[Qoder context tier] Failed to read selection", {
2583
+ ...scope,
2584
+ error
2585
+ });
2586
+ return;
2587
+ }
1940
2588
  },
1941
2589
  subscribeSessionTiers: (scope, listener) => tierEvents.subscribe(scope, listener),
1942
- subscribe: (listener) => ctx.remote.$on("credentials/reference-updated", (ref) => {
1943
- if (ref === "QODER_MANAGED_CREDENTIAL") listener();
1944
- })
2590
+ subscribe: (listener) => {
2591
+ const reference = ctx.remote.$on("credentials/reference-updated", (ref) => {
2592
+ if (ref === "QODER_MANAGED_CREDENTIAL") listener();
2593
+ });
2594
+ const record = ctx.remote.$on("credentials/record-updated", (key) => {
2595
+ if (key === `provider-qoder/${regionOf(readModelSnapshot().value)}`) listener();
2596
+ });
2597
+ return () => {
2598
+ reference();
2599
+ record();
2600
+ };
2601
+ }
1945
2602
  };
1946
2603
  const rawT = ctx.locale.bind(localeNamespace);
1947
2604
  const t = (key, values) => {
@@ -1953,6 +2610,17 @@ window.__ModuleLoader__.load({
1953
2610
  * switch re-resolves provider copy instead of reusing a setup-time snapshot.
1954
2611
  */
1955
2612
  const activeLocale = () => ctx.locale.getLocale().active;
2613
+ ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
2614
+ name: "conversation.input.dock",
2615
+ id: "qoder-model-queue",
2616
+ order: 30,
2617
+ locale: localeNamespace,
2618
+ inject: (sessionId) => ({
2619
+ sessionId,
2620
+ rpc,
2621
+ t
2622
+ })
2623
+ }, QoderQueueStatus));
1956
2624
  ctx.slots.inject("settings.section", () => ctx.slots.register({
1957
2625
  name: "settings.section",
1958
2626
  id: "qoder",