dsh-codex-subscription 3.0.0-beta.3 → 3.0.0-beta.5

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
@@ -1075,6 +1075,8 @@ window.__ModuleLoader__.load({
1075
1075
  "account/select",
1076
1076
  "account/remove",
1077
1077
  "usage",
1078
+ "usage/history",
1079
+ "usage/profile",
1078
1080
  "diagnostics",
1079
1081
  "preferences/status",
1080
1082
  "preferences/models",
@@ -1091,6 +1093,8 @@ window.__ModuleLoader__.load({
1091
1093
  "remote/enable",
1092
1094
  "remote/disable",
1093
1095
  "remote/pair",
1096
+ "remote/clients",
1097
+ "remote/revoke",
1094
1098
  "reset-credit/inspect",
1095
1099
  "reset-credit/prepare",
1096
1100
  "reset-credit/consume",
@@ -5676,6 +5680,24 @@ window.__ModuleLoader__.load({
5676
5680
  inputImageDetail_low: "低",
5677
5681
  inputImageDetail_high: "高",
5678
5682
  inputImageDetail_original: "原图",
5683
+ connectors: "ChatGPT 连接器",
5684
+ connectorsHint: "让 DSH 里的任何模型使用你在 ChatGPT 网页里已连接的应用(GitHub、Gmail、Google 云端硬盘、日历等)。只读:模型只能读取;允许写入:发邮件、改文件等写操作每次都要你批准。应用返回的内容来自第三方,模型不会照其中的指令行事。需先在 ChatGPT 里连接应用。",
5685
+ connectors_off: "关闭",
5686
+ connectors_read: "只读",
5687
+ connectors_ask: "允许写入(每次审批)",
5688
+ reasoningSummary: "推理摘要",
5689
+ reasoningSummaryHint: "让模型在会话的“思考”部分给出推理摘要。自动由模型决定;简洁更短;详细更完整;关闭则不要摘要。",
5690
+ retryPolicy: "请求重试",
5691
+ retryPolicyHint: "请求因网络或服务端错误失败时的自动重试次数。默认沿用 DSH 的标准重试;无限会一直重试直到成功或手动停止。",
5692
+ retryPolicy_default: "默认",
5693
+ retryPolicy_off: "不重试",
5694
+ retryPolicy_10: "10 次",
5695
+ retryPolicy_20: "20 次",
5696
+ retryPolicy_unlimited: "无限",
5697
+ reasoningSummary_auto: "自动",
5698
+ reasoningSummary_concise: "简洁",
5699
+ reasoningSummary_detailed: "详细",
5700
+ reasoningSummary_none: "关闭",
5679
5701
  subagentBackendTitle: "独立子任务",
5680
5702
  subagentBackend_dsh: "DSH",
5681
5703
  subagentBackend_codex: "Codex",
@@ -5688,6 +5710,11 @@ window.__ModuleLoader__.load({
5688
5710
  remoteConnecting: "正在连接",
5689
5711
  remoteError: "连接失败,会自动重试",
5690
5712
  remoteStopped: "已停止",
5713
+ remotePaired: "已配对的手机",
5714
+ remoteNoPhones: "还没有手机配对。",
5715
+ remoteRevoke: "移除",
5716
+ remoteLastSeen: "最近 {date}",
5717
+ remotePhoneUnknown: "未命名手机",
5691
5718
  remotePhones: "{count} 个手机连接",
5692
5719
  remotePair: "显示配对码",
5693
5720
  remotePairAgain: "重新生成配对码",
@@ -5697,7 +5724,7 @@ window.__ModuleLoader__.load({
5697
5724
  remoteQrLabel: "配对二维码",
5698
5725
  remoteExpires: "约 {minutes} 分钟内有效",
5699
5726
  remoteExpired: "配对码已过期,请重新生成。",
5700
- remoteLimits: "手机上可以查看和继续 DSH 里的对话、新建对话、切换模型、选择权限并审批。手机暂不能直接在电脑上执行命令。",
5727
+ remoteLimits: "手机上可以查看和继续 DSH 里的对话、新建对话、发图片、切换模型、选择权限并审批,也能查看改动。手机不能在电脑上执行其他命令。",
5701
5728
  reviewModelTitle: "Auto review 审查模型",
5702
5729
  reviewModel_session: "当前模型",
5703
5730
  reviewModel_official: "Codex 官方审查模型",
@@ -5965,6 +5992,10 @@ window.__ModuleLoader__.load({
5965
5992
  deviceHint: "在登录页输入此设备代码:",
5966
5993
  waiting: "正在等待登录完成…",
5967
5994
  failed: "登录失败,请重试。",
5995
+ failed_account_claim: "登录已授权,但这个账号的令牌里没有 ChatGPT 账号 ID(常见于只用手机号注册的账号)。请改用邮箱账号登录,或先在 ChatGPT 里为账号绑定邮箱后重试。",
5996
+ failed_network: "登录时网络连接失败。请检查网络或代理后重试。",
5997
+ failed_token_exchange: "授权已完成,但换取令牌失败。请重试;反复出现时请检查网络或代理。",
5998
+ failed_callback: "没有收到浏览器的授权回调。请重试,或改用设备码登录。",
5968
5999
  accountRetry: "重试",
5969
6000
  accountRetrying: "正在重试账户状态…",
5970
6001
  accountCredentialUnavailable: "登录凭据暂时不可用。请重试;不会删除已保存的登录信息。",
@@ -5997,6 +6028,45 @@ window.__ModuleLoader__.load({
5997
6028
  refresh: "刷新",
5998
6029
  refreshing: "刷新中…",
5999
6030
  noUsage: "登录后可读取 ChatGPT 返回的额度窗口。",
6031
+ overviewTitle: "使用概览",
6032
+ overviewLoading: "正在读取使用统计…",
6033
+ overviewUnavailable: "当前账户没有提供使用统计。",
6034
+ overviewHeatmap: "最近半年每天的 token 用量",
6035
+ overviewNoUse: "没有使用",
6036
+ overviewTokens: "{value} token",
6037
+ overviewDays: "{value} 天",
6038
+ overviewLifetime: "累计 token",
6039
+ overviewPeak: "单日最高",
6040
+ overviewStreak: "连续使用",
6041
+ overviewLongestStreak: "最长连续",
6042
+ overviewThreads: "会话总数",
6043
+ overviewEffort: "最常用推理档",
6044
+ overviewFast: "快速模式占比",
6045
+ overviewLongestTurn: "最长单轮",
6046
+ settingsRestartRequired: "设置已保存,但运行中的 DSH 没有应用它(宿主无法热更新这项设置)。请重启 DSH 后生效。",
6047
+ historyTitle: "额度去向(每周)",
6048
+ historyLoading: "正在读取用量历史…",
6049
+ historyUnavailable: "当前账户没有提供用量历史。",
6050
+ historyEmpty: "还没有已统计完成的额度周期。官方统计有延迟,过一两天再看。",
6051
+ historyPeriods: "额度周期",
6052
+ historyUsed: "这个周期已用 {value}% 的周额度",
6053
+ historyPartial: "(统计尚未完成)",
6054
+ historyApproximate: "数据来自官方用量报告,是近似值,可能有一两天延迟。",
6055
+ historyBy_model: "按模型",
6056
+ historyBy_surface: "按入口",
6057
+ historyBy_thread_source: "按来源",
6058
+ historyBy_turn_trigger: "按触发方式",
6059
+ historyDesktopApp: "桌面应用",
6060
+ historyCli: "命令行",
6061
+ historyIde: "IDE 扩展",
6062
+ historyWeb: "网页",
6063
+ historyMobile: "手机",
6064
+ historyUser: "你的对话",
6065
+ historySubagent: "子任务",
6066
+ historyMemory: "记忆整理",
6067
+ historyReview: "审查",
6068
+ historyComposer: "输入框发送",
6069
+ historyAutomation: "自动任务",
6000
6070
  usageLoading: "正在读取额度…",
6001
6071
  usageEmpty: "当前账户没有返回可显示的额度窗口。请稍后刷新;这不代表额度为零。",
6002
6072
  usageUpdated: "更新于 {value}",
@@ -6126,6 +6196,8 @@ window.__ModuleLoader__.load({
6126
6196
  effortLabel: "推理等级",
6127
6197
  providerDefault: "默认",
6128
6198
  selectModel: "选择模型",
6199
+ modelSearch: "搜索模型",
6200
+ modelNoMatch: "没有匹配的模型。",
6129
6201
  modelsLoading: "正在读取模型…",
6130
6202
  modelsEmpty: "没有可用模型;请先登录,并确认网络可用。",
6131
6203
  modelsHidden: "所有模型都已从列表中隐藏;可在设置中重新显示。",
@@ -6281,6 +6353,24 @@ window.__ModuleLoader__.load({
6281
6353
  inputImageDetail_low: "Low",
6282
6354
  inputImageDetail_high: "High",
6283
6355
  inputImageDetail_original: "Original",
6356
+ connectors: "ChatGPT connectors",
6357
+ connectorsHint: "Lets any model in DSH use the apps you have connected in ChatGPT (GitHub, Gmail, Google Drive, Calendar and more). Read-only: models can only read. Allow writes: anything that changes data, such as sending mail or editing files, asks for your approval every time. What apps return is third-party content and models do not follow instructions inside it. Connect the apps in ChatGPT first.",
6358
+ connectors_off: "Off",
6359
+ connectors_read: "Read-only",
6360
+ connectors_ask: "Allow writes (ask each time)",
6361
+ reasoningSummary: "Reasoning summary",
6362
+ reasoningSummaryHint: "Shows a summary of the reasoning in the Thinking section of the conversation. Auto lets the model decide; concise is shorter; detailed is fuller; off asks for none.",
6363
+ retryPolicy: "Request retries",
6364
+ retryPolicyHint: "How many times a request is retried after a network or server error. Default keeps the standard DSH retries; Unlimited keeps retrying until it succeeds or you stop it.",
6365
+ retryPolicy_default: "Default",
6366
+ retryPolicy_off: "No retries",
6367
+ retryPolicy_10: "10",
6368
+ retryPolicy_20: "20",
6369
+ retryPolicy_unlimited: "Unlimited",
6370
+ reasoningSummary_auto: "Auto",
6371
+ reasoningSummary_concise: "Concise",
6372
+ reasoningSummary_detailed: "Detailed",
6373
+ reasoningSummary_none: "Off",
6284
6374
  subagentBackendTitle: "Independent subtasks",
6285
6375
  subagentBackend_dsh: "DSH",
6286
6376
  subagentBackend_codex: "Codex",
@@ -6293,6 +6383,11 @@ window.__ModuleLoader__.load({
6293
6383
  remoteConnecting: "Connecting",
6294
6384
  remoteError: "Connection failed, retrying",
6295
6385
  remoteStopped: "Stopped",
6386
+ remotePaired: "Paired phones",
6387
+ remoteNoPhones: "No phone is paired yet.",
6388
+ remoteRevoke: "Remove",
6389
+ remoteLastSeen: "last seen {date}",
6390
+ remotePhoneUnknown: "Unnamed phone",
6296
6391
  remotePhones: "{count} phone(s) connected",
6297
6392
  remotePair: "Show pairing code",
6298
6393
  remotePairAgain: "New pairing code",
@@ -6302,7 +6397,7 @@ window.__ModuleLoader__.load({
6302
6397
  remoteQrLabel: "Pairing QR code",
6303
6398
  remoteExpires: "Valid for about {minutes} minute(s)",
6304
6399
  remoteExpired: "The pairing code expired. Create a new one.",
6305
- remoteLimits: "From the phone you can follow and continue DSH conversations, start new ones, switch models, choose permissions and approve actions. The phone cannot run commands on the computer directly.",
6400
+ remoteLimits: "From the phone you can follow and continue DSH conversations, start new ones, send photos, switch models, choose permissions, approve actions and view changes. The phone cannot run other commands on the computer.",
6306
6401
  reviewModelTitle: "Auto review model",
6307
6402
  reviewModel_session: "Current model",
6308
6403
  reviewModel_official: "Codex reviewer",
@@ -6570,6 +6665,10 @@ window.__ModuleLoader__.load({
6570
6665
  deviceHint: "Enter this device code on the sign-in page:",
6571
6666
  waiting: "Waiting for sign-in to finish…",
6572
6667
  failed: "Sign-in failed. Try again.",
6668
+ failed_account_claim: "Sign-in was authorized, but the token of this account has no ChatGPT account ID (common for accounts created with only a phone number). Sign in with an email account, or add an email to the account in ChatGPT first, then try again.",
6669
+ failed_network: "The network connection failed during sign-in. Check the network or proxy and try again.",
6670
+ failed_token_exchange: "Authorization finished, but exchanging it for a token failed. Try again; if it keeps happening, check the network or proxy.",
6671
+ failed_callback: "The browser did not send the authorization back. Try again, or use device code sign-in.",
6573
6672
  accountRetry: "Retry",
6574
6673
  accountRetrying: "Retrying account status…",
6575
6674
  accountCredentialUnavailable: "The saved sign-in credentials are temporarily unavailable. Retry; saved sign-in information will not be deleted.",
@@ -6602,6 +6701,45 @@ window.__ModuleLoader__.load({
6602
6701
  refresh: "Refresh",
6603
6702
  refreshing: "Refreshing…",
6604
6703
  noUsage: "Sign in to read quota windows reported by ChatGPT.",
6704
+ overviewTitle: "Usage overview",
6705
+ overviewLoading: "Reading usage statistics…",
6706
+ overviewUnavailable: "This account does not provide usage statistics.",
6707
+ overviewHeatmap: "Daily token use over the last half year",
6708
+ overviewNoUse: "no use",
6709
+ overviewTokens: "{value} tokens",
6710
+ overviewDays: "{value} days",
6711
+ overviewLifetime: "Lifetime tokens",
6712
+ overviewPeak: "Busiest day",
6713
+ overviewStreak: "Current streak",
6714
+ overviewLongestStreak: "Longest streak",
6715
+ overviewThreads: "Conversations",
6716
+ overviewEffort: "Most used reasoning",
6717
+ overviewFast: "Fast mode share",
6718
+ overviewLongestTurn: "Longest turn",
6719
+ settingsRestartRequired: "The setting was saved, but the running DSH did not apply it (the host cannot update it live). Restart DSH to apply it.",
6720
+ historyTitle: "Where the allowance went (weekly)",
6721
+ historyLoading: "Reading usage history…",
6722
+ historyUnavailable: "This account does not provide a usage history.",
6723
+ historyEmpty: "No allowance period has been counted yet. The official report lags; check again in a day or two.",
6724
+ historyPeriods: "Allowance periods",
6725
+ historyUsed: "{value}% of this period's weekly allowance used",
6726
+ historyPartial: "(still being counted)",
6727
+ historyApproximate: "From the official usage report; values are approximate and may lag by a day or two.",
6728
+ historyBy_model: "By model",
6729
+ historyBy_surface: "By surface",
6730
+ historyBy_thread_source: "By source",
6731
+ historyBy_turn_trigger: "By trigger",
6732
+ historyDesktopApp: "Desktop app",
6733
+ historyCli: "CLI",
6734
+ historyIde: "IDE extension",
6735
+ historyWeb: "Web",
6736
+ historyMobile: "Mobile",
6737
+ historyUser: "Your chats",
6738
+ historySubagent: "Subtasks",
6739
+ historyMemory: "Memory upkeep",
6740
+ historyReview: "Review",
6741
+ historyComposer: "Composer",
6742
+ historyAutomation: "Automations",
6605
6743
  usageLoading: "Reading quota…",
6606
6744
  usageEmpty: "This account returned no displayable quota windows. Refresh later; this does not mean zero quota.",
6607
6745
  usageUpdated: "Updated {value}",
@@ -6731,6 +6869,8 @@ window.__ModuleLoader__.load({
6731
6869
  effortLabel: "Effort",
6732
6870
  providerDefault: "Default",
6733
6871
  selectModel: "Select model",
6872
+ modelSearch: "Search models",
6873
+ modelNoMatch: "No matching models.",
6734
6874
  modelsLoading: "Loading models…",
6735
6875
  modelsEmpty: "No models available. Sign in and make sure the network is reachable.",
6736
6876
  modelsHidden: "All models are hidden from this list. Show one in settings.",
@@ -6878,6 +7018,28 @@ window.__ModuleLoader__.load({
6878
7018
  .codexSubscriptionRefresh{flex:0 0 auto;min-width:72px;width:max-content;white-space:nowrap!important;word-break:keep-all!important;overflow-wrap:normal!important;writing-mode:horizontal-tb!important}
6879
7019
  .codexSubscriptionRefresh *{white-space:nowrap!important;word-break:keep-all!important;writing-mode:horizontal-tb!important}
6880
7020
  .codexSubscriptionEmpty{padding:18px;border:1px dashed var(--dsw-alias-border-l3);border-radius:10px;text-align:center;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}
7021
+ .codexSubscriptionHistory{margin-top:10px;border-top:1px solid var(--dsw-alias-border-l3);padding-top:8px}
7022
+ .codexSubscriptionHistory>summary{cursor:pointer;font-size:13px;font-weight:500;color:var(--dsw-alias-label-secondary)}
7023
+ .codexSubscriptionHistoryPeriods{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0}
7024
+ .codexSubscriptionHistoryPeriods button{height:26px;padding:0 10px;border:1px solid var(--dsw-alias-border-l3);border-radius:13px;background:transparent;color:inherit;font-size:12px;cursor:pointer}
7025
+ .codexSubscriptionHistoryPeriods button[aria-pressed=true]{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-inverted)}
7026
+ .codexSubscriptionHistorySummary{margin:4px 0 8px;font-size:13px}
7027
+ .codexSubscriptionHistoryGroup{margin:8px 0}
7028
+ .codexSubscriptionHistoryGroup h4{margin:0 0 4px;font-size:12px;font-weight:500;color:var(--dsw-alias-label-tertiary)}
7029
+ .codexSubscriptionOverviewStats{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:8px;margin:10px 0}
7030
+ .codexSubscriptionOverviewStats div{padding:8px 10px;border-radius:10px;background:var(--dsw-alias-bg-layer-3,rgba(127,127,127,.08))}
7031
+ .codexSubscriptionOverviewStats dt{margin:0;font-size:11px;color:var(--dsw-alias-label-tertiary)}
7032
+ .codexSubscriptionOverviewStats dd{margin:2px 0 0;font-size:15px;font-weight:600}
7033
+ .codexSubscriptionHeatmap{display:block;width:100%;max-width:520px;margin:6px 0 4px}
7034
+ .codexSubscriptionHeatmap rect{fill:var(--dsw-alias-border-l3,rgba(127,127,127,.25))}
7035
+ .codexSubscriptionHeatmap rect[data-level="1"]{fill:#0a84ff;fill-opacity:.3}
7036
+ .codexSubscriptionHeatmap rect[data-level="2"]{fill:#0a84ff;fill-opacity:.5}
7037
+ .codexSubscriptionHeatmap rect[data-level="3"]{fill:#0a84ff;fill-opacity:.75}
7038
+ .codexSubscriptionHeatmap rect[data-level="4"]{fill:#0a84ff}
7039
+ .codexSubscriptionHistoryRow{display:grid;grid-template-columns:minmax(80px,32%) 1fr 52px;align-items:center;gap:8px;font-size:12px;line-height:20px}
7040
+ .codexSubscriptionHistoryKey{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
7041
+ .codexSubscriptionHistoryRow progress{width:100%;height:6px}
7042
+ .codexSubscriptionHistoryRow strong{text-align:right;font-weight:500}
6881
7043
  .codexSubscriptionLimits{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:6px}
6882
7044
  .codexSubscriptionLimit{min-width:0;border-radius:10px;padding:9px 12px;background:var(--dsw-alias-bg-module-platform);display:flex;flex-direction:column;gap:6px}
6883
7045
  .codexSubscriptionLimitTop{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
@@ -6979,13 +7141,17 @@ window.__ModuleLoader__.load({
6979
7141
  .codexModelSelectMenu,.codexModelSelectSubmenu{position:absolute;z-index:30;box-sizing:border-box;width:max-content;min-width:min(240px,calc(100vw - 32px));max-width:min(420px,calc(100vw - 32px));max-height:min(360px,calc(100vh - 96px));padding:4px;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#2c2c2e);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);overflow:hidden}
6980
7142
  .codexModelSelectMenu{right:0;bottom:calc(100% + 8px)}
6981
7143
  .codexModelSelectSubmenu{right:calc(100% + 8px);bottom:0;min-width:min(230px,calc(100vw - 32px))}
7144
+ /* Keep search outside the scroll viewport; let the model list fit the bounded menu. */
7145
+ .codexModelSelectModelMenu{display:flex;flex-direction:column}
6982
7146
  .codexModelSelectCell{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;height:40px;box-sizing:border-box;padding:0 10px;border:0;border-radius:10px;background:transparent;color:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer}
6983
7147
  .codexModelSelectCell:hover,.codexModelSelectCell:focus-visible,.codexModelSelectCell[data-open=true]{background:var(--dsw-alias-interactive-bg-hover);outline:0}
6984
7148
  .codexModelSelectCell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
6985
7149
  .codexModelSelectCellLabel{flex:none;white-space:nowrap}
6986
7150
  .codexModelSelectCellValue{flex:auto;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap}
6987
7151
  .codexModelSelectCellChevron{flex:none;color:var(--dsw-alias-label-tertiary)}
6988
- .codexModelSelectGroups{min-height:0;max-height:352px;overflow-y:auto}
7152
+ .codexModelSelectSearch{display:block;flex-shrink:0;width:100%;box-sizing:border-box;height:32px;margin:0 0 4px;padding:0 10px;border:1px solid var(--dsw-alias-border-l3);border-radius:8px;outline:0;background:transparent;color:inherit;font:inherit;font-size:13px}
7153
+ .codexModelSelectSearch:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}
7154
+ .codexModelSelectGroups{flex:1 1 auto;min-height:0;overflow-y:auto}
6989
7155
  .codexModelSelectGroup+.codexModelSelectGroup{margin-top:4px}
6990
7156
  .codexModelSelectGroupTitle{position:sticky;top:0;z-index:1;padding:5px 8px 3px;background:var(--dsw-alias-bg-layer-2,#2c2c2e);color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}
6991
7157
  .codexModelSelectOption{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;min-height:38px;box-sizing:border-box;padding:6px 8px;border:0;border-radius:10px;outline:0;background:transparent;color:inherit;text-align:left;cursor:pointer}
@@ -8407,6 +8573,29 @@ window.__ModuleLoader__.load({
8407
8573
  const OUTPUT_VERBOSITY_MEDIUM = "medium";
8408
8574
  const OUTPUT_VERBOSITY_HIGH = "high";
8409
8575
  const DEFAULT_OUTPUT_VERBOSITY = OUTPUT_VERBOSITY_DEFAULT;
8576
+ const REASONING_SUMMARY_FIELD = "reasoningSummary";
8577
+ const REASONING_SUMMARIES = Object.freeze([
8578
+ "auto",
8579
+ "concise",
8580
+ "detailed",
8581
+ "none"
8582
+ ]);
8583
+ const DEFAULT_REASONING_SUMMARY = "auto";
8584
+ const RETRY_POLICY_FIELD = "retryPolicy";
8585
+ const RETRY_POLICIES = Object.freeze([
8586
+ "default",
8587
+ "off",
8588
+ "10",
8589
+ "20",
8590
+ "unlimited"
8591
+ ]);
8592
+ const DEFAULT_RETRY_POLICY = "default";
8593
+ const CONNECTORS_FIELD = "connectors";
8594
+ const CONNECTOR_MODES = Object.freeze([
8595
+ "off",
8596
+ "read",
8597
+ "ask"
8598
+ ]);
8410
8599
  const INPUT_IMAGE_DETAIL_FIELD = "inputImageDetail";
8411
8600
  const INPUT_IMAGE_DETAILS = Object.freeze([
8412
8601
  "low",
@@ -8466,6 +8655,9 @@ window.__ModuleLoader__.load({
8466
8655
  "medium",
8467
8656
  "high"
8468
8657
  ].includes(value) ? value : DEFAULT_OUTPUT_VERBOSITY;
8658
+ const normalizeReasoningSummary = (value) => REASONING_SUMMARIES.includes(value) ? value : DEFAULT_REASONING_SUMMARY;
8659
+ const normalizeRetryPolicy = (value) => RETRY_POLICIES.includes(value) ? value : DEFAULT_RETRY_POLICY;
8660
+ const normalizeConnectorMode = (value) => CONNECTOR_MODES.includes(value) ? value : "off";
8469
8661
  const normalizeInputImageDetail = (value) => INPUT_IMAGE_DETAILS.includes(value) ? value : DEFAULT_INPUT_IMAGE_DETAIL;
8470
8662
  const normalizeStreamIdleTimeoutMinutes = (value) => STREAM_IDLE_TIMEOUT_MINUTES.includes(value) ? value : 10;
8471
8663
  const normalizeSpeedMode = (value) => [
@@ -8520,6 +8712,7 @@ window.__ModuleLoader__.load({
8520
8712
  let disposed = false;
8521
8713
  let subagentBackendAvailable = false;
8522
8714
  let subagentRuntimeInstalled = false;
8715
+ let restartRequired = false;
8523
8716
  const sameModels = (left, right) => left.length === right.length && left.every((model, index) => JSON.stringify(model) === JSON.stringify(right[index]));
8524
8717
  const read = () => {
8525
8718
  const current = fallback ?? { status: "unavailable" };
@@ -8544,6 +8737,9 @@ window.__ModuleLoader__.load({
8544
8737
  speedMode: normalizeSpeedMode(value?.[SPEED_MODE_FIELD]),
8545
8738
  outputVerbosity: normalizeOutputVerbosity(value?.[OUTPUT_VERBOSITY_FIELD]),
8546
8739
  inputImageDetail: normalizeInputImageDetail(value?.[INPUT_IMAGE_DETAIL_FIELD]),
8740
+ reasoningSummary: normalizeReasoningSummary(value?.[REASONING_SUMMARY_FIELD]),
8741
+ retryPolicy: normalizeRetryPolicy(value?.[RETRY_POLICY_FIELD]),
8742
+ connectors: normalizeConnectorMode(value?.[CONNECTORS_FIELD]),
8547
8743
  streamIdleTimeoutMinutes: normalizeStreamIdleTimeoutMinutes(value?.[STREAM_IDLE_TIMEOUT_MINUTES_FIELD]),
8548
8744
  contextMode: normalizeContextMode(value?.[CONTEXT_MODE_FIELD]),
8549
8745
  customContextWindow: normalizeCustomContextWindow(value?.[CUSTOM_CONTEXT_WINDOW_FIELD]),
@@ -8562,6 +8758,7 @@ window.__ModuleLoader__.load({
8562
8758
  modelError,
8563
8759
  writable: !updating && current.status === "ready" && current.writable === true,
8564
8760
  saving: updating,
8761
+ restartRequired,
8565
8762
  error
8566
8763
  });
8567
8764
  };
@@ -8572,6 +8769,7 @@ window.__ModuleLoader__.load({
8572
8769
  for (const listener of listeners) listener();
8573
8770
  };
8574
8771
  const acceptFallback = (value) => {
8772
+ if (value?.liveSynced === false) restartRequired = true;
8575
8773
  subagentBackendAvailable = value?.subagentBackendAvailable === true;
8576
8774
  subagentRuntimeInstalled = value?.subagentRuntimeInstalled === true;
8577
8775
  if (!modelRefreshStarted) {
@@ -8598,6 +8796,9 @@ window.__ModuleLoader__.load({
8598
8796
  [SPEED_MODE_FIELD]: normalizeSpeedMode(value?.[SPEED_MODE_FIELD]),
8599
8797
  [OUTPUT_VERBOSITY_FIELD]: normalizeOutputVerbosity(value?.[OUTPUT_VERBOSITY_FIELD]),
8600
8798
  [INPUT_IMAGE_DETAIL_FIELD]: normalizeInputImageDetail(value?.[INPUT_IMAGE_DETAIL_FIELD]),
8799
+ [REASONING_SUMMARY_FIELD]: normalizeReasoningSummary(value?.[REASONING_SUMMARY_FIELD]),
8800
+ [RETRY_POLICY_FIELD]: normalizeRetryPolicy(value?.[RETRY_POLICY_FIELD]),
8801
+ [CONNECTORS_FIELD]: normalizeConnectorMode(value?.[CONNECTORS_FIELD]),
8601
8802
  [STREAM_IDLE_TIMEOUT_MINUTES_FIELD]: normalizeStreamIdleTimeoutMinutes(value?.[STREAM_IDLE_TIMEOUT_MINUTES_FIELD]),
8602
8803
  [CONTEXT_MODE_FIELD]: normalizeContextMode(value?.[CONTEXT_MODE_FIELD]),
8603
8804
  [CUSTOM_CONTEXT_WINDOW_FIELD]: normalizeCustomContextWindow(value?.[CUSTOM_CONTEXT_WINDOW_FIELD]),
@@ -8986,7 +9187,6 @@ window.__ModuleLoader__.load({
8986
9187
  const NS = "settings.codexSubscription";
8987
9188
  const SUPPORT_ISSUE_URL = "https://github.com/WSL043/dsh-codex-subscription/issues/new?template=install-problem.yml";
8988
9189
  const QUICK_QUOTA_REFRESH_EVENT = "dsh-codex-subscription:refresh-quick-quota";
8989
- const QUICK_QUOTA_REFRESH_MS = 6e4;
8990
9190
  const accountStatusErrorText = (error, t) => {
8991
9191
  const key = {
8992
9192
  "credential-unavailable": "accountCredentialUnavailable",
@@ -9004,7 +9204,7 @@ window.__ModuleLoader__.load({
9004
9204
  if (local.length <= 2) return `${local.slice(0, 1)}••@${domain}`;
9005
9205
  return `${local[0]}•••${local.at(-1)}@${domain}`;
9006
9206
  };
9007
- const hours = (seconds) => Math.round(seconds / 3600 * 10) / 10;
9207
+ const hours$1 = (seconds) => Math.round(seconds / 3600 * 10) / 10;
9008
9208
  const percent = (value) => Number(value).toLocaleString(void 0, { maximumFractionDigits: 1 });
9009
9209
  const isApproximateWindow = (seconds, expected) => seconds >= expected * .95 && seconds <= expected * 1.05;
9010
9210
  const windowLabel = (seconds, t) => {
@@ -9013,7 +9213,7 @@ window.__ModuleLoader__.load({
9013
9213
  if (isApproximateWindow(seconds, 604800)) return t("windowWeekly");
9014
9214
  if (isApproximateWindow(seconds, 2592e3)) return t("windowMonthly");
9015
9215
  if (isApproximateWindow(seconds, 31536e3)) return t("windowAnnual");
9016
- return seconds >= 86400 && seconds % 86400 === 0 ? fill(t("windowDays"), { value: seconds / 86400 }) : fill(t("windowHours"), { value: hours(seconds) });
9216
+ return seconds >= 86400 && seconds % 86400 === 0 ? fill(t("windowDays"), { value: seconds / 86400 }) : fill(t("windowHours"), { value: hours$1(seconds) });
9017
9217
  };
9018
9218
  const validDate = (value) => {
9019
9219
  const date = new Date(value);
@@ -9082,7 +9282,7 @@ window.__ModuleLoader__.load({
9082
9282
  }
9083
9283
  //#endregion
9084
9284
  //#region src/version.js
9085
- const PACKAGE_VERSION = "3.0.0-beta.3";
9285
+ const PACKAGE_VERSION = "3.0.0-beta.5";
9086
9286
  //#endregion
9087
9287
  //#region src/client-recovery.js
9088
9288
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
@@ -9110,6 +9310,21 @@ window.__ModuleLoader__.load({
9110
9310
  };
9111
9311
  }
9112
9312
  //#endregion
9313
+ //#region src/quota-cadence.js
9314
+ /** Milliseconds until the next quota read, from the highest used percentage of the windows that matter. */
9315
+ function quotaRefreshMs(percent) {
9316
+ if (!Number.isFinite(percent)) return 6e4;
9317
+ if (percent >= 99) return 5e3;
9318
+ if (percent >= 90) return 15e3;
9319
+ if (percent >= 75) return 3e4;
9320
+ return 6e4;
9321
+ }
9322
+ /** Highest used percentage among windows (objects with usedPercent), or undefined when there are none. */
9323
+ function highestUsed(windows) {
9324
+ const values = (Array.isArray(windows) ? windows : []).map((window) => window?.usedPercent).filter(Number.isFinite);
9325
+ return values.length === 0 ? void 0 : Math.max(...values);
9326
+ }
9327
+ //#endregion
9113
9328
  //#region src/client-quota.jsx
9114
9329
  function useQuickQuota(rpc, enabled, model) {
9115
9330
  const [quota, setQuota] = (0, react.useState)();
@@ -9121,6 +9336,8 @@ window.__ModuleLoader__.load({
9121
9336
  setQuota(void 0);
9122
9337
  let live = true;
9123
9338
  let loading = false;
9339
+ let timer;
9340
+ let latest;
9124
9341
  const load = async () => {
9125
9342
  if (loading) return;
9126
9343
  loading = true;
@@ -9132,25 +9349,31 @@ window.__ModuleLoader__.load({
9132
9349
  return;
9133
9350
  }
9134
9351
  const usage = await recoveryCall(rpc, "usage", { force: false });
9135
- if (live) setQuota(selectModelQuotaWindows(usage, model)?.map((window) => ({
9352
+ const windows = selectModelQuotaWindows(usage, model)?.map((window) => ({
9136
9353
  ...window,
9137
9354
  fetchedAt: usage.fetchedAt
9138
- })));
9355
+ }));
9356
+ latest = windows;
9357
+ if (live) setQuota(windows);
9139
9358
  } catch {
9359
+ latest = void 0;
9140
9360
  if (live) setQuota(void 0);
9141
9361
  } finally {
9142
9362
  loading = false;
9363
+ if (live) {
9364
+ window.clearTimeout(timer);
9365
+ timer = window.setTimeout(refresh, quotaRefreshMs(highestUsed(latest)));
9366
+ }
9143
9367
  }
9144
9368
  };
9145
9369
  const refresh = () => {
9146
9370
  load();
9147
9371
  };
9148
9372
  load();
9149
- const timer = window.setInterval(refresh, QUICK_QUOTA_REFRESH_MS);
9150
9373
  window.addEventListener(QUICK_QUOTA_REFRESH_EVENT, refresh);
9151
9374
  return () => {
9152
9375
  live = false;
9153
- window.clearInterval(timer);
9376
+ window.clearTimeout(timer);
9154
9377
  window.removeEventListener(QUICK_QUOTA_REFRESH_EVENT, refresh);
9155
9378
  };
9156
9379
  }, [
@@ -9335,6 +9558,7 @@ window.__ModuleLoader__.load({
9335
9558
  const preferenceSnapshot = usePreferenceSnapshot(preference);
9336
9559
  const [open, setOpen] = (0, react.useState)(false);
9337
9560
  const [pane, setPane] = (0, react.useState)("root");
9561
+ const [query, setQuery] = (0, react.useState)("");
9338
9562
  const rootRef = (0, react.useRef)(null);
9339
9563
  const triggerRef = (0, react.useRef)(null);
9340
9564
  const id = (0, react.useId)();
@@ -9370,6 +9594,17 @@ window.__ModuleLoader__.load({
9370
9594
  ...effort.description === void 0 ? {} : { description: effort.description }
9371
9595
  }))], [reasoning, t]);
9372
9596
  const modelLabel = currentChoice?.model.name ?? t("selectModel");
9597
+ const searchable = visibleGroups.reduce((total, group) => total + group.models.length, 0) > 4;
9598
+ const needle = searchable ? query.trim().toLocaleLowerCase() : "";
9599
+ const shownGroups = needle === "" ? visibleGroups : visibleGroups.map((group) => ({
9600
+ ...group,
9601
+ models: group.models.filter((model) => [
9602
+ model.name,
9603
+ model.id,
9604
+ model.description,
9605
+ group.name
9606
+ ].some((text) => typeof text === "string" && text.toLocaleLowerCase().includes(needle)))
9607
+ })).filter((group) => group.models.length > 0);
9373
9608
  const speedSupported = state.current?.provider === "openai-codex" && (preferenceSnapshot.fastModels?.includes(state.current?.model) ?? supportsCodexFastMode(state.current?.model));
9374
9609
  const speedWritable = preferenceSnapshot.status === "ready" && preferenceSnapshot.writable === true;
9375
9610
  const ultrafastSupported = state.current?.provider === "openai-codex" && (preferenceSnapshot.ultrafastModels ?? []).includes(state.current?.model);
@@ -9411,11 +9646,15 @@ window.__ModuleLoader__.load({
9411
9646
  if (!rootRef.current?.contains(event.target)) {
9412
9647
  setOpen(false);
9413
9648
  setPane("root");
9649
+ setQuery("");
9414
9650
  }
9415
9651
  };
9416
9652
  document.addEventListener("mousedown", closeOutside);
9417
9653
  return () => document.removeEventListener("mousedown", closeOutside);
9418
9654
  }, [open]);
9655
+ (0, react.useEffect)(() => {
9656
+ if (pane !== "model") setQuery("");
9657
+ }, [pane]);
9419
9658
  (0, react.useEffect)(() => {
9420
9659
  if (!speedSupported && pane === "speed") setPane("root");
9421
9660
  if (!verbositySupported && pane === "verbosity") setPane("root");
@@ -9428,6 +9667,7 @@ window.__ModuleLoader__.load({
9428
9667
  const close = (restoreFocus = false) => {
9429
9668
  setOpen(false);
9430
9669
  setPane("root");
9670
+ setQuery("");
9431
9671
  if (restoreFocus) queueMicrotask(() => triggerRef.current?.focus());
9432
9672
  };
9433
9673
  const settleSelection = (accepted) => {
@@ -9503,7 +9743,7 @@ window.__ModuleLoader__.load({
9503
9743
  });
9504
9744
  let submenu = null;
9505
9745
  if (pane === "model") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9506
- className: "codexModelSelectSubmenu",
9746
+ className: "codexModelSelectSubmenu codexModelSelectModelMenu",
9507
9747
  role: "menu",
9508
9748
  "aria-label": t("modelLabel"),
9509
9749
  children: [
@@ -9527,9 +9767,18 @@ window.__ModuleLoader__.load({
9527
9767
  value: failure.message
9528
9768
  })
9529
9769
  }, failure.id)),
9770
+ searchable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
9771
+ className: "codexModelSelectSearch",
9772
+ type: "search",
9773
+ value: query,
9774
+ autoFocus: true,
9775
+ placeholder: t("modelSearch"),
9776
+ "aria-label": t("modelSearch"),
9777
+ onChange: (event) => setQuery(event.target.value)
9778
+ }) : null,
9530
9779
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9531
9780
  className: "codexModelSelectGroups scrollable",
9532
- children: visibleGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9781
+ children: shownGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
9533
9782
  className: "codexModelSelectGroup",
9534
9783
  role: "group",
9535
9784
  "aria-labelledby": `${id}-${group.id}`,
@@ -9560,6 +9809,10 @@ window.__ModuleLoader__.load({
9560
9809
  state.status === "ready" && visibleGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9561
9810
  className: "codexModelSelectEmpty",
9562
9811
  children: t(choices.length === 0 ? "modelsEmpty" : "modelsHidden")
9812
+ }) : null,
9813
+ state.status === "ready" && visibleGroups.length > 0 && shownGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9814
+ className: "codexModelSelectEmpty",
9815
+ children: t("modelNoMatch")
9563
9816
  }) : null
9564
9817
  ]
9565
9818
  });
@@ -12422,6 +12675,8 @@ window.__ModuleLoader__.load({
12422
12675
  const [busy, setBusy] = (0, react.useState)(false);
12423
12676
  const [failed, setFailed] = (0, react.useState)(false);
12424
12677
  const [now, setNow] = (0, react.useState)(Date.now());
12678
+ const [clients, setClients] = (0, react.useState)();
12679
+ const [removing, setRemoving] = (0, react.useState)();
12425
12680
  const alive = (0, react.useRef)(false);
12426
12681
  const on = snapshot.remoteControl === "on";
12427
12682
  const read = async () => {
@@ -12430,12 +12685,49 @@ window.__ModuleLoader__.load({
12430
12685
  if (alive.current && result.ok) setState(result.value);
12431
12686
  } catch {}
12432
12687
  };
12688
+ const readClients = async () => {
12689
+ try {
12690
+ const result = await rpc.call(CHANNEL, "remote/clients", {});
12691
+ if (alive.current && result.ok) setClients(result.value);
12692
+ } catch {}
12693
+ };
12433
12694
  (0, react.useEffect)(() => {
12434
12695
  alive.current = true;
12435
12696
  return () => {
12436
12697
  alive.current = false;
12437
12698
  };
12438
12699
  }, []);
12700
+ (0, react.useEffect)(() => {
12701
+ if (!on) {
12702
+ setClients(void 0);
12703
+ return;
12704
+ }
12705
+ let stopped = false, timer;
12706
+ const poll = async () => {
12707
+ await readClients();
12708
+ if (!stopped) timer = setTimeout(poll, 2e4);
12709
+ };
12710
+ poll();
12711
+ return () => {
12712
+ stopped = true;
12713
+ clearTimeout(timer);
12714
+ };
12715
+ }, [on, rpc]);
12716
+ const remove = async (client) => {
12717
+ if (removing) return;
12718
+ setRemoving(client.clientId);
12719
+ setFailed(false);
12720
+ try {
12721
+ const result = await rpc.call(CHANNEL, "remote/revoke", { clientId: client.clientId });
12722
+ if (!alive.current) return;
12723
+ if (result.ok) setClients(result.value);
12724
+ else setFailed(true);
12725
+ } catch {
12726
+ if (alive.current) setFailed(true);
12727
+ } finally {
12728
+ if (alive.current) setRemoving(void 0);
12729
+ }
12730
+ };
12439
12731
  (0, react.useEffect)(() => {
12440
12732
  if (!on) {
12441
12733
  setState(void 0);
@@ -12567,6 +12859,34 @@ window.__ModuleLoader__.load({
12567
12859
  className: "codexSubscriptionHelp",
12568
12860
  children: t("remoteExpired")
12569
12861
  }) : null,
12862
+ clients ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12863
+ className: "codexSubscriptionRemoteClients",
12864
+ role: "list",
12865
+ "aria-label": t("remotePaired"),
12866
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
12867
+ className: "codexSubscriptionPreferenceLabel",
12868
+ children: t("remotePaired")
12869
+ }), clients.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
12870
+ className: "codexSubscriptionHelp",
12871
+ children: t("remoteNoPhones")
12872
+ }) : clients.map((client) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12873
+ role: "listitem",
12874
+ className: "codexSubscriptionPreference",
12875
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: [
12876
+ client.name ?? t("remotePhoneUnknown"),
12877
+ client.platform,
12878
+ client.lastSeenAt ? t("remoteLastSeen").replace("{date}", new Date(client.lastSeenAt).toLocaleString()) : null
12879
+ ].filter(Boolean).join(" · ") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
12880
+ type: "button",
12881
+ variant: "outline",
12882
+ disabled: Boolean(removing),
12883
+ onClick: () => {
12884
+ remove(client);
12885
+ },
12886
+ children: t("remoteRevoke")
12887
+ })]
12888
+ }, client.clientId))]
12889
+ }) : null,
12570
12890
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
12571
12891
  className: "codexSubscriptionHelp",
12572
12892
  children: t("remoteLimits")
@@ -12760,6 +13080,115 @@ window.__ModuleLoader__.load({
12760
13080
  })]
12761
13081
  });
12762
13082
  }
13083
+ function ReasoningSummaryPreference({ preference, t }) {
13084
+ const snapshot = usePreferenceSnapshot(preference);
13085
+ const writable = snapshot.status === "ready" && snapshot.writable === true;
13086
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13087
+ className: "codexSubscriptionPreference",
13088
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13089
+ className: "codexSubscriptionPreferenceCopy",
13090
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13091
+ className: "codexSubscriptionPreferenceLabel",
13092
+ children: t("reasoningSummary")
13093
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13094
+ className: "codexSubscriptionPreferenceHint",
13095
+ children: t("reasoningSummaryHint")
13096
+ })]
13097
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13098
+ className: "codexSubscriptionQuotaModes",
13099
+ "data-saving": snapshot.saving || void 0,
13100
+ "aria-busy": snapshot.saving || void 0,
13101
+ role: "radiogroup",
13102
+ "aria-label": t("reasoningSummary"),
13103
+ children: REASONING_SUMMARIES.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13104
+ className: "codexSubscriptionQuotaMode",
13105
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13106
+ type: "radio",
13107
+ name: "codex-reasoning-summary",
13108
+ checked: snapshot.reasoningSummary === value,
13109
+ disabled: !writable,
13110
+ onChange: () => {
13111
+ preference.set({ [REASONING_SUMMARY_FIELD]: value });
13112
+ }
13113
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`reasoningSummary_${value}`) })]
13114
+ }, value))
13115
+ })]
13116
+ });
13117
+ }
13118
+ function RetryPolicyPreference({ preference, t }) {
13119
+ const snapshot = usePreferenceSnapshot(preference);
13120
+ const writable = snapshot.status === "ready" && snapshot.writable === true;
13121
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13122
+ className: "codexSubscriptionPreference",
13123
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13124
+ className: "codexSubscriptionPreferenceCopy",
13125
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13126
+ className: "codexSubscriptionPreferenceLabel",
13127
+ children: t("retryPolicy")
13128
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13129
+ className: "codexSubscriptionPreferenceHint",
13130
+ children: t("retryPolicyHint")
13131
+ })]
13132
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13133
+ className: "codexSubscriptionQuotaModes",
13134
+ "data-saving": snapshot.saving || void 0,
13135
+ "aria-busy": snapshot.saving || void 0,
13136
+ role: "radiogroup",
13137
+ "aria-label": t("retryPolicy"),
13138
+ children: RETRY_POLICIES.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13139
+ className: "codexSubscriptionQuotaMode",
13140
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13141
+ type: "radio",
13142
+ name: "codex-retry-policy",
13143
+ checked: snapshot.retryPolicy === value,
13144
+ disabled: !writable,
13145
+ onChange: () => {
13146
+ preference.set({ [RETRY_POLICY_FIELD]: value });
13147
+ }
13148
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`retryPolicy_${value}`) })]
13149
+ }, value))
13150
+ })]
13151
+ });
13152
+ }
13153
+ function ConnectorsPreference({ preference, t }) {
13154
+ const snapshot = usePreferenceSnapshot(preference);
13155
+ const writable = snapshot.status === "ready" && snapshot.writable === true;
13156
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13157
+ className: "codexSubscriptionPreference",
13158
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13159
+ className: "codexSubscriptionPreferenceCopy",
13160
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13161
+ className: "codexSubscriptionPreferenceLabel",
13162
+ children: [
13163
+ t("connectors"),
13164
+ " ",
13165
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13166
+ ]
13167
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13168
+ className: "codexSubscriptionPreferenceHint",
13169
+ children: t("connectorsHint")
13170
+ })]
13171
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13172
+ className: "codexSubscriptionQuotaModes",
13173
+ "data-saving": snapshot.saving || void 0,
13174
+ "aria-busy": snapshot.saving || void 0,
13175
+ role: "radiogroup",
13176
+ "aria-label": t("connectors"),
13177
+ children: CONNECTOR_MODES.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13178
+ className: "codexSubscriptionQuotaMode",
13179
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13180
+ type: "radio",
13181
+ name: "codex-connectors",
13182
+ checked: snapshot.connectors === value,
13183
+ disabled: !writable,
13184
+ onChange: () => {
13185
+ preference.set({ [CONNECTORS_FIELD]: value });
13186
+ }
13187
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`connectors_${value}`) })]
13188
+ }, value))
13189
+ })]
13190
+ });
13191
+ }
12763
13192
  function StreamIdleTimeoutPreference({ preference, t }) {
12764
13193
  const snapshot = usePreferenceSnapshot(preference);
12765
13194
  const writable = snapshot.status === "ready" && snapshot.writable === true;
@@ -13034,245 +13463,267 @@ window.__ModuleLoader__.load({
13034
13463
  const snapshot = usePreferenceSnapshot(preference);
13035
13464
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13036
13465
  className: section === "advanced" ? "codexSubscriptionAdvancedPreferences" : "codexSubscriptionCard codexSubscriptionPreferencesCard",
13037
- children: [section === "advanced" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13038
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13039
- className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13040
- "aria-label": t("modelsSectionTitle"),
13041
- children: [
13042
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("modelsSectionTitle") }),
13043
- defaultModel === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultModelPreference, {
13044
- preference,
13045
- defaultModel,
13046
- t
13047
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" })] }),
13048
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelCatalogStatus, {
13049
- preference,
13050
- t
13051
- }),
13052
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13053
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PickerModelsPreference, {
13054
- preference,
13055
- t
13056
- }),
13057
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13058
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextWindowPreference, {
13059
- preference,
13060
- t
13061
- }),
13062
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13063
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputImageDetailPreference, {
13466
+ children: [
13467
+ snapshot.restartRequired ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
13468
+ className: "codexSubscriptionError",
13469
+ role: "status",
13470
+ children: t("settingsRestartRequired")
13471
+ }) : null,
13472
+ section === "advanced" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13473
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13474
+ className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13475
+ "aria-label": t("modelsSectionTitle"),
13476
+ children: [
13477
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("modelsSectionTitle") }),
13478
+ defaultModel === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultModelPreference, {
13479
+ preference,
13480
+ defaultModel,
13481
+ t
13482
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" })] }),
13483
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelCatalogStatus, {
13484
+ preference,
13485
+ t
13486
+ }),
13487
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13488
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PickerModelsPreference, {
13489
+ preference,
13490
+ t
13491
+ }),
13492
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13493
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextWindowPreference, {
13494
+ preference,
13495
+ t
13496
+ }),
13497
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13498
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputImageDetailPreference, {
13499
+ preference,
13500
+ t
13501
+ }),
13502
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13503
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningSummaryPreference, {
13504
+ preference,
13505
+ t
13506
+ }),
13507
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13508
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RetryPolicyPreference, {
13509
+ preference,
13510
+ t
13511
+ }),
13512
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorsPreference, {
13513
+ preference,
13514
+ t
13515
+ })
13516
+ ]
13517
+ }),
13518
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13519
+ className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13520
+ "aria-label": t("searchSectionTitle"),
13521
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("searchSectionTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchProviderPreference, {
13064
13522
  preference,
13065
13523
  t
13524
+ })]
13525
+ }),
13526
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13527
+ className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13528
+ "aria-label": t("connectionTitle"),
13529
+ children: [
13530
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13531
+ className: "codexSubscriptionPreference",
13532
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13533
+ className: "codexSubscriptionPreferenceCopy",
13534
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13535
+ className: "codexSubscriptionPreferenceLabel",
13536
+ children: [
13537
+ t("connectionTitle"),
13538
+ " ",
13539
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13540
+ ]
13541
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13542
+ className: "codexSubscriptionPreferenceHint",
13543
+ children: t("connectionHint")
13544
+ })]
13545
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13546
+ className: "codexSubscriptionQuotaModes",
13547
+ role: "radiogroup",
13548
+ "aria-label": t("connectionTitle"),
13549
+ "aria-busy": snapshot.saving || void 0,
13550
+ children: ["sse", "websocket"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13551
+ className: "codexSubscriptionQuotaMode",
13552
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13553
+ type: "radio",
13554
+ name: "codex-connection-mode",
13555
+ checked: snapshot.connectionMode === value,
13556
+ disabled: !snapshot.writable,
13557
+ onChange: () => {
13558
+ preference.set({ connectionMode: value });
13559
+ }
13560
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: value === "sse" ? "SSE" : "WebSocket" })]
13561
+ }, value))
13562
+ })]
13563
+ }),
13564
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13565
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StreamIdleTimeoutPreference, {
13566
+ preference,
13567
+ t
13568
+ })
13569
+ ]
13570
+ }),
13571
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
13572
+ className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13573
+ "aria-label": t("reviewModelTitle"),
13574
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13575
+ className: "codexSubscriptionPreference",
13576
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13577
+ className: "codexSubscriptionPreferenceCopy",
13578
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13579
+ className: "codexSubscriptionPreferenceLabel",
13580
+ children: [
13581
+ t("reviewModelTitle"),
13582
+ " ",
13583
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13584
+ ]
13585
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13586
+ className: "codexSubscriptionPreferenceHint",
13587
+ children: t("reviewModelHint")
13588
+ })]
13589
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13590
+ className: "codexSubscriptionQuotaModes",
13591
+ role: "radiogroup",
13592
+ "aria-label": t("reviewModelTitle"),
13593
+ "aria-busy": snapshot.saving || void 0,
13594
+ children: ["session", "official"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13595
+ className: "codexSubscriptionQuotaMode",
13596
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13597
+ type: "radio",
13598
+ name: "codex-review-model",
13599
+ checked: snapshot.reviewModel === value,
13600
+ disabled: !snapshot.writable,
13601
+ onChange: () => {
13602
+ preference.set({ reviewModel: value });
13603
+ }
13604
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`reviewModel_${value}`) })]
13605
+ }, value))
13606
+ })]
13066
13607
  })
13067
- ]
13068
- }),
13069
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13070
- className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13071
- "aria-label": t("searchSectionTitle"),
13072
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("searchSectionTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchProviderPreference, {
13608
+ }),
13609
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RemoteControlCard, {
13610
+ rpc,
13073
13611
  preference,
13612
+ snapshot,
13074
13613
  t
13075
- })]
13076
- }),
13077
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13078
- className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13079
- "aria-label": t("connectionTitle"),
13080
- children: [
13081
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13614
+ }),
13615
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
13616
+ className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13617
+ "aria-label": t("compactionTitle"),
13618
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13082
13619
  className: "codexSubscriptionPreference",
13083
13620
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13084
13621
  className: "codexSubscriptionPreferenceCopy",
13085
13622
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13086
13623
  className: "codexSubscriptionPreferenceLabel",
13087
13624
  children: [
13088
- t("connectionTitle"),
13625
+ t("compactionTitle"),
13089
13626
  " ",
13090
13627
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13091
13628
  ]
13092
13629
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13093
13630
  className: "codexSubscriptionPreferenceHint",
13094
- children: t("connectionHint")
13631
+ children: t("compactionHint")
13095
13632
  })]
13096
13633
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13097
13634
  className: "codexSubscriptionQuotaModes",
13098
13635
  role: "radiogroup",
13099
- "aria-label": t("connectionTitle"),
13636
+ "aria-label": t("compactionTitle"),
13100
13637
  "aria-busy": snapshot.saving || void 0,
13101
- children: ["sse", "websocket"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13638
+ children: ["dsh", "cloud"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13102
13639
  className: "codexSubscriptionQuotaMode",
13103
13640
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13104
13641
  type: "radio",
13105
- name: "codex-connection-mode",
13106
- checked: snapshot.connectionMode === value,
13642
+ name: "codex-compaction-mode",
13643
+ checked: snapshot.compactionMode === value,
13107
13644
  disabled: !snapshot.writable,
13108
13645
  onChange: () => {
13109
- preference.set({ connectionMode: value });
13646
+ preference.set({ compactionMode: value });
13110
13647
  }
13111
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: value === "sse" ? "SSE" : "WebSocket" })]
13648
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`compaction_${value}`) })]
13112
13649
  }, value))
13113
13650
  })]
13114
- }),
13115
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13116
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StreamIdleTimeoutPreference, {
13117
- preference,
13118
- t
13119
13651
  })
13120
- ]
13121
- }),
13122
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
13123
- className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13124
- "aria-label": t("reviewModelTitle"),
13125
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13126
- className: "codexSubscriptionPreference",
13127
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13128
- className: "codexSubscriptionPreferenceCopy",
13129
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13130
- className: "codexSubscriptionPreferenceLabel",
13131
- children: [
13132
- t("reviewModelTitle"),
13133
- " ",
13134
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13135
- ]
13136
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13137
- className: "codexSubscriptionPreferenceHint",
13138
- children: t("reviewModelHint")
13139
- })]
13140
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13141
- className: "codexSubscriptionQuotaModes",
13142
- role: "radiogroup",
13143
- "aria-label": t("reviewModelTitle"),
13144
- "aria-busy": snapshot.saving || void 0,
13145
- children: ["session", "official"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13146
- className: "codexSubscriptionQuotaMode",
13147
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13148
- type: "radio",
13149
- name: "codex-review-model",
13150
- checked: snapshot.reviewModel === value,
13151
- disabled: !snapshot.writable,
13152
- onChange: () => {
13153
- preference.set({ reviewModel: value });
13154
- }
13155
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`reviewModel_${value}`) })]
13156
- }, value))
13157
- })]
13158
- })
13159
- }),
13160
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RemoteControlCard, {
13161
- rpc,
13162
- preference,
13163
- snapshot,
13164
- t
13165
- }),
13166
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
13167
- className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13168
- "aria-label": t("compactionTitle"),
13169
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13170
- className: "codexSubscriptionPreference",
13652
+ }),
13653
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13654
+ className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13655
+ "aria-label": t("subagentBackendTitle"),
13171
13656
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13172
- className: "codexSubscriptionPreferenceCopy",
13173
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13174
- className: "codexSubscriptionPreferenceLabel",
13175
- children: [
13176
- t("compactionTitle"),
13177
- " ",
13178
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13179
- ]
13180
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13181
- className: "codexSubscriptionPreferenceHint",
13182
- children: t("compactionHint")
13657
+ className: "codexSubscriptionPreference",
13658
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13659
+ className: "codexSubscriptionPreferenceCopy",
13660
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13661
+ className: "codexSubscriptionPreferenceLabel",
13662
+ children: [
13663
+ t("subagentBackendTitle"),
13664
+ " ",
13665
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13666
+ ]
13667
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13668
+ className: "codexSubscriptionPreferenceHint",
13669
+ children: t(snapshot.subagentBackendAvailable ? "subagentBackendHint" : "subagentBackendUnavailable")
13670
+ })]
13671
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13672
+ className: "codexSubscriptionQuotaModes",
13673
+ role: "radiogroup",
13674
+ "aria-label": t("subagentBackendTitle"),
13675
+ "aria-busy": snapshot.saving || void 0,
13676
+ children: ["dsh", "codex"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13677
+ className: "codexSubscriptionQuotaMode",
13678
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13679
+ type: "radio",
13680
+ name: "codex-subagent-backend",
13681
+ checked: snapshot.subagentBackend === value,
13682
+ disabled: !snapshot.writable || !snapshot.subagentBackendAvailable || value === "codex" && !snapshot.subagentRuntimeInstalled,
13683
+ onChange: () => {
13684
+ preference.set({ subagentBackend: value });
13685
+ }
13686
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`subagentBackend_${value}`) })]
13687
+ }, value))
13183
13688
  })]
13184
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13185
- className: "codexSubscriptionQuotaModes",
13186
- role: "radiogroup",
13187
- "aria-label": t("compactionTitle"),
13188
- "aria-busy": snapshot.saving || void 0,
13189
- children: ["dsh", "cloud"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13190
- className: "codexSubscriptionQuotaMode",
13191
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13192
- type: "radio",
13193
- name: "codex-compaction-mode",
13194
- checked: snapshot.compactionMode === value,
13195
- disabled: !snapshot.writable,
13196
- onChange: () => {
13197
- preference.set({ compactionMode: value });
13198
- }
13199
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`compaction_${value}`) })]
13200
- }, value))
13689
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RuntimeManagement, {
13690
+ rpc,
13691
+ preference,
13692
+ t
13201
13693
  })]
13202
13694
  })
13203
- }),
13204
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
13205
- className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
13206
- "aria-label": t("subagentBackendTitle"),
13207
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13208
- className: "codexSubscriptionPreference",
13209
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13210
- className: "codexSubscriptionPreferenceCopy",
13211
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
13212
- className: "codexSubscriptionPreferenceLabel",
13213
- children: [
13214
- t("subagentBackendTitle"),
13215
- " ",
13216
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
13217
- ]
13218
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13219
- className: "codexSubscriptionPreferenceHint",
13220
- children: t(snapshot.subagentBackendAvailable ? "subagentBackendHint" : "subagentBackendUnavailable")
13221
- })]
13222
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13223
- className: "codexSubscriptionQuotaModes",
13224
- role: "radiogroup",
13225
- "aria-label": t("subagentBackendTitle"),
13226
- "aria-busy": snapshot.saving || void 0,
13227
- children: ["dsh", "codex"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
13228
- className: "codexSubscriptionQuotaMode",
13229
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
13230
- type: "radio",
13231
- name: "codex-subagent-backend",
13232
- checked: snapshot.subagentBackend === value,
13233
- disabled: !snapshot.writable || !snapshot.subagentBackendAvailable || value === "codex" && !snapshot.subagentRuntimeInstalled,
13234
- onChange: () => {
13235
- preference.set({ subagentBackend: value });
13236
- }
13237
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`subagentBackend_${value}`) })]
13238
- }, value))
13239
- })]
13240
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RuntimeManagement, {
13241
- rpc,
13695
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13696
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuickQuotaPreference, {
13242
13697
  preference,
13243
13698
  t
13699
+ }),
13700
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CapabilityPreferences, {
13701
+ preference,
13702
+ t,
13703
+ section: "quota"
13704
+ }),
13705
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13706
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoQuotaRetryPreference, {
13707
+ preference,
13708
+ t
13709
+ })
13710
+ ] }),
13711
+ snapshot.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13712
+ className: "codexSubscriptionRecover",
13713
+ role: "alert",
13714
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
13715
+ className: "codexSubscriptionError",
13716
+ children: t("preferenceFailed")
13717
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
13718
+ type: "button",
13719
+ variant: "outline",
13720
+ onClick: () => {
13721
+ preference.retry();
13722
+ },
13723
+ children: t("preferenceRetry")
13244
13724
  })]
13245
- })
13246
- ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13247
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuickQuotaPreference, {
13248
- preference,
13249
- t
13250
- }),
13251
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CapabilityPreferences, {
13252
- preference,
13253
- t,
13254
- section: "quota"
13255
- }),
13256
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
13257
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoQuotaRetryPreference, {
13258
- preference,
13259
- t
13260
- })
13261
- ] }), snapshot.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13262
- className: "codexSubscriptionRecover",
13263
- role: "alert",
13264
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
13265
- className: "codexSubscriptionError",
13266
- children: t("preferenceFailed")
13267
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
13268
- type: "button",
13269
- variant: "outline",
13270
- onClick: () => {
13271
- preference.retry();
13272
- },
13273
- children: t("preferenceRetry")
13274
- })]
13275
- }) : null]
13725
+ }) : null
13726
+ ]
13276
13727
  });
13277
13728
  }
13278
13729
  //#endregion
@@ -13318,6 +13769,12 @@ window.__ModuleLoader__.load({
13318
13769
  }
13319
13770
  //#endregion
13320
13771
  //#region src/client-account.jsx
13772
+ const LOGIN_FAILURES = [
13773
+ "account-claim",
13774
+ "network",
13775
+ "token-exchange",
13776
+ "callback"
13777
+ ];
13321
13778
  function AccountEmail({ candidate, fallback, t, emailVisible, onClick }) {
13322
13779
  if (typeof candidate?.email !== "string" || candidate.email.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
13323
13780
  title: t("emailUnavailable"),
@@ -13677,7 +14134,7 @@ window.__ModuleLoader__.load({
13677
14134
  flow?.phase === "failed" || error !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
13678
14135
  className: "codexSubscriptionError",
13679
14136
  role: "alert",
13680
- children: error ?? t("failed")
14137
+ children: error ?? (LOGIN_FAILURES.includes(flow?.failure) ? t(`failed_${flow.failure.replace("-", "_")}`) : t("failed"))
13681
14138
  }) : null
13682
14139
  ]
13683
14140
  });
@@ -14130,6 +14587,276 @@ window.__ModuleLoader__.load({
14130
14587
  };
14131
14588
  }
14132
14589
  //#endregion
14590
+ //#region src/client-usage-overview.jsx
14591
+ const uiLocale = () => typeof document === "undefined" ? void 0 : document.documentElement.lang || void 0;
14592
+ const WEEKS = 26;
14593
+ const compact = (value) => new Intl.NumberFormat(uiLocale(), {
14594
+ notation: "compact",
14595
+ maximumFractionDigits: 1
14596
+ }).format(value);
14597
+ const hours = (seconds) => seconds >= 3600 ? `${Math.round(seconds / 360) / 10} h` : `${Math.max(1, Math.round(seconds / 60))} min`;
14598
+ const key = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
14599
+ function UsageHeatmap({ days, t }) {
14600
+ const byDate = new Map(days.map((day) => [day.date, day.tokens]));
14601
+ const today = /* @__PURE__ */ new Date();
14602
+ today.setHours(0, 0, 0, 0);
14603
+ const start = new Date(today);
14604
+ start.setDate(start.getDate() - ((WEEKS - 1) * 7 + today.getDay()));
14605
+ const cells = [];
14606
+ for (let index = 0; index < WEEKS * 7; index += 1) {
14607
+ const date = new Date(start);
14608
+ date.setDate(start.getDate() + index);
14609
+ if (date > today) break;
14610
+ cells.push({
14611
+ date: key(date),
14612
+ tokens: byDate.get(key(date)) ?? 0,
14613
+ column: Math.floor(index / 7),
14614
+ row: index % 7
14615
+ });
14616
+ }
14617
+ const busy = cells.map((cell) => cell.tokens).filter((tokens) => tokens > 0).sort((a, b) => a - b);
14618
+ const level = (tokens) => tokens === 0 ? 0 : 1 + [
14619
+ .25,
14620
+ .5,
14621
+ .75
14622
+ ].filter((point) => tokens > busy[Math.floor((busy.length - 1) * point)]).length;
14623
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
14624
+ className: "codexSubscriptionHeatmap",
14625
+ viewBox: `0 0 ${WEEKS * 14} 98`,
14626
+ role: "img",
14627
+ "aria-label": t("overviewHeatmap"),
14628
+ children: cells.map((cell) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
14629
+ x: cell.column * 14,
14630
+ y: cell.row * 14,
14631
+ width: "11",
14632
+ height: "11",
14633
+ rx: "2",
14634
+ "data-level": level(cell.tokens),
14635
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("title", { children: `${cell.date}: ${cell.tokens === 0 ? t("overviewNoUse") : fill(t("overviewTokens"), { value: compact(cell.tokens) })}` })
14636
+ }, cell.date))
14637
+ });
14638
+ }
14639
+ function UsageOverview({ rpc, t, signedIn, resetKey }) {
14640
+ const [open, setOpen] = (0, react.useState)(false);
14641
+ const [state, setState] = (0, react.useState)({ status: "idle" });
14642
+ const request = (0, react.useRef)(0);
14643
+ (0, react.useEffect)(() => {
14644
+ request.current += 1;
14645
+ setState({ status: "idle" });
14646
+ }, [signedIn, resetKey]);
14647
+ (0, react.useEffect)(() => {
14648
+ if (!open || !signedIn || state.status !== "idle") return;
14649
+ const id = ++request.current;
14650
+ setState({ status: "loading" });
14651
+ recoveryCall(rpc, "usage/profile", {}).then((value) => {
14652
+ if (request.current === id) setState({
14653
+ status: "ready",
14654
+ value
14655
+ });
14656
+ }).catch((error) => {
14657
+ if (request.current === id) setState({
14658
+ status: "error",
14659
+ message: error.message
14660
+ });
14661
+ });
14662
+ }, [
14663
+ open,
14664
+ signedIn,
14665
+ state.status,
14666
+ rpc
14667
+ ]);
14668
+ if (!signedIn) return null;
14669
+ const value = state.value;
14670
+ const stats = value === void 0 || value.available === false ? [] : [
14671
+ [t("overviewLifetime"), value.lifetimeTokens === void 0 ? void 0 : compact(value.lifetimeTokens)],
14672
+ [t("overviewPeak"), value.peakDailyTokens === void 0 ? void 0 : compact(value.peakDailyTokens)],
14673
+ [t("overviewStreak"), value.currentStreakDays === void 0 ? void 0 : fill(t("overviewDays"), { value: value.currentStreakDays })],
14674
+ [t("overviewLongestStreak"), value.longestStreakDays === void 0 ? void 0 : fill(t("overviewDays"), { value: value.longestStreakDays })],
14675
+ [t("overviewThreads"), value.totalThreads === void 0 ? void 0 : value.totalThreads.toLocaleString(uiLocale())],
14676
+ [t("overviewEffort"), value.mostUsedReasoningEffort === void 0 ? void 0 : `${value.mostUsedReasoningEffort}${value.mostUsedReasoningEffortPercent === void 0 ? "" : ` · ${value.mostUsedReasoningEffortPercent}%`}`],
14677
+ [t("overviewFast"), value.fastModePercent === void 0 ? void 0 : `${value.fastModePercent}%`],
14678
+ [t("overviewLongestTurn"), value.longestRunningTurnSeconds === void 0 ? void 0 : hours(value.longestRunningTurnSeconds)]
14679
+ ].filter(([, text]) => text !== void 0);
14680
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
14681
+ className: "codexSubscriptionHistory",
14682
+ onToggle: (event) => setOpen(event.currentTarget.open),
14683
+ children: [
14684
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("overviewTitle") }),
14685
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14686
+ "aria-live": "polite",
14687
+ children: [
14688
+ state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14689
+ className: "codexSubscriptionEmpty",
14690
+ role: "status",
14691
+ children: t("overviewLoading")
14692
+ }) : null,
14693
+ state.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14694
+ className: "codexSubscriptionError",
14695
+ role: "alert",
14696
+ children: state.message
14697
+ }) : null,
14698
+ state.status === "ready" && stats.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14699
+ className: "codexSubscriptionEmpty",
14700
+ role: "status",
14701
+ children: t("overviewUnavailable")
14702
+ }) : null
14703
+ ]
14704
+ }),
14705
+ stats.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
14706
+ className: "codexSubscriptionOverviewStats",
14707
+ children: stats.map(([label, text]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: text })] }, label))
14708
+ }), value.days.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageHeatmap, {
14709
+ days: value.days,
14710
+ t
14711
+ })] })
14712
+ ]
14713
+ });
14714
+ }
14715
+ //#endregion
14716
+ //#region src/client-usage-history.jsx
14717
+ const DIMENSIONS = [
14718
+ "model",
14719
+ "surface",
14720
+ "thread_source",
14721
+ "turn_trigger"
14722
+ ];
14723
+ const LABELS = /* @__PURE__ */ new Map([
14724
+ ["desktop_app", "historyDesktopApp"],
14725
+ ["cli", "historyCli"],
14726
+ ["ide_extension", "historyIde"],
14727
+ ["web", "historyWeb"],
14728
+ ["mobile", "historyMobile"],
14729
+ ["user", "historyUser"],
14730
+ ["subagent", "historySubagent"],
14731
+ ["memory_consolidation", "historyMemory"],
14732
+ ["review", "historyReview"],
14733
+ ["composer", "historyComposer"],
14734
+ ["automation", "historyAutomation"]
14735
+ ]);
14736
+ const day = (value) => new Date(value).toLocaleDateString(uiLocale(), {
14737
+ month: "numeric",
14738
+ day: "numeric"
14739
+ });
14740
+ const amount = (value) => value > 0 && value < .1 ? "<0.1" : (value >= 10 ? Math.round(value) : Math.round(value * 10) / 10).toLocaleString(uiLocale());
14741
+ const labelOf = (dimension, key, t) => dimension === "model" ? key : LABELS.has(key) ? t(LABELS.get(key)) : key.replaceAll("_", " ");
14742
+ function Rows({ dimension, rows, total, t }) {
14743
+ const top = Math.max(total, ...rows.map((row) => row.percent));
14744
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14745
+ className: "codexSubscriptionHistoryGroup",
14746
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", { children: t(`historyBy_${dimension}`) }), rows.toSorted((a, b) => b.percent - a.percent).map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14747
+ className: "codexSubscriptionHistoryRow",
14748
+ children: [
14749
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
14750
+ className: "codexSubscriptionHistoryKey",
14751
+ children: labelOf(dimension, row.key, t)
14752
+ }),
14753
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("progress", {
14754
+ max: top,
14755
+ value: row.percent,
14756
+ "aria-label": `${labelOf(dimension, row.key, t)} ${amount(row.percent)}%`
14757
+ }),
14758
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [amount(row.percent), "%"] })
14759
+ ]
14760
+ }, row.key))]
14761
+ });
14762
+ }
14763
+ function UsageHistory({ rpc, t, signedIn, resetKey }) {
14764
+ const [open, setOpen] = (0, react.useState)(false);
14765
+ const [state, setState] = (0, react.useState)({ status: "idle" });
14766
+ const [selected, setSelected] = (0, react.useState)(0);
14767
+ const request = (0, react.useRef)(0);
14768
+ (0, react.useEffect)(() => {
14769
+ request.current += 1;
14770
+ setState({ status: "idle" });
14771
+ setSelected(0);
14772
+ }, [signedIn, resetKey]);
14773
+ (0, react.useEffect)(() => {
14774
+ if (!open || !signedIn || state.status !== "idle") return;
14775
+ const id = ++request.current;
14776
+ setState({ status: "loading" });
14777
+ recoveryCall(rpc, "usage/history", {}).then((value) => {
14778
+ if (request.current === id) setState({
14779
+ status: "ready",
14780
+ value
14781
+ });
14782
+ }).catch((error) => {
14783
+ if (request.current === id) setState({
14784
+ status: "error",
14785
+ message: error.message
14786
+ });
14787
+ });
14788
+ }, [
14789
+ open,
14790
+ signedIn,
14791
+ state.status,
14792
+ rpc
14793
+ ]);
14794
+ if (!signedIn) return null;
14795
+ const value = state.value;
14796
+ const periods = (value?.periods ?? []).filter((period) => period.usedPercent !== void 0);
14797
+ const period = periods[Math.min(selected, Math.max(0, periods.length - 1))];
14798
+ const present = DIMENSIONS.filter((dimension) => period?.breakdowns?.[dimension]?.length > 0);
14799
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
14800
+ className: "codexSubscriptionHistory",
14801
+ onToggle: (event) => setOpen(event.currentTarget.open),
14802
+ children: [
14803
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("historyTitle") }),
14804
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14805
+ "aria-live": "polite",
14806
+ children: [
14807
+ state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14808
+ className: "codexSubscriptionEmpty",
14809
+ role: "status",
14810
+ children: t("historyLoading")
14811
+ }) : null,
14812
+ state.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14813
+ className: "codexSubscriptionError",
14814
+ role: "alert",
14815
+ children: state.message
14816
+ }) : null,
14817
+ state.status === "ready" && value.available === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14818
+ className: "codexSubscriptionEmpty",
14819
+ role: "status",
14820
+ children: t("historyUnavailable")
14821
+ }) : null,
14822
+ state.status === "ready" && value.available !== false && period === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14823
+ className: "codexSubscriptionEmpty",
14824
+ role: "status",
14825
+ children: t("historyEmpty")
14826
+ }) : null
14827
+ ]
14828
+ }),
14829
+ period === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
14830
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
14831
+ className: "codexSubscriptionHistoryPeriods",
14832
+ role: "group",
14833
+ "aria-label": t("historyPeriods"),
14834
+ children: periods.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
14835
+ type: "button",
14836
+ "aria-pressed": item === period,
14837
+ onClick: () => setSelected(index),
14838
+ children: `${day(item.startsAt)}–${day(item.endsAt)}`
14839
+ }, item.startsAt))
14840
+ }),
14841
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
14842
+ className: "codexSubscriptionHistorySummary",
14843
+ children: [fill(t("historyUsed"), { value: amount(period.usedPercent) }), period.complete ? "" : ` ${t("historyPartial")}`]
14844
+ }),
14845
+ present.map((dimension) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Rows, {
14846
+ dimension,
14847
+ rows: period.breakdowns[dimension],
14848
+ total: period.usedPercent,
14849
+ t
14850
+ }, dimension)),
14851
+ value.approximate ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14852
+ className: "codexSubscriptionCreditNote",
14853
+ children: t("historyApproximate")
14854
+ }) : null
14855
+ ] })
14856
+ ]
14857
+ });
14858
+ }
14859
+ //#endregion
14133
14860
  //#region src/client-usage.jsx
14134
14861
  const count = (value) => Number(value).toLocaleString();
14135
14862
  const creditAmount = (value) => Number.isFinite(Number(value)) && String(value).trim() !== "" ? Number(value).toLocaleString(void 0, { maximumFractionDigits: 2 }) : value;
@@ -14495,6 +15222,18 @@ window.__ModuleLoader__.load({
14495
15222
  ]
14496
15223
  }, `${limit.id}-${window.windowSeconds}-${index}`)))
14497
15224
  }),
15225
+ limits.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageOverview, {
15226
+ rpc,
15227
+ t,
15228
+ signedIn,
15229
+ resetKey
15230
+ }),
15231
+ limits.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageHistory, {
15232
+ rpc,
15233
+ t,
15234
+ signedIn,
15235
+ resetKey
15236
+ }),
14498
15237
  visibleUsage?.chatPass === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
14499
15238
  className: "codexSubscriptionLimits",
14500
15239
  children: visibleUsage.chatPass.windows.map((window, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {